aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6')
-rw-r--r--sources/shiboken6/.cmake.conf2
-rw-r--r--sources/shiboken6/ApiExtractor/CMakeLists.txt120
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaargument.cpp6
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaargument.h5
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp1052
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.h33
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp17
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h148
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaenum.cpp101
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaenum.h21
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafield.cpp4
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafield.h4
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.cpp203
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.h73
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.cpp437
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.h88
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang_enums.h3
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h15
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang_typedefs.h13
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetatype.cpp163
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetatype.h30
-rw-r--r--sources/shiboken6/ApiExtractor/addedfunction.cpp25
-rw-r--r--sources/shiboken6/ApiExtractor/addedfunction.h13
-rw-r--r--sources/shiboken6/ApiExtractor/addedfunction_p.h13
-rw-r--r--sources/shiboken6/ApiExtractor/anystringview_helpers.cpp56
-rw-r--r--sources/shiboken6/ApiExtractor/anystringview_helpers.h18
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractor.cpp363
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractor.h29
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorflags.h8
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorresult.cpp68
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorresult.h29
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorresultdata_p.h29
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp321
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h4
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.cpp102
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.h2
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp13
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangparser.h8
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangutils.cpp87
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangutils.h31
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp123
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/compilersupport.h4
-rw-r--r--sources/shiboken6/ApiExtractor/classdocumentation.cpp103
-rw-r--r--sources/shiboken6/ApiExtractor/classdocumentation.h14
-rw-r--r--sources/shiboken6/ApiExtractor/cmake_uninstall.cmake3
-rw-r--r--sources/shiboken6/ApiExtractor/codesnip.cpp4
-rw-r--r--sources/shiboken6/ApiExtractor/codesnip.h9
-rw-r--r--sources/shiboken6/ApiExtractor/complextypeentry.h8
-rw-r--r--sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp8
-rw-r--r--sources/shiboken6/ApiExtractor/conditionalstreamreader.h2
-rw-r--r--sources/shiboken6/ApiExtractor/configurabletypeentry.h28
-rw-r--r--sources/shiboken6/ApiExtractor/containertypeentry.h28
-rw-r--r--sources/shiboken6/ApiExtractor/customconversion.cpp10
-rw-r--r--sources/shiboken6/ApiExtractor/customconversion_typedefs.h5
-rw-r--r--sources/shiboken6/ApiExtractor/debughelpers_p.h56
-rw-r--r--sources/shiboken6/ApiExtractor/dependency.h4
-rw-r--r--sources/shiboken6/ApiExtractor/docparser.cpp125
-rw-r--r--sources/shiboken6/ApiExtractor/docparser.h23
-rw-r--r--sources/shiboken6/ApiExtractor/documentation.cpp6
-rw-r--r--sources/shiboken6/ApiExtractor/documentation.h14
-rw-r--r--sources/shiboken6/ApiExtractor/dotview.cpp6
-rw-r--r--sources/shiboken6/ApiExtractor/doxygenparser.cpp25
-rw-r--r--sources/shiboken6/ApiExtractor/doxygenparser.h2
-rw-r--r--sources/shiboken6/ApiExtractor/enclosingclassmixin.cpp4
-rw-r--r--sources/shiboken6/ApiExtractor/enclosingclassmixin.h13
-rw-r--r--sources/shiboken6/ApiExtractor/enumtypeentry.h8
-rw-r--r--sources/shiboken6/ApiExtractor/fileout.cpp2
-rw-r--r--sources/shiboken6/ApiExtractor/fileout.h2
-rw-r--r--sources/shiboken6/ApiExtractor/flagstypeentry.h1
-rw-r--r--sources/shiboken6/ApiExtractor/functiontypeentry.h5
-rw-r--r--sources/shiboken6/ApiExtractor/icecc.cmake3
-rw-r--r--sources/shiboken6/ApiExtractor/include.cpp19
-rw-r--r--sources/shiboken6/ApiExtractor/include.h53
-rw-r--r--sources/shiboken6/ApiExtractor/messages.cpp189
-rw-r--r--sources/shiboken6/ApiExtractor/messages.h41
-rw-r--r--sources/shiboken6/ApiExtractor/modifications.cpp42
-rw-r--r--sources/shiboken6/ApiExtractor/modifications.h25
-rw-r--r--sources/shiboken6/ApiExtractor/modifications_typedefs.h5
-rw-r--r--sources/shiboken6/ApiExtractor/optionsparser.cpp232
-rw-r--r--sources/shiboken6/ApiExtractor/optionsparser.h98
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel.cpp313
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel.h170
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel_enums.h15
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h31
-rw-r--r--sources/shiboken6/ApiExtractor/parser/enumvalue.cpp46
-rw-r--r--sources/shiboken6/ApiExtractor/parser/enumvalue.h18
-rw-r--r--sources/shiboken6/ApiExtractor/parser/typeinfo.cpp60
-rw-r--r--sources/shiboken6/ApiExtractor/parser/typeinfo.h26
-rw-r--r--sources/shiboken6/ApiExtractor/predefined_templates.cpp61
-rw-r--r--sources/shiboken6/ApiExtractor/predefined_templates.h4
-rw-r--r--sources/shiboken6/ApiExtractor/propertyspec.cpp29
-rw-r--r--sources/shiboken6/ApiExtractor/propertyspec.h9
-rw-r--r--sources/shiboken6/ApiExtractor/pymethoddefentry.cpp9
-rw-r--r--sources/shiboken6/ApiExtractor/pymethoddefentry.h9
-rw-r--r--sources/shiboken6/ApiExtractor/qtcompat.h2
-rw-r--r--sources/shiboken6/ApiExtractor/qtdocparser.cpp162
-rw-r--r--sources/shiboken6/ApiExtractor/qtdocparser.h12
-rw-r--r--sources/shiboken6/ApiExtractor/reporthandler.cpp23
-rw-r--r--sources/shiboken6/ApiExtractor/tests/CMakeLists.txt3
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp114
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp20
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp135
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp14
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp20
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testcontainer.cpp10
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp32
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp30
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testctorinformation.cpp14
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp68
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testdtorinformation.cpp34
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testenum.cpp34
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testextrainclude.cpp10
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp10
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp26
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testinserttemplate.cpp8
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp14
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp104
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp4
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testnamespace.cpp20
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp23
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp4
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.cpp6
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp16
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp8
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testremovefield.cpp43
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testremovefield.h1
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp8
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp49
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testresolvetype.cpp40
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp22
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testtemplates.cpp116
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp10
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testutil.h6
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.cpp6
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp24
-rw-r--r--sources/shiboken6/ApiExtractor/textstream.h36
-rw-r--r--sources/shiboken6/ApiExtractor/typedatabase.cpp395
-rw-r--r--sources/shiboken6/ApiExtractor/typedatabase.h37
-rw-r--r--sources/shiboken6/ApiExtractor/typedatabase_p.h3
-rw-r--r--sources/shiboken6/ApiExtractor/typeparser.cpp16
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.cpp249
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem_enums.h1
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem_typedefs.h79
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp1068
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser_p.h33
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemtypeentry.h10
-rw-r--r--sources/shiboken6/ApiExtractor/usingmember.h2
-rw-r--r--sources/shiboken6/ApiExtractor/xmlutils.cpp4
-rw-r--r--sources/shiboken6/ApiExtractor/xmlutils.h7
-rw-r--r--sources/shiboken6/ApiExtractor/xmlutils_libxslt.cpp21
-rw-r--r--sources/shiboken6/ApiExtractor/xmlutils_libxslt.h5
-rw-r--r--sources/shiboken6/ApiExtractor/xmlutils_qt.h5
-rw-r--r--sources/shiboken6/CMakeLists.txt8
-rw-r--r--sources/shiboken6/cmake/FindDocTools.cmake3
-rw-r--r--sources/shiboken6/cmake/ShibokenHelpers.cmake307
-rw-r--r--sources/shiboken6/cmake/ShibokenSetup.cmake21
-rw-r--r--sources/shiboken6/cmake_uninstall.cmake3
-rw-r--r--sources/shiboken6/config.tests/target_python_info/CMakeLists.txt3
-rw-r--r--sources/shiboken6/config.tests/target_qt_info/CMakeLists.txt3
-rw-r--r--sources/shiboken6/config.tests/target_qt_mkspec/CMakeLists.txt3
-rw-r--r--sources/shiboken6/data/CMakeLists.txt3
-rw-r--r--sources/shiboken6/data/Shiboken6Config-spec.cmake.in8
-rw-r--r--sources/shiboken6/data/Shiboken6ToolsConfig.cmake.in2
-rw-r--r--sources/shiboken6/data/shiboken6.pc.in6
-rw-r--r--sources/shiboken6/doc/CMakeLists.txt5
-rw-r--r--sources/shiboken6/doc/_static/css/qt_font.css8
-rw-r--r--sources/shiboken6/doc/_static/css/qt_style.css117
-rw-r--r--sources/shiboken6/doc/_static/shiboken.pngbin0 -> 17343 bytes
-rw-r--r--sources/shiboken6/doc/_static/shiboken.svg129
-rw-r--r--sources/shiboken6/doc/_themes/pysidedocs_qthelp/static/pyside.css8
-rw-r--r--sources/shiboken6/doc/conf.py.in72
-rw-r--r--sources/shiboken6/doc/considerations.rst70
-rw-r--r--sources/shiboken6/doc/examples/index.rst18
-rw-r--r--sources/shiboken6/doc/examples/samplebinding.rst246
-rw-r--r--sources/shiboken6/doc/gettingstarted.rst12
-rw-r--r--sources/shiboken6/doc/images/boostgen.pngbin153473 -> 0 bytes
-rw-r--r--sources/shiboken6/doc/images/converter.pngbin22467 -> 34204 bytes
-rw-r--r--sources/shiboken6/doc/images/converter.svg2522
-rw-r--r--sources/shiboken6/doc/images/genrunnerarch.pngbin68761 -> 0 bytes
-rw-r--r--sources/shiboken6/doc/images/genrunnerarch.svg654
-rw-r--r--sources/shiboken6/doc/images/qtforpython-underthehood.pngbin19144 -> 62001 bytes
-rw-r--r--sources/shiboken6/doc/images/qtforpython-underthehood.svg1502
-rw-r--r--sources/shiboken6/doc/images/shibokenqtarch.pngbin17602 -> 28655 bytes
-rw-r--r--sources/shiboken6/doc/images/shibokenqtarch.svg71
-rw-r--r--sources/shiboken6/doc/index.rst112
-rw-r--r--sources/shiboken6/doc/shiboken-genpyi.rst32
-rw-r--r--sources/shiboken6/doc/shibokengenerator.rst80
-rw-r--r--sources/shiboken6/doc/shibokenmodule.rst37
-rw-r--r--sources/shiboken6/doc/typediscovery.rst145
-rw-r--r--sources/shiboken6/doc/typesystem.rst1
-rw-r--r--sources/shiboken6/doc/typesystem_arguments.rst272
-rw-r--r--sources/shiboken6/doc/typesystem_builtin_types.rst14
-rw-r--r--sources/shiboken6/doc/typesystem_codeinjection.rst379
-rw-r--r--sources/shiboken6/doc/typesystem_containers.rst114
-rw-r--r--sources/shiboken6/doc/typesystem_conversionrule.rst184
-rw-r--r--sources/shiboken6/doc/typesystem_converters.rst285
-rw-r--r--sources/shiboken6/doc/typesystem_documentation.rst63
-rw-r--r--sources/shiboken6/doc/typesystem_manipulating_objects.rst692
-rw-r--r--sources/shiboken6/doc/typesystem_modify_function.rst68
-rw-r--r--sources/shiboken6/doc/typesystem_ownership.rst190
-rw-r--r--sources/shiboken6/doc/typesystem_solving_compilation.rst96
-rw-r--r--sources/shiboken6/doc/typesystem_specialfunctions.rst22
-rw-r--r--sources/shiboken6/doc/typesystem_specifying_types.rst1223
-rw-r--r--sources/shiboken6/doc/typesystem_templates.rst145
-rw-r--r--sources/shiboken6/doc/typesystem_variables.rst180
-rw-r--r--sources/shiboken6/generator/CMakeLists.txt43
-rw-r--r--sources/shiboken6/generator/_config.py.in1
-rw-r--r--sources/shiboken6/generator/defaultvalue.cpp4
-rw-r--r--sources/shiboken6/generator/generator.cpp172
-rw-r--r--sources/shiboken6/generator/generator.h48
-rw-r--r--sources/shiboken6/generator/generatorcontext.h8
-rw-r--r--sources/shiboken6/generator/main.cpp831
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp990
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.h76
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp272
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinx.h24
-rw-r--r--sources/shiboken6/generator/qtdoc/rstformat.h22
-rw-r--r--sources/shiboken6/generator/shiboken/configurablescope.h33
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp2916
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h340
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator_container.cpp140
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp474
-rw-r--r--sources/shiboken6/generator/shiboken/ctypenames.h40
-rw-r--r--sources/shiboken6/generator/shiboken/generatorstrings.h39
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.cpp580
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.h51
-rw-r--r--sources/shiboken6/generator/shiboken/overloaddata.cpp86
-rw-r--r--sources/shiboken6/generator/shiboken/overloaddata.h7
-rw-r--r--sources/shiboken6/generator/shiboken/pytypenames.h26
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp873
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.h188
-rw-r--r--sources/shiboken6/generators/shiboken/shiboken.cpp7
-rw-r--r--sources/shiboken6/icecc.cmake3
-rw-r--r--sources/shiboken6/libshiboken/CMakeLists.txt68
-rw-r--r--sources/shiboken6/libshiboken/autodecref.h51
-rw-r--r--sources/shiboken6/libshiboken/basewrapper.cpp533
-rw-r--r--sources/shiboken6/libshiboken/basewrapper.h104
-rw-r--r--sources/shiboken6/libshiboken/basewrapper_p.h117
-rw-r--r--sources/shiboken6/libshiboken/bindingmanager.cpp373
-rw-r--r--sources/shiboken6/libshiboken/bindingmanager.h28
-rw-r--r--sources/shiboken6/libshiboken/bufferprocs_py37.h4
-rw-r--r--sources/shiboken6/libshiboken/debugfreehook.cpp4
-rw-r--r--sources/shiboken6/libshiboken/embed/embedding_generator.py21
-rw-r--r--sources/shiboken6/libshiboken/embed/signature_bootstrap.py75
-rw-r--r--sources/shiboken6/libshiboken/helper.cpp248
-rw-r--r--sources/shiboken6/libshiboken/helper.h9
-rw-r--r--sources/shiboken6/libshiboken/pep384_issue33738.cpp121
-rw-r--r--sources/shiboken6/libshiboken/pep384ext.h89
-rw-r--r--sources/shiboken6/libshiboken/pep384impl.cpp416
-rw-r--r--sources/shiboken6/libshiboken/pep384impl.h110
-rw-r--r--sources/shiboken6/libshiboken/pyobjectholder.h86
-rw-r--r--sources/shiboken6/libshiboken/sbkarrayconverter.cpp6
-rw-r--r--sources/shiboken6/libshiboken/sbkarrayconverter.h6
-rw-r--r--sources/shiboken6/libshiboken/sbkarrayconverter_p.h2
-rw-r--r--sources/shiboken6/libshiboken/sbkcontainer.cpp7
-rw-r--r--sources/shiboken6/libshiboken/sbkcontainer.h81
-rw-r--r--sources/shiboken6/libshiboken/sbkconverter.cpp173
-rw-r--r--sources/shiboken6/libshiboken/sbkconverter.h14
-rw-r--r--sources/shiboken6/libshiboken/sbkconverter_p.h18
-rw-r--r--sources/shiboken6/libshiboken/sbkcppstring.cpp5
-rw-r--r--sources/shiboken6/libshiboken/sbkcppstring.h2
-rw-r--r--sources/shiboken6/libshiboken/sbkcpptonumpy.cpp6
-rw-r--r--sources/shiboken6/libshiboken/sbkenum.cpp1140
-rw-r--r--sources/shiboken6/libshiboken/sbkenum.h139
-rw-r--r--sources/shiboken6/libshiboken/sbkenum_p.h53
-rw-r--r--sources/shiboken6/libshiboken/sbkerrors.cpp100
-rw-r--r--sources/shiboken6/libshiboken/sbkerrors.h37
-rw-r--r--sources/shiboken6/libshiboken/sbkfeature_base.cpp306
-rw-r--r--sources/shiboken6/libshiboken/sbkmodule.cpp465
-rw-r--r--sources/shiboken6/libshiboken/sbkmodule.h36
-rw-r--r--sources/shiboken6/libshiboken/sbknumpy.cpp18
-rw-r--r--sources/shiboken6/libshiboken/sbknumpyarrayconverter.cpp19
-rw-r--r--sources/shiboken6/libshiboken/sbknumpyview.cpp102
-rw-r--r--sources/shiboken6/libshiboken/sbknumpyview.h2
-rw-r--r--sources/shiboken6/libshiboken/sbksmartpointer.cpp58
-rw-r--r--sources/shiboken6/libshiboken/sbksmartpointer.h18
-rw-r--r--sources/shiboken6/libshiboken/sbkstaticstrings.cpp2
-rw-r--r--sources/shiboken6/libshiboken/sbkstaticstrings.h1
-rw-r--r--sources/shiboken6/libshiboken/sbkstring.cpp18
-rw-r--r--sources/shiboken6/libshiboken/sbkstring.h3
-rw-r--r--sources/shiboken6/libshiboken/sbktypefactory.cpp69
-rw-r--r--sources/shiboken6/libshiboken/sbkversion.h.in6
-rw-r--r--sources/shiboken6/libshiboken/sbkwindows.h17
-rw-r--r--sources/shiboken6/libshiboken/shiboken.h2
-rw-r--r--sources/shiboken6/libshiboken/signature.h1
-rw-r--r--sources/shiboken6/libshiboken/signature/signature.cpp33
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_extend.cpp40
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_globals.cpp20
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_helper.cpp41
-rw-r--r--sources/shiboken6/libshiboken/signature_p.h7
-rw-r--r--sources/shiboken6/libshiboken/voidptr.cpp69
-rw-r--r--sources/shiboken6/shibokenmodule/CMakeLists.txt12
-rw-r--r--sources/shiboken6/shibokenmodule/Shiboken.pyi3
-rw-r--r--sources/shiboken6/shibokenmodule/_config.py.in1
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/feature.py27
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/fix-complaints.py4
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py18
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py4
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py24
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py34
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py47
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py8
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/loader.py35
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py131
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py52
-rw-r--r--sources/shiboken6/shibokenmodule/shibokenmodule.cpp119
-rw-r--r--sources/shiboken6/shibokenmodule/typesystem_shiboken.xml119
-rw-r--r--sources/shiboken6/tests/CMakeLists.txt17
-rw-r--r--sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt3
-rw-r--r--sources/shiboken6/tests/dumpcodemodel/main.cpp14
-rw-r--r--sources/shiboken6/tests/libminimal/CMakeLists.txt14
-rw-r--r--sources/shiboken6/tests/libminimal/containeruser.cpp55
-rw-r--r--sources/shiboken6/tests/libminimal/containeruser.h36
-rw-r--r--sources/shiboken6/tests/libminimal/libminimalmacros.h24
-rw-r--r--sources/shiboken6/tests/libminimal/listuser.cpp44
-rw-r--r--sources/shiboken6/tests/libminimal/listuser.h12
-rw-r--r--sources/shiboken6/tests/libminimal/minbool.h11
-rw-r--r--sources/shiboken6/tests/libminimal/obj.cpp5
-rw-r--r--sources/shiboken6/tests/libminimal/obj.h6
-rw-r--r--sources/shiboken6/tests/libminimal/spanuser.cpp58
-rw-r--r--sources/shiboken6/tests/libminimal/spanuser.h35
-rw-r--r--sources/shiboken6/tests/libminimal/val.h6
-rw-r--r--sources/shiboken6/tests/libother/CMakeLists.txt17
-rw-r--r--sources/shiboken6/tests/libother/extendsnoimplicitconversion.h3
-rw-r--r--sources/shiboken6/tests/libother/number.cpp20
-rw-r--r--sources/shiboken6/tests/libother/number.h4
-rw-r--r--sources/shiboken6/tests/libother/otherderived.cpp16
-rw-r--r--sources/shiboken6/tests/libother/otherderived.h16
-rw-r--r--sources/shiboken6/tests/libother/othermultiplederived.cpp11
-rw-r--r--sources/shiboken6/tests/libother/othermultiplederived.h6
-rw-r--r--sources/shiboken6/tests/libother/otherobjecttype.cpp5
-rw-r--r--sources/shiboken6/tests/libother/otherobjecttype.h8
-rw-r--r--sources/shiboken6/tests/libother/smartptrtester.cpp2
-rw-r--r--sources/shiboken6/tests/libsample/CMakeLists.txt140
-rw-r--r--sources/shiboken6/tests/libsample/abstract.cpp69
-rw-r--r--sources/shiboken6/tests/libsample/abstract.h32
-rw-r--r--sources/shiboken6/tests/libsample/blackbox.cpp71
-rw-r--r--sources/shiboken6/tests/libsample/blackbox.h22
-rw-r--r--sources/shiboken6/tests/libsample/bucket.cpp26
-rw-r--r--sources/shiboken6/tests/libsample/bucket.h6
-rw-r--r--sources/shiboken6/tests/libsample/bytearray.cpp110
-rw-r--r--sources/shiboken6/tests/libsample/bytearray.h67
-rw-r--r--sources/shiboken6/tests/libsample/collector.cpp8
-rw-r--r--sources/shiboken6/tests/libsample/collector.h20
-rw-r--r--sources/shiboken6/tests/libsample/complex.cpp15
-rw-r--r--sources/shiboken6/tests/libsample/complex.h10
-rw-r--r--sources/shiboken6/tests/libsample/ctorconvrule.h6
-rw-r--r--sources/shiboken6/tests/libsample/cvlist.h6
-rw-r--r--sources/shiboken6/tests/libsample/derived.cpp38
-rw-r--r--sources/shiboken6/tests/libsample/derived.h22
-rw-r--r--sources/shiboken6/tests/libsample/echo.h18
-rw-r--r--sources/shiboken6/tests/libsample/expression.cpp83
-rw-r--r--sources/shiboken6/tests/libsample/expression.h29
-rw-r--r--sources/shiboken6/tests/libsample/filter.cpp12
-rw-r--r--sources/shiboken6/tests/libsample/filter.h22
-rw-r--r--sources/shiboken6/tests/libsample/functions.cpp115
-rw-r--r--sources/shiboken6/tests/libsample/functions.h27
-rw-r--r--sources/shiboken6/tests/libsample/handle.cpp8
-rw-r--r--sources/shiboken6/tests/libsample/handle.h30
-rw-r--r--sources/shiboken6/tests/libsample/implicitconv.cpp20
-rw-r--r--sources/shiboken6/tests/libsample/implicitconv.h24
-rw-r--r--sources/shiboken6/tests/libsample/injectcode.cpp33
-rw-r--r--sources/shiboken6/tests/libsample/injectcode.h26
-rw-r--r--sources/shiboken6/tests/libsample/list.h42
-rw-r--r--sources/shiboken6/tests/libsample/listuser.cpp28
-rw-r--r--sources/shiboken6/tests/libsample/listuser.h15
-rw-r--r--sources/shiboken6/tests/libsample/main.cpp220
-rw-r--r--sources/shiboken6/tests/libsample/mapuser.cpp34
-rw-r--r--sources/shiboken6/tests/libsample/mapuser.h17
-rw-r--r--sources/shiboken6/tests/libsample/modelindex.h13
-rw-r--r--sources/shiboken6/tests/libsample/modifications.cpp49
-rw-r--r--sources/shiboken6/tests/libsample/modifications.h30
-rw-r--r--sources/shiboken6/tests/libsample/modified_constructor.cpp3
-rw-r--r--sources/shiboken6/tests/libsample/modified_constructor.h4
-rw-r--r--sources/shiboken6/tests/libsample/multiple_derived.cpp33
-rw-r--r--sources/shiboken6/tests/libsample/multiple_derived.h134
-rw-r--r--sources/shiboken6/tests/libsample/noimplicitconversion.h9
-rw-r--r--sources/shiboken6/tests/libsample/nondefaultctor.h14
-rw-r--r--sources/shiboken6/tests/libsample/nontypetemplate.h4
-rw-r--r--sources/shiboken6/tests/libsample/null.h8
-rw-r--r--sources/shiboken6/tests/libsample/objectmodel.cpp6
-rw-r--r--sources/shiboken6/tests/libsample/objectmodel.h10
-rw-r--r--sources/shiboken6/tests/libsample/objecttype.cpp115
-rw-r--r--sources/shiboken6/tests/libsample/objecttype.h94
-rw-r--r--sources/shiboken6/tests/libsample/objecttypebyvalue.h6
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeholder.cpp12
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeholder.h12
-rw-r--r--sources/shiboken6/tests/libsample/objecttypelayout.cpp16
-rw-r--r--sources/shiboken6/tests/libsample/objecttypelayout.h13
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeoperators.cpp12
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeoperators.h22
-rw-r--r--sources/shiboken6/tests/libsample/objectview.cpp13
-rw-r--r--sources/shiboken6/tests/libsample/objectview.h16
-rw-r--r--sources/shiboken6/tests/libsample/oddbool.cpp2
-rw-r--r--sources/shiboken6/tests/libsample/oddbool.h12
-rw-r--r--sources/shiboken6/tests/libsample/onlycopy.cpp30
-rw-r--r--sources/shiboken6/tests/libsample/onlycopy.h18
-rw-r--r--sources/shiboken6/tests/libsample/overload.cpp6
-rw-r--r--sources/shiboken6/tests/libsample/overload.h18
-rw-r--r--sources/shiboken6/tests/libsample/overloadsort.h11
-rw-r--r--sources/shiboken6/tests/libsample/pairuser.cpp20
-rw-r--r--sources/shiboken6/tests/libsample/pairuser.h12
-rw-r--r--sources/shiboken6/tests/libsample/pen.cpp10
-rw-r--r--sources/shiboken6/tests/libsample/pen.h10
-rw-r--r--sources/shiboken6/tests/libsample/photon.cpp14
-rw-r--r--sources/shiboken6/tests/libsample/photon.h61
-rw-r--r--sources/shiboken6/tests/libsample/point.cpp79
-rw-r--r--sources/shiboken6/tests/libsample/point.h62
-rw-r--r--sources/shiboken6/tests/libsample/pointerholder.h13
-rw-r--r--sources/shiboken6/tests/libsample/pointf.cpp65
-rw-r--r--sources/shiboken6/tests/libsample/pointf.h52
-rw-r--r--sources/shiboken6/tests/libsample/polygon.cpp25
-rw-r--r--sources/shiboken6/tests/libsample/polygon.h16
-rw-r--r--sources/shiboken6/tests/libsample/privatector.h12
-rw-r--r--sources/shiboken6/tests/libsample/privatedtor.h19
-rw-r--r--sources/shiboken6/tests/libsample/protected.h81
-rw-r--r--sources/shiboken6/tests/libsample/rect.h53
-rw-r--r--sources/shiboken6/tests/libsample/reference.cpp30
-rw-r--r--sources/shiboken6/tests/libsample/reference.h42
-rw-r--r--sources/shiboken6/tests/libsample/removednamespaces.h1
-rw-r--r--sources/shiboken6/tests/libsample/sample.cpp2
-rw-r--r--sources/shiboken6/tests/libsample/sample.h4
-rw-r--r--sources/shiboken6/tests/libsample/samplenamespace.cpp66
-rw-r--r--sources/shiboken6/tests/libsample/samplenamespace.h38
-rw-r--r--sources/shiboken6/tests/libsample/sbkdate.h3
-rw-r--r--sources/shiboken6/tests/libsample/simplefile.cpp70
-rw-r--r--sources/shiboken6/tests/libsample/simplefile.h19
-rw-r--r--sources/shiboken6/tests/libsample/size.cpp9
-rw-r--r--sources/shiboken6/tests/libsample/size.h67
-rw-r--r--sources/shiboken6/tests/libsample/sometime.cpp26
-rw-r--r--sources/shiboken6/tests/libsample/sometime.h27
-rw-r--r--sources/shiboken6/tests/libsample/stdcomplex.cpp32
-rw-r--r--sources/shiboken6/tests/libsample/stdcomplex.h55
-rw-r--r--sources/shiboken6/tests/libsample/str.cpp86
-rw-r--r--sources/shiboken6/tests/libsample/str.h31
-rw-r--r--sources/shiboken6/tests/libsample/strlist.cpp6
-rw-r--r--sources/shiboken6/tests/libsample/strlist.h29
-rw-r--r--sources/shiboken6/tests/libsample/templateptr.h9
-rw-r--r--sources/shiboken6/tests/libsample/transform.cpp34
-rw-r--r--sources/shiboken6/tests/libsample/transform.h12
-rw-r--r--sources/shiboken6/tests/libsample/valueandvirtual.h12
-rw-r--r--sources/shiboken6/tests/libsample/virtualmethods.cpp9
-rw-r--r--sources/shiboken6/tests/libsample/virtualmethods.h40
-rw-r--r--sources/shiboken6/tests/libsample/voidholder.h17
-rw-r--r--sources/shiboken6/tests/libsmart/CMakeLists.txt17
-rw-r--r--sources/shiboken6/tests/libsmart/smart_integer.h5
-rw-r--r--sources/shiboken6/tests/libsmart/smart_obj.h4
-rw-r--r--sources/shiboken6/tests/libsmart/smart_sharedptr.h7
-rw-r--r--sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp20
-rw-r--r--sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h5
-rw-r--r--sources/shiboken6/tests/minimalbinding/CMakeLists.txt5
-rw-r--r--sources/shiboken6/tests/minimalbinding/brace_pattern_test.py8
-rw-r--r--sources/shiboken6/tests/minimalbinding/containeruser_test.py44
-rw-r--r--sources/shiboken6/tests/minimalbinding/global.h2
-rw-r--r--sources/shiboken6/tests/minimalbinding/listuser_test.py24
-rw-r--r--sources/shiboken6/tests/minimalbinding/minbool_test.py22
-rw-r--r--sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject1
-rw-r--r--sources/shiboken6/tests/minimalbinding/obj_test.py2
-rw-r--r--sources/shiboken6/tests/minimalbinding/spanuser_test.py42
-rw-r--r--sources/shiboken6/tests/minimalbinding/typedef_test.py52
-rw-r--r--sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml47
-rw-r--r--sources/shiboken6/tests/minimalbinding/val_test.py1
-rw-r--r--sources/shiboken6/tests/otherbinding/CMakeLists.txt3
-rw-r--r--sources/shiboken6/tests/otherbinding/collector_external_operator_test.py3
-rw-r--r--sources/shiboken6/tests/otherbinding/conversion_operator_for_class_without_implicit_conversions_test.py28
-rw-r--r--sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py3
-rw-r--r--sources/shiboken6/tests/otherbinding/module_reload_test.py2
-rw-r--r--sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py11
-rw-r--r--sources/shiboken6/tests/otherbinding/objtypehashes_test.py5
-rw-r--r--sources/shiboken6/tests/otherbinding/otherderived_test.py15
-rw-r--r--sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py3
-rw-r--r--sources/shiboken6/tests/otherbinding/signature_test.py4
-rw-r--r--sources/shiboken6/tests/otherbinding/smartptr_test.py2
-rw-r--r--sources/shiboken6/tests/otherbinding/star_import_test.py99
-rw-r--r--sources/shiboken6/tests/otherbinding/test_module_template.py13
-rw-r--r--sources/shiboken6/tests/otherbinding/typediscovery_test.py27
-rw-r--r--sources/shiboken6/tests/otherbinding/typesystem_other.xml4
-rw-r--r--sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py2
-rw-r--r--sources/shiboken6/tests/otherbinding/wrongctor_test.py10
-rw-r--r--sources/shiboken6/tests/qtxmltosphinx/CMakeLists.txt3
-rw-r--r--sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt3
-rw-r--r--sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp89
-rw-r--r--sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h2
-rw-r--r--sources/shiboken6/tests/samplebinding/CMakeLists.txt4
-rw-r--r--sources/shiboken6/tests/samplebinding/__del___test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/abstract_test.py11
-rw-r--r--sources/shiboken6/tests/samplebinding/addedfunction_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/argumentmodifications_test.py15
-rw-r--r--sources/shiboken6/tests/samplebinding/array_numpy_test.py10
-rw-r--r--sources/shiboken6/tests/samplebinding/array_sequence_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/bug_554_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/bug_704_test.py5
-rw-r--r--sources/shiboken6/tests/samplebinding/bytearray_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/child_return_test.py5
-rw-r--r--sources/shiboken6/tests/samplebinding/class_fields_test.py15
-rw-r--r--sources/shiboken6/tests/samplebinding/collector_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/complex_test.py11
-rw-r--r--sources/shiboken6/tests/samplebinding/conversion_operator_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/copy_test.py1
-rw-r--r--sources/shiboken6/tests/samplebinding/ctorconvrule_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/cyclic_test.py7
-rw-r--r--sources/shiboken6/tests/samplebinding/date_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/decisor_test.py15
-rw-r--r--sources/shiboken6/tests/samplebinding/delete_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/deprecated_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/derived_test.py53
-rw-r--r--sources/shiboken6/tests/samplebinding/duck_punching_test.py13
-rw-r--r--sources/shiboken6/tests/samplebinding/echo_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/enum_test.py62
-rw-r--r--sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py14
-rw-r--r--sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/event_loop_thread_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/exception_test.py21
-rw-r--r--sources/shiboken6/tests/samplebinding/filter_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/global.h1
-rw-r--r--sources/shiboken6/tests/samplebinding/handleholder_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/hashabletype_test.py5
-rw-r--r--sources/shiboken6/tests/samplebinding/ignorederefop_test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py1
-rw-r--r--sources/shiboken6/tests/samplebinding/implicitconv_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/injectcode_test.py19
-rw-r--r--sources/shiboken6/tests/samplebinding/innerclass_test.py5
-rw-r--r--sources/shiboken6/tests/samplebinding/intlist_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/intwrapper_test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/keep_reference_test.py13
-rw-r--r--sources/shiboken6/tests/samplebinding/list_test.py7
-rw-r--r--sources/shiboken6/tests/samplebinding/lock_test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/map_test.py15
-rw-r--r--sources/shiboken6/tests/samplebinding/metaclass_test.py14
-rw-r--r--sources/shiboken6/tests/samplebinding/mixed_mi_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/modelindex_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/modelview_test.py7
-rw-r--r--sources/shiboken6/tests/samplebinding/modifications_test.py40
-rw-r--r--sources/shiboken6/tests/samplebinding/modified_constructor_test.py5
-rw-r--r--sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py12
-rw-r--r--sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py39
-rw-r--r--sources/shiboken6/tests/samplebinding/multiple_derived_test.py43
-rw-r--r--sources/shiboken6/tests/samplebinding/namespace_test.py42
-rw-r--r--sources/shiboken6/tests/samplebinding/newdivision_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/nondefaultctor_test.py9
-rw-r--r--sources/shiboken6/tests/samplebinding/nontypetemplate_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/nonzero_test.py1
-rw-r--r--sources/shiboken6/tests/samplebinding/numericaltypedef_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/numpy_test.py5
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttype_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py8
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypebyvalue_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypelayout_test.py28
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/oddbool_test.py14
-rw-r--r--sources/shiboken6/tests/samplebinding/onlycopyclass_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/overflow_test.py16
-rw-r--r--sources/shiboken6/tests/samplebinding/overload_sorting_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/overload_test.py12
-rw-r--r--sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py9
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_delete_child_in_cpp_test.py1
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_delete_child_in_python_test.py1
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py12
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_transference_test.py16
-rw-r--r--sources/shiboken6/tests/samplebinding/pair_test.py13
-rw-r--r--sources/shiboken6/tests/samplebinding/pen_test.py1
-rw-r--r--sources/shiboken6/tests/samplebinding/point_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/pointerholder_test.py8
-rw-r--r--sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/pointf_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/primitivereferenceargument_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/privatector_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/privatedtor_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/protected_test.py81
-rw-r--r--sources/shiboken6/tests/samplebinding/pstrlist_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/pystr_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/python_thread_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/reference_test.py24
-rw-r--r--sources/shiboken6/tests/samplebinding/referencetopointer_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/renaming_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/return_null_test.py6
-rw-r--r--sources/shiboken6/tests/samplebinding/richcompare_test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/sample_test.py48
-rw-r--r--sources/shiboken6/tests/samplebinding/samplesnippets.cpp34
-rw-r--r--sources/shiboken6/tests/samplebinding/simplefile_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/size_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py8
-rw-r--r--sources/shiboken6/tests/samplebinding/stdcomplex_test.py71
-rw-r--r--sources/shiboken6/tests/samplebinding/str_test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/strlist_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/time_test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/transform_test.py2
-rw-r--r--sources/shiboken6/tests/samplebinding/typeconverters_test.py20
-rw-r--r--sources/shiboken6/tests/samplebinding/typedealloc_test.py9
-rw-r--r--sources/shiboken6/tests/samplebinding/typedtordoublefree_test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/typesystem_sample.xml84
-rw-r--r--sources/shiboken6/tests/samplebinding/typesystypedef_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/unsafe_parent_test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/useraddedctor_test.py7
-rw-r--r--sources/shiboken6/tests/samplebinding/virtualdtor_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/virtualmethods_test.py11
-rw-r--r--sources/shiboken6/tests/samplebinding/visibilitychange_test.py10
-rw-r--r--sources/shiboken6/tests/samplebinding/voidholder_test.py3
-rw-r--r--sources/shiboken6/tests/samplebinding/weakref_test.py4
-rw-r--r--sources/shiboken6/tests/samplebinding/writableclassdict_test.py6
-rw-r--r--sources/shiboken6/tests/shibokenmodule/module_test.py26
-rw-r--r--sources/shiboken6/tests/smartbinding/CMakeLists.txt4
-rw-r--r--sources/shiboken6/tests/smartbinding/smart_pointer_test.py2
-rw-r--r--sources/shiboken6/tests/smartbinding/std_optional_test.py1
-rw-r--r--sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py12
-rw-r--r--sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py1
-rw-r--r--sources/shiboken6/tests/smartbinding/typesystem_smart.xml2
-rw-r--r--sources/shiboken6/tests/test_generator/CMakeLists.txt3
-rw-r--r--sources/shiboken6/tests/test_generator/run_test.cmake3
621 files changed, 24110 insertions, 15845 deletions
diff --git a/sources/shiboken6/.cmake.conf b/sources/shiboken6/.cmake.conf
index e9e426412..ecc0a433d 100644
--- a/sources/shiboken6/.cmake.conf
+++ b/sources/shiboken6/.cmake.conf
@@ -1,5 +1,5 @@
set(shiboken_MAJOR_VERSION "6")
-set(shiboken_MINOR_VERSION "4")
+set(shiboken_MINOR_VERSION "7")
set(shiboken_MICRO_VERSION "0")
set(shiboken_PRE_RELEASE_VERSION_TYPE "a")
set(shiboken_PRE_RELEASE_VERSION "1")
diff --git a/sources/shiboken6/ApiExtractor/CMakeLists.txt b/sources/shiboken6/ApiExtractor/CMakeLists.txt
index f3337edc8..7aa2fbd11 100644
--- a/sources/shiboken6/ApiExtractor/CMakeLists.txt
+++ b/sources/shiboken6/ApiExtractor/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(apiextractor)
cmake_minimum_required(VERSION 3.18)
@@ -6,50 +9,78 @@ cmake_policy(VERSION 3.18)
set(CMAKE_AUTOMOC ON)
set(apiextractor_SRC
-apiextractor.cpp
-apiextractorresult.cpp
-abstractmetaargument.cpp
-abstractmetabuilder.cpp
+abstractmetaargument.cpp abstractmetaargument.h
+abstractmetabuilder.cpp abstractmetabuilder.h abstractmetabuilder_p.h
abstractmetabuilder_helpers.cpp
-abstractmetaenum.cpp
-abstractmetafield.cpp
-abstractmetafunction.cpp
-abstractmetatype.cpp
-abstractmetalang.cpp
-addedfunction.cpp
-classdocumentation.cpp
-codesnip.cpp
-codesniphelpers.cpp
-conditionalstreamreader.cpp
-customconversion.cpp
-documentation.cpp
-dotview.cpp
-enclosingclassmixin.cpp
-fileout.cpp
-messages.cpp
-modifications.cpp
-predefined_templates.cpp
-propertyspec.cpp
-pymethoddefentry.cpp
-reporthandler.cpp
-sourcelocation.cpp
-typeparser.cpp
-typesystem.cpp
-typesystemparser.cpp
-include.cpp
-typedatabase.cpp
-textstream.cpp
+abstractmetaenum.cpp abstractmetaenum.h
+abstractmetafield.cpp abstractmetafield.h
+abstractmetafunction.cpp abstractmetafunction.h
+abstractmetalang.cpp abstractmetalang.h abstractmetalang_helpers.h abstractmetalang_typedefs.h
+abstractmetatype.cpp abstractmetatype.h
+addedfunction.cpp addedfunction.h addedfunction_p.h
+anystringview_helpers.cpp anystringview_helpers.h
+apiextractor.cpp apiextractor.h apiextractorflags.h
+apiextractorresult.cpp apiextractorresult.h
+arraytypeentry.h
+classdocumentation.cpp classdocumentation.h
+codesnip.cpp codesnip.h
+codesniphelpers.cpp codesniphelpers.h
+complextypeentry.h
+conditionalstreamreader.cpp conditionalstreamreader.h
+configurabletypeentry.h
+constantvaluetypeentry.h
+containertypeentry.h
+customconversion.cpp customconversion.h customconversion_typedefs.h
+customtypenentry.h
+debughelpers_p.h
+dependency.h
+documentation.cpp documentation.h
+dotview.cpp dotview.h
+enclosingclassmixin.cpp enclosingclassmixin.h
+enumtypeentry.h
+enumvaluetypeentry.h
+exception.h
+fileout.cpp fileout.h
+flagstypeentry.h
+functiontypeentry.h
+graph.h
+header_paths.h
+include.cpp include.h
+messages.cpp messages.h
+modifications.cpp modifications.h modifications_typedefs.h
+namespacetypeentry.h
+objecttypeentry.h
+optionsparser.cpp optionsparser.h
+predefined_templates.cpp predefined_templates.h
+primitivetypeentry.h
+propertyspec.cpp propertyspec.h
+pymethoddefentry.cpp pymethoddefentry.h
+pythontypeentry.h
+reporthandler.cpp reporthandler.h
+smartpointertypeentry.h
+sourcelocation.cpp sourcelocation.h
+templateargumententry.h
+textstream.cpp textstream.h
+typedatabase.cpp typedatabase.h typedatabase_p.h typedatabase_typedefs.h
+typedefentry.h
+typeparser.cpp typeparser.h
+typesystem.cpp typesystem.h typesystem_enums.h typesystem_typedefs.h
+typesystemparser.cpp typesystemparser_p.h
+usingmember.h
+valuetypeentry.h
+varargstypeentry.h
+voidtypeentry.h
+xmlutils.cpp xmlutils.h xmlutils_libxslt.h xmlutils_qt.h
# Clang
-clangparser/compilersupport.cpp
-clangparser/clangparser.cpp
-clangparser/clangbuilder.cpp
-clangparser/clangdebugutils.cpp
-clangparser/clangutils.cpp
+clangparser/clangbuilder.cpp clangparser/clangbuilder.h
+clangparser/clangdebugutils.cpp clangparser/clangdebugutils.h
+clangparser/clangparser.cpp clangparser/clangparser.h
+clangparser/clangutils.cpp clangparser/clangutils.h
+clangparser/compilersupport.cpp clangparser/compilersupport.h
# Old parser
-parser/typeinfo.cpp
-parser/codemodel.cpp
-parser/enumvalue.cpp
-xmlutils.cpp
+parser/codemodel.cpp parser/codemodel.h parser/codemodel_fwd.h parser/codemodel_enums.h
+parser/enumvalue.cpp parser/enumvalue.h
+parser/typeinfo.cpp parser/typeinfo.h
)
find_package(LibXml2 2.6.32)
@@ -87,9 +118,10 @@ if (HAS_LIBXSLT)
endif()
if (NOT DISABLE_DOCSTRINGS)
- target_sources(apiextractor PRIVATE docparser.cpp
- doxygenparser.cpp
- qtdocparser.cpp)
+ target_sources(apiextractor PRIVATE
+ docparser.cpp docparser.h
+ doxygenparser.cpp doxygenparser.h
+ qtdocparser.cpp qtdocparser.h)
endif()
target_compile_definitions(apiextractor
diff --git a/sources/shiboken6/ApiExtractor/abstractmetaargument.cpp b/sources/shiboken6/ApiExtractor/abstractmetaargument.cpp
index bd6a80434..05cebe10a 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetaargument.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetaargument.cpp
@@ -38,9 +38,9 @@ AbstractMetaArgument::AbstractMetaArgument(const AbstractMetaArgument &) = defau
AbstractMetaArgument &AbstractMetaArgument::operator=(const AbstractMetaArgument &) = default;
-AbstractMetaArgument::AbstractMetaArgument(AbstractMetaArgument &&) = default;
+AbstractMetaArgument::AbstractMetaArgument(AbstractMetaArgument &&) noexcept = default;
-AbstractMetaArgument &AbstractMetaArgument::operator=(AbstractMetaArgument &&) = default;
+AbstractMetaArgument &AbstractMetaArgument::operator=(AbstractMetaArgument &&) noexcept = default;
const AbstractMetaType &AbstractMetaArgument::type() const
{
@@ -191,7 +191,7 @@ QDebug operator<<(QDebug d, const AbstractMetaArgument *aa)
d.noquote();
d.nospace();
d << "AbstractMetaArgument(";
- if (aa)
+ if (aa != nullptr)
d << aa->toString();
else
d << '0';
diff --git a/sources/shiboken6/ApiExtractor/abstractmetaargument.h b/sources/shiboken6/ApiExtractor/abstractmetaargument.h
index 1e5e32613..38402e369 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetaargument.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetaargument.h
@@ -19,9 +19,8 @@ public:
~AbstractMetaArgument();
AbstractMetaArgument(const AbstractMetaArgument &);
AbstractMetaArgument &operator=(const AbstractMetaArgument &);
- AbstractMetaArgument(AbstractMetaArgument &&);
- AbstractMetaArgument &operator=(AbstractMetaArgument &&);
-
+ AbstractMetaArgument(AbstractMetaArgument &&) noexcept;
+ AbstractMetaArgument &operator=(AbstractMetaArgument &&) noexcept;
const AbstractMetaType &type() const;
void setType(const AbstractMetaType &type);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
index 4eff0ee62..fa0767a62 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
@@ -9,6 +9,7 @@
#include "abstractmetatype.h"
#include "addedfunction.h"
#include "graph.h"
+#include "debughelpers_p.h"
#include "exception.h"
#include "messages.h"
#include "propertyspec.h"
@@ -54,11 +55,9 @@
using namespace Qt::StringLiterals;
-static inline QString colonColon() { return QStringLiteral("::"); }
-
static QString stripTemplateArgs(const QString &name)
{
- int pos = name.indexOf(u'<');
+ const auto pos = name.indexOf(u'<');
return pos < 0 ? name : name.left(pos);
}
@@ -68,6 +67,31 @@ static void fixArgumentIndexes(AbstractMetaArgumentList *list)
(*list)[i].setArgumentIndex(i);
}
+bool operator<(const RejectEntry &re1, const RejectEntry &re2)
+{
+ return re1.reason != re2.reason
+ ? (re1.reason < re2.reason) : (re1.sortkey < re2.sortkey);
+}
+
+QTextStream &operator<<(QTextStream &str, const RejectEntry &re)
+{
+ str << re.signature;
+ if (!re.message.isEmpty())
+ str << ": " << re.message;
+ return str;
+}
+
+static void applyCachedFunctionModifications(AbstractMetaFunction *metaFunction,
+ const FunctionModificationList &functionMods)
+{
+ for (const FunctionModification &mod : functionMods) {
+ if (mod.exceptionHandling() != TypeSystem::ExceptionHandling::Unspecified)
+ metaFunction->setExceptionHandlingModification(mod.exceptionHandling());
+ if (mod.allowThread() != TypeSystem::AllowThread::Unspecified)
+ metaFunction->setAllowThreadModification(mod.allowThread());
+ }
+}
+
bool AbstractMetaBuilderPrivate::m_useGlobalHeader = false;
bool AbstractMetaBuilderPrivate::m_codeModelTestMode = false;
@@ -76,13 +100,6 @@ AbstractMetaBuilderPrivate::AbstractMetaBuilderPrivate() :
{
}
-AbstractMetaBuilderPrivate::~AbstractMetaBuilderPrivate()
-{
- qDeleteAll(m_templates);
- qDeleteAll(m_smartPointers);
- qDeleteAll(m_metaClasses);
-}
-
AbstractMetaBuilder::AbstractMetaBuilder() : d(new AbstractMetaBuilderPrivate)
{
d->q = this;
@@ -144,18 +161,23 @@ const QHash<TypeEntryCPtr, AbstractMetaEnum> &AbstractMetaBuilder::typeEntryToEn
return d->m_enums;
}
-void AbstractMetaBuilderPrivate::checkFunctionModifications()
+const QMultiHash<QString, QString> &AbstractMetaBuilder::typedefTargetToName() const
+{
+ return d->m_typedefTargetToName;
+}
+
+void AbstractMetaBuilderPrivate::checkFunctionModifications() const
{
const auto &entries = TypeDatabase::instance()->entries();
for (auto it = entries.cbegin(), end = entries.cend(); it != end; ++it) {
TypeEntryCPtr entry = it.value();
- if (entry.isNull())
+ if (!entry)
continue;
if (!entry->isComplex() || !entry->generateCode())
continue;
- auto centry = qSharedPointerCast<const ComplexTypeEntry>(entry);
+ auto centry = std::static_pointer_cast<const ComplexTypeEntry>(entry);
if (!centry->generateCode())
continue;
@@ -168,7 +190,7 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications()
QString name = signature.trimmed();
name.truncate(name.indexOf(u'('));
- AbstractMetaClass *clazz = AbstractMetaClass::findClass(m_metaClasses, centry);
+ const auto clazz = AbstractMetaClass::findClass(m_metaClasses, centry);
if (!clazz)
continue;
@@ -198,15 +220,15 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications()
}
}
-AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentModelItem &argument,
- const AbstractMetaClass *currentClass)
+AbstractMetaClassPtr AbstractMetaBuilderPrivate::argumentToClass(const ArgumentModelItem &argument,
+ const AbstractMetaClassCPtr &currentClass)
{
- AbstractMetaClass *returned = nullptr;
+ AbstractMetaClassPtr returned;
auto type = translateType(argument->type(), currentClass);
if (!type.has_value())
return returned;
TypeEntryCPtr entry = type->typeEntry();
- if (!entry.isNull() && entry->isComplex())
+ if (entry && entry->isComplex())
returned = AbstractMetaClass::findClass(m_metaClasses, entry);
return returned;
}
@@ -215,20 +237,20 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentMod
* Checks the argument of a hash function and flags the type if it is a complex type
*/
void AbstractMetaBuilderPrivate::registerHashFunction(const FunctionModelItem &function_item,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
if (function_item->isDeleted())
return;
ArgumentList arguments = function_item->arguments();
if (arguments.size() >= 1) { // (Class, Hash seed).
- if (AbstractMetaClass *cls = argumentToClass(arguments.at(0), currentClass))
+ if (AbstractMetaClassPtr cls = argumentToClass(arguments.at(0), currentClass))
cls->setHashFunction(function_item->name());
}
}
void AbstractMetaBuilderPrivate::registerToStringCapabilityIn(const NamespaceModelItem &nsItem)
{
- const FunctionList &streamOps = nsItem->findFunctions(u"operator<<"_s);
+ const FunctionList &streamOps = nsItem->findFunctions("operator<<");
for (const FunctionModelItem &item : streamOps)
registerToStringCapability(item, nullptr);
for (const NamespaceModelItem &ni : nsItem->namespaces())
@@ -240,13 +262,13 @@ void AbstractMetaBuilderPrivate::registerToStringCapabilityIn(const NamespaceMod
*/
void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelItem &function_item,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
ArgumentList arguments = function_item->arguments();
if (arguments.size() == 2) {
if (arguments.at(0)->type().toString() == u"QDebug") {
const ArgumentModelItem &arg = arguments.at(1);
- if (AbstractMetaClass *cls = argumentToClass(arg, currentClass)) {
+ if (AbstractMetaClassPtr cls = argumentToClass(arg, currentClass)) {
if (arg->type().indirections() < 2)
cls->setToStringCapability(true, int(arg->type().indirections()));
}
@@ -255,7 +277,7 @@ void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelI
}
void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelItem &item,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
if (item->accessPolicy() != Access::Public)
return;
@@ -275,7 +297,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
} else {
auto type = translateType(item->type(), currentClass);
const auto retType = type.has_value() ? type->typeEntry() : TypeEntryCPtr{};
- AbstractMetaClass *otherArgClass = argumentToClass(itemArguments.at(1), currentClass);
+ const auto otherArgClass = argumentToClass(itemArguments.at(1), currentClass);
if (otherArgClass && retType
&& (retType->isValue() || retType->isObject())
&& retType != baseoperandClass->typeEntry()
@@ -284,11 +306,14 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
firstArgumentIsSelf = false;
}
}
- if (baseoperandClass == nullptr)
+ if (!baseoperandClass) {
+ rejectFunction(item, currentClass, AbstractMetaBuilder::UnmatchedOperator,
+ u"base operand class not found."_s);
return;
+ }
if (item->isSpaceshipOperator() && !item->isDeleted()) {
- baseoperandClass->addSynthesizedComparisonOperators();
+ AbstractMetaClass::addSynthesizedComparisonOperators(baseoperandClass);
return;
}
@@ -325,7 +350,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
}
metaFunction->setFlags(flags);
metaFunction->setAccess(Access::Public);
- baseoperandClass->addFunction(AbstractMetaFunctionCPtr(metaFunction));
+ AbstractMetaClass::addFunction(baseoperandClass, AbstractMetaFunctionCPtr(metaFunction));
if (!metaFunction->arguments().isEmpty()) {
const auto include = metaFunction->arguments().constFirst().type().typeEntry()->include();
baseoperandClass->typeEntry()->addArgumentInclude(include);
@@ -334,7 +359,7 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
}
bool AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem &item,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
ArgumentList itemArguments = item->arguments();
if (itemArguments.size() != 2 || item->accessPolicy() != Access::Public)
@@ -361,10 +386,9 @@ bool AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem
streamFunction->setArguments(arguments);
- *streamFunction += AbstractMetaFunction::FinalInTargetLang;
streamFunction->setAccess(Access::Public);
- AbstractMetaClass *funcClass;
+ AbstractMetaClassPtr funcClass;
if (!streamClass->typeEntry()->generateCode()) {
AbstractMetaArgumentList reverseArgs = streamFunction->arguments();
@@ -377,7 +401,7 @@ bool AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem
funcClass = streamClass;
}
- funcClass->addFunction(AbstractMetaFunctionCPtr(streamFunction));
+ AbstractMetaClass::addFunction(funcClass, AbstractMetaFunctionCPtr(streamFunction));
auto funcTe = funcClass->typeEntry();
if (funcClass == streamClass)
funcTe->addArgumentInclude(streamedClass->typeEntry()->include());
@@ -389,7 +413,7 @@ bool AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem
static bool metaEnumLessThan(const AbstractMetaEnum &e1, const AbstractMetaEnum &e2)
{ return e1.fullName() < e2.fullName(); }
-static bool metaClassLessThan(const AbstractMetaClass *c1, const AbstractMetaClass *c2)
+static bool metaClassLessThan(const AbstractMetaClassCPtr &c1, const AbstractMetaClassCPtr &c2)
{ return c1->fullName() < c2->fullName(); }
static bool metaFunctionLessThan(const AbstractMetaFunctionCPtr &f1, const AbstractMetaFunctionCPtr &f2)
@@ -402,8 +426,8 @@ void AbstractMetaBuilderPrivate::sortLists()
// this is a temporary solution before new type revision implementation
// We need move QMetaObject register before QObject.
Dependencies additionalDependencies;
- if (auto qObjectClass = AbstractMetaClass::findClass(m_metaClasses, u"QObject")) {
- if (auto qMetaObjectClass = AbstractMetaClass::findClass(m_metaClasses, u"QMetaObject")) {
+ if (auto qObjectClass = AbstractMetaClass::findClass(m_metaClasses, "QObject")) {
+ if (auto qMetaObjectClass = AbstractMetaClass::findClass(m_metaClasses, "QMetaObject")) {
Dependency dependency;
dependency.parent = qMetaObjectClass;
dependency.child = qObjectClass;
@@ -412,7 +436,7 @@ void AbstractMetaBuilderPrivate::sortLists()
}
m_metaClasses = classesTopologicalSorted(m_metaClasses, additionalDependencies);
- for (AbstractMetaClass *cls : std::as_const(m_metaClasses))
+ for (const auto &cls : std::as_const(m_metaClasses))
cls->sortFunctions();
// Ensure that indexes are in alphabetical order, roughly, except
@@ -429,7 +453,7 @@ FileModelItem AbstractMetaBuilderPrivate::buildDom(QByteArrayList arguments,
unsigned clangFlags)
{
clang::Builder builder;
- builder.setSystemIncludes(TypeDatabase::instance()->systemIncludes());
+ builder.setForceProcessSystemIncludes(TypeDatabase::instance()->forceProcessSystemIncludes());
if (addCompilerSupportArguments) {
if (level == LanguageLevel::Default)
level = clang::emulatedCompilerLanguageLevel();
@@ -437,7 +461,7 @@ FileModelItem AbstractMetaBuilderPrivate::buildDom(QByteArrayList arguments,
+ clang::languageLevelOption(level));
}
FileModelItem result = clang::parse(arguments, addCompilerSupportArguments,
- clangFlags, builder)
+ level, clangFlags, builder)
? builder.dom() : FileModelItem();
const clang::BaseVisitor::Diagnostics &diagnostics = builder.diagnostics();
if (const auto diagnosticsCount = diagnostics.size()) {
@@ -456,7 +480,7 @@ static QStringList functionCandidates(const AbstractMetaFunctionCList &list,
const QString &signature)
{
QString name = signature;
- const int parenPos = name.indexOf(u'(');
+ const auto parenPos = name.indexOf(u'(');
if (parenPos > 0)
name.truncate(parenPos);
QStringList result;
@@ -477,18 +501,18 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
// Start the generation...
const ClassList &typeValues = dom->classes();
- ReportHandler::startProgress("Generating class model ("
- + QByteArray::number(typeValues.size()) + ")...");
+ ReportHandler::startProgress("Generated class model ("
+ + QByteArray::number(typeValues.size()) + ").");
for (const ClassModelItem &item : typeValues) {
- if (AbstractMetaClass *cls = traverseClass(dom, item, nullptr))
- addAbstractMetaClass(cls, item.data());
+ if (const auto cls = traverseClass(dom, item, nullptr))
+ addAbstractMetaClass(cls, item.get());
}
// We need to know all global enums
const EnumList &enums = dom->enums();
- ReportHandler::startProgress("Generating enum model ("
- + QByteArray::number(enums.size()) + ")...");
+ ReportHandler::startProgress("Generated enum model ("
+ + QByteArray::number(enums.size()) + ").");
for (const EnumModelItem &item : enums) {
auto metaEnum = traverseEnum(item, nullptr, QSet<QString>());
if (metaEnum.has_value()) {
@@ -498,19 +522,19 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
}
const auto &namespaceTypeValues = dom->namespaces();
- ReportHandler::startProgress("Generating namespace model ("
- + QByteArray::number(namespaceTypeValues.size()) + ")...");
+ ReportHandler::startProgress("Generated namespace model ("
+ + QByteArray::number(namespaceTypeValues.size()) + ").");
for (const NamespaceModelItem &item : namespaceTypeValues)
traverseNamespace(dom, item);
// Go through all typedefs to see if we have defined any
// specific typedefs to be used as classes.
const TypeDefList typeDefs = dom->typeDefs();
- ReportHandler::startProgress("Resolving typedefs ("
- + QByteArray::number(typeDefs.size()) + ")...");
+ ReportHandler::startProgress("Resolved typedefs ("
+ + QByteArray::number(typeDefs.size()) + ").");
for (const TypeDefModelItem &typeDef : typeDefs) {
- if (AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, nullptr))
- addAbstractMetaClass(cls, typeDef.data());
+ if (const auto cls = traverseTypeDef(dom, typeDef, nullptr))
+ addAbstractMetaClass(cls, typeDef.get());
}
traverseTypesystemTypedefs();
@@ -528,7 +552,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
continue;
FunctionTypeEntryPtr funcEntry = types->findFunctionType(func->name());
- if (funcEntry.isNull() || !funcEntry->generateCode())
+ if (!funcEntry || !funcEntry->generateCode())
continue;
AbstractMetaFunction *metaFunc = traverseFunction(func, nullptr);
@@ -548,8 +572,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
m_globalFunctions << metaFuncPtr;
}
- ReportHandler::startProgress("Fixing class inheritance...");
- for (AbstractMetaClass *cls : std::as_const(m_metaClasses)) {
+ ReportHandler::startProgress("Fixed class inheritance.");
+ for (const auto &cls : std::as_const(m_metaClasses)) {
if (cls->needsInheritanceSetup()) {
setupInheritance(cls);
traverseUsingMembers(cls);
@@ -561,14 +585,14 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
}
}
- ReportHandler::startProgress("Detecting inconsistencies in class model...");
- for (AbstractMetaClass *cls : std::as_const(m_metaClasses)) {
- cls->fixFunctions();
+ ReportHandler::startProgress("Checked for inconsistencies in class model.");
+ for (const auto &cls : std::as_const(m_metaClasses)) {
+ AbstractMetaClass::fixFunctions(cls);
if (cls->canAddDefaultConstructor())
- cls->addDefaultConstructor();
+ AbstractMetaClass::addDefaultConstructor(cls);
if (cls->canAddDefaultCopyConstructor())
- cls->addDefaultCopyConstructor();
+ AbstractMetaClass::addDefaultCopyConstructor(cls);
const bool avoidProtectedHack = flags.testFlag(ApiExtractorFlag::AvoidProtectedHack);
const bool vco =
@@ -579,10 +603,10 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
const auto &allEntries = types->entries();
- ReportHandler::startProgress("Detecting inconsistencies in typesystem ("
- + QByteArray::number(allEntries.size()) + ")...");
+ ReportHandler::startProgress("Checked for inconsistencies in typesystem ("
+ + QByteArray::number(allEntries.size()) + ").");
for (auto it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) {
- TypeEntryPtr entry = it.value();
+ const TypeEntryPtr &entry = it.value();
if (!entry->isPrimitive()) {
if ((entry->isValue() || entry->isObject())
&& !types->shouldDropTypeEntry(entry->qualifiedCppName())
@@ -592,7 +616,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
&& !AbstractMetaClass::findClass(m_metaClasses, entry)) {
qCWarning(lcShiboken, "%s", qPrintable(msgTypeNotDefined(entry)));
} else if (entry->generateCode() && entry->type() == TypeEntry::FunctionType) {
- auto fte = qSharedPointerCast<const FunctionTypeEntry>(entry);
+ auto fte = std::static_pointer_cast<const FunctionTypeEntry>(entry);
const QStringList &signatures = fte->signatures();
for (const QString &signature : signatures) {
bool ok = false;
@@ -610,9 +634,9 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
}
}
} else if (entry->isEnum() && entry->generateCode()) {
- const auto enumEntry = qSharedPointerCast<const EnumTypeEntry>(entry);
- AbstractMetaClass *cls = AbstractMetaClass::findClass(m_metaClasses,
- enumEntry->parent());
+ const auto enumEntry = std::static_pointer_cast<const EnumTypeEntry>(entry);
+ const auto cls = AbstractMetaClass::findClass(m_metaClasses,
+ enumEntry->parent());
const bool enumFound = cls
? cls->findEnum(entry->targetLangEntryName()).has_value()
@@ -629,7 +653,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
}
{
- const FunctionList &hashFunctions = dom->findFunctions(u"qHash"_s);
+ const FunctionList &hashFunctions = dom->findFunctions("qHash");
for (const FunctionModelItem &item : hashFunctions)
registerHashFunction(item, nullptr);
}
@@ -652,13 +676,13 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
}
}
- ReportHandler::startProgress("Checking inconsistencies in function modifications...");
+ ReportHandler::startProgress("Checked for inconsistencies in function modifications.");
checkFunctionModifications();
- ReportHandler::startProgress("Writing log files...");
+ ReportHandler::startProgress("Wrote log files.");
- for (AbstractMetaClass *cls : std::as_const(m_metaClasses)) {
+ for (const auto &cls : std::as_const(m_metaClasses)) {
// setupEquals(cls);
// setupComparable(cls);
setupExternalConversion(cls);
@@ -702,10 +726,10 @@ bool AbstractMetaBuilder::build(const QByteArrayList &arguments,
{
const FileModelItem dom = d->buildDom(arguments, addCompilerSupportArguments,
level, clangFlags);
- if (dom.isNull())
+ if (!dom)
return false;
if (ReportHandler::isDebug(ReportHandler::MediumDebug))
- qCDebug(lcShiboken) << dom.data();
+ qCDebug(lcShiboken) << dom.get();
d->traverseDom(dom, apiExtractorFlags);
return true;
@@ -718,7 +742,7 @@ void AbstractMetaBuilder::setLogDirectory(const QString &logDir)
d->m_logDirectory.append(QDir::separator());
}
-void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls,
+void AbstractMetaBuilderPrivate::addAbstractMetaClass(const AbstractMetaClassPtr &cls,
const _CodeModelItem *item)
{
m_itemToClass.insert(item, cls);
@@ -732,23 +756,27 @@ void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls,
}
}
-AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModelItem &dom,
- const NamespaceModelItem &namespaceItem)
+AbstractMetaClassPtr
+ AbstractMetaBuilderPrivate::traverseNamespace(const FileModelItem &dom,
+ const NamespaceModelItem &namespaceItem)
{
- QString namespaceName = currentScope()->qualifiedName().join(colonColon());
+ QString namespaceName = currentScope()->qualifiedName().join(u"::"_s);
if (!namespaceName.isEmpty())
- namespaceName.append(colonColon());
+ namespaceName.append(u"::"_s);
namespaceName.append(namespaceItem->name());
if (TypeDatabase::instance()->isClassRejected(namespaceName)) {
- m_rejectedClasses.insert(namespaceName, AbstractMetaBuilder::GenerationDisabled);
- return nullptr;
+ m_rejectedClasses.insert({AbstractMetaBuilder::GenerationDisabled,
+ namespaceName, namespaceName, QString{}});
+ return {};
}
auto type = TypeDatabase::instance()->findNamespaceType(namespaceName, namespaceItem->fileName());
if (!type) {
- qCWarning(lcShiboken, "%s",
- qPrintable(msgNamespaceNoTypeEntry(namespaceItem, namespaceName)));
+ const QString rejectReason = msgNamespaceNoTypeEntry(namespaceItem, namespaceName);
+ qCWarning(lcShiboken, "%s", qPrintable(rejectReason));
+ m_rejectedClasses.insert({AbstractMetaBuilder::GenerationDisabled,
+ namespaceName, namespaceName, rejectReason});
return nullptr;
}
@@ -758,22 +786,22 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
}
// Continue populating namespace?
- AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, type);
+ AbstractMetaClassPtr metaClass = AbstractMetaClass::findClass(m_metaClasses, type);
if (!metaClass) {
- metaClass = new AbstractMetaClass;
+ metaClass.reset(new AbstractMetaClass);
metaClass->setTypeEntry(type);
- addAbstractMetaClass(metaClass, namespaceItem.data());
+ addAbstractMetaClass(metaClass, namespaceItem.get());
if (auto extendsType = type->extends()) {
- AbstractMetaClass *extended = AbstractMetaClass::findClass(m_metaClasses, extendsType);
+ const auto extended = AbstractMetaClass::findClass(m_metaClasses, extendsType);
if (!extended) {
qCWarning(lcShiboken, "%s",
qPrintable(msgNamespaceToBeExtendedNotFound(extendsType->name(), extendsType->targetLangPackage())));
- return nullptr;
+ return {};
}
metaClass->setExtendedNamespace(extended);
}
} else {
- m_itemToClass.insert(namespaceItem.data(), metaClass);
+ m_itemToClass.insert(namespaceItem.get(), metaClass);
}
traverseEnums(namespaceItem, metaClass, namespaceItem->enumsDeclarations());
@@ -782,11 +810,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
const ClassList &classes = namespaceItem->classes();
for (const ClassModelItem &cls : classes) {
- AbstractMetaClass *mjc = traverseClass(dom, cls, metaClass);
+ const auto mjc = traverseClass(dom, cls, metaClass);
if (mjc) {
metaClass->addInnerClass(mjc);
mjc->setEnclosingClass(metaClass);
- addAbstractMetaClass(mjc, cls.data());
+ addAbstractMetaClass(mjc, cls.get());
}
}
@@ -794,22 +822,22 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
// specific typedefs to be used as classes.
const TypeDefList typeDefs = namespaceItem->typeDefs();
for (const TypeDefModelItem &typeDef : typeDefs) {
- AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, metaClass);
+ const auto cls = traverseTypeDef(dom, typeDef, metaClass);
if (cls) {
metaClass->addInnerClass(cls);
cls->setEnclosingClass(metaClass);
- addAbstractMetaClass(cls, typeDef.data());
+ addAbstractMetaClass(cls, typeDef.get());
}
}
// Traverse namespaces recursively
for (const NamespaceModelItem &ni : namespaceItem->namespaces()) {
- AbstractMetaClass *mjc = traverseNamespace(dom, ni);
+ const auto mjc = traverseNamespace(dom, ni);
if (mjc) {
metaClass->addInnerClass(mjc);
mjc->setEnclosingClass(metaClass);
- m_classToItem.insert(mjc, ni.data()); // Add for enum lookup.
- m_itemToClass.insert(ni.data(), mjc);
+ m_classToItem.insert(mjc, ni.get()); // Add for enum lookup.
+ m_itemToClass.insert(ni.get(), mjc);
}
}
@@ -823,10 +851,10 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
std::optional<AbstractMetaEnum>
AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &enumItem,
- AbstractMetaClass *enclosing,
+ const AbstractMetaClassPtr &enclosing,
const QSet<QString> &enumsDeclarations)
{
- QString qualifiedName = enumItem->qualifiedName().join(colonColon());
+ QString qualifiedName = enumItem->qualifiedName().join(u"::"_s);
TypeEntryPtr typeEntry;
const auto enclosingTypeEntry = enclosing ? enclosing->typeEntry() : TypeEntryCPtr{};
@@ -842,7 +870,7 @@ std::optional<AbstractMetaEnum>
for (const EnumeratorModelItem &enumValue : enums) {
tmpQualifiedName.removeLast();
tmpQualifiedName << enumValue->name();
- qualifiedName = tmpQualifiedName.join(colonColon());
+ qualifiedName = tmpQualifiedName.join(u"::"_s);
typeEntry = TypeDatabase::instance()->findType(qualifiedName);
if (typeEntry)
break;
@@ -859,66 +887,75 @@ std::optional<AbstractMetaEnum>
if (TypeDatabase::instance()->isEnumRejected(className, enumName, &rejectReason)) {
if (typeEntry)
typeEntry->setCodeGeneration(TypeEntry::GenerateNothing);
- m_rejectedEnums.insert(qualifiedName + rejectReason, AbstractMetaBuilder::GenerationDisabled);
+ m_rejectedEnums.insert({AbstractMetaBuilder::GenerationDisabled, qualifiedName,
+ qualifiedName, rejectReason});
return {};
}
const bool rejectionWarning = !enclosing || enclosing->typeEntry()->generateCode();
if (!typeEntry) {
+ const QString rejectReason = msgNoEnumTypeEntry(enumItem, className);
if (rejectionWarning)
- qCWarning(lcShiboken, "%s", qPrintable(msgNoEnumTypeEntry(enumItem, className)));
- m_rejectedEnums.insert(qualifiedName, AbstractMetaBuilder::NotInTypeSystem);
+ qCWarning(lcShiboken, "%s", qPrintable(rejectReason));
+ m_rejectedEnums.insert({AbstractMetaBuilder::NotInTypeSystem, qualifiedName,
+ qualifiedName, rejectReason});
return {};
}
if (!typeEntry->isEnum()) {
- if (rejectionWarning) {
- qCWarning(lcShiboken, "%s",
- qPrintable(msgNoEnumTypeConflict(enumItem, className, typeEntry)));
- }
- m_rejectedEnums.insert(qualifiedName, AbstractMetaBuilder::NotInTypeSystem);
+ const QString rejectReason = msgNoEnumTypeConflict(enumItem, className, typeEntry);
+ if (rejectionWarning)
+ qCWarning(lcShiboken, "%s", qPrintable(rejectReason));
+ m_rejectedEnums.insert({AbstractMetaBuilder::NotInTypeSystem, qualifiedName,
+ qualifiedName, rejectReason});
return {};
}
AbstractMetaEnum metaEnum;
metaEnum.setEnumKind(enumItem->enumKind());
metaEnum.setDeprecated(enumItem->isDeprecated());
+ metaEnum.setUnderlyingType(enumItem->underlyingType());
metaEnum.setSigned(enumItem->isSigned());
if (enumsDeclarations.contains(qualifiedName)
|| enumsDeclarations.contains(enumName)) {
metaEnum.setHasQEnumsDeclaration(true);
}
- auto enumTypeEntry = qSharedPointerCast<EnumTypeEntry>(typeEntry);
+ auto enumTypeEntry = std::static_pointer_cast<EnumTypeEntry>(typeEntry);
metaEnum.setTypeEntry(enumTypeEntry);
metaEnum.setAccess(enumItem->accessPolicy());
if (metaEnum.access() == Access::Private)
typeEntry->setCodeGeneration(TypeEntry::GenerateNothing);
-
+ // PYSIDE-2088, MSVC signedness issue in Qt
+ const bool castToUnsigned = enumItem->isSigned()
+ && enumTypeEntry->cppType().contains(u"unsigned"_s);
const EnumeratorList &enums = enumItem->enumerators();
- for (const EnumeratorModelItem &value : enums) {
+ for (const EnumeratorModelItem &valueItem : enums) {
AbstractMetaEnumValue metaEnumValue;
- metaEnumValue.setName(value->name());
+ metaEnumValue.setName(valueItem->name());
// Deciding the enum value...
- metaEnumValue.setStringValue(value->stringValue());
- metaEnumValue.setValue(value->value());
- metaEnumValue.setDeprecated(value->isDeprecated());
+ metaEnumValue.setStringValue(valueItem->stringValue());
+ const auto value = valueItem->value();
+ metaEnumValue.setValue(castToUnsigned ? value.toUnsigned() : value);
+ metaEnumValue.setDeprecated(valueItem->isDeprecated());
metaEnum.addEnumValue(metaEnumValue);
}
- if (!metaEnum.typeEntry()->include().isValid())
- setInclude(metaEnum.typeEntry(), enumItem->fileName());
+ if (!metaEnum.typeEntry()->include().isValid()) {
+ auto te = std::const_pointer_cast<EnumTypeEntry>(metaEnum.typeEntry());
+ setInclude(te, enumItem->fileName());
+ }
// Register all enum values on Type database
const bool isScopedEnum = enumItem->enumKind() == EnumClass;
const EnumeratorList &enumerators = enumItem->enumerators();
for (const EnumeratorModelItem &e : enumerators) {
- EnumValueTypeEntryPtr enumValue(new EnumValueTypeEntry(e->name(), e->stringValue(),
- enumTypeEntry, isScopedEnum,
- enumTypeEntry->version()));
+ auto enumValue = std::make_shared<EnumValueTypeEntry>(e->name(), e->stringValue(),
+ enumTypeEntry, isScopedEnum,
+ enumTypeEntry->version());
TypeDatabase::instance()->addType(enumValue);
if (e->value().isNullValue())
enumTypeEntry->setNullValue(enumValue);
@@ -930,9 +967,31 @@ std::optional<AbstractMetaEnum>
return metaEnum;
}
-AbstractMetaClass *AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelItem &,
- const TypeDefModelItem &typeDef,
- AbstractMetaClass *currentClass)
+AbstractMetaClassPtr
+ AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelItem &dom,
+ const TypeDefModelItem &typeDef,
+ const AbstractMetaClassPtr &currentClass)
+{
+ auto result = traverseTypeDefHelper(dom, typeDef, currentClass);
+ if (!result && typeDef->type().isPlain()) {
+ const auto &type = typeDef->type();
+ QString fullName;
+ if (currentClass)
+ fullName += currentClass->qualifiedCppName() + "::"_L1;
+ fullName += typeDef->name();
+ QString targetName = typeDef->type().toString();
+ m_typedefTargetToName.insert(targetName, fullName);
+ const QByteArray normalized = QMetaObject::normalizedType(targetName.toUtf8().constData());
+ if (targetName != QLatin1StringView(normalized))
+ m_typedefTargetToName.insert(QString::fromUtf8(normalized), fullName);
+ }
+ return result;
+}
+
+AbstractMetaClassPtr
+ AbstractMetaBuilderPrivate::traverseTypeDefHelper(const FileModelItem &,
+ const TypeDefModelItem &typeDef,
+ const AbstractMetaClassPtr &currentClass)
{
TypeDatabase *types = TypeDatabase::instance();
QString className = stripTemplateArgs(typeDef->name());
@@ -941,7 +1000,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelIt
// we have an inner class
if (currentClass) {
fullClassName = stripTemplateArgs(currentClass->typeEntry()->qualifiedCppName())
- + colonColon() + fullClassName;
+ + u"::"_s + fullClassName;
}
// If this is the alias for a primitive type
@@ -951,7 +1010,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelIt
const auto &targetNames = typeDef->type().qualifiedName();
const auto pTarget = targetNames.size() == 1
? types->findPrimitiveType(targetNames.constFirst()) : PrimitiveTypeEntryPtr{};
- if (!ptype.isNull()) {
+ if (ptype) {
ptype->setReferencedTypeEntry(pTarget);
return nullptr;
}
@@ -960,7 +1019,8 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelIt
// (like size_t = unsigned)? Add it to the type DB.
if (pTarget && isCppPrimitive(basicReferencedNonBuiltinTypeEntry(pTarget))
&& currentClass == nullptr) {
- PrimitiveTypeEntryPtr pte(new PrimitiveTypeEntry(className, {}, {}));
+ auto pte = std::make_shared<PrimitiveTypeEntry>(className, QVersionNumber{},
+ TypeEntryCPtr{});
pte->setReferencedTypeEntry(pTarget);
pte->setBuiltIn(true);
types->addType(pte);
@@ -969,10 +1029,10 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelIt
// If we haven't specified anything for the typedef, then we don't care
auto type = types->findComplexType(fullClassName);
- if (type.isNull())
+ if (!type)
return nullptr;
- auto *metaClass = new AbstractMetaClass;
+ auto metaClass = std::make_shared<AbstractMetaClass>();
metaClass->setTypeDef(true);
metaClass->setTypeEntry(type);
metaClass->setBaseClassNames(QStringList(typeDef->type().toString()));
@@ -991,8 +1051,8 @@ void AbstractMetaBuilderPrivate::traverseTypesystemTypedefs()
{
const auto &entries = TypeDatabase::instance()->typedefEntries();
for (auto it = entries.begin(), end = entries.end(); it != end; ++it) {
- TypedefEntryPtr te = it.value();
- auto *metaClass = new AbstractMetaClass;
+ const TypedefEntryPtr &te = it.value();
+ auto metaClass = std::make_shared<AbstractMetaClass>();
metaClass->setTypeDef(true);
metaClass->setTypeEntry(te->target());
metaClass->setBaseClassNames(QStringList(te->sourceType()));
@@ -1018,9 +1078,9 @@ void AbstractMetaBuilderPrivate::traverseTypesystemTypedefs()
}
}
-AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem &dom,
+AbstractMetaClassPtr AbstractMetaBuilderPrivate::traverseClass(const FileModelItem &dom,
const ClassModelItem &classItem,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
QString className = stripTemplateArgs(classItem->name());
QString fullClassName = className;
@@ -1028,7 +1088,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
// we have inner an class
if (currentClass) {
fullClassName = stripTemplateArgs(currentClass->typeEntry()->qualifiedCppName())
- + colonColon() + fullClassName;
+ + u"::"_s + fullClassName;
}
const auto type = TypeDatabase::instance()->findComplexType(fullClassName);
@@ -1036,9 +1096,9 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
if (TypeDatabase::instance()->isClassRejected(fullClassName)) {
reason = AbstractMetaBuilder::GenerationDisabled;
- } else if (type.isNull()) {
+ } else if (!type) {
TypeEntryPtr te = TypeDatabase::instance()->findType(fullClassName);
- if (!te.isNull() && !te->isComplex()) {
+ if (te && !te->isComplex()) {
reason = AbstractMetaBuilder::RedefinedToNotClass;
// Set the default include file name
if (!te->include().isValid())
@@ -1054,11 +1114,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
QTextStream(&fullClassName) << "anonymous struct at " << classItem->fileName()
<< ':' << classItem->startLine();
}
- m_rejectedClasses.insert(fullClassName, reason);
+ m_rejectedClasses.insert({reason, fullClassName, fullClassName, QString{}});
return nullptr;
}
- auto *metaClass = new AbstractMetaClass;
+ auto metaClass = std::make_shared<AbstractMetaClass>();
metaClass->setSourceLocation(classItem->sourceLocation());
metaClass->setTypeEntry(type);
if ((type->typeFlags() & ComplexTypeEntry::ForceAbstract) != 0)
@@ -1094,7 +1154,8 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
auto argumentParent = typeSystemTypeEntry(metaClass->typeEntry());
for (qsizetype i = 0; i < template_parameters.size(); ++i) {
const TemplateParameterModelItem &param = template_parameters.at(i);
- auto param_type = new TemplateArgumentEntry(param->name(), type->version(),
+ auto param_type =
+ std::make_shared<TemplateArgumentEntry>(param->name(), type->version(),
argumentParent);
param_type->setOrdinal(i);
template_args.append(TypeEntryCPtr(param_type));
@@ -1109,11 +1170,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
{
const ClassList &innerClasses = classItem->classes();
for (const ClassModelItem &ci : innerClasses) {
- AbstractMetaClass *cl = traverseClass(dom, ci, metaClass);
+ const auto cl = traverseClass(dom, ci, metaClass);
if (cl) {
cl->setEnclosingClass(metaClass);
metaClass->addInnerClass(cl);
- addAbstractMetaClass(cl, ci.data());
+ addAbstractMetaClass(cl, ci.get());
}
}
@@ -1123,10 +1184,10 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
// specific typedefs to be used as classes.
const TypeDefList typeDefs = classItem->typeDefs();
for (const TypeDefModelItem &typeDef : typeDefs) {
- AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, metaClass);
+ const auto cls = traverseTypeDef(dom, typeDef, metaClass);
if (cls) {
cls->setEnclosingClass(metaClass);
- addAbstractMetaClass(cls, typeDef.data());
+ addAbstractMetaClass(cls, typeDef.get());
}
}
@@ -1138,7 +1199,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
}
void AbstractMetaBuilderPrivate::traverseScopeMembers(const ScopeModelItem &item,
- AbstractMetaClass *metaClass)
+ const AbstractMetaClassPtr &metaClass)
{
// Classes/Namespace members
traverseFields(item, metaClass);
@@ -1152,28 +1213,25 @@ void AbstractMetaBuilderPrivate::traverseScopeMembers(const ScopeModelItem &item
void AbstractMetaBuilderPrivate::traverseClassMembers(const ClassModelItem &item)
{
- AbstractMetaClass *metaClass = m_itemToClass.value(item.data());
- if (!metaClass)
- return;
-
- // Class members
- traverseScopeMembers(item, metaClass);
+ const auto metaClass = m_itemToClass.value(item.get());
+ if (metaClass) // Class members
+ traverseScopeMembers(item, metaClass);
}
-void AbstractMetaBuilderPrivate::traverseUsingMembers(AbstractMetaClass *metaClass)
+void AbstractMetaBuilderPrivate::traverseUsingMembers(const AbstractMetaClassPtr &metaClass) const
{
const _CodeModelItem *item = m_classToItem.value(metaClass);
if (item == nullptr || item->kind() != _CodeModelItem::Kind_Class)
return;
- auto classItem = static_cast<const _ClassModelItem *>(item);
+ const auto *classItem = static_cast<const _ClassModelItem *>(item);
for (const auto &um : classItem->usingMembers()) {
QString className = um.className;
- int pos = className.indexOf(u'<'); // strip "QList<value>"
+ auto pos = className.indexOf(u'<'); // strip "QList<value>"
if (pos != -1)
className.truncate(pos);
- if (auto baseClass = metaClass->AbstractMetaClass::findBaseClass(className)) {
+ if (auto baseClass = findBaseClass(metaClass, className)) {
QString name = um.memberName;
- const int lastQualPos = name.lastIndexOf(colonColon());
+ const auto lastQualPos = name.lastIndexOf(u"::"_s);
if (lastQualPos != -1)
name.remove(0, lastQualPos + 2);
metaClass->addUsingMember({name, baseClass, um.access});
@@ -1187,7 +1245,7 @@ void AbstractMetaBuilderPrivate::traverseUsingMembers(AbstractMetaClass *metaCla
void AbstractMetaBuilderPrivate::traverseNamespaceMembers(const NamespaceModelItem &item)
{
- AbstractMetaClass *metaClass = m_itemToClass.value(item.data());
+ const auto metaClass = m_itemToClass.value(item.get());
if (!metaClass)
return;
@@ -1202,18 +1260,18 @@ void AbstractMetaBuilderPrivate::traverseNamespaceMembers(const NamespaceModelIt
static inline QString fieldSignatureWithType(const VariableModelItem &field)
{
- return field->name() + QStringLiteral(" -> ") + field->type().toString();
+ return field->name() + " -> "_L1 + field->type().toString();
}
static inline QString qualifiedFieldSignatureWithType(const QString &className,
const VariableModelItem &field)
{
- return className + colonColon() + fieldSignatureWithType(field);
+ return className + u"::"_s + fieldSignatureWithType(field);
}
std::optional<AbstractMetaField>
AbstractMetaBuilderPrivate::traverseField(const VariableModelItem &field,
- const AbstractMetaClass *cls)
+ const AbstractMetaClassCPtr &cls)
{
QString fieldName = field->name();
QString className = cls->typeEntry()->qualifiedCppName();
@@ -1227,8 +1285,9 @@ std::optional<AbstractMetaField>
QString rejectReason;
if (TypeDatabase::instance()->isFieldRejected(className, fieldName, &rejectReason)) {
- m_rejectedFields.insert(qualifiedFieldSignatureWithType(className, field) + rejectReason,
- AbstractMetaBuilder::GenerationDisabled);
+ const QString signature = qualifiedFieldSignatureWithType(className, field);
+ m_rejectedFields.insert({AbstractMetaBuilder::GenerationDisabled,
+ signature, signature, rejectReason});
return {};
}
@@ -1241,7 +1300,7 @@ std::optional<AbstractMetaField>
auto metaType = translateType(fieldType, cls);
if (!metaType.has_value()) {
- const QString type = TypeInfo::resolveType(fieldType, currentScope()).qualifiedName().join(colonColon());
+ const QString type = TypeInfo::resolveType(fieldType, currentScope()).qualifiedName().join(u"::"_s);
if (cls->typeEntry()->generateCode()) {
qCWarning(lcShiboken, "%s",
qPrintable(msgSkippingField(field, cls->name(), type)));
@@ -1276,7 +1335,7 @@ static bool applyFieldModifications(AbstractMetaField *f)
}
void AbstractMetaBuilderPrivate::traverseFields(const ScopeModelItem &scope_item,
- AbstractMetaClass *metaClass)
+ const AbstractMetaClassPtr &metaClass)
{
const VariableList &variables = scope_item->variables();
for (const VariableModelItem &field : variables) {
@@ -1295,7 +1354,7 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF
return;
TypeDatabase *types = TypeDatabase::instance();
- static const QRegularExpression operatorRegExp(QStringLiteral("^operator "));
+ static const QRegularExpression operatorRegExp("^operator "_L1);
Q_ASSERT(operatorRegExp.isValid());
QString castTo = metaFunction->name().remove(operatorRegExp).trimmed();
@@ -1305,7 +1364,7 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF
castTo.remove(0, 6);
TypeEntryPtr retType = types->findType(castTo);
- if (retType.isNull())
+ if (!retType)
return;
AbstractMetaType metaType(retType);
@@ -1316,7 +1375,7 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF
AbstractMetaFunctionRawPtrList
AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem,
AbstractMetaClass::Attributes *constructorAttributes,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
*constructorAttributes = {};
AbstractMetaFunctionRawPtrList result;
@@ -1328,7 +1387,7 @@ AbstractMetaFunctionRawPtrList
traverseOperatorFunction(function, currentClass);
} else if (function->isSpaceshipOperator() && !function->isDeleted()) {
if (currentClass)
- currentClass->addSynthesizedComparisonOperators();
+ AbstractMetaClass::addSynthesizedComparisonOperators(currentClass);
} else if (auto *metaFunction = traverseFunction(function, currentClass)) {
result.append(metaFunction);
} else if (!function->isDeleted() && function->functionType() == CodeModel::Constructor) {
@@ -1341,8 +1400,8 @@ AbstractMetaFunctionRawPtrList
return result;
}
-void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
- AbstractMetaClass *metaClass)
+void AbstractMetaBuilderPrivate::traverseFunctions(const ScopeModelItem& scopeItem,
+ const AbstractMetaClassPtr &metaClass)
{
AbstractMetaClass::Attributes constructorAttributes;
const AbstractMetaFunctionRawPtrList functions =
@@ -1351,7 +1410,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
for (AbstractMetaFunction *metaFunction : functions) {
if (metaClass->isNamespace())
- *metaFunction += AbstractMetaFunction::Static;
+ metaFunction->setCppAttribute(FunctionAttribute::Static);
const auto propertyFunction = metaClass->searchPropertyFunction(metaFunction->name());
if (propertyFunction.index >= 0) {
@@ -1392,18 +1451,12 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
}
}
- const bool isInvalidDestructor = metaFunction->isDestructor() && metaFunction->isPrivate();
- const bool isInvalidConstructor = metaFunction->functionType() == AbstractMetaFunction::ConstructorFunction
- && metaFunction->isPrivate();
- if (isInvalidConstructor)
+ if (metaFunction->functionType() == AbstractMetaFunction::ConstructorFunction
+ && metaFunction->isPrivate()) {
metaClass->setHasPrivateConstructor(true);
- if ((isInvalidDestructor || isInvalidConstructor)
- && !metaClass->hasNonPrivateConstructor()) {
- *metaClass += AbstractMetaClass::FinalInTargetLang;
- } else if (metaFunction->isConstructor() && !metaFunction->isPrivate()) {
- *metaClass -= AbstractMetaClass::FinalInTargetLang;
- metaClass->setHasNonPrivateConstructor(true);
}
+ if (metaFunction->isConstructor() && !metaFunction->isPrivate()) // Including Copy CT
+ metaClass->setHasNonPrivateConstructor(true);
if (!metaFunction->isDestructor()
&& !(metaFunction->isPrivate() && metaFunction->functionType() == AbstractMetaFunction::ConstructorFunction)) {
@@ -1414,7 +1467,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
if (metaFunction->isConversionOperator())
fixReturnTypeOfConversionOperator(metaFunction);
- metaClass->addFunction(AbstractMetaFunctionCPtr(metaFunction));
+ AbstractMetaClass::addFunction(metaClass, AbstractMetaFunctionCPtr(metaFunction));
applyFunctionModifications(metaFunction);
} else if (metaFunction->isDestructor()) {
metaClass->setHasPrivateDestructor(metaFunction->isPrivate());
@@ -1430,7 +1483,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
fillAddedFunctions(metaClass);
}
-void AbstractMetaBuilderPrivate::fillAddedFunctions(AbstractMetaClass *metaClass)
+void AbstractMetaBuilderPrivate::fillAddedFunctions(const AbstractMetaClassPtr &metaClass)
{
// Add the functions added by the typesystem
QString errorMessage;
@@ -1494,26 +1547,17 @@ void AbstractMetaBuilderPrivate::applyFunctionModifications(AbstractMetaFunction
func->setOriginalName(func->name());
func->setName(mod.renamedToName());
} else if (mod.isAccessModifier()) {
- funcRef -= AbstractMetaFunction::Friendly;
-
if (mod.isPublic())
funcRef.modifyAccess(Access::Public);
else if (mod.isProtected())
funcRef.modifyAccess(Access::Protected);
else if (mod.isPrivate())
funcRef.modifyAccess(Access::Private);
- else if (mod.isFriendly())
- funcRef += AbstractMetaFunction::Friendly;
}
-
- if (mod.isFinal())
- funcRef += AbstractMetaFunction::FinalInTargetLang;
- else if (mod.isNonFinal())
- funcRef -= AbstractMetaFunction::FinalInTargetLang;
}
}
-bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
+bool AbstractMetaBuilderPrivate::setupInheritance(const AbstractMetaClassPtr &metaClass)
{
if (metaClass->inheritanceDone())
return true;
@@ -1526,11 +1570,12 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
if (baseClasses.size() == 1 && baseClasses.constFirst().contains(u'<')) {
TypeInfo info;
ComplexTypeEntryPtr baseContainerType;
- auto *templ = findTemplateClass(baseClasses.constFirst(), metaClass,
- &info, &baseContainerType);
+ const auto templ = findTemplateClass(baseClasses.constFirst(), metaClass,
+ &info, &baseContainerType);
if (templ) {
setupInheritance(templ);
- inheritTemplate(metaClass, templ, info);
+ if (!inheritTemplate(metaClass, templ, info))
+ return false;
metaClass->typeEntry()->setBaseContainerType(templ->typeEntry());
return true;
}
@@ -1547,9 +1592,9 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
return true;
}
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("template baseclass '%1' of '%2' is not known")
- .arg(baseClasses.constFirst(), metaClass->name());
+ qCWarning(lcShiboken, "template baseclass '%s' of '%s' is not known",
+ qPrintable(baseClasses.constFirst()),
+ qPrintable(metaClass->name()));
return false;
}
@@ -1584,7 +1629,7 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
} else {
QString message;
QTextStream(&message) << "Class \"" << defaultSuperclassName
- << "\" specified as \"default-superclass\" of \"" << metaClass->name()
+ << R"(" specified as "default-superclass" of ")" << metaClass->name()
<< "\" could not be found in the code model.";
qCWarning(lcShiboken, "%s", qPrintable(message));
}
@@ -1594,7 +1639,7 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
}
void AbstractMetaBuilderPrivate::traverseEnums(const ScopeModelItem &scopeItem,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
const QStringList &enumsDeclarations)
{
const EnumList &enums = scopeItem->enums();
@@ -1642,7 +1687,7 @@ bool AbstractMetaBuilderPrivate::traverseAddedGlobalFunction(const AddedFunction
AbstractMetaFunction *
AbstractMetaBuilderPrivate::traverseAddedFunctionHelper(const AddedFunctionPtr &addedFunc,
- AbstractMetaClass *metaClass /* = nullptr */,
+ const AbstractMetaClassPtr &metaClass /* = {} */,
QString *errorMessage)
{
auto returnType = translateType(addedFunc->returnType(), metaClass, {}, errorMessage);
@@ -1654,7 +1699,7 @@ AbstractMetaFunction *
return nullptr;
}
- auto metaFunction = new AbstractMetaFunction(addedFunc);
+ auto *metaFunction = new AbstractMetaFunction(addedFunc);
metaFunction->setType(returnType.value());
metaFunction->setFunctionType(functionTypeFromName(addedFunc->name()));
@@ -1711,6 +1756,7 @@ AbstractMetaFunction *
// Find the correct default values
const FunctionModificationList functionMods = metaFunction->modifications(metaClass);
+ applyCachedFunctionModifications(metaFunction, functionMods);
for (qsizetype i = 0; i < metaArguments.size(); ++i) {
AbstractMetaArgument &metaArg = metaArguments[i];
@@ -1726,7 +1772,7 @@ AbstractMetaFunction *
}
bool AbstractMetaBuilderPrivate::traverseAddedMemberFunction(const AddedFunctionPtr &addedFunc,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
QString *errorMessage)
{
AbstractMetaFunction *metaFunction =
@@ -1736,7 +1782,7 @@ bool AbstractMetaBuilderPrivate::traverseAddedMemberFunction(const AddedFunction
const AbstractMetaArgumentList fargs = metaFunction->arguments();
if (metaClass->isNamespace())
- *metaFunction += AbstractMetaFunction::Static;
+ metaFunction->setCppAttribute(FunctionAttribute::Static);
if (metaFunction->name() == metaClass->name()) {
metaFunction->setFunctionType(AbstractMetaFunction::ConstructorFunction);
if (fargs.size() == 1) {
@@ -1750,7 +1796,7 @@ bool AbstractMetaBuilderPrivate::traverseAddedMemberFunction(const AddedFunction
metaFunction->setDeclaringClass(metaClass);
metaFunction->setImplementingClass(metaClass);
- metaClass->addFunction(AbstractMetaFunctionCPtr(metaFunction));
+ AbstractMetaClass::addFunction(metaClass, AbstractMetaFunctionCPtr(metaFunction));
metaClass->setHasNonPrivateConstructor(true);
return true;
}
@@ -1786,7 +1832,7 @@ static inline QString qualifiedFunctionSignatureWithType(const FunctionModelItem
{
QString result = functionItem->type().toString() + u' ';
if (!className.isEmpty())
- result += className + colonColon();
+ result += className + u"::"_s;
result += functionSignature(functionItem);
return result;
}
@@ -1898,9 +1944,48 @@ static bool applyArrayArgumentModifications(const FunctionModificationList &func
return true;
}
+// Create the meta type for a view (std::string_view -> std::string)
+static AbstractMetaType createViewOnType(const AbstractMetaType &metaType,
+ const TypeEntryCPtr &viewOnTypeEntry)
+{
+ auto result = metaType;
+ result.setTypeEntry(viewOnTypeEntry);
+ if (!metaType.isContainer() || !viewOnTypeEntry->isContainer())
+ return result;
+ // For containers, when sth with several template parameters
+ // (std::span<T, int N>) is mapped onto a std::vector<T>,
+ // remove the superfluous template parameters and strip 'const'.
+ const auto vcte = std::static_pointer_cast<const ContainerTypeEntry>(viewOnTypeEntry);
+ const auto &instantiations = metaType.instantiations();
+ AbstractMetaTypeList viewInstantiations;
+ const auto size = std::min(vcte->templateParameterCount(), instantiations.size());
+ for (qsizetype i = 0; i < size; ++i) {
+ auto ins = instantiations.at(i);
+ ins.setConstant(false);
+ viewInstantiations.append(ins);
+ }
+ result.setInstantiations(viewInstantiations);
+ return result;
+}
+
+void AbstractMetaBuilderPrivate::rejectFunction(const FunctionModelItem &functionItem,
+ const AbstractMetaClassPtr &currentClass,
+ AbstractMetaBuilder::RejectReason reason,
+ const QString &rejectReason)
+{
+ QString sortKey;
+ if (currentClass)
+ sortKey += currentClass->typeEntry()->qualifiedCppName() + u"::"_s;
+ sortKey += functionSignature(functionItem); // Sort without return type
+ const QString signatureWithType = functionItem->type().toString() + u' ' + sortKey;
+ m_rejectedFunctions.insert({reason, signatureWithType, sortKey, rejectReason});
+}
+
AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
+ const auto *tdb = TypeDatabase::instance();
+
if (!functionItem->templateParameters().isEmpty())
return nullptr;
@@ -1941,20 +2026,17 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
}
} // PySide extensions
- // Store original signature with unresolved typedefs for message/log purposes
- const QString originalQualifiedSignatureWithReturn =
- qualifiedFunctionSignatureWithType(functionItem, className);
-
QString rejectReason;
- if (TypeDatabase::instance()->isFunctionRejected(className, functionName, &rejectReason)) {
- m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled);
+ if (tdb->isFunctionRejected(className, functionName, &rejectReason)) {
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, rejectReason);
return nullptr;
}
- const QString &signature = functionSignature(functionItem);
- const bool rejected =
- TypeDatabase::instance()->isFunctionRejected(className, signature, &rejectReason);
- if (rejected) {
+ const QString &signature = functionSignature(functionItem);
+ if (tdb->isFunctionRejected(className, signature, &rejectReason)) {
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, rejectReason);
if (ReportHandler::isDebug(ReportHandler::MediumDebug)) {
qCInfo(lcShiboken, "%s::%s was rejected by the type database (%s).",
qPrintable(className), qPrintable(signature), qPrintable(rejectReason));
@@ -1965,15 +2047,17 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
if (functionItem->isFriend())
return nullptr;
- const bool deprecated = functionItem->isDeprecated();
+ const auto cppAttributes = functionItem->attributes();
+ const bool deprecated = cppAttributes.testFlag(FunctionAttribute::Deprecated);
if (deprecated && m_skipDeprecated) {
- m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + u" is deprecated."_s,
- AbstractMetaBuilder::GenerationDisabled);
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, u" is deprecated."_s);
return nullptr;
}
AbstractMetaFunction::Flags flags;
auto *metaFunction = new AbstractMetaFunction(functionName);
+ metaFunction->setCppAttributes(cppAttributes);
const QByteArray cSignature = signature.toUtf8();
const QString unresolvedSignature =
QString::fromUtf8(QMetaObject::normalizedSignature(cSignature.constData()));
@@ -1981,35 +2065,12 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
if (functionItem->isHiddenFriend())
flags.setFlag(AbstractMetaFunction::Flag::HiddenFriend);
metaFunction->setSourceLocation(functionItem->sourceLocation());
- if (deprecated)
- *metaFunction += AbstractMetaFunction::Deprecated;
// Additional check for assignment/move assignment down below
metaFunction->setFunctionType(functionTypeFromCodeModel(functionItem->functionType()));
metaFunction->setConstant(functionItem->isConstant());
metaFunction->setExceptionSpecification(functionItem->exceptionSpecification());
- if (functionItem->isAbstract())
- *metaFunction += AbstractMetaFunction::Abstract;
-
- if (functionItem->isVirtual()) {
- *metaFunction += AbstractMetaFunction::VirtualCppMethod;
- if (functionItem->isOverride())
- *metaFunction += AbstractMetaFunction::OverriddenCppMethod;
- if (functionItem->isFinal())
- *metaFunction += AbstractMetaFunction::FinalCppMethod;
- } else {
- *metaFunction += AbstractMetaFunction::FinalInTargetLang;
- }
-
- if (functionItem->isInvokable())
- *metaFunction += AbstractMetaFunction::Invokable;
-
- if (functionItem->isStatic()) {
- *metaFunction += AbstractMetaFunction::Static;
- *metaFunction += AbstractMetaFunction::FinalInTargetLang;
- }
-
// Access rights
metaFunction->setAccess(functionItem->accessPolicy());
@@ -2019,25 +2080,30 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
metaFunction->setType(AbstractMetaType::createVoid());
break;
case AbstractMetaFunction::ConstructorFunction:
- metaFunction->setExplicit(functionItem->isExplicit());
metaFunction->setName(currentClass->name());
metaFunction->setType(AbstractMetaType::createVoid());
break;
default: {
TypeInfo returnType = functionItem->type();
- if (TypeDatabase::instance()->isReturnTypeRejected(className, returnType.toString(), &rejectReason)) {
- m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled);
+ if (tdb->isReturnTypeRejected(className, returnType.toString(), &rejectReason)) {
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, rejectReason);
delete metaFunction;
return nullptr;
}
- auto type = translateType(returnType, currentClass, {}, &errorMessage);
+ TranslateTypeFlags flags;
+ if (functionItem->scopeResolution())
+ flags.setFlag(AbstractMetaBuilder::NoClassScopeLookup);
+ auto type = translateType(returnType, currentClass, flags, &errorMessage);
if (!type.has_value()) {
const QString reason = msgUnmatchedReturnType(functionItem, errorMessage);
+ const QString signature = qualifiedFunctionSignatureWithType(functionItem, className);
qCWarning(lcShiboken, "%s",
- qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason)));
- m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn, AbstractMetaBuilder::UnmatchedReturnType);
+ qPrintable(msgSkippingFunction(functionItem, signature, reason)));
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::UnmatchedReturnType, reason);
delete metaFunction;
return nullptr;
}
@@ -2067,30 +2133,37 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
for (qsizetype i = 0; i < arguments.size(); ++i) {
const ArgumentModelItem &arg = arguments.at(i);
- if (TypeDatabase::instance()->isArgumentTypeRejected(className, arg->type().toString(), &rejectReason)) {
- m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled);
+ if (tdb->isArgumentTypeRejected(className, arg->type().toString(), &rejectReason)) {
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, rejectReason);
delete metaFunction;
return nullptr;
}
- auto metaTypeO = translateType(arg->type(), currentClass, {}, &errorMessage);
+ TranslateTypeFlags flags;
+ if (arg->scopeResolution())
+ flags.setFlag(AbstractMetaBuilder::NoClassScopeLookup);
+ auto metaTypeO = translateType(arg->type(), currentClass, flags, &errorMessage);
if (!metaTypeO.has_value()) {
// If an invalid argument has a default value, simply remove it
// unless the function is virtual (since the override in the
// wrapper can then not correctly be generated).
- if (arg->defaultValue() && !functionItem->isVirtual()) {
+ if (arg->defaultValue()
+ && !functionItem->attributes().testFlag(FunctionAttribute::Virtual)) {
if (!currentClass || currentClass->typeEntry()->generateCode()) {
+ const QString signature = qualifiedFunctionSignatureWithType(functionItem, className);
qCWarning(lcShiboken, "%s",
- qPrintable(msgStrippingArgument(functionItem, i, originalQualifiedSignatureWithReturn, arg)));
+ qPrintable(msgStrippingArgument(functionItem, i, signature,
+ arg, errorMessage)));
}
break;
}
const QString reason = msgUnmatchedParameterType(arg, i, errorMessage);
+ const QString signature = qualifiedFunctionSignatureWithType(functionItem, className);
qCWarning(lcShiboken, "%s",
- qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason)));
- const QString rejectedFunctionSignature = originalQualifiedSignatureWithReturn
- + u": "_s + reason;
- m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedArgumentType);
+ qPrintable(msgSkippingFunction(functionItem, signature, reason)));
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::UnmatchedArgumentType, reason);
delete metaFunction;
return nullptr;
}
@@ -2101,10 +2174,8 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
auto viewOnTypeEntry = metaType.typeEntry()->viewOn();
if (viewOnTypeEntry != nullptr && metaType.indirections() == 0
&& metaType.arrayElementType() == nullptr
- && !metaType.hasInstantiations()) {
- auto viewOn = metaType;
- viewOn.setTypeEntry(viewOnTypeEntry);
- metaType.setViewOn(viewOn);
+ && (!metaType.hasInstantiations() || metaType.isContainer())) {
+ metaType.setViewOn(createViewOnType(metaType, viewOnTypeEntry));
}
AbstractMetaArgument metaArgument;
@@ -2120,12 +2191,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
? AbstractMetaFunction::findClassModifications(metaFunction, currentClass)
: AbstractMetaFunction::findGlobalModifications(metaFunction);
- for (const FunctionModification &mod : functionMods) {
- if (mod.exceptionHandling() != TypeSystem::ExceptionHandling::Unspecified)
- metaFunction->setExceptionHandlingModification(mod.exceptionHandling());
- if (mod.allowThread() != TypeSystem::AllowThread::Unspecified)
- metaFunction->setAllowThreadModification(mod.allowThread());
- }
+ applyCachedFunctionModifications(metaFunction, functionMods);
// Find the correct default values
for (qsizetype i = 0, size = metaArguments.size(); i < size; ++i) {
@@ -2186,13 +2252,13 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
return metaFunction;
}
-static TypeEntryCPtr findTypeEntryUsingContext(const AbstractMetaClass *metaClass,
+static TypeEntryCPtr findTypeEntryUsingContext(const AbstractMetaClassCPtr &metaClass,
const QString& qualifiedName)
{
TypeEntryCPtr type;
- QStringList context = metaClass->qualifiedCppName().split(colonColon());
+ QStringList context = metaClass->qualifiedCppName().split(u"::"_s);
while (!type && !context.isEmpty()) {
- type = TypeDatabase::instance()->findType(context.join(colonColon()) + colonColon() + qualifiedName);
+ type = TypeDatabase::instance()->findType(context.join(u"::"_s) + u"::"_s + qualifiedName);
context.removeLast();
}
return type;
@@ -2201,18 +2267,20 @@ static TypeEntryCPtr findTypeEntryUsingContext(const AbstractMetaClass *metaClas
// Helper for findTypeEntries/translateTypeStatic()
TypeEntryCList AbstractMetaBuilderPrivate::findTypeEntriesHelper(const QString &qualifiedName,
const QString &name,
- const AbstractMetaClass *currentClass,
+ TranslateTypeFlags flags,
+ const AbstractMetaClassCPtr &currentClass,
AbstractMetaBuilderPrivate *d)
{
// 5.1 - Try first using the current scope
- if (currentClass) {
+ if (currentClass != nullptr
+ && !flags.testFlag(AbstractMetaBuilder::NoClassScopeLookup)) {
if (auto type = findTypeEntryUsingContext(currentClass, qualifiedName))
return {type};
// 5.1.1 - Try using the class parents' scopes
if (d && !currentClass->baseClassNames().isEmpty()) {
const auto &baseClasses = d->getBaseClasses(currentClass);
- for (const AbstractMetaClass *cls : baseClasses) {
+ for (const auto &cls : baseClasses) {
if (auto type = findTypeEntryUsingContext(cls, qualifiedName))
return {type};
}
@@ -2248,11 +2316,13 @@ TypeEntryCList AbstractMetaBuilderPrivate::findTypeEntriesHelper(const QString &
// and does some error checking.
TypeEntryCList AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualifiedName,
const QString &name,
- const AbstractMetaClass *currentClass,
+ TranslateTypeFlags flags,
+ const AbstractMetaClassCPtr &currentClass,
AbstractMetaBuilderPrivate *d,
QString *errorMessage)
{
- TypeEntryCList types = findTypeEntriesHelper(qualifiedName, name, currentClass, d);
+ TypeEntryCList types = findTypeEntriesHelper(qualifiedName, name, flags,
+ currentClass, d);
if (types.isEmpty()) {
if (errorMessage != nullptr)
*errorMessage = msgCannotFindTypeEntry(qualifiedName);
@@ -2264,7 +2334,7 @@ TypeEntryCList AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualif
for (qsizetype i = 0, size = types.size(); i < size; ++i) {
const auto &e = types.at(i);
if (e->isPrimitive()) {
- const auto pte = qSharedPointerCast<const PrimitiveTypeEntry>(e);
+ const auto pte = std::static_pointer_cast<const PrimitiveTypeEntry>(e);
types[i] = basicReferencedNonBuiltinTypeEntry(pte);
}
}
@@ -2297,10 +2367,10 @@ TypeEntryCList AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualif
// Reverse lookup of AbstractMetaType representing a template specialization
// found during traversing function arguments to its type system typedef'ed
// class.
-const AbstractMetaClass *AbstractMetaBuilderPrivate::resolveTypeSystemTypeDef(const AbstractMetaType &t) const
+AbstractMetaClassCPtr AbstractMetaBuilderPrivate::resolveTypeSystemTypeDef(const AbstractMetaType &t) const
{
if (t.hasInstantiations()) {
- auto pred = [t](const TypeClassEntry &e) { return e.type.equals(t); };
+ auto pred = [t](const TypeClassEntry &e) { return e.type == t; };
auto it = std::find_if(m_typeSystemTypeDefs.cbegin(), m_typeSystemTypeDefs.cend(), pred);
if (it != m_typeSystemTypeDefs.cend())
return it->klass;
@@ -2321,30 +2391,30 @@ static void synthesizeWarning(const AbstractMetaFunctionCPtr &f)
}
static AbstractMetaFunctionPtr
- addMethod(AbstractMetaClass *s, const AbstractMetaType &returnType,
+ addMethod(const AbstractMetaClassPtr &s, const AbstractMetaType &returnType,
const QString &name, bool isConst = true)
{
- AbstractMetaFunctionPtr function(new AbstractMetaFunction(name));
+ auto function = std::make_shared<AbstractMetaFunction>(name);
function->setType(returnType);
- s->addFunction(function);
+ AbstractMetaClass::addFunction(s, function);
function->setConstant(isConst);
synthesizeWarning(function);
return function;
}
static AbstractMetaFunctionPtr
- addMethod(AbstractMetaClass *s, const QString &returnTypeName,
+ addMethod(const AbstractMetaClassPtr &s, const QString &returnTypeName,
const QString &name, bool isConst = true)
{
auto typeEntry = TypeDatabase::instance()->findPrimitiveType(returnTypeName);
- Q_ASSERT(!typeEntry.isNull());
+ Q_ASSERT(typeEntry);
AbstractMetaType returnType(typeEntry);
returnType.decideUsagePattern();
return addMethod(s, returnType, name, isConst);
}
// Create the instantiation type of a smart pointer
-static AbstractMetaType instantiationType(const AbstractMetaClass *s,
+static AbstractMetaType instantiationType(const AbstractMetaClassCPtr &s,
const SmartPointerTypeEntryCPtr &ste)
{
AbstractMetaType type(s->templateArguments().constFirst());
@@ -2355,7 +2425,7 @@ static AbstractMetaType instantiationType(const AbstractMetaClass *s,
}
// Create the pointee argument of a smart pointer constructor or reset()
-static AbstractMetaArgument pointeeArgument(const AbstractMetaClass *s,
+static AbstractMetaArgument pointeeArgument(const AbstractMetaClassCPtr &s,
const SmartPointerTypeEntryCPtr &ste)
{
AbstractMetaArgument pointee;
@@ -2366,7 +2436,7 @@ static AbstractMetaArgument pointeeArgument(const AbstractMetaClass *s,
// Add the smart pointer constructors. For MSVC, (when not specifying
// <system-header>), clang only sees the default constructor.
-static void fixSmartPointerConstructors(AbstractMetaClass *s,
+static void fixSmartPointerConstructors(const AbstractMetaClassPtr &s,
const SmartPointerTypeEntryCPtr &ste)
{
const auto ctors = s->queryFunctions(FunctionQueryOption::Constructors);
@@ -2380,23 +2450,23 @@ static void fixSmartPointerConstructors(AbstractMetaClass *s,
}
if (!seenParameter) {
- AbstractMetaFunctionPtr constructor(new AbstractMetaFunction(s->name()));
+ auto constructor = std::make_shared<AbstractMetaFunction>(s->name());
constructor->setFunctionType(AbstractMetaFunction::ConstructorFunction);
constructor->addArgument(pointeeArgument(s, ste));
- s->addFunction(constructor);
+ AbstractMetaClass::addFunction(s, constructor);
synthesizeWarning(constructor);
}
if (!seenDefaultConstructor) {
- AbstractMetaFunctionPtr constructor(new AbstractMetaFunction(s->name()));
+ auto constructor = std::make_shared<AbstractMetaFunction>(s->name());
constructor->setFunctionType(AbstractMetaFunction::ConstructorFunction);
- s->addFunction(constructor);
+ AbstractMetaClass::addFunction(s, constructor);
synthesizeWarning(constructor);
}
}
// Similarly, add the smart pointer reset() functions
-static void fixSmartPointerReset(AbstractMetaClass *s,
+static void fixSmartPointerReset(const AbstractMetaClassPtr &s,
const SmartPointerTypeEntryCPtr &ste)
{
const QString resetMethodName = ste->resetMethod();
@@ -2411,21 +2481,21 @@ static void fixSmartPointerReset(AbstractMetaClass *s,
}
if (!seenParameter) {
- AbstractMetaFunctionPtr f(new AbstractMetaFunction(resetMethodName));
+ auto f = std::make_shared<AbstractMetaFunction>(resetMethodName);
f->addArgument(pointeeArgument(s, ste));
- s->addFunction(f);
+ AbstractMetaClass::addFunction(s, f);
synthesizeWarning(f);
}
if (!seenParameterLess) {
- AbstractMetaFunctionPtr f(new AbstractMetaFunction(resetMethodName));
- s->addFunction(f);
+ auto f = std::make_shared<AbstractMetaFunction>(resetMethodName);
+ AbstractMetaClass::addFunction(s, f);
synthesizeWarning(f);
}
}
// Add the relevant missing smart pointer functions.
-static void fixSmartPointerClass(AbstractMetaClass *s,
+static void fixSmartPointerClass(const AbstractMetaClassPtr &s,
const SmartPointerTypeEntryCPtr &ste)
{
fixSmartPointerConstructors(s, ste);
@@ -2434,43 +2504,43 @@ static void fixSmartPointerClass(AbstractMetaClass *s,
fixSmartPointerReset(s, ste);
const QString getterName = ste->getter();
- if (s->findFunction(getterName).isNull())
+ if (!s->findFunction(getterName))
addMethod(s, instantiationType(s, ste), getterName);
const QString refCountName = ste->refCountMethodName();
- if (!refCountName.isEmpty() && s->findFunction(refCountName).isNull())
+ if (!refCountName.isEmpty() && !s->findFunction(refCountName))
addMethod(s, u"int"_s, refCountName);
const QString valueCheckMethod = ste->valueCheckMethod();
- if (!valueCheckMethod.isEmpty() && s->findFunction(valueCheckMethod).isNull()) {
+ if (!valueCheckMethod.isEmpty() && !s->findFunction(valueCheckMethod)) {
auto f = addMethod(s, u"bool"_s, valueCheckMethod);
if (valueCheckMethod == u"operator bool")
f->setFunctionType(AbstractMetaFunction::ConversionOperator);
}
const QString nullCheckMethod = ste->nullCheckMethod();
- if (!nullCheckMethod.isEmpty() && s->findFunction(nullCheckMethod).isNull())
+ if (!nullCheckMethod.isEmpty() && !s->findFunction(nullCheckMethod))
addMethod(s, u"bool"_s, nullCheckMethod);
}
// Create a missing smart pointer class
-static AbstractMetaClass *createSmartPointerClass(const SmartPointerTypeEntryCPtr &ste,
- const AbstractMetaClassList &allClasses)
+static AbstractMetaClassPtr createSmartPointerClass(const SmartPointerTypeEntryCPtr &ste,
+ const AbstractMetaClassList &allClasses)
{
- auto *result = new AbstractMetaClass();
- result->setTypeEntry(qSharedPointerConstCast<SmartPointerTypeEntry>(ste));
- TypeEntryCPtr templateArg(new TemplateArgumentEntry(u"T"_s, ste->version(),
- typeSystemTypeEntry(ste)));
+ auto result = std::make_shared<AbstractMetaClass>();
+ result->setTypeEntry(std::const_pointer_cast<SmartPointerTypeEntry>(ste));
+ auto templateArg = std::make_shared<TemplateArgumentEntry>(u"T"_s, ste->version(),
+ typeSystemTypeEntry(ste));
result->setTemplateArguments({templateArg});
fixSmartPointerClass(result, ste);
auto enclosingTe = ste->parent();
if (!enclosingTe->isTypeSystem()) {
- auto *enclosing = AbstractMetaClass::findClass(allClasses, enclosingTe);
- if (enclosing == nullptr)
+ const auto enclosing = AbstractMetaClass::findClass(allClasses, enclosingTe);
+ if (!enclosing)
throw Exception(msgEnclosingClassNotFound(ste));
result->setEnclosingClass(enclosing);
auto inner = enclosing->innerClasses();
- inner.append(result);
+ inner.append(std::const_pointer_cast<const AbstractMetaClass>(result));
enclosing->setInnerClasses(inner);
}
return result;
@@ -2480,10 +2550,11 @@ void AbstractMetaBuilderPrivate::fixSmartPointers()
{
const auto smartPointerTypes = TypeDatabase::instance()->smartPointerTypes();
for (const auto &ste : smartPointerTypes) {
- const AbstractMetaClass *smartPointerClass =
+ const auto smartPointerClass =
AbstractMetaClass::findClass(m_smartPointers, ste);
if (smartPointerClass) {
- fixSmartPointerClass(const_cast<AbstractMetaClass *>(smartPointerClass), ste);
+ fixSmartPointerClass(std::const_pointer_cast<AbstractMetaClass>(smartPointerClass),
+ ste);
} else {
qCWarning(lcShiboken, "Synthesizing smart pointer \"%s\"...",
qPrintable(ste->qualifiedCppName()));
@@ -2494,7 +2565,7 @@ void AbstractMetaBuilderPrivate::fixSmartPointers()
std::optional<AbstractMetaType>
AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
- const AbstractMetaClass *currentClass,
+ const AbstractMetaClassCPtr &currentClass,
TranslateTypeFlags flags,
QString *errorMessage)
{
@@ -2507,9 +2578,16 @@ static bool isNumber(const QString &s)
[](QChar c) { return c.isDigit(); });
}
+// A type entry relevant only for non type template "X<5>"
+static bool isNonTypeTemplateArgument(const TypeEntryCPtr &te)
+{
+ const auto type = te->type();
+ return type == TypeEntry::EnumValue || type == TypeEntry::ConstantValueType;
+}
+
std::optional<AbstractMetaType>
AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei,
- const AbstractMetaClass *currentClass,
+ const AbstractMetaClassCPtr &currentClass,
AbstractMetaBuilderPrivate *d,
TranslateTypeFlags flags,
QString *errorMessageIn)
@@ -2539,7 +2617,7 @@ std::optional<AbstractMetaType>
qsizetype i = d ? d->m_scopes.size() - 1 : -1;
while (i >= 0) {
typeInfo = TypeInfo::resolveType(_typei, d->m_scopes.at(i--));
- if (typeInfo.qualifiedName().join(colonColon()) != _typei.qualifiedName().join(colonColon()))
+ if (typeInfo.qualifiedName().join(u"::"_s) != _typei.qualifiedName().join(u"::"_s))
break;
}
@@ -2563,7 +2641,7 @@ std::optional<AbstractMetaType>
bool isConstCharStarCase =
oneDimensionalArrayOfUnspecifiedSize
&& typeInfo.qualifiedName().size() == 1
- && typeInfo.qualifiedName().at(0) == QStringLiteral("char")
+ && typeInfo.qualifiedName().at(0) == "char"_L1
&& typeInfo.indirections() == 0
&& typeInfo.isConstant()
&& typeInfo.referenceType() == NoReference
@@ -2606,8 +2684,8 @@ std::optional<AbstractMetaType>
arrayType.setArrayElementCount(int(elems));
}
auto elementTypeEntry = elementType->typeEntry();
- TypeEntryCPtr at(new ArrayTypeEntry(elementTypeEntry, elementTypeEntry->version(),
- elementTypeEntry->parent()));
+ auto at = std::make_shared<ArrayTypeEntry>(elementTypeEntry, elementTypeEntry->version(),
+ elementTypeEntry->parent());
arrayType.setTypeEntry(at);
arrayType.decideUsagePattern();
@@ -2627,7 +2705,7 @@ std::optional<AbstractMetaType>
return {};
}
- QString qualifiedName = qualifierList.join(colonColon());
+ QString qualifiedName = qualifierList.join(u"::"_s);
QString name = qualifierList.takeLast();
// 4. Special case QFlags (include instantiation in name)
@@ -2636,7 +2714,16 @@ std::optional<AbstractMetaType>
typeInfo.clearInstantiations();
}
- const TypeEntryCList types = findTypeEntries(qualifiedName, name, currentClass, d, errorMessageIn);
+ TypeEntryCList types = findTypeEntries(qualifiedName, name, flags,
+ currentClass, d, errorMessageIn);
+ if (!flags.testFlag(AbstractMetaBuilder::TemplateArgument)) {
+ // Avoid clashes between QByteArray and enum value QMetaType::QByteArray
+ // unless we are looking for template arguments.
+ auto end = std::remove_if(types.begin(), types.end(),
+ isNonTypeTemplateArgument);
+ types.erase(end, types.end());
+ }
+
if (types.isEmpty()) {
if (errorMessageIn != nullptr)
*errorMessageIn = msgUnableToTranslateType(_typei, *errorMessageIn);
@@ -2656,11 +2743,13 @@ std::optional<AbstractMetaType>
const auto &templateArguments = typeInfo.instantiations();
for (qsizetype t = 0, size = templateArguments.size(); t < size; ++t) {
const TypeInfo &ti = templateArguments.at(t);
- auto targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage);
+ auto targType = translateTypeStatic(ti, currentClass, d,
+ flags | AbstractMetaBuilder::TemplateArgument,
+ &errorMessage);
// For non-type template parameters, create a dummy type entry on the fly
// as is done for classes.
if (!targType.has_value()) {
- const QString value = ti.qualifiedName().join(colonColon());
+ const QString value = ti.qualifiedName().join(u"::"_s);
if (isNumber(value)) {
auto module = typeSystemTypeEntry(type);
TypeDatabase::instance()->addConstantValueTypeEntry(value, module);
@@ -2690,7 +2779,7 @@ std::optional<AbstractMetaType>
} else {
auto it = std::find_if(types.cbegin(), types.cend(),
[instantiationType](const TypeEntryCPtr &e) {
- auto smartPtr = qSharedPointerCast<const SmartPointerTypeEntry>(e);
+ auto smartPtr = std::static_pointer_cast<const SmartPointerTypeEntry>(e);
return smartPtr->matchesInstantiation(instantiationType);
});
if (it == types.cend()) {
@@ -2724,7 +2813,7 @@ std::optional<AbstractMetaType>
std::optional<AbstractMetaType>
AbstractMetaBuilder::translateType(const TypeInfo &_typei,
- AbstractMetaClass *currentClass,
+ const AbstractMetaClassPtr &currentClass,
TranslateTypeFlags flags,
QString *errorMessage)
{
@@ -2735,7 +2824,7 @@ std::optional<AbstractMetaType>
std::optional<AbstractMetaType>
AbstractMetaBuilder::translateType(const QString &t,
- AbstractMetaClass *currentClass,
+ const AbstractMetaClassPtr &currentClass,
TranslateTypeFlags flags,
QString *errorMessageIn)
{
@@ -2765,7 +2854,7 @@ qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringV
// This is a very lame way to handle expression evaluation,
// but it is not critical and will do for the time being.
- static const QRegularExpression variableNameRegExp(QStringLiteral("^[a-zA-Z_][a-zA-Z0-9_]*$"));
+ static const QRegularExpression variableNameRegExp("^[a-zA-Z_][a-zA-Z0-9_]*$"_L1);
Q_ASSERT(variableNameRegExp.isValid());
if (!variableNameRegExp.match(stringValue).hasMatch()) {
ok = true;
@@ -2802,9 +2891,10 @@ static bool isUnderQualifiedSpec(QStringView qualifiedType, QStringView candidat
}
QString AbstractMetaBuilder::fixEnumDefault(const AbstractMetaType &type,
- const QString &expr) const
+ const QString &expr,
+ const AbstractMetaClassCPtr &klass) const
{
- return d->fixEnumDefault(type, expr);
+ return d->fixEnumDefault(type, expr, klass);
}
void AbstractMetaBuilder::setCodeModelTestMode(bool b)
@@ -2815,7 +2905,7 @@ void AbstractMetaBuilder::setCodeModelTestMode(bool b)
// Helper to fix a simple default value (field or enum reference) in a
// class context.
QString AbstractMetaBuilderPrivate::fixSimpleDefaultValue(QStringView expr,
- const AbstractMetaClass *klass) const
+ const AbstractMetaClassCPtr &klass) const
{
const QString field = qualifyStaticField(klass, expr);
@@ -2834,7 +2924,7 @@ QString AbstractMetaBuilderPrivate::fixSimpleDefaultValue(QStringView expr,
// see TestResolveType::testFixDefaultArguments()
QString AbstractMetaBuilderPrivate::fixDefaultValue(QString expr, const AbstractMetaType &type,
- const AbstractMetaClass *implementingClass) const
+ const AbstractMetaClassCPtr &implementingClass) const
{
expr.replace(u'\n', u' '); // breaks signature parser
@@ -2842,7 +2932,7 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(QString expr, const Abstract
return expr;
if (type.isFlags() || type.isEnum()) {
- expr = fixEnumDefault(type, expr);
+ expr = fixEnumDefault(type, expr, implementingClass);
} else if (type.isContainer() && expr.contains(u'<')) {
// Expand a container of a nested class, fex
// "QList<FormatRange>()" -> "QList<QTextLayout::FormatRange>()"
@@ -2917,7 +3007,7 @@ QString AbstractMetaBuilderPrivate::fixDefaultValue(QString expr, const Abstract
}
QString AbstractMetaBuilder::fixDefaultValue(const QString &expr, const AbstractMetaType &type,
- const AbstractMetaClass *c) const
+ const AbstractMetaClassCPtr &c) const
{
return d->fixDefaultValue(expr, type, c);
}
@@ -2928,23 +3018,24 @@ bool AbstractMetaBuilderPrivate::isEnum(const FileModelItem &dom, const QStringL
return item && item->kind() == _EnumModelItem::__node_kind;
}
-AbstractMetaClass *AbstractMetaBuilderPrivate::findTemplateClass(const QString &name,
- const AbstractMetaClass *context,
- TypeInfo *info,
- ComplexTypeEntryPtr *baseContainerType) const
+AbstractMetaClassPtr
+ AbstractMetaBuilderPrivate::findTemplateClass(const QString &name,
+ const AbstractMetaClassCPtr &context,
+ TypeInfo *info,
+ ComplexTypeEntryPtr *baseContainerType) const
{
if (baseContainerType)
baseContainerType->reset();
auto *types = TypeDatabase::instance();
- QStringList scope = context->typeEntry()->qualifiedCppName().split(colonColon());
+ QStringList scope = context->typeEntry()->qualifiedCppName().split(u"::"_s);
QString errorMessage;
scope.removeLast();
for (auto i = scope.size(); i >= 0; --i) {
- QString prefix = i > 0 ? QStringList(scope.mid(0, i)).join(colonColon()) + colonColon() : QString();
+ QString prefix = i > 0 ? QStringList(scope.mid(0, i)).join(u"::"_s) + u"::"_s : QString();
QString completeName = prefix + name;
const TypeInfo parsed = TypeParser::parse(completeName, &errorMessage);
- QString qualifiedName = parsed.qualifiedName().join(colonColon());
+ QString qualifiedName = parsed.qualifiedName().join(u"::"_s);
if (qualifiedName.isEmpty()) {
qWarning().noquote().nospace() << "Unable to parse type \"" << completeName
<< "\" while looking for template \"" << name << "\": " << errorMessage;
@@ -2953,8 +3044,8 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::findTemplateClass(const QString &
if (info)
*info = parsed;
- AbstractMetaClass *templ = nullptr;
- for (AbstractMetaClass *c : std::as_const(m_templates)) {
+ AbstractMetaClassPtr templ;
+ for (const auto &c : std::as_const(m_templates)) {
if (c->typeEntry()->name() == qualifiedName) {
templ = c;
break;
@@ -2975,7 +3066,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::findTemplateClass(const QString &
}
AbstractMetaClassCList
- AbstractMetaBuilderPrivate::getBaseClasses(const AbstractMetaClass *metaClass) const
+ AbstractMetaBuilderPrivate::getBaseClasses(const AbstractMetaClassCPtr &metaClass) const
{
// Shortcut if inheritance has already been set up
if (metaClass->inheritanceDone() || !metaClass->needsInheritanceSetup())
@@ -2983,11 +3074,9 @@ AbstractMetaClassCList
AbstractMetaClassCList baseClasses;
const QStringList &baseClassNames = metaClass->baseClassNames();
for (const QString& parent : baseClassNames) {
- AbstractMetaClass *cls = nullptr;
- if (parent.contains(u'<'))
- cls = findTemplateClass(parent, metaClass);
- else
- cls = AbstractMetaClass::findClass(m_metaClasses, parent);
+ const auto cls = parent.contains(u'<')
+ ? findTemplateClass(parent, metaClass)
+ : AbstractMetaClass::findClass(m_metaClasses, parent);
if (cls)
baseClasses << cls;
@@ -3007,7 +3096,7 @@ std::optional<AbstractMetaType>
returned.setOriginalTemplateType(metaType);
if (returned.typeEntry()->isTemplateArgument()) {
- const auto tae = qSharedPointerCast<const TemplateArgumentEntry>(returned.typeEntry());
+ const auto tae = std::static_pointer_cast<const TemplateArgumentEntry>(returned.typeEntry());
// If the template is intantiated with void we special case this as rejecting the functions that use this
// parameter from the instantiation.
@@ -3037,83 +3126,106 @@ std::optional<AbstractMetaType>
return returned;
}
-AbstractMetaClass *
+AbstractMetaClassPtr
AbstractMetaBuilder::inheritTemplateClass(const ComplexTypeEntryPtr &te,
- const AbstractMetaClass *templateClass,
- const AbstractMetaTypeList &templateTypes,
- InheritTemplateFlags flags)
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes)
{
- auto result = std::make_unique<AbstractMetaClass>();
+ auto result = std::make_shared<AbstractMetaClass>();
result->setTypeDef(true);
result->setTypeEntry(te);
- if (!AbstractMetaBuilderPrivate::inheritTemplate(result.get(), templateClass,
- templateTypes, flags)) {
- return nullptr;
+ if (!AbstractMetaBuilderPrivate::inheritTemplate(result, templateClass,
+ templateTypes)) {
+ return {};
}
- AbstractMetaBuilderPrivate::inheritTemplateFunctions(result.get());
- return result.release();
+ AbstractMetaBuilderPrivate::inheritTemplateFunctions(result);
+ return result;
}
-bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
- const AbstractMetaClass *templateClass,
+
+static std::optional<AbstractMetaType>
+ inheritTemplateParameter(const AbstractMetaClassPtr &subclass,
+ const AbstractMetaClassCPtr &templateClass,
+ const TypeInfo &info, QString *errorMessage)
+{
+ QString typeName = info.qualifiedName().join("::"_L1);
+ TypeDatabase *typeDb = TypeDatabase::instance();
+ TypeEntryPtr t;
+ // Check for a non-type template integer parameter, that is, for a base
+ // "template <int R, int C> Matrix<R, C>" and subclass
+ // "typedef Matrix<2,3> Matrix2x3;". If so, create dummy entries of
+ // EnumValueTypeEntry for the integer values encountered on the fly.
+ if (isNumber(typeName)) {
+ t = typeDb->findType(typeName);
+ if (!t) {
+ auto parent = typeSystemTypeEntry(subclass->typeEntry());
+ t = TypeDatabase::instance()->addConstantValueTypeEntry(typeName, parent);
+ }
+ } else {
+ QStringList possibleNames;
+ possibleNames << subclass->qualifiedCppName() + "::"_L1 + typeName;
+ possibleNames << templateClass->qualifiedCppName() + "::"_L1 + typeName;
+ if (subclass->enclosingClass())
+ possibleNames << subclass->enclosingClass()->qualifiedCppName() + "::"_L1 + typeName;
+ possibleNames << typeName;
+
+ for (const QString &possibleName : std::as_const(possibleNames)) {
+ t = typeDb->findType(possibleName);
+ if (t)
+ break;
+ }
+ }
+
+ if (!t) {
+ *errorMessage = msgIgnoringTemplateParameter(typeName,
+ "The corresponding type was not found in the typesystem.");
+ return std::nullopt;
+ }
+
+ if (t->isContainer()) {
+ *errorMessage = msgIgnoringTemplateParameter(typeName,
+ "Template inheritance from nested containers is not supported");
+ return std::nullopt;
+ }
+ AbstractMetaType result(t);
+ result.setConstant(info.isConstant());
+ result.setReferenceType(info.referenceType());
+ result.setIndirectionsV(info.indirectionsV());
+ result.decideUsagePattern();
+ return result;
+}
+
+bool AbstractMetaBuilderPrivate::inheritTemplate(const AbstractMetaClassPtr &subclass,
+ const AbstractMetaClassCPtr &templateClass,
const TypeInfo &info)
{
AbstractMetaTypeList templateTypes;
+ QString errorMessage;
for (const TypeInfo &i : info.instantiations()) {
- QString typeName = i.qualifiedName().join(colonColon());
- TypeDatabase *typeDb = TypeDatabase::instance();
- TypeEntryPtr t;
- // Check for a non-type template integer parameter, that is, for a base
- // "template <int R, int C> Matrix<R, C>" and subclass
- // "typedef Matrix<2,3> Matrix2x3;". If so, create dummy entries of
- // EnumValueTypeEntry for the integer values encountered on the fly.
- if (isNumber(typeName)) {
- t = typeDb->findType(typeName);
- if (!t) {
- auto parent = typeSystemTypeEntry(subclass->typeEntry());
- t = TypeDatabase::instance()->addConstantValueTypeEntry(typeName, parent);
- }
+ const auto typeO = inheritTemplateParameter(subclass, templateClass, i, &errorMessage);
+ if (typeO.has_value()) {
+ templateTypes.append(typeO.value());
} else {
- QStringList possibleNames;
- possibleNames << subclass->qualifiedCppName() + colonColon() + typeName;
- possibleNames << templateClass->qualifiedCppName() + colonColon() + typeName;
- if (subclass->enclosingClass())
- possibleNames << subclass->enclosingClass()->qualifiedCppName() + colonColon() + typeName;
- possibleNames << typeName;
-
- for (const QString &possibleName : std::as_const(possibleNames)) {
- t = typeDb->findType(possibleName);
- if (t)
- break;
- }
- }
-
- if (t) {
- AbstractMetaType temporaryType(t);
- temporaryType.setConstant(i.isConstant());
- temporaryType.setReferenceType(i.referenceType());
- temporaryType.setIndirectionsV(i.indirectionsV());
- temporaryType.decideUsagePattern();
- templateTypes << temporaryType;
- } else {
- qCWarning(lcShiboken).noquote().nospace()
- << "Ignoring template parameter " << typeName << " from "
- << info.toString() << ". The corresponding type was not found in the typesystem.";
+ errorMessage = msgInheritTemplateIssue(subclass, info, errorMessage);
+ qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
}
}
+ if (templateTypes.isEmpty()) {
+ errorMessage = msgInheritTemplateIssue(subclass, info,
+ "No template parameters could be inherited"_L1);
+ qCWarning(lcShiboken, "%s", qPrintable(errorMessage));
+ return false;
+ }
return inheritTemplate(subclass, templateClass, templateTypes);
}
-bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
- const AbstractMetaClass *templateClass,
- const AbstractMetaTypeList &templateTypes,
- InheritTemplateFlags flags)
+bool AbstractMetaBuilderPrivate::inheritTemplate(const AbstractMetaClassPtr &subclass,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes)
{
subclass->setTemplateBaseClass(templateClass);
- if (flags.testFlag(InheritTemplateFlag::SetEnclosingClass))
- subclass->setEnclosingClass(templateClass->enclosingClass());
subclass->setTemplateBaseClassInstantiations(templateTypes);
subclass->setBaseClass(templateClass->baseClass());
return true;
@@ -3157,11 +3269,11 @@ AbstractMetaFunctionPtr
AbstractMetaFunctionPtr
AbstractMetaBuilderPrivate::inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
const AbstractMetaTypeList &templateTypes,
- const AbstractMetaClass *templateClass,
- AbstractMetaClass *subclass)
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass)
{
AbstractMetaFunctionPtr f = inheritTemplateFunction(function, templateTypes);
- if (f.isNull())
+ if (!f)
return {};
// There is no base class in the target language to inherit from here, so
@@ -3215,8 +3327,8 @@ AbstractMetaFunctionPtr
AbstractMetaFunctionPtr
AbstractMetaBuilder::inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
const AbstractMetaTypeList &templateTypes,
- const AbstractMetaClass *templateClass,
- AbstractMetaClass *subclass)
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass)
{
return AbstractMetaBuilderPrivate::inheritTemplateMember(function, templateTypes,
templateClass, subclass);
@@ -3224,8 +3336,8 @@ AbstractMetaFunctionPtr
static bool doInheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
const AbstractMetaFunctionCList &existingSubclassFuncs,
- const AbstractMetaClass *templateBaseClass,
- const AbstractMetaClass *subclass)
+ const AbstractMetaClassCPtr &templateBaseClass,
+ const AbstractMetaClassCPtr &subclass)
{
// If the function is modified or the instantiation has an equally named
// function we are shadowing, so we need to skip it (unless the subclass
@@ -3238,7 +3350,7 @@ static bool doInheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
|| subclass->isUsingMember(templateBaseClass, function->name(), Access::Protected);
}
-void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *subclass)
+void AbstractMetaBuilderPrivate::inheritTemplateFunctions(const AbstractMetaClassPtr &subclass)
{
auto templateClass = subclass->templateBaseClass();
@@ -3259,8 +3371,8 @@ void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *sub
templateClass, subclass)) {
AbstractMetaFunctionCPtr f = inheritTemplateMember(function, templateTypes,
templateClass, subclass);
- if (!f.isNull())
- subclass->addFunction(f);
+ if (f)
+ AbstractMetaClass::addFunction(subclass, f);
}
}
@@ -3285,7 +3397,7 @@ void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *sub
}
}
-void AbstractMetaBuilderPrivate::parseQ_Properties(AbstractMetaClass *metaClass,
+void AbstractMetaBuilderPrivate::parseQ_Properties(const AbstractMetaClassPtr &metaClass,
const QStringList &declarations)
{
const QStringList scopes = currentScope()->qualifiedName();
@@ -3296,7 +3408,7 @@ void AbstractMetaBuilderPrivate::parseQ_Properties(AbstractMetaClass *metaClass,
if (spec.has_value()) {
spec->setIndex(i);
metaClass->addPropertySpec(spec.value());
- } else {
+ } else if (!errorMessage.isEmpty()) {
QString message;
QTextStream str(&message);
str << metaClass->sourceLocation() << errorMessage;
@@ -3325,24 +3437,35 @@ void AbstractMetaBuilderPrivate::parseQ_Properties(AbstractMetaClass *metaClass,
}
}
-void AbstractMetaBuilderPrivate::setupExternalConversion(const AbstractMetaClass *cls)
+void AbstractMetaBuilderPrivate::setupExternalConversion(const AbstractMetaClassCPtr &cls)
{
const auto &convOps = cls->operatorOverloads(OperatorQueryOption::ConversionOp);
for (const auto &func : convOps) {
if (func->isModifiedRemoved())
continue;
- AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, func->type().typeEntry());
+ const auto metaClass =
+ AbstractMetaClass::findClass(m_metaClasses, func->type().typeEntry());
if (!metaClass)
continue;
metaClass->addExternalConversionOperator(func);
}
- for (auto *innerClass : cls->innerClasses())
+ for (const auto &innerClass : cls->innerClasses())
setupExternalConversion(innerClass);
}
static void writeRejectLogFile(const QString &name,
- const QMap<QString, AbstractMetaBuilder::RejectReason> &rejects)
-{
+ const AbstractMetaBuilderPrivate::RejectSet &rejects)
+{
+ static const QHash<AbstractMetaBuilder::RejectReason, QByteArray> descriptions ={
+ {AbstractMetaBuilder::NotInTypeSystem, "Not in type system"_ba},
+ {AbstractMetaBuilder::GenerationDisabled, "Generation disabled by type system"_ba},
+ {AbstractMetaBuilder::RedefinedToNotClass, "Type redefined to not be a class"_ba},
+ {AbstractMetaBuilder::UnmatchedReturnType, "Unmatched return type"_ba},
+ {AbstractMetaBuilder::UnmatchedArgumentType, "Unmatched argument type"_ba},
+ {AbstractMetaBuilder::UnmatchedOperator, "Unmatched operator"_ba},
+ {AbstractMetaBuilder::Deprecated, "Deprecated"_ba}
+ };
+
QFile f(name);
if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
qCWarning(lcShiboken, "%s", qPrintable(msgCannotOpenForWriting(f)));
@@ -3351,53 +3474,19 @@ static void writeRejectLogFile(const QString &name,
QTextStream s(&f);
-
- for (int reason = 0; reason < AbstractMetaBuilder::NoReason; ++reason) {
- s << QByteArray(72, '*') << '\n';
- switch (reason) {
- case AbstractMetaBuilder::NotInTypeSystem:
- s << "Not in type system";
- break;
- case AbstractMetaBuilder::GenerationDisabled:
- s << "Generation disabled by type system";
- break;
- case AbstractMetaBuilder::RedefinedToNotClass:
- s << "Type redefined to not be a class";
- break;
-
- case AbstractMetaBuilder::UnmatchedReturnType:
- s << "Unmatched return type";
- break;
-
- case AbstractMetaBuilder::UnmatchedArgumentType:
- s << "Unmatched argument type";
- break;
-
- case AbstractMetaBuilder::ApiIncompatible:
- s << "Incompatible API";
- break;
-
- case AbstractMetaBuilder::Deprecated:
- s << "Deprecated";
- break;
-
- default:
- s << "unknown reason";
- break;
- }
-
- s << Qt::endl;
-
- for (QMap<QString, AbstractMetaBuilder::RejectReason>::const_iterator it = rejects.constBegin();
- it != rejects.constEnd(); ++it) {
- if (it.value() != reason)
- continue;
- s << " - " << it.key() << Qt::endl;
+ int lastReason = -1;
+ for (const auto &e : rejects) {
+ if (e.reason != lastReason) {
+ const QByteArray description = descriptions.value(e.reason, "Unknown reason"_ba);
+ const QByteArray underline(description.size(), '*');
+ if (lastReason != -1)
+ s << '\n';
+ s << underline << '\n' << description << '\n' << underline << "\n\n";
+ lastReason = e.reason;
}
- s << QByteArray(72, '*') << "\n\n";
+ s << " - " << e << '\n';
}
-
}
void AbstractMetaBuilderPrivate::dumpLog() const
@@ -3412,10 +3501,10 @@ void AbstractMetaBuilderPrivate::dumpLog() const
// AbstractMetaClassList/AbstractMetaClassCList.
// Add a dependency of the class associated with typeEntry on clazz.
template <class MetaClass>
-static bool addClassDependency(const QList<MetaClass *> &classList,
+static bool addClassDependency(const QList<std::shared_ptr<MetaClass> > &classList,
const TypeEntryCPtr &typeEntry,
- MetaClass *clazz,
- Graph<MetaClass *> *graph)
+ std::shared_ptr<MetaClass> clazz,
+ Graph<std::shared_ptr<MetaClass> > *graph)
{
if (!typeEntry->isComplex() || typeEntry == clazz->typeEntry())
return false;
@@ -3426,10 +3515,11 @@ static bool addClassDependency(const QList<MetaClass *> &classList,
}
template <class MetaClass>
-static QList<MetaClass *> topologicalSortHelper(const QList<MetaClass *> &classList,
- const Dependencies &additionalDependencies)
+static QList<std::shared_ptr<MetaClass> >
+ topologicalSortHelper(const QList<std::shared_ptr<MetaClass> > &classList,
+ const Dependencies &additionalDependencies)
{
- Graph<MetaClass *> graph(classList.cbegin(), classList.cend());
+ Graph<std::shared_ptr<MetaClass> > graph(classList.cbegin(), classList.cend());
for (const auto &dep : additionalDependencies) {
if (!graph.addEdge(dep.parent, dep.child)) {
@@ -3439,14 +3529,14 @@ static QList<MetaClass *> topologicalSortHelper(const QList<MetaClass *> &classL
}
}
- for (auto *clazz : classList) {
+ for (const auto &clazz : classList) {
if (auto enclosingC = clazz->enclosingClass()) {
- auto enclosing = const_cast<AbstractMetaClass *>(enclosingC);
+ const auto enclosing = std::const_pointer_cast<MetaClass>(enclosingC);
graph.addEdge(enclosing, clazz);
}
- for (auto baseClass : clazz->baseClasses())
- graph.addEdge(const_cast<MetaClass *>(baseClass), clazz);
+ for (const auto &baseClass : clazz->baseClasses())
+ graph.addEdge(std::const_pointer_cast<MetaClass>(baseClass), clazz);
for (const auto &func : clazz->functions()) {
const AbstractMetaArgumentList &arguments = func->arguments();
@@ -3474,16 +3564,22 @@ static QList<MetaClass *> topologicalSortHelper(const QList<MetaClass *> &classL
if (!result.isValid() && graph.nodeCount()) {
QTemporaryFile tempFile(QDir::tempPath() + u"/cyclic_depXXXXXX.dot"_s);
tempFile.setAutoRemove(false);
- tempFile.open();
- graph.dumpDot(tempFile.fileName(),
- [] (const AbstractMetaClass *c) { return c->name(); });
+ const bool ok = tempFile.open();
+ if (ok) {
+ graph.dumpDot(tempFile.fileName(),
+ [] (const AbstractMetaClassCPtr &c) { return c->name(); });
+ }
QString message;
QTextStream str(&message);
str << "Cyclic dependency of classes found:";
- for (auto c : result.cyclic)
+ for (const auto &c : result.cyclic)
str << ' ' << c->name();
- str << ". Graph can be found at \"" << QDir::toNativeSeparators(tempFile.fileName()) << '"';
+ str << '.';
+ if (ok) {
+ str << " Graph can be found at \""
+ << QDir::toNativeSeparators(tempFile.fileName()) << '"';
+ }
qCWarning(lcShiboken, "%s", qPrintable(message));
}
@@ -3517,8 +3613,8 @@ void AbstractMetaBuilderPrivate::pushScope(const NamespaceModelItem &item)
}
}
if (candidates.size() > 1) {
- NamespaceModelItem joined(new _NamespaceModelItem(m_scopes.constLast()->model(),
- name, _CodeModelItem::Kind_Namespace));
+ auto joined = std::make_shared<_NamespaceModelItem>(m_scopes.constLast()->model(),
+ name, _CodeModelItem::Kind_Namespace);
joined->setScope(item->scope());
for (const auto &n : candidates)
joined->appendNamespace(*n);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
index 04069cefc..20261ed3c 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
@@ -29,13 +29,15 @@ class TypeEntry;
class AbstractMetaBuilder
{
public:
+ Q_DISABLE_COPY_MOVE(AbstractMetaBuilder)
+
enum RejectReason {
NotInTypeSystem,
GenerationDisabled,
RedefinedToNotClass,
UnmatchedArgumentType,
UnmatchedReturnType,
- ApiIncompatible,
+ UnmatchedOperator,
Deprecated,
NoReason
};
@@ -52,6 +54,7 @@ public:
const AbstractMetaFunctionCList &globalFunctions() const;
const AbstractMetaEnumList &globalEnums() const;
const QHash<TypeEntryCPtr, AbstractMetaEnum> &typeEntryToEnumsHash() const;
+ const QMultiHash<QString, QString> &typedefTargetToName() const;
bool build(const QByteArrayList &arguments,
ApiExtractorFlags apiExtractorFlags = {},
@@ -75,15 +78,17 @@ public:
void setApiExtractorFlags(ApiExtractorFlags flags);
enum TranslateTypeFlag {
- DontResolveType = 0x1
+ DontResolveType = 0x1,
+ TemplateArgument = 0x2,
+ NoClassScopeLookup = 0x4
};
Q_DECLARE_FLAGS(TranslateTypeFlags, TranslateTypeFlag);
static std::optional<AbstractMetaType>
- translateType(const TypeInfo &_typei, AbstractMetaClass *currentClass = nullptr,
+ translateType(const TypeInfo &_typei, const AbstractMetaClassPtr &currentClass = {},
TranslateTypeFlags flags = {}, QString *errorMessage = nullptr);
static std::optional<AbstractMetaType>
- translateType(const QString &t, AbstractMetaClass *currentClass = nullptr,
+ translateType(const QString &t, const AbstractMetaClassPtr &currentClass = {},
TranslateTypeFlags flags = {}, QString *errorMessage = nullptr);
/// Performs a template specialization of the function.
@@ -94,11 +99,10 @@ public:
inheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
const AbstractMetaTypeList &templateTypes);
- static AbstractMetaClass *
- inheritTemplateClass(const ComplexTypeEntryPtr &te,
- const AbstractMetaClass *templateClass,
- const AbstractMetaTypeList &templateTypes,
- InheritTemplateFlags flags = {});
+ static AbstractMetaClassPtr
+ inheritTemplateClass(const ComplexTypeEntryPtr &te,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes);
/// Performs a template specialization of the member function.
/// \param function Member function
@@ -109,23 +113,24 @@ public:
static AbstractMetaFunctionPtr
inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
const AbstractMetaTypeList &templateTypes,
- const AbstractMetaClass *templateClass,
- AbstractMetaClass *subclass);
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass);
static QString getSnakeCaseName(const QString &name);
// Names under which an item will be registered to Python depending on snakeCase
static QStringList definitionNames(const QString &name,
TypeSystem::SnakeCase snakeCase);
- static QString resolveScopePrefix(const AbstractMetaClass *scope,
+ static QString resolveScopePrefix(const AbstractMetaClassCPtr &scope,
QStringView value);
static bool dontFixDefaultValue(QStringView expr);
// For testing purposes
QString fixDefaultValue(const QString &expr, const AbstractMetaType &type,
- const AbstractMetaClass *) const;
- QString fixEnumDefault(const AbstractMetaType &type, const QString &expr) const;
+ const AbstractMetaClassCPtr &) const;
+ QString fixEnumDefault(const AbstractMetaType &type, const QString &expr,
+ const AbstractMetaClassCPtr & = {}) const;
static void setCodeModelTestMode(bool b);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp
index 7695aabfc..68eef737a 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp
@@ -30,7 +30,7 @@ static QString resolveScopePrefixHelper(const QStringViewList &scopeList,
return name;
}
-QString AbstractMetaBuilder::resolveScopePrefix(const AbstractMetaClass *scope,
+QString AbstractMetaBuilder::resolveScopePrefix(const AbstractMetaClassCPtr &scope,
QStringView value)
{
if (!scope)
@@ -45,7 +45,7 @@ QString AbstractMetaBuilder::resolveScopePrefix(const AbstractMetaClass *scope,
static QString resolveEnumValueScopePrefix(const AbstractMetaEnum &metaEnum,
QStringView value)
{
- const AbstractMetaClass *scope = metaEnum.enclosingClass();
+ AbstractMetaClassCPtr scope = metaEnum.enclosingClass();
if (!scope)
return {}; // global enum, value should work as is
const QString &qualifiedCppName = scope->qualifiedCppName();
@@ -85,21 +85,26 @@ static bool isFloatConstant(const QStringView expr)
// to the default value, making it usable from Python wrapper code outside the
// owner class hierarchy. See TestEnum::testEnumDefaultValues().
QString AbstractMetaBuilderPrivate::fixEnumDefault(const AbstractMetaType &type,
- const QString &expr) const
+ const QString &expr,
+ const AbstractMetaClassCPtr &klass) const
{
// QFlags construct from integers, do not fix that
if (isIntegerConstant(expr))
return expr;
+ const QString field = qualifyStaticField(klass, expr);
+ if (!field.isEmpty())
+ return field;
+
const auto typeEntry = type.typeEntry();
EnumTypeEntryCPtr enumTypeEntry;
FlagsTypeEntryCPtr flagsTypeEntry;
if (typeEntry->isFlags()) {
- flagsTypeEntry = qSharedPointerCast<const FlagsTypeEntry>(typeEntry);
+ flagsTypeEntry = std::static_pointer_cast<const FlagsTypeEntry>(typeEntry);
enumTypeEntry = flagsTypeEntry->originator();
} else {
Q_ASSERT(typeEntry->isEnum());
- enumTypeEntry = qSharedPointerCast<const EnumTypeEntry>(typeEntry);
+ enumTypeEntry = std::static_pointer_cast<const EnumTypeEntry>(typeEntry);
}
// Use the enum's qualified name (would otherwise be "QFlags<Enum>")
if (!enumTypeEntry->qualifiedCppName().contains(u"::"))
@@ -177,7 +182,7 @@ bool AbstractMetaBuilder::dontFixDefaultValue(QStringView expr)
|| isIntegerConstant(expr) || isFloatConstant(expr);
}
-QString AbstractMetaBuilderPrivate::qualifyStaticField(const AbstractMetaClass *c,
+QString AbstractMetaBuilderPrivate::qualifyStaticField(const AbstractMetaClassCPtr &c,
QStringView field)
{
if (!c || c->fields().isEmpty())
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
index 5a6aee3a9..e65a4f176 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
@@ -17,19 +17,31 @@
#include <QtCore/QFileInfo>
#include <QtCore/QList>
#include <QtCore/QMap>
+#include <QtCore/QMultiHash>
#include <QtCore/QSet>
#include <optional>
+#include <set>
class TypeDatabase;
+struct RejectEntry
+{
+ AbstractMetaBuilder::RejectReason reason;
+ QString signature;
+ QString sortkey;
+ QString message;
+};
+
+bool operator<(const RejectEntry &re1, const RejectEntry &re2);
+
class AbstractMetaBuilderPrivate
{
public:
struct TypeClassEntry
{
AbstractMetaType type;
- const AbstractMetaClass *klass;
+ AbstractMetaClassCPtr klass;
};
using TranslateTypeFlags = AbstractMetaBuilder::TranslateTypeFlags;
@@ -37,7 +49,6 @@ public:
Q_DISABLE_COPY(AbstractMetaBuilderPrivate)
AbstractMetaBuilderPrivate();
- ~AbstractMetaBuilderPrivate();
static FileModelItem buildDom(QByteArrayList arguments,
bool addCompilerSupportArguments,
@@ -60,57 +71,66 @@ public:
NamespaceModelItem currentScope() const { return m_scopes.constLast(); }
- AbstractMetaClass *argumentToClass(const ArgumentModelItem &,
- const AbstractMetaClass *currentClass);
+ AbstractMetaClassPtr argumentToClass(const ArgumentModelItem &,
+ const AbstractMetaClassCPtr &currentClass);
- void addAbstractMetaClass(AbstractMetaClass *cls, const _CodeModelItem *item);
- AbstractMetaClass *traverseTypeDef(const FileModelItem &dom,
+ void addAbstractMetaClass(const AbstractMetaClassPtr &cls, const _CodeModelItem *item);
+ AbstractMetaClassPtr traverseTypeDef(const FileModelItem &dom,
const TypeDefModelItem &typeDef,
- AbstractMetaClass *currentClass);
+ const AbstractMetaClassPtr &currentClass);
+ AbstractMetaClassPtr traverseTypeDefHelper(const FileModelItem &dom,
+ const TypeDefModelItem &typeDef,
+ const AbstractMetaClassPtr &currentClass);
void traverseTypesystemTypedefs();
- AbstractMetaClass *traverseClass(const FileModelItem &dom,
+ AbstractMetaClassPtr traverseClass(const FileModelItem &dom,
const ClassModelItem &item,
- AbstractMetaClass *currentClass);
- void traverseScopeMembers(const ScopeModelItem &item, AbstractMetaClass *metaClass);
+ const AbstractMetaClassPtr &currentClass);
+ void traverseScopeMembers(const ScopeModelItem &item,
+ const AbstractMetaClassPtr &metaClass);
void traverseClassMembers(const ClassModelItem &scopeItem);
- void traverseUsingMembers(AbstractMetaClass *metaClass);
+ void traverseUsingMembers(const AbstractMetaClassPtr &metaClass) const;
void traverseNamespaceMembers(const NamespaceModelItem &scopeItem);
- bool setupInheritance(AbstractMetaClass *metaClass);
- AbstractMetaClass *traverseNamespace(const FileModelItem &dom,
+ bool setupInheritance(const AbstractMetaClassPtr &metaClass);
+ AbstractMetaClassPtr traverseNamespace(const FileModelItem &dom,
const NamespaceModelItem &item);
std::optional<AbstractMetaEnum> traverseEnum(const EnumModelItem &item,
- AbstractMetaClass *enclosing,
+ const AbstractMetaClassPtr &enclosing,
const QSet<QString> &enumsDeclarations);
- void traverseEnums(const ScopeModelItem &item, AbstractMetaClass *parent,
+ void traverseEnums(const ScopeModelItem &item, const AbstractMetaClassPtr &parent,
const QStringList &enumsDeclarations);
AbstractMetaFunctionRawPtrList classFunctionList(const ScopeModelItem &scopeItem,
AbstractMetaClass::Attributes *constructorAttributes,
- AbstractMetaClass *currentClass);
- void traverseFunctions(ScopeModelItem item, AbstractMetaClass *parent);
+ const AbstractMetaClassPtr &currentClass);
+ void traverseFunctions(const ScopeModelItem& item,
+ const AbstractMetaClassPtr &parent);
static void applyFunctionModifications(AbstractMetaFunction *func);
- void traverseFields(const ScopeModelItem &item, AbstractMetaClass *parent);
+ void traverseFields(const ScopeModelItem &item, const AbstractMetaClassPtr &parent);
bool traverseStreamOperator(const FunctionModelItem &functionItem,
- AbstractMetaClass *currentClass);
+ const AbstractMetaClassPtr &currentClass);
void traverseOperatorFunction(const FunctionModelItem &item,
- AbstractMetaClass *currentClass);
+ const AbstractMetaClassPtr &currentClass);
AbstractMetaFunction *traverseAddedFunctionHelper(const AddedFunctionPtr &addedFunc,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
QString *errorMessage);
bool traverseAddedGlobalFunction(const AddedFunctionPtr &addedFunc,
QString *errorMessage);
bool traverseAddedMemberFunction(const AddedFunctionPtr &addedFunc,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
QString *errorMessage);
- AbstractMetaFunction *traverseFunction(const FunctionModelItem &function,
- AbstractMetaClass *currentClass);
+ void rejectFunction(const FunctionModelItem &functionItem,
+ const AbstractMetaClassPtr &currentClass,
+ AbstractMetaBuilder::RejectReason reason,
+ const QString &rejectReason);
+ AbstractMetaFunction *traverseFunction(const FunctionModelItem &function,
+ const AbstractMetaClassPtr &currentClass);
std::optional<AbstractMetaField> traverseField(const VariableModelItem &field,
- const AbstractMetaClass *cls);
- void checkFunctionModifications();
+ const AbstractMetaClassCPtr &cls);
+ void checkFunctionModifications() const;
void registerHashFunction(const FunctionModelItem &functionItem,
- AbstractMetaClass *currentClass);
+ const AbstractMetaClassPtr &currentClass);
void registerToStringCapabilityIn(const NamespaceModelItem &namespaceItem);
void registerToStringCapability(const FunctionModelItem &functionItem,
- AbstractMetaClass *currentClass);
+ const AbstractMetaClassPtr &currentClass);
/**
* A conversion operator function should not have its owner class as
@@ -124,50 +144,53 @@ public:
*/
static void fixReturnTypeOfConversionOperator(AbstractMetaFunction *metaFunction);
- void parseQ_Properties(AbstractMetaClass *metaClass, const QStringList &declarations);
- void setupEquals(AbstractMetaClass *metaClass);
- void setupComparable(AbstractMetaClass *metaClass);
- void setupExternalConversion(const AbstractMetaClass *cls);
+ void parseQ_Properties(const AbstractMetaClassPtr &metaClass,
+ const QStringList &declarations);
+ void setupEquals(const AbstractMetaClassPtr &metaClass);
+ void setupComparable(const AbstractMetaClassPtr &metaClass);
+ void setupExternalConversion(const AbstractMetaClassCPtr &cls);
static bool isQualifiedCppIdentifier(QStringView e);
QString fixDefaultValue(QString expr, const AbstractMetaType &type,
- const AbstractMetaClass *) const;
+ const AbstractMetaClassCPtr &) const;
QString fixSimpleDefaultValue(QStringView expr,
- const AbstractMetaClass *klass) const;
+ const AbstractMetaClassCPtr &klass) const;
- QString fixEnumDefault(const AbstractMetaType &type, const QString &expr) const;
+ QString fixEnumDefault(const AbstractMetaType &type, const QString &expr,
+ const AbstractMetaClassCPtr &) const;
/// Qualify a static field name for default value expressions
- static QString qualifyStaticField(const AbstractMetaClass *c, QStringView field);
+ static QString qualifyStaticField(const AbstractMetaClassCPtr &c, QStringView field);
std::optional<AbstractMetaType>
- translateType(const TypeInfo &type, const AbstractMetaClass *currentClass,
+ translateType(const TypeInfo &type, const AbstractMetaClassCPtr &currentClass,
TranslateTypeFlags flags = {}, QString *errorMessage = nullptr);
static std::optional<AbstractMetaType>
- translateTypeStatic(const TypeInfo &type, const AbstractMetaClass *current,
+ translateTypeStatic(const TypeInfo &type, const AbstractMetaClassCPtr &current,
AbstractMetaBuilderPrivate *d = nullptr, TranslateTypeFlags flags = {},
QString *errorMessageIn = nullptr);
static TypeEntryCList findTypeEntriesHelper(const QString &qualifiedName, const QString &name,
- const AbstractMetaClass *currentClass = nullptr,
+ TranslateTypeFlags flags = {},
+ const AbstractMetaClassCPtr &currentClass = {},
AbstractMetaBuilderPrivate *d = nullptr);
static TypeEntryCList findTypeEntries(const QString &qualifiedName, const QString &name,
- const AbstractMetaClass *currentClass = nullptr,
+ TranslateTypeFlags flags = {},
+ const AbstractMetaClassCPtr &currentClass = {},
AbstractMetaBuilderPrivate *d = nullptr,
QString *errorMessage = nullptr);
qint64 findOutValueFromString(const QString &stringValue, bool &ok);
- AbstractMetaClass *findTemplateClass(const QString& name, const AbstractMetaClass *context,
- TypeInfo *info = Q_NULLPTR,
+ AbstractMetaClassPtr findTemplateClass(const QString& name, const AbstractMetaClassCPtr &context,
+ TypeInfo *info = nullptr,
ComplexTypeEntryPtr *baseContainerType = nullptr) const;
- AbstractMetaClassCList getBaseClasses(const AbstractMetaClass *metaClass) const;
+ AbstractMetaClassCList getBaseClasses(const AbstractMetaClassCPtr &metaClass) const;
- static bool inheritTemplate(AbstractMetaClass *subclass,
- const AbstractMetaClass *templateClass,
+ static bool inheritTemplate(const AbstractMetaClassPtr &subclass,
+ const AbstractMetaClassCPtr &templateClass,
const TypeInfo &info);
- static bool inheritTemplate(AbstractMetaClass *subclass,
- const AbstractMetaClass *templateClass,
- const AbstractMetaTypeList &templateTypes,
- InheritTemplateFlags flags = {});
+ static bool inheritTemplate(const AbstractMetaClassPtr &subclass,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes);
static AbstractMetaFunctionPtr
inheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
@@ -176,10 +199,10 @@ public:
static AbstractMetaFunctionPtr
inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
const AbstractMetaTypeList &templateTypes,
- const AbstractMetaClass *templateClass,
- AbstractMetaClass *subclass);
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass);
- static void inheritTemplateFunctions(AbstractMetaClass *subclass);
+ static void inheritTemplateFunctions(const AbstractMetaClassPtr &subclass);
static std::optional<AbstractMetaType>
inheritTemplateType(const AbstractMetaTypeList &templateTypes,
const AbstractMetaType &metaType);
@@ -191,26 +214,26 @@ public:
void setInclude(const TypeEntryPtr &te, const QString &path) const;
static void fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods);
- void fillAddedFunctions(AbstractMetaClass *metaClass);
- const AbstractMetaClass *resolveTypeSystemTypeDef(const AbstractMetaType &t) const;
+ void fillAddedFunctions(const AbstractMetaClassPtr &metaClass);
+ AbstractMetaClassCPtr resolveTypeSystemTypeDef(const AbstractMetaType &t) const;
void fixSmartPointers();
- AbstractMetaBuilder *q;
+ AbstractMetaBuilder *q = nullptr;
AbstractMetaClassList m_metaClasses;
AbstractMetaClassList m_templates;
AbstractMetaClassList m_smartPointers;
- QHash<const _CodeModelItem *, AbstractMetaClass *> m_itemToClass;
- QHash<const AbstractMetaClass *, const _CodeModelItem *> m_classToItem;
+ QHash<const _CodeModelItem *, AbstractMetaClassPtr > m_itemToClass;
+ QHash<AbstractMetaClassCPtr, const _CodeModelItem *> m_classToItem;
AbstractMetaFunctionCList m_globalFunctions;
AbstractMetaEnumList m_globalEnums;
- using RejectMap = QMap<QString, AbstractMetaBuilder::RejectReason>;
+ using RejectSet = std::set<RejectEntry>;
- RejectMap m_rejectedClasses;
- RejectMap m_rejectedEnums;
- RejectMap m_rejectedFunctions;
- RejectMap m_rejectedFields;
+ RejectSet m_rejectedClasses;
+ RejectSet m_rejectedEnums;
+ RejectSet m_rejectedFunctions;
+ RejectSet m_rejectedFields;
QHash<TypeEntryCPtr, AbstractMetaEnum> m_enums;
@@ -220,6 +243,7 @@ public:
QFileInfoList m_globalHeaders;
QStringList m_headerPaths;
mutable QHash<QString, Include> m_resolveIncludeHash;
+ QMultiHash<QString, QString> m_typedefTargetToName;
QList<TypeClassEntry> m_typeSystemTypeDefs; // look up metatype->class for type system typedefs
ApiExtractorFlags m_apiExtractorFlags;
bool m_skipDeprecated = false;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetaenum.cpp b/sources/shiboken6/ApiExtractor/abstractmetaenum.cpp
index e44d4ef7e..780170c22 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetaenum.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetaenum.cpp
@@ -32,8 +32,8 @@ AbstractMetaEnumValue::AbstractMetaEnumValue() :
AbstractMetaEnumValue::AbstractMetaEnumValue(const AbstractMetaEnumValue &) = default;
AbstractMetaEnumValue &AbstractMetaEnumValue::operator=(const AbstractMetaEnumValue &) = default;
-AbstractMetaEnumValue::AbstractMetaEnumValue(AbstractMetaEnumValue &&) = default;
-AbstractMetaEnumValue &AbstractMetaEnumValue::operator=(AbstractMetaEnumValue &&) = default;
+AbstractMetaEnumValue::AbstractMetaEnumValue(AbstractMetaEnumValue &&) noexcept = default;
+AbstractMetaEnumValue &AbstractMetaEnumValue::operator=(AbstractMetaEnumValue &&) noexcept = default;
AbstractMetaEnumValue::~AbstractMetaEnumValue() = default;
EnumValue AbstractMetaEnumValue::value() const
@@ -101,10 +101,14 @@ public:
{
}
+ int unsignedUsedBits() const;
+ int signedUsedBits() const;
+
AbstractMetaEnumValueList m_enumValues;
- EnumTypeEntryPtr m_typeEntry;
+ EnumTypeEntryCPtr m_typeEntry;
Documentation m_doc;
+ QString m_underlyingType;
EnumKind m_enumKind = CEnum;
Access m_access = Access::Public;
@@ -113,14 +117,46 @@ public:
uint m_signed : 1;
};
+static int _usedBits(uint64_t v)
+{
+ return (v >> 32) ? 64 : (v >> 16) ? 32 : (v >> 8) ? 16 : 8;
+}
+
+static int _usedBits(int64_t v)
+{
+ return (v >> 31) ? 64 : (v >> 15) ? 32 : (v >> 7) ? 16 : 8;
+}
+
+int AbstractMetaEnumData::unsignedUsedBits() const
+{
+ uint64_t maxValue = 0;
+ for (const auto &v : m_enumValues) {
+ if (const auto uv = v.value().unsignedValue(); uv > maxValue)
+ maxValue = uv;
+ }
+ return _usedBits(maxValue);
+}
+
+int AbstractMetaEnumData::signedUsedBits() const
+{
+ int64_t maxValue = 0;
+ for (const auto &v : m_enumValues) {
+ const auto sv = v.value().value();
+ const auto absV = sv < 0 ? ~sv : sv;
+ if (absV > maxValue)
+ maxValue = absV;
+ }
+ return _usedBits(maxValue);
+}
+
AbstractMetaEnum::AbstractMetaEnum() : d(new AbstractMetaEnumData)
{
}
AbstractMetaEnum::AbstractMetaEnum(const AbstractMetaEnum &) = default;
AbstractMetaEnum &AbstractMetaEnum::operator=(const AbstractMetaEnum&) = default;
-AbstractMetaEnum::AbstractMetaEnum(AbstractMetaEnum &&) = default;
-AbstractMetaEnum &AbstractMetaEnum::operator=(AbstractMetaEnum &&) = default;
+AbstractMetaEnum::AbstractMetaEnum(AbstractMetaEnum &&) noexcept = default;
+AbstractMetaEnum &AbstractMetaEnum::operator=(AbstractMetaEnum &&) noexcept = default;
AbstractMetaEnum::~AbstractMetaEnum() = default;
const AbstractMetaEnumValueList &AbstractMetaEnum::values() const
@@ -128,6 +164,16 @@ const AbstractMetaEnumValueList &AbstractMetaEnum::values() const
return d->m_enumValues;
}
+AbstractMetaEnumValueList AbstractMetaEnum::nonRejectedValues() const
+{
+ auto te = d->m_typeEntry;
+ AbstractMetaEnumValueList result = d->m_enumValues;
+ auto pred = [te](const AbstractMetaEnumValue &v) {
+ return te->isEnumValueRejected(v.name()); };
+ result.erase(std::remove_if(result.begin(), result.end(), pred), result.end());
+ return result;
+}
+
void AbstractMetaEnum::addEnumValue(const AbstractMetaEnumValue &enumValue)
{
d->m_enumValues << enumValue;
@@ -263,12 +309,12 @@ void AbstractMetaEnum::setHasQEnumsDeclaration(bool on)
d->m_hasQenumsDeclaration = on;
}
-EnumTypeEntryPtr AbstractMetaEnum::typeEntry() const
+EnumTypeEntryCPtr AbstractMetaEnum::typeEntry() const
{
return d->m_typeEntry;
}
-void AbstractMetaEnum::setTypeEntry(const EnumTypeEntryPtr &entry)
+void AbstractMetaEnum::setTypeEntry(const EnumTypeEntryCPtr &entry)
{
if (d->m_typeEntry != entry)
d->m_typeEntry = entry;
@@ -285,12 +331,37 @@ void AbstractMetaEnum::setSigned(bool s)
d->m_signed = s;
}
+QString AbstractMetaEnum::underlyingType() const
+{
+ return d->m_underlyingType;
+}
+
+void AbstractMetaEnum::setUnderlyingType(const QString &underlyingType)
+{
+ if (d->m_underlyingType != underlyingType)
+ d->m_underlyingType = underlyingType;
+}
+
+int AbstractMetaEnum::usedBits() const
+{
+ return isSigned() ? d->signedUsedBits() : d->unsignedUsedBits();
+}
+
+QString AbstractMetaEnum::intTypeForSize(int usedBits, bool isSigned)
+{
+ QString result = u"int"_s + QString::number(usedBits) + u"_t"_s;
+ return isSigned ? result : u'u' + result;
+}
+
#ifndef QT_NO_DEBUG_STREAM
-static void formatMetaEnumValue(QDebug &d, const AbstractMetaEnumValue &v)
+static void formatMetaEnumValue(QDebug &d, const AbstractMetaEnumValue &v, bool forceHex = false)
{
d << v.name() << '=';
- v.value().formatDebug(d);
+ if (forceHex)
+ v.value().formatDebugHex(d);
+ else
+ v.value().formatDebug(d);
if (v.isDeprecated())
d << " (deprecated)";
}
@@ -308,17 +379,19 @@ QDebug operator<<(QDebug d, const AbstractMetaEnumValue &v)
static void formatMetaEnum(QDebug &d, const AbstractMetaEnum &e)
{
- d << e.fullName();
+ d << '"' << e.fullName() << '"';
if (e.isDeprecated())
- d << " (deprecated) ";
+ d << " (deprecated)";
+ d << " \"" << e.underlyingType() << '"';
if (!e.isSigned())
- d << " (unsigned) ";
- d << '[';
+ d << " (unsigned)";
+ d << " [";
const AbstractMetaEnumValueList &values = e.values();
+ const bool hasFlags = e.typeEntry()->flags() != nullptr;
for (qsizetype i = 0, count = values.size(); i < count; ++i) {
if (i)
d << ", ";
- formatMetaEnumValue(d, values.at(i));
+ formatMetaEnumValue(d, values.at(i), hasFlags);
}
d << ']';
}
diff --git a/sources/shiboken6/ApiExtractor/abstractmetaenum.h b/sources/shiboken6/ApiExtractor/abstractmetaenum.h
index 0e356c1aa..03d7a3082 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetaenum.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetaenum.h
@@ -28,8 +28,8 @@ public:
AbstractMetaEnumValue();
AbstractMetaEnumValue(const AbstractMetaEnumValue &);
AbstractMetaEnumValue &operator=(const AbstractMetaEnumValue &);
- AbstractMetaEnumValue(AbstractMetaEnumValue &&);
- AbstractMetaEnumValue &operator=(AbstractMetaEnumValue &&);
+ AbstractMetaEnumValue(AbstractMetaEnumValue &&) noexcept;
+ AbstractMetaEnumValue &operator=(AbstractMetaEnumValue &&) noexcept;
~AbstractMetaEnumValue();
EnumValue value() const;
@@ -47,6 +47,8 @@ public:
Documentation documentation() const;
void setDocumentation(const Documentation& doc);
+ int usedBits() const;
+
private:
QSharedDataPointer<AbstractMetaEnumValueData> d;
};
@@ -57,11 +59,12 @@ public:
AbstractMetaEnum();
AbstractMetaEnum(const AbstractMetaEnum &);
AbstractMetaEnum &operator=(const AbstractMetaEnum &);
- AbstractMetaEnum(AbstractMetaEnum &&);
- AbstractMetaEnum &operator=(AbstractMetaEnum &&);
+ AbstractMetaEnum(AbstractMetaEnum &&) noexcept;
+ AbstractMetaEnum &operator=(AbstractMetaEnum &&) noexcept;
~AbstractMetaEnum();
const AbstractMetaEnumValueList &values() const;
+ AbstractMetaEnumValueList nonRejectedValues() const;
void addEnumValue(const AbstractMetaEnumValue &enumValue);
std::optional<AbstractMetaEnumValue> findEnumValue(QStringView value) const;
@@ -97,12 +100,18 @@ public:
bool hasQEnumsDeclaration() const;
void setHasQEnumsDeclaration(bool on);
- EnumTypeEntryPtr typeEntry() const;
- void setTypeEntry(const EnumTypeEntryPtr &entry);
+ EnumTypeEntryCPtr typeEntry() const;
+ void setTypeEntry(const EnumTypeEntryCPtr &entry);
bool isSigned() const;
void setSigned(bool s);
+ QString underlyingType() const;
+ void setUnderlyingType(const QString &underlyingType);
+
+ static QString intTypeForSize(int usedBits, bool isSigned);
+ int usedBits() const;
+
private:
QSharedDataPointer<AbstractMetaEnumData> d;
};
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafield.cpp b/sources/shiboken6/ApiExtractor/abstractmetafield.cpp
index 06bdbee1e..27a76d04d 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafield.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetafield.cpp
@@ -36,8 +36,8 @@ AbstractMetaField::AbstractMetaField() : d(new AbstractMetaFieldData)
AbstractMetaField::AbstractMetaField(const AbstractMetaField &) = default;
AbstractMetaField &AbstractMetaField::operator=(const AbstractMetaField &) = default;
-AbstractMetaField::AbstractMetaField(AbstractMetaField &&) = default;
-AbstractMetaField &AbstractMetaField::operator=(AbstractMetaField &&) = default;
+AbstractMetaField::AbstractMetaField(AbstractMetaField &&) noexcept = default;
+AbstractMetaField &AbstractMetaField::operator=(AbstractMetaField &&) noexcept = default;
AbstractMetaField::~AbstractMetaField() = default;
// returned->setEnclosingClass(nullptr);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafield.h b/sources/shiboken6/ApiExtractor/abstractmetafield.h
index 7de1298f3..0fa858791 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafield.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetafield.h
@@ -26,8 +26,8 @@ public:
AbstractMetaField();
AbstractMetaField(const AbstractMetaField &);
AbstractMetaField &operator=(const AbstractMetaField &);
- AbstractMetaField(AbstractMetaField &&);
- AbstractMetaField &operator=(AbstractMetaField &&);
+ AbstractMetaField(AbstractMetaField &&) noexcept;
+ AbstractMetaField &operator=(AbstractMetaField &&) noexcept;
~AbstractMetaField();
FieldModificationList modifications() const;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
index 03e795ec2..11a02f154 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
@@ -18,6 +18,7 @@
#include "sourcelocation.h"
#include "typedatabase.h"
#include "complextypeentry.h"
+#include "containertypeentry.h"
#include "functiontypeentry.h"
#include "primitivetypeentry.h"
#include "typesystemtypeentry.h"
@@ -27,13 +28,15 @@
#include <QtCore/QDebug>
#include <QtCore/QRegularExpression>
+#include <algorithm>
+
using namespace Qt::StringLiterals;
// Cache FunctionModificationList in a flat list per class (0 for global
// functions, or typically owner/implementing/declaring class.
struct ModificationCacheEntry
{
- const AbstractMetaClass *klass;
+ AbstractMetaClassCPtr klass;
FunctionModificationList modifications;
};
@@ -45,7 +48,6 @@ public:
AbstractMetaFunctionPrivate()
: m_constant(false),
m_reverse(false),
- m_explicit(false),
m_pointerOperator(false),
m_isCallOperator(false)
{
@@ -58,7 +60,7 @@ public:
int overloadNumber(const AbstractMetaFunction *q) const;
const FunctionModificationList &modifications(const AbstractMetaFunction *q,
- const AbstractMetaClass *implementor) const;
+ const AbstractMetaClassCPtr &implementor) const;
bool applyTypeModification(const AbstractMetaFunction *q,
const QString &type, int number, QString *errorMessage);
@@ -75,19 +77,19 @@ public:
AbstractMetaFunction::FunctionType m_functionType = AbstractMetaFunction::NormalFunction;
AbstractMetaType m_type;
QString m_modifiedTypeName;
- const AbstractMetaClass *m_class = nullptr;
- const AbstractMetaClass *m_implementingClass = nullptr;
- const AbstractMetaClass *m_declaringClass = nullptr;
+ AbstractMetaClassCPtr m_class;
+ AbstractMetaClassCPtr m_implementingClass;
+ AbstractMetaClassCPtr m_declaringClass;
mutable ModificationCache m_modificationCache;
int m_propertySpecIndex = -1;
AbstractMetaArgumentList m_arguments;
AddedFunctionPtr m_addedFunction;
SourceLocation m_sourceLocation;
AbstractMetaFunction::Attributes m_attributes;
+ FunctionAttributes m_cppAttributes;
AbstractMetaFunction::Flags m_flags;
uint m_constant : 1;
uint m_reverse : 1;
- uint m_explicit : 1;
uint m_pointerOperator : 1;
uint m_isCallOperator : 1;
mutable int m_cachedOverloadNumber = TypeSystem::OverloadNumberUnset;
@@ -117,9 +119,9 @@ AbstractMetaFunction::AbstractMetaFunction(const AddedFunctionPtr &addedFunc) :
setAccess(Access::Public);
break;
}
- AbstractMetaFunction::Attributes atts = AbstractMetaFunction::FinalInTargetLang;
+ AbstractMetaFunction::Attributes atts;
if (addedFunc->isStatic())
- atts |= AbstractMetaFunction::Static;
+ setCppAttribute(FunctionAttribute::Static);
if (addedFunc->isClassMethod())
atts |= AbstractMetaFunction::ClassMethod;
setAttributes(atts);
@@ -212,12 +214,12 @@ void AbstractMetaFunction::setPointerOperator(bool value)
bool AbstractMetaFunction::isExplicit() const
{
- return d->m_explicit;
+ return d->m_cppAttributes.testFlag(FunctionAttribute::Explicit);
}
void AbstractMetaFunction::setExplicit(bool isExplicit)
{
- d->m_explicit = isExplicit;
+ d->m_cppAttributes.setFlag(FunctionAttribute::Explicit, isExplicit);
}
bool AbstractMetaFunction::returnsBool() const
@@ -259,6 +261,21 @@ void AbstractMetaFunction::operator-=(AbstractMetaFunction::Attribute attribute)
d->m_attributes.setFlag(attribute, false);
}
+FunctionAttributes AbstractMetaFunction::cppAttributes() const
+{
+ return d->m_cppAttributes;
+}
+
+void AbstractMetaFunction::setCppAttributes(FunctionAttributes a)
+{
+ d->m_cppAttributes = a;
+}
+
+void AbstractMetaFunction::setCppAttribute(FunctionAttribute a, bool on)
+{
+ d->m_cppAttributes.setFlag(a, on);
+}
+
AbstractMetaFunction::Flags AbstractMetaFunction::flags() const
{
return d->m_flags;
@@ -272,9 +289,9 @@ void AbstractMetaFunction::setFlags(Flags f)
/*******************************************************************************
* Indicates that this function has a modification that removes it
*/
-bool AbstractMetaFunction::isModifiedRemoved(const AbstractMetaClass *cls) const
+bool AbstractMetaFunction::isModifiedRemoved(AbstractMetaClassCPtr cls) const
{
- if (!isInGlobalScope() && cls == nullptr)
+ if (!isInGlobalScope() && !cls)
cls = d->m_implementingClass;
for (const auto &mod : modifications(cls)) {
if (mod.isRemoved())
@@ -284,7 +301,7 @@ bool AbstractMetaFunction::isModifiedRemoved(const AbstractMetaClass *cls) const
return false;
}
-bool AbstractMetaFunction::isModifiedFinal(const AbstractMetaClass *cls) const
+bool AbstractMetaFunction::isModifiedFinal(AbstractMetaClassCPtr cls) const
{
if (!isInGlobalScope() && cls == nullptr)
cls = d->m_implementingClass;
@@ -310,12 +327,12 @@ void AbstractMetaFunction::setType(const AbstractMetaType &type)
d->m_type = type;
}
-const AbstractMetaClass *AbstractMetaFunction::ownerClass() const
+AbstractMetaClassCPtr AbstractMetaFunction::ownerClass() const
{
return d->m_class;
}
-void AbstractMetaFunction::setOwnerClass(const AbstractMetaClass *cls)
+void AbstractMetaFunction::setOwnerClass(const AbstractMetaClassCPtr &cls)
{
d->m_class = cls;
}
@@ -339,7 +356,7 @@ AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const Abstra
result |= EqualImplementor;
// Attributes
- if (attributes() == other->attributes())
+ if (attributes() == other->attributes() && cppAttributes() == other->cppAttributes())
result |= EqualAttributes;
// Compare types
@@ -424,6 +441,10 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const
{
auto *cpy = new AbstractMetaFunction;
cpy->setAttributes(attributes());
+ auto ca = cppAttributes();
+ // Historical bug: explicit was not copied! (causing nontypetemplate_test.py fail)
+ ca.setFlag(FunctionAttribute::Explicit, false);
+ cpy->setCppAttributes(ca);
cpy->setFlags(flags());
cpy->setAccess(access());
cpy->setName(name());
@@ -461,6 +482,9 @@ bool AbstractMetaFunction::generateBinding() const
{
switch (d->m_functionType) {
case ConversionOperator:
+ if (d->m_name != u"operator int" && d->m_name != u"operator double")
+ return false;
+ break;
case AssignmentOperatorFunction:
case MoveAssignmentOperatorFunction:
case AbstractMetaFunction::MoveConstructorFunction:
@@ -470,9 +494,19 @@ bool AbstractMetaFunction::generateBinding() const
return false;
break;
}
+ // Can we access the wrapper in case of a protected method? If not,
+ // disable for consistency regardless of avoidProtectedHack.
+ if (isProtected()) {
+ const auto typeFlags = ownerClass()->typeEntry()->typeFlags();
+ if (typeFlags.testFlag(ComplexTypeEntry::DisableWrapper))
+ return false;
+ }
if (isPrivate() && d->m_functionType != EmptyFunction)
return false;
- return d->m_name != u"qt_metacall" && !usesRValueReferences()
+ // RValue references only for user-specified
+ // functions (<add-function>/<declare-function>/<function>)
+ return d->m_name != u"qt_metacall" &&
+ (!usesRValueReferences() || d->m_addedFunction || d->m_typeEntry)
&& !isModifiedRemoved();
}
@@ -482,7 +516,7 @@ bool AbstractMetaFunction::isWhiteListed() const
case NormalFunction:
case SignalFunction:
case SlotFunction:
- if (auto *dc = declaringClass()) {
+ if (auto dc = declaringClass()) {
const QSet<QString> &whiteList = dc->typeEntry()->generateFunctions();
return whiteList.isEmpty() || whiteList.contains(d->m_name)
|| whiteList.contains(minimalSignature());
@@ -555,12 +589,17 @@ void AbstractMetaFunction::setConstant(bool constant)
bool AbstractMetaFunction::isUserAdded() const
{
- return !d->m_addedFunction.isNull() && !d->m_addedFunction->isDeclaration();
+ return d->m_addedFunction && !d->m_addedFunction->isDeclaration();
+}
+
+bool AbstractMetaFunction::isUserAddedPythonOverride() const
+{
+ return d->m_addedFunction && d->m_addedFunction->isPythonOverride();
}
bool AbstractMetaFunction::isUserDeclared() const
{
- return !d->m_addedFunction.isNull() && d->m_addedFunction->isDeclaration();
+ return d->m_addedFunction && d->m_addedFunction->isDeclaration();
}
int AbstractMetaFunction::actualMinimumArgumentCount() const
@@ -590,7 +629,7 @@ int AbstractMetaFunction::actualArgumentIndex(int index) const
}
// Returns reference counts for argument at idx, or all arguments if idx == -2
-QList<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaClass *cls, int idx) const
+QList<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaClassCPtr &cls, int idx) const
{
QList<ReferenceCount> returned;
@@ -605,7 +644,7 @@ QList<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaCl
return returned;
}
-ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls, int idx) const
+ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClassCPtr &cls, int idx) const
{
for (const auto &mod : modifications(cls)) {
for (const ArgumentModification &argumentMod : mod.argument_mods()) {
@@ -654,28 +693,28 @@ bool AbstractMetaFunction::argumentRemoved(int key) const
return false;
}
-const AbstractMetaClass *AbstractMetaFunction::targetLangOwner() const
+AbstractMetaClassCPtr AbstractMetaFunction::targetLangOwner() const
{
return d->m_class && d->m_class->isInvisibleNamespace()
? d->m_class->targetLangEnclosingClass() : d->m_class;
}
-const AbstractMetaClass *AbstractMetaFunction::declaringClass() const
+AbstractMetaClassCPtr AbstractMetaFunction::declaringClass() const
{
return d->m_declaringClass;
}
-void AbstractMetaFunction::setDeclaringClass(const AbstractMetaClass *cls)
+void AbstractMetaFunction::setDeclaringClass(const AbstractMetaClassCPtr &cls)
{
d->m_declaringClass = cls;
}
-const AbstractMetaClass *AbstractMetaFunction::implementingClass() const
+AbstractMetaClassCPtr AbstractMetaFunction::implementingClass() const
{
return d->m_implementingClass;
}
-void AbstractMetaFunction::setImplementingClass(const AbstractMetaClass *cls)
+void AbstractMetaFunction::setImplementingClass(const AbstractMetaClassCPtr &cls)
{
d->m_implementingClass = cls;
}
@@ -700,15 +739,23 @@ void AbstractMetaFunction::addArgument(const AbstractMetaArgument &argument)
d->m_arguments << argument;
}
+static bool modifiedDeprecated(const FunctionModification &mod)
+{
+ return mod.modifiers().testFlag(FunctionModification::Deprecated);
+}
+
+static bool modifiedUndeprecated(const FunctionModification &mod)
+{
+ return mod.modifiers().testFlag(FunctionModification::Undeprecated);
+}
+
bool AbstractMetaFunction::isDeprecated() const
{
- if (d->m_attributes.testFlag(Attribute::Deprecated))
- return true;
- for (const auto &modification : modifications(declaringClass())) {
- if (modification.isDeprecated())
- return true;
- }
- return false;
+ const auto &mods = modifications(declaringClass());
+
+ return d->m_cppAttributes.testFlag(FunctionAttribute::Deprecated)
+ ? std::none_of(mods.cbegin(), mods.cend(), modifiedUndeprecated)
+ : std::any_of(mods.cbegin(), mods.cend(), modifiedDeprecated);
}
bool AbstractMetaFunction::isConstructor() const
@@ -799,12 +846,12 @@ void AbstractMetaFunction::setSourceLocation(const SourceLocation &sourceLocatio
d->m_sourceLocation = sourceLocation;
}
-static inline TypeSystem::AllowThread allowThreadMod(const AbstractMetaClass *klass)
+static inline TypeSystem::AllowThread allowThreadMod(const AbstractMetaClassCPtr &klass)
{
return klass->typeEntry()->allowThread();
}
-static inline bool hasAllowThreadMod(const AbstractMetaClass *klass)
+static inline bool hasAllowThreadMod(const AbstractMetaClassCPtr &klass)
{
return allowThreadMod(klass) != TypeSystem::AllowThread::Unspecified;
}
@@ -837,7 +884,7 @@ bool AbstractMetaFunction::allowThread() const
return result;
}
-TypeSystem::Ownership AbstractMetaFunction::argumentTargetOwnership(const AbstractMetaClass *cls, int idx) const
+TypeSystem::Ownership AbstractMetaFunction::argumentTargetOwnership(const AbstractMetaClassCPtr &cls, int idx) const
{
for (const auto &modification : modifications(cls)) {
for (const ArgumentModification &argumentModification : modification.argument_mods()) {
@@ -856,10 +903,15 @@ const QString &AbstractMetaFunction::modifiedTypeName() const
bool AbstractMetaFunction::generateOpaqueContainerReturn() const
{
- return isTypeModified()
- && d->m_type.typeUsagePattern() == AbstractMetaType::ContainerPattern
- && d->m_type.referenceType() == LValueReference
- && d->m_type.generateOpaqueContainerForGetter(d->m_modifiedTypeName);
+ if (!isTypeModified() || d->m_type.typeUsagePattern() != AbstractMetaType::ContainerPattern)
+ return false;
+ // Needs to be a reference to a container, allow by value only for spans
+ if (d->m_type.referenceType() != LValueReference) {
+ auto cte = std::static_pointer_cast<const ContainerTypeEntry>(d->m_type.typeEntry());
+ if (cte->containerKind() != ContainerTypeEntry::SpanContainer)
+ return false;
+ }
+ return d->m_type.generateOpaqueContainerForGetter(d->m_modifiedTypeName);
}
bool AbstractMetaFunction::isModifiedToArray(int argumentIndex) const
@@ -947,12 +999,14 @@ QString AbstractMetaFunctionPrivate::formatMinimalSignature(const AbstractMetaFu
{
QString result = m_originalName + u'(';
for (qsizetype i = 0; i < m_arguments.size(); ++i) {
+ const auto &argument = m_arguments.at(i);
if (i > 0)
result += u',';
- result += comment
- ? m_arguments.at(i).modifiedType().minimalSignature()
- : m_arguments.at(i).type().minimalSignature();
+ const auto &type = comment ? argument.modifiedType() : argument.type();
+ result += type.minimalSignature();
+ if (comment && argument.hasDefaultValueExpression())
+ result += u'=';
}
result += u')';
if (m_constant)
@@ -990,9 +1044,10 @@ QString AbstractMetaFunction::signatureComment() const
QString AbstractMetaFunction::debugSignature() const
{
QString result;
- const bool isOverride = attributes() & AbstractMetaFunction::OverriddenCppMethod;
- const bool isFinal = attributes() & AbstractMetaFunction::FinalCppMethod;
- if (!isOverride && !isFinal && (attributes() & AbstractMetaFunction::VirtualCppMethod))
+ const auto attributes = cppAttributes();
+ const bool isOverride = attributes.testFlag(FunctionAttribute::Override);
+ const bool isFinal = attributes.testFlag(FunctionAttribute::Final);
+ if (!isOverride && !isFinal && (attributes.testFlag(FunctionAttribute::Virtual)))
result += u"virtual "_s;
if (d->m_implementingClass)
result += d->m_implementingClass->qualifiedCppName() + u"::"_s;
@@ -1005,7 +1060,7 @@ QString AbstractMetaFunction::debugSignature() const
}
FunctionModificationList AbstractMetaFunction::findClassModifications(const AbstractMetaFunction *f,
- const AbstractMetaClass *implementor)
+ AbstractMetaClassCPtr implementor)
{
const auto signatures = f->modificationSignatures();
FunctionModificationList mods;
@@ -1028,9 +1083,9 @@ FunctionModificationList AbstractMetaFunction::findGlobalModifications(const Abs
const FunctionModificationList &
AbstractMetaFunctionPrivate::modifications(const AbstractMetaFunction *q,
- const AbstractMetaClass *implementor) const
+ const AbstractMetaClassCPtr &implementor) const
{
- if (!m_addedFunction.isNull())
+ if (m_addedFunction)
return m_addedFunction->modifications();
for (const auto &ce : m_modificationCache) {
if (ce.klass == implementor)
@@ -1045,9 +1100,9 @@ const FunctionModificationList &
}
const FunctionModificationList &
- AbstractMetaFunction::modifications(const AbstractMetaClass *implementor) const
+ AbstractMetaFunction::modifications(AbstractMetaClassCPtr implementor) const
{
- if (implementor == nullptr)
+ if (!implementor)
implementor = d->m_class;
return d->modifications(this, implementor);
}
@@ -1059,13 +1114,13 @@ void AbstractMetaFunction::clearModificationsCache()
const DocModificationList AbstractMetaFunction::addedFunctionDocModifications() const
{
- return d->m_addedFunction.isNull()
- ? DocModificationList{} : d->m_addedFunction->docModifications();
+ return d->m_addedFunction
+ ? d->m_addedFunction->docModifications() : DocModificationList{};
}
QString AbstractMetaFunction::argumentName(int index,
bool /* create */,
- const AbstractMetaClass * /* implementor */) const
+ AbstractMetaClassCPtr /* implementor */) const
{
return d->m_arguments[--index].name();
}
@@ -1090,6 +1145,17 @@ void AbstractMetaFunction::setTypeEntry(const FunctionTypeEntryPtr &typeEntry)
d->m_typeEntry = typeEntry;
}
+QString AbstractMetaFunction::targetLangPackage() const
+{
+ if (d->m_addedFunction != nullptr)
+ return d->m_addedFunction->targetLangPackage();
+ if (d->m_class != nullptr)
+ return d->m_class->typeEntry()->targetLangPackage();
+ if (d->m_typeEntry != nullptr)
+ return d->m_typeEntry->targetLangPackage();
+ return {};
+}
+
bool AbstractMetaFunction::isCallOperator() const
{
return d->m_name == u"operator()";
@@ -1186,12 +1252,12 @@ void AbstractMetaFunction::setExceptionSpecification(ExceptionSpecification e)
d->m_exceptionSpecification = e;
}
-static inline TypeSystem::ExceptionHandling exceptionMod(const AbstractMetaClass *klass)
+static inline TypeSystem::ExceptionHandling exceptionMod(const AbstractMetaClassCPtr &klass)
{
return klass->typeEntry()->exceptionHandling();
}
-static inline bool hasExceptionMod(const AbstractMetaClass *klass)
+static inline bool hasExceptionMod(const AbstractMetaClassCPtr &klass)
{
return exceptionMod(klass) != TypeSystem::ExceptionHandling::Unspecified;
}
@@ -1345,7 +1411,7 @@ bool AbstractMetaFunction::isInplaceOperator() const
bool AbstractMetaFunction::isVirtual() const
{
- return d->m_attributes.testFlag(AbstractMetaFunction::VirtualCppMethod);
+ return d->m_cppAttributes.testFlag(FunctionAttribute::Virtual);
}
QString AbstractMetaFunctionPrivate::modifiedName(const AbstractMetaFunction *q) const
@@ -1370,7 +1436,7 @@ QString AbstractMetaFunction::modifiedName() const
AbstractMetaFunctionCPtr
AbstractMetaFunction::find(const AbstractMetaFunctionCList &haystack,
- QStringView needle)
+ QAnyStringView needle)
{
for (const auto &f : haystack) {
if (f->name() == needle)
@@ -1468,11 +1534,8 @@ TypeSystem::SnakeCase AbstractMetaFunction::snakeCase() const
return mod.snakeCase();
}
- if (d->m_typeEntry) { // Global function
- const auto snakeCase = d->m_typeEntry->snakeCase();
- return snakeCase != TypeSystem::SnakeCase::Unspecified
- ? snakeCase : typeSystemTypeEntry(d->m_typeEntry)->snakeCase();
- }
+ if (d->m_typeEntry) // Global function
+ return typeSystemTypeEntry(d->m_typeEntry)->snakeCase();
if (d->m_class) {
auto typeEntry = d->m_class->typeEntry();
@@ -1492,7 +1555,7 @@ bool AbstractMetaFunction::injectedCodeUsesPySelf() const
bool AbstractMetaFunction::injectedCodeCallsPythonOverride() const
{
static const QRegularExpression
- overrideCallRegexCheck(QStringLiteral(R"(PyObject_Call\s*\(\s*%PYTHON_METHOD_OVERRIDE\s*,)"));
+ overrideCallRegexCheck(R"(PyObject_Call\s*\(\s*%PYTHON_METHOD_OVERRIDE\s*,)"_L1);
Q_ASSERT(overrideCallRegexCheck.isValid());
return injectedCodeContains(overrideCallRegexCheck, TypeSystem::CodeSnipPositionAny,
TypeSystem::NativeCode);
@@ -1502,13 +1565,13 @@ bool AbstractMetaFunction::injectedCodeHasReturnValueAttribution(TypeSystem::Lan
{
if (language == TypeSystem::TargetLangCode) {
static const QRegularExpression
- retValAttributionRegexCheck_target(QStringLiteral(R"(%PYARG_0\s*=[^=]\s*.+)"));
+ retValAttributionRegexCheck_target(R"(%PYARG_0\s*=[^=]\s*.+)"_L1);
Q_ASSERT(retValAttributionRegexCheck_target.isValid());
return injectedCodeContains(retValAttributionRegexCheck_target, TypeSystem::CodeSnipPositionAny, language);
}
static const QRegularExpression
- retValAttributionRegexCheck_native(QStringLiteral(R"(%0\s*=[^=]\s*.+)"));
+ retValAttributionRegexCheck_native(R"(%0\s*=[^=]\s*.+)"_L1);
Q_ASSERT(retValAttributionRegexCheck_native.isValid());
return injectedCodeContains(retValAttributionRegexCheck_native, TypeSystem::CodeSnipPositionAny, language);
}
@@ -1606,9 +1669,9 @@ void AbstractMetaFunction::formatDebugVerbose(QDebug &debug) const
debug << " [userAdded]";
if (isUserDeclared())
debug << " [userDeclared]";
- if (d->m_explicit)
+ if (d->m_cppAttributes.testFlag(FunctionAttribute::Explicit))
debug << " [explicit]";
- if (attributes().testFlag(AbstractMetaFunction::Deprecated))
+ if (d->m_cppAttributes.testFlag(FunctionAttribute::Deprecated))
debug << " [deprecated]";
if (d->m_pointerOperator)
debug << " [operator->]";
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.h b/sources/shiboken6/ApiExtractor/abstractmetafunction.h
index e1f8e774d..e252e439d 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafunction.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.h
@@ -11,6 +11,7 @@
#include "typesystem_typedefs.h"
#include "parser/codemodel_enums.h"
+#include <QtCore/QMetaObject>
#include <QtCore/QScopedPointer>
#include <optional>
@@ -31,6 +32,8 @@ class AbstractMetaFunction
{
Q_GADGET
public:
+ Q_DISABLE_COPY_MOVE(AbstractMetaFunction)
+
enum FunctionType {
ConstructorFunction,
CopyConstructorFunction,
@@ -89,14 +92,8 @@ public:
enum Attribute {
None = 0x00000000,
- Friendly = 0x00000001,
-
- Abstract = 0x00000002,
- Static = 0x00000004,
ClassMethod = 0x00000008,
- FinalInTargetLang = 0x00000010,
-
GetterFunction = 0x00000020,
SetterFunction = 0x00000040,
@@ -105,14 +102,8 @@ public:
PropertyResetter = 0x00000400,
PropertyNotify = 0x00000800,
- Invokable = 0x00001000,
-
- VirtualCppMethod = 0x00010000,
- OverriddenCppMethod = 0x00020000,
- FinalCppMethod = 0x00040000,
// Add by meta builder (implicit constructors, inherited methods, etc)
AddedMethod = 0x001000000,
- Deprecated = 0x002000000 // Code annotation
};
Q_DECLARE_FLAGS(Attributes, Attribute)
Q_FLAG(Attribute)
@@ -123,6 +114,10 @@ public:
void operator+=(Attribute attribute);
void operator-=(Attribute attribute);
+ FunctionAttributes cppAttributes() const;
+ void setCppAttributes(FunctionAttributes a);
+ void setCppAttribute(FunctionAttribute a, bool on = true);
+
enum class Flag { // Internal flags not relevant for comparing functions
// Binary operator whose leading/trailing argument was removed by metabuilder
OperatorLeadingClassArgumentRemoved = 0x1,
@@ -137,11 +132,9 @@ public:
Flags flags() const;
void setFlags(Flags f);
- bool isFinalInTargetLang() const;
bool isAbstract() const;
bool isClassMethod() const;
bool isStatic() const;
- bool isInvokable() const;
bool isPropertyReader() const;
bool isPropertyWriter() const;
bool isPropertyResetter() const;
@@ -241,8 +234,8 @@ public:
QString signatureComment() const;
QString debugSignature() const; // including virtual/override/final, etc., for debugging only.
- bool isModifiedRemoved(const AbstractMetaClass *cls = nullptr) const;
- bool isModifiedFinal(const AbstractMetaClass *cls = nullptr) const;
+ bool isModifiedRemoved(AbstractMetaClassCPtr cls = {}) const;
+ bool isModifiedFinal(AbstractMetaClassCPtr cls = {}) const;
bool isVoid() const;
@@ -250,19 +243,19 @@ public:
void setType(const AbstractMetaType &type);
// The class that has this function as a member.
- const AbstractMetaClass *ownerClass() const;
- void setOwnerClass(const AbstractMetaClass *cls);
+ AbstractMetaClassCPtr ownerClass() const;
+ void setOwnerClass(const AbstractMetaClassCPtr &cls);
// Owner excluding invisible namespaces
- const AbstractMetaClass *targetLangOwner() const;
+ AbstractMetaClassCPtr targetLangOwner() const;
// The first class in a hierarchy that declares the function
- const AbstractMetaClass *declaringClass() const;
- void setDeclaringClass(const AbstractMetaClass *cls);
+ AbstractMetaClassCPtr declaringClass() const;
+ void setDeclaringClass(const AbstractMetaClassCPtr &cls);
// The class that actually implements this function
- const AbstractMetaClass *implementingClass() const;
- void setImplementingClass(const AbstractMetaClass *cls);
+ AbstractMetaClassCPtr implementingClass() const;
+ void setImplementingClass(const AbstractMetaClassCPtr &cls);
const AbstractMetaArgumentList &arguments() const;
AbstractMetaArgumentList &arguments();
@@ -307,6 +300,7 @@ public:
/// Returns true if the AbstractMetaFunction was added by the user via the type system description.
bool isUserAdded() const;
+ bool isUserAddedPythonOverride() const;
/// Returns true if the AbstractMetaFunction was declared by the user via
/// the type system description.
bool isUserDeclared() const;
@@ -320,11 +314,13 @@ public:
QString conversionRule(TypeSystem::Language language, int idx) const;
bool hasConversionRule(TypeSystem::Language language, int idx) const;
- QList<ReferenceCount> referenceCounts(const AbstractMetaClass *cls, int idx = -2) const;
- ArgumentOwner argumentOwner(const AbstractMetaClass *cls, int idx) const;
+ QList<ReferenceCount>
+ referenceCounts(const AbstractMetaClassCPtr &cls, int idx = -2) const;
+ ArgumentOwner argumentOwner(const AbstractMetaClassCPtr &cls, int idx) const;
// Returns the ownership rules for the given argument (target lang).
- TypeSystem::Ownership argumentTargetOwnership(const AbstractMetaClass *cls, int idx) const;
+ TypeSystem::Ownership
+ argumentTargetOwnership(const AbstractMetaClassCPtr &cls, int idx) const;
const QString &modifiedTypeName() const;
bool isTypeModified() const { return !modifiedTypeName().isEmpty(); }
@@ -364,31 +360,32 @@ public:
*/
bool hasSignatureModifications() const;
- const FunctionModificationList &modifications(const AbstractMetaClass *implementor = nullptr) const;
+ const FunctionModificationList &modifications(AbstractMetaClassCPtr implementor = {}) const;
void clearModificationsCache();
const DocModificationList addedFunctionDocModifications() const;
static FunctionModificationList findClassModifications(const AbstractMetaFunction *f,
- const AbstractMetaClass *implementor);
+ AbstractMetaClassCPtr implementor);
static FunctionModificationList findGlobalModifications(const AbstractMetaFunction *f);
/**
* Return the argument name if there is a modification the renamed value will be returned
*/
- QString argumentName(int index, bool create = true, const AbstractMetaClass *cl = nullptr) const;
+ QString argumentName(int index, bool create = true, AbstractMetaClassCPtr cl = {}) const;
int propertySpecIndex() const;
void setPropertySpecIndex(int i);
FunctionTypeEntryPtr typeEntry() const;
-
void setTypeEntry(const FunctionTypeEntryPtr &typeEntry);
+ QString targetLangPackage() const;
+
bool isCallOperator() const;
static AbstractMetaFunctionCPtr
- find(const AbstractMetaFunctionCList &haystack, QStringView needle);
+ find(const AbstractMetaFunctionCList &haystack, QAnyStringView needle);
bool matches(OperatorQueryOptions) const;
@@ -447,19 +444,14 @@ private:
QScopedPointer<AbstractMetaFunctionPrivate> d;
};
-inline bool AbstractMetaFunction::isFinalInTargetLang() const
-{
- return attributes().testFlag(FinalInTargetLang);
-}
-
inline bool AbstractMetaFunction::isAbstract() const
{
- return attributes().testFlag(Abstract);
+ return cppAttributes().testFlag(FunctionAttribute::Abstract);
}
inline bool AbstractMetaFunction::isStatic() const
{
- return attributes().testFlag(Static);
+ return cppAttributes().testFlag(FunctionAttribute::Static);
}
inline bool AbstractMetaFunction::isClassMethod() const
@@ -467,11 +459,6 @@ inline bool AbstractMetaFunction::isClassMethod() const
return attributes().testFlag(ClassMethod);
}
-inline bool AbstractMetaFunction::isInvokable() const
-{
- return attributes().testFlag(Invokable);
-}
-
inline bool AbstractMetaFunction::isPropertyReader() const
{
return attributes().testFlag(PropertyReader);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
index 77d346a9d..fb49cc9d0 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "abstractmetalang.h"
+#include "anystringview_helpers.h"
#include "abstractmetalang_helpers.h"
#include "abstractmetaargument.h"
#include "abstractmetaenum.h"
@@ -60,13 +61,16 @@ public:
static AbstractMetaFunction *
createFunction(const QString &name, AbstractMetaFunction::FunctionType t,
Access access, const AbstractMetaArgumentList &arguments,
- const AbstractMetaType &returnType, AbstractMetaClass *q);
+ const AbstractMetaType &returnType, const AbstractMetaClassPtr &q);
void addConstructor(AbstractMetaFunction::FunctionType t,
Access access,
const AbstractMetaArgumentList &arguments,
- AbstractMetaClass *q);
- void addUsingConstructors(AbstractMetaClass *q);
- bool isUsingMember(const AbstractMetaClass *c, const QString &memberName,
+ const AbstractMetaClassPtr &q);
+ void addUsingConstructors(const AbstractMetaClassPtr &q);
+ void sortFunctions();
+ void setFunctions(const AbstractMetaFunctionCList &functions,
+ const AbstractMetaClassCPtr &q);
+ bool isUsingMember(const AbstractMetaClassCPtr &c, const QString &memberName,
Access minimumAccess) const;
bool hasConstructors() const;
qsizetype indexOfProperty(const QString &name) const;
@@ -90,14 +94,15 @@ public:
Documentation m_doc;
- const AbstractMetaClass *m_enclosingClass = nullptr;
- const AbstractMetaClass *m_defaultSuperclass = nullptr;
+ AbstractMetaClassCPtr m_enclosingClass;
+ AbstractMetaClassCPtr m_defaultSuperclass;
AbstractMetaClassCList m_baseClasses; // Real base classes after setting up inheritance
AbstractMetaTypeList m_baseTemplateInstantiations;
- const AbstractMetaClass *m_extendedNamespace = nullptr;
+ AbstractMetaClassCPtr m_extendedNamespace;
- const AbstractMetaClass *m_templateBaseClass = nullptr;
+ AbstractMetaClassCPtr m_templateBaseClass;
AbstractMetaFunctionCList m_functions;
+ AbstractMetaFunctionCList m_userAddedPythonOverrides;
AbstractMetaFieldList m_fields;
AbstractMetaEnumList m_enums;
QList<QPropertySpec> m_propertySpecs;
@@ -173,29 +178,16 @@ AbstractMetaFunctionCList AbstractMetaClass::functionsInTargetLang() const
FunctionQueryOptions default_flags = FunctionQueryOption::NormalFunctions
| FunctionQueryOption::Visible | FunctionQueryOption::NotRemoved;
- // Only public functions in final classes
- // default_flags |= isFinal() ? WasPublic : 0;
- FunctionQueryOptions public_flags;
- if (isFinalInTargetLang())
- public_flags |= FunctionQueryOption::WasPublic;
-
// Constructors
AbstractMetaFunctionCList returned = queryFunctions(FunctionQueryOption::AnyConstructor
- | default_flags | public_flags);
-
- // Final functions
- returned += queryFunctions(FunctionQueryOption::FinalInTargetLangFunctions
- | FunctionQueryOption::NonStaticFunctions
- | default_flags | public_flags);
+ | default_flags);
- // Virtual functions
- returned += queryFunctions(FunctionQueryOption::VirtualInTargetLangFunctions
- | FunctionQueryOption::NonStaticFunctions
- | default_flags | public_flags);
+ returned += queryFunctions(FunctionQueryOption::NonStaticFunctions
+ | default_flags);
// Static functions
returned += queryFunctions(FunctionQueryOption::StaticFunctions
- | default_flags | public_flags);
+ | default_flags);
// Empty, private functions, since they aren't caught by the other ones
returned += queryFunctions(FunctionQueryOption::Empty | FunctionQueryOption::Invisible);
@@ -314,15 +306,15 @@ bool AbstractMetaClass::hasStaticFields() const
void AbstractMetaClass::sortFunctions()
{
- std::sort(d->m_functions.begin(), d->m_functions.end(), function_sorter);
+ d->sortFunctions();
}
-const AbstractMetaClass *AbstractMetaClass::templateBaseClass() const
+AbstractMetaClassCPtr AbstractMetaClass::templateBaseClass() const
{
return d->m_templateBaseClass;
}
-void AbstractMetaClass::setTemplateBaseClass(const AbstractMetaClass *cls)
+void AbstractMetaClass::setTemplateBaseClass(const AbstractMetaClassCPtr &cls)
{
d->m_templateBaseClass = cls;
}
@@ -332,17 +324,28 @@ const AbstractMetaFunctionCList &AbstractMetaClass::functions() const
return d->m_functions;
}
-void AbstractMetaClass::setFunctions(const AbstractMetaFunctionCList &functions)
+const AbstractMetaFunctionCList &AbstractMetaClass::userAddedPythonOverrides() const
+{
+ return d->m_userAddedPythonOverrides;
+}
+
+void AbstractMetaClassPrivate::sortFunctions()
+{
+ std::sort(m_functions.begin(), m_functions.end(), function_sorter);
+}
+
+void AbstractMetaClassPrivate::setFunctions(const AbstractMetaFunctionCList &functions,
+ const AbstractMetaClassCPtr &q)
{
- d->m_functions = functions;
+ m_functions = functions;
// Functions must be sorted by name before next loop
sortFunctions();
- for (const auto &f : std::as_const(d->m_functions)) {
- qSharedPointerConstCast<AbstractMetaFunction>(f)->setOwnerClass(this);
+ for (const auto &f : std::as_const(m_functions)) {
+ std::const_pointer_cast<AbstractMetaFunction>(f)->setOwnerClass(q);
if (!f->isPublic())
- d->m_hasNonpublic = true;
+ m_hasNonpublic = true;
}
}
@@ -379,20 +382,27 @@ void AbstractMetaClassPrivate::addFunction(const AbstractMetaFunctionCPtr &funct
&& function->functionType() == AbstractMetaFunction::ConstructorFunction;
}
-void AbstractMetaClass::addFunction(const AbstractMetaFunctionCPtr &function)
+void AbstractMetaClass::addFunction(const AbstractMetaClassPtr &klass,
+ const AbstractMetaFunctionCPtr &function)
{
- auto nonConstF = qSharedPointerConstCast<AbstractMetaFunction>(function);
- nonConstF->setOwnerClass(this);
+ auto nonConstF = std::const_pointer_cast<AbstractMetaFunction>(function);
+ nonConstF->setOwnerClass(klass);
// Set the default value of the declaring class. This may be changed
// in fixFunctions later on
- nonConstF->setDeclaringClass(this);
+ nonConstF->setDeclaringClass(klass);
// Some of the queries below depend on the implementing class being set
// to function properly. Such as function modifications
- nonConstF->setImplementingClass(this);
+ nonConstF->setImplementingClass(klass);
- d->addFunction(function);
+ if (function->isUserAddedPythonOverride()) {
+ nonConstF->setConstant(false);
+ nonConstF->setCppAttribute(FunctionAttribute::Static);
+ klass->d->m_userAddedPythonOverrides.append(function);
+ } else {
+ klass->d->addFunction(function);
+ }
}
bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const
@@ -430,17 +440,17 @@ QString AbstractMetaClass::baseClassName() const
}
// Attribute "default-superclass"
-const AbstractMetaClass *AbstractMetaClass::defaultSuperclass() const
+AbstractMetaClassCPtr AbstractMetaClass::defaultSuperclass() const
{
return d->m_defaultSuperclass;
}
-void AbstractMetaClass::setDefaultSuperclass(AbstractMetaClass *s)
+void AbstractMetaClass::setDefaultSuperclass(const AbstractMetaClassPtr &s)
{
d->m_defaultSuperclass = s;
}
-const AbstractMetaClass *AbstractMetaClass::baseClass() const
+AbstractMetaClassCPtr AbstractMetaClass::baseClass() const
{
return d->m_baseClasses.value(0, nullptr);
}
@@ -455,7 +465,7 @@ const AbstractMetaClassCList &AbstractMetaClass::baseClasses() const
AbstractMetaClassCList AbstractMetaClass::typeSystemBaseClasses() const
{
AbstractMetaClassCList result = d->m_baseClasses;
- if (d->m_defaultSuperclass != nullptr) {
+ if (d->m_defaultSuperclass) {
result.removeAll(d->m_defaultSuperclass);
result.prepend(d->m_defaultSuperclass);
}
@@ -467,21 +477,21 @@ AbstractMetaClassCList AbstractMetaClass::allTypeSystemAncestors() const
{
AbstractMetaClassCList result;
const auto baseClasses = typeSystemBaseClasses();
- for (auto *base : baseClasses) {
+ for (const auto &base : baseClasses) {
result.append(base);
result.append(base->allTypeSystemAncestors());
}
return result;
}
-void AbstractMetaClass::addBaseClass(const AbstractMetaClass *baseClass)
+void AbstractMetaClass::addBaseClass(const AbstractMetaClassCPtr &baseClass)
{
Q_ASSERT(baseClass);
d->m_baseClasses.append(baseClass);
d->m_isPolymorphic |= baseClass->isPolymorphic();
}
-void AbstractMetaClass::setBaseClass(const AbstractMetaClass *baseClass)
+void AbstractMetaClass::setBaseClass(const AbstractMetaClassCPtr &baseClass)
{
if (baseClass) {
d->m_baseClasses.prepend(baseClass);
@@ -489,12 +499,12 @@ void AbstractMetaClass::setBaseClass(const AbstractMetaClass *baseClass)
}
}
-const AbstractMetaClass *AbstractMetaClass::extendedNamespace() const
+AbstractMetaClassCPtr AbstractMetaClass::extendedNamespace() const
{
return d->m_extendedNamespace;
}
-void AbstractMetaClass::setExtendedNamespace(const AbstractMetaClass *e)
+void AbstractMetaClass::setExtendedNamespace(const AbstractMetaClassCPtr &e)
{
d->m_extendedNamespace = e;
}
@@ -504,7 +514,7 @@ const AbstractMetaClassCList &AbstractMetaClass::innerClasses() const
return d->m_innerClasses;
}
-void AbstractMetaClass::addInnerClass(AbstractMetaClass *cl)
+void AbstractMetaClass::addInnerClass(const AbstractMetaClassPtr &cl)
{
d->m_innerClasses << cl;
}
@@ -536,17 +546,12 @@ bool AbstractMetaClass::isInlineNamespace() const
{
bool result = false;
if (d->m_typeEntry->isNamespace()) {
- const auto nte = qSharedPointerCast<const NamespaceTypeEntry>(d->m_typeEntry);
+ const auto nte = std::static_pointer_cast<const NamespaceTypeEntry>(d->m_typeEntry);
result = nte->isInlineNamespace();
}
return result;
}
-bool AbstractMetaClass::isQObject() const
-{
- return inheritsFrom(u"QObject"_s);
-}
-
bool AbstractMetaClass::isQtNamespace() const
{
return isNamespace() && name() == u"Qt";
@@ -559,15 +564,15 @@ QString AbstractMetaClass::qualifiedCppName() const
bool AbstractMetaClass::hasFunction(const QString &str) const
{
- return !findFunction(str).isNull();
+ return bool(findFunction(str));
}
-AbstractMetaFunctionCPtr AbstractMetaClass::findFunction(QStringView functionName) const
+AbstractMetaFunctionCPtr AbstractMetaClass::findFunction(QAnyStringView functionName) const
{
return AbstractMetaFunction::find(d->m_functions, functionName);
}
-AbstractMetaFunctionCList AbstractMetaClass::findFunctions(QStringView functionName) const
+AbstractMetaFunctionCList AbstractMetaClass::findFunctions(QAnyStringView functionName) const
{
AbstractMetaFunctionCList result;
std::copy_if(d->m_functions.cbegin(), d->m_functions.cend(),
@@ -798,41 +803,40 @@ bool AbstractMetaClass::hasCopyConstructor() const
bool AbstractMetaClass::hasPrivateCopyConstructor() const
{
const auto copyCt = copyConstructor();
- return !copyCt.isNull() && copyCt->isPrivate();
+ return copyCt && copyCt->isPrivate();
}
void AbstractMetaClassPrivate::addConstructor(AbstractMetaFunction::FunctionType t,
Access access,
const AbstractMetaArgumentList &arguments,
- AbstractMetaClass *q)
+ const AbstractMetaClassPtr &q)
{
auto *f = createFunction(q->name(), t, access, arguments, AbstractMetaType::createVoid(), q);
if (access != Access::Private)
m_hasNonPrivateConstructor = true;
- f->setAttributes(AbstractMetaFunction::FinalInTargetLang
- | AbstractMetaFunction::AddedMethod);
+ f->setAttributes(AbstractMetaFunction::AddedMethod);
addFunction(AbstractMetaFunctionCPtr(f));
}
-void AbstractMetaClass::addDefaultConstructor()
+void AbstractMetaClass::addDefaultConstructor(const AbstractMetaClassPtr &klass)
{
- d->addConstructor(AbstractMetaFunction::ConstructorFunction,
- Access::Public, {}, this);
+ klass->d->addConstructor(AbstractMetaFunction::ConstructorFunction,
+ Access::Public, {}, klass);
}
-void AbstractMetaClass::addDefaultCopyConstructor()
+void AbstractMetaClass::addDefaultCopyConstructor(const AbstractMetaClassPtr &klass)
{
- AbstractMetaType argType(typeEntry());
+ AbstractMetaType argType(klass->typeEntry());
argType.setReferenceType(LValueReference);
argType.setConstant(true);
argType.setTypeUsagePattern(AbstractMetaType::ValuePattern);
AbstractMetaArgument arg;
arg.setType(argType);
- arg.setName(name());
+ arg.setName(klass->name());
- d->addConstructor(AbstractMetaFunction::CopyConstructorFunction,
- Access::Public, {arg}, this);
+ klass->d->addConstructor(AbstractMetaFunction::CopyConstructorFunction,
+ Access::Public, {arg}, klass);
}
AbstractMetaFunction *
@@ -841,7 +845,7 @@ AbstractMetaFunction *
Access access,
const AbstractMetaArgumentList &arguments,
const AbstractMetaType &returnType,
- AbstractMetaClass *q)
+ const AbstractMetaClassPtr &q)
{
auto *f = new AbstractMetaFunction(name);
f->setType(returnType);
@@ -857,7 +861,7 @@ AbstractMetaFunction *
static AbstractMetaType boolType()
{
auto boolType = TypeDatabase::instance()->findType(u"bool"_s);
- Q_ASSERT(!boolType.isNull());
+ Q_ASSERT(boolType);
AbstractMetaType result(boolType);
result.decideUsagePattern();
return result;
@@ -866,11 +870,11 @@ static AbstractMetaType boolType()
// Helper to synthesize comparison operators from a spaceship operator. Since
// shiboken also generates code for comparing to different types, this fits
// better than of handling it in the generator code.
-void AbstractMetaClass::addSynthesizedComparisonOperators()
+void AbstractMetaClass::addSynthesizedComparisonOperators(const AbstractMetaClassPtr &c)
{
static const auto returnType = boolType();
- AbstractMetaType selfType(typeEntry());
+ AbstractMetaType selfType(c->typeEntry());
selfType.setConstant(true);
selfType.setReferenceType(LValueReference);
selfType.decideUsagePattern();
@@ -885,8 +889,8 @@ void AbstractMetaClass::addSynthesizedComparisonOperators()
auto *f = AbstractMetaClassPrivate::createFunction(QLatin1StringView(op),
AbstractMetaFunction::ComparisonOperator,
Access::Public, arguments,
- returnType, this);
- d->addFunction(AbstractMetaFunctionCPtr(f));
+ returnType, c);
+ c->d->addFunction(AbstractMetaFunctionCPtr(f));
}
}
@@ -992,7 +996,7 @@ bool AbstractMetaClass::isImplicitlyDefaultConstructible() const
return std::all_of(d->m_fields.cbegin(), d->m_fields.cend(),
defaultConstructibleField)
&& std::all_of(d->m_baseClasses.cbegin(), d->m_baseClasses.cend(),
- [] (const AbstractMetaClass *c) {
+ [] (const AbstractMetaClassCPtr &c) {
return c->isDefaultConstructible();
});
}
@@ -1027,7 +1031,7 @@ bool AbstractMetaClass::isImplicitlyCopyConstructible() const
{
// Fields are currently not considered
return std::all_of(d->m_baseClasses.cbegin(), d->m_baseClasses.cend(),
- [] (const AbstractMetaClass *c) {
+ [] (const AbstractMetaClassCPtr &c) {
return c->isCopyConstructible();
});
}
@@ -1042,16 +1046,16 @@ bool AbstractMetaClass::canAddDefaultCopyConstructor() const
return isImplicitlyCopyConstructible();
}
-static bool classHasParentManagement(const AbstractMetaClass *c)
+static bool classHasParentManagement(const AbstractMetaClassCPtr &c)
{
const auto flags = c->typeEntry()->typeFlags();
return flags.testFlag(ComplexTypeEntry::ParentManagement);
}
-TypeEntryCPtr AbstractMetaClass::parentManagementEntry() const
+TypeEntryCPtr parentManagementEntry(const AbstractMetaClassCPtr &klass)
{
- if (isObjectType()) {
- if (auto *c = recurseClassHierarchy(this, classHasParentManagement))
+ if (klass->typeEntry()->isObject()) {
+ if (auto c = recurseClassHierarchy(klass, classHasParentManagement))
return c->typeEntry();
}
return nullptr;
@@ -1121,7 +1125,7 @@ void AbstractMetaClass::addUsingMember(const UsingMember &um)
d->m_usingMembers.append(um);
}
-bool AbstractMetaClassPrivate::isUsingMember(const AbstractMetaClass *c,
+bool AbstractMetaClassPrivate::isUsingMember(const AbstractMetaClassCPtr &c,
const QString &memberName,
Access minimumAccess) const
{
@@ -1132,7 +1136,7 @@ bool AbstractMetaClassPrivate::isUsingMember(const AbstractMetaClass *c,
return it != m_usingMembers.cend() && it->access >= minimumAccess;
}
-bool AbstractMetaClass::isUsingMember(const AbstractMetaClass *c,
+bool AbstractMetaClass::isUsingMember(const AbstractMetaClassCPtr &c,
const QString &memberName,
Access minimumAccess) const
{
@@ -1163,24 +1167,15 @@ bool AbstractMetaClass::queryFunction(const AbstractMetaFunction *f, FunctionQue
if (query.testFlag(FunctionQueryOption::Visible) && f->isPrivate())
return false;
- if (query.testFlag(FunctionQueryOption::VirtualInTargetLangFunctions) && f->isFinalInTargetLang())
- return false;
-
if (query.testFlag(FunctionQueryOption::Invisible) && !f->isPrivate())
return false;
if (query.testFlag(FunctionQueryOption::Empty) && !f->isEmptyFunction())
return false;
- if (query.testFlag(FunctionQueryOption::WasPublic) && !f->wasPublic())
- return false;
-
if (query.testFlag(FunctionQueryOption::ClassImplements) && f->ownerClass() != f->implementingClass())
return false;
- if (query.testFlag(FunctionQueryOption::FinalInTargetLangFunctions) && !f->isFinalInTargetLang())
- return false;
-
if (query.testFlag(FunctionQueryOption::VirtualInCppFunctions) && !f->isVirtual())
return false;
@@ -1244,7 +1239,7 @@ AbstractMetaFunctionCList AbstractMetaClass::queryFunctionList(const AbstractMet
{
AbstractMetaFunctionCList result;
for (const auto &f : list) {
- if (queryFunction(f.data(), query))
+ if (queryFunction(f.get(), query))
result.append(f);
}
return result;
@@ -1254,7 +1249,7 @@ AbstractMetaFunctionCPtr AbstractMetaClass::queryFirstFunction(const AbstractMet
FunctionQueryOptions query)
{
for (const auto &f : list) {
- if (queryFunction(f.data(), query))
+ if (queryFunction(f.get(), query))
return f;
}
return {};
@@ -1344,7 +1339,7 @@ void AbstractMetaClass::getEnumsToBeGenerated(AbstractMetaEnumList *enumList) co
void AbstractMetaClass::getEnumsFromInvisibleNamespacesToBeGenerated(AbstractMetaEnumList *enumList) const
{
if (isNamespace()) {
- invisibleNamespaceRecursion([enumList](const AbstractMetaClass *c) {
+ invisibleNamespaceRecursion([enumList](const AbstractMetaClassCPtr &c) {
c->getEnumsToBeGenerated(enumList);
});
}
@@ -1353,7 +1348,7 @@ void AbstractMetaClass::getEnumsFromInvisibleNamespacesToBeGenerated(AbstractMet
void AbstractMetaClass::getFunctionsFromInvisibleNamespacesToBeGenerated(AbstractMetaFunctionCList *funcList) const
{
if (isNamespace()) {
- invisibleNamespaceRecursion([funcList](const AbstractMetaClass *c) {
+ invisibleNamespaceRecursion([funcList](const AbstractMetaClassCPtr &c) {
funcList->append(c->functions());
});
}
@@ -1364,7 +1359,8 @@ QString AbstractMetaClass::fullName() const
return package() + u'.' + d->m_typeEntry->targetLangName();
}
-static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType &type)
+static void addExtraIncludeForType(const AbstractMetaClassPtr &metaClass,
+ const AbstractMetaType &type)
{
Q_ASSERT(metaClass);
@@ -1381,7 +1377,7 @@ static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractM
}
}
-static void addExtraIncludesForFunction(AbstractMetaClass *metaClass,
+static void addExtraIncludesForFunction(const AbstractMetaClassPtr &metaClass,
const AbstractMetaFunctionCPtr &meta_function)
{
Q_ASSERT(metaClass);
@@ -1416,7 +1412,7 @@ static bool addSuperFunction(const AbstractMetaFunctionCPtr &f)
// Add constructors imported via "using" from the base classes. This is not
// needed for normal hidden inherited member functions since we generate a
// cast to the base class to call them into binding code.
-void AbstractMetaClassPrivate::addUsingConstructors(AbstractMetaClass *q)
+void AbstractMetaClassPrivate::addUsingConstructors(const AbstractMetaClassPtr &q)
{
// Restricted to the non-constructor case currently to avoid
// having to compare the parameter lists of existing constructors.
@@ -1425,7 +1421,7 @@ void AbstractMetaClassPrivate::addUsingConstructors(AbstractMetaClass *q)
return;
}
- for (auto superClass : m_baseClasses) {
+ for (const auto &superClass : m_baseClasses) {
// Find any "using base-constructor" directives
if (isUsingMember(superClass, superClass->name(), Access::Protected)) {
// Add to derived class with parameter lists.
@@ -1440,41 +1436,51 @@ void AbstractMetaClassPrivate::addUsingConstructors(AbstractMetaClass *q)
}
}
-void AbstractMetaClass::fixFunctions()
+static inline bool isSignal(const AbstractMetaFunctionCPtr &f)
{
+ return f->isSignal();
+}
+
+void AbstractMetaClass::fixFunctions(const AbstractMetaClassPtr &klass)
+{
+ auto *d = klass->d.data();
if (d->m_functionsFixed)
return;
d->m_functionsFixed = true;
- AbstractMetaFunctionCList funcs = functions();
+ AbstractMetaFunctionCList funcs = klass->functions();
AbstractMetaFunctionCList nonRemovedFuncs;
nonRemovedFuncs.reserve(funcs.size());
- d->addUsingConstructors(this);
+ d->addUsingConstructors(klass);
for (const auto &f : std::as_const(funcs)) {
// Fishy: Setting up of implementing/declaring/base classes changes
// the applicable modifications; clear cached ones.
- qSharedPointerConstCast<AbstractMetaFunction>(f)->clearModificationsCache();
+ std::const_pointer_cast<AbstractMetaFunction>(f)->clearModificationsCache();
if (!f->isModifiedRemoved())
nonRemovedFuncs.append(f);
}
- for (auto *superClassC : d->m_baseClasses) {
- auto *superClass = const_cast<AbstractMetaClass *>(superClassC);
- superClass->fixFunctions();
+ for (const auto &superClassC : d->m_baseClasses) {
+ for (const auto &pof : superClassC->userAddedPythonOverrides()) {
+ auto *clonedPof = pof->copy();
+ clonedPof->setOwnerClass(klass);
+ d->m_userAddedPythonOverrides.append(AbstractMetaFunctionCPtr{clonedPof});
+ }
+
+ auto superClass = std::const_pointer_cast<AbstractMetaClass>(superClassC);
+ AbstractMetaClass::fixFunctions(superClass);
// Since we always traverse the complete hierarchy we are only
// interrested in what each super class implements, not what
// we may have propagated from their base classes again.
AbstractMetaFunctionCList superFuncs;
- // Super classes can never be final
- if (superClass->isFinalInTargetLang()) {
- qCWarning(lcShiboken).noquote().nospace()
- << "Final class '" << superClass->name() << "' set to non-final, as it is extended by other classes";
- *superClass -= AbstractMetaClass::FinalInTargetLang;
- }
superFuncs = superClass->queryFunctions(FunctionQueryOption::ClassImplements);
+ // We are not interested in signals as no bindings are generated for them;
+ // they cause documentation warnings.
+ superFuncs.erase(std::remove_if(superFuncs.begin(), superFuncs.end(), isSignal),
+ superFuncs.end());
const auto virtuals = superClass->queryFunctions(FunctionQueryOption::VirtualInCppFunctions);
superFuncs += virtuals;
@@ -1484,7 +1490,7 @@ void AbstractMetaClass::fixFunctions()
continue;
// skip functions added in base classes
- if (sf->isUserAdded() && sf->declaringClass() != this)
+ if (sf->isUserAdded() && sf->declaringClass() != klass)
continue;
// Skip base class comparison operators declared as members (free
@@ -1496,42 +1502,24 @@ void AbstractMetaClass::fixFunctions()
// virtual in case they override abstract functions.
bool add = addSuperFunction(sf);
for (const auto &cf : std::as_const(nonRemovedFuncs)) {
- AbstractMetaFunctionPtr f(qSharedPointerConstCast<AbstractMetaFunction>(cf));
- const AbstractMetaFunction::CompareResult cmp = cf->compareTo(sf.data());
+ AbstractMetaFunctionPtr f(std::const_pointer_cast<AbstractMetaFunction>(cf));
+ const AbstractMetaFunction::CompareResult cmp = cf->compareTo(sf.get());
if (cmp & AbstractMetaFunction::EqualModifiedName) {
add = false;
if (cmp & AbstractMetaFunction::EqualArguments) {
// Set "override" in case it was not spelled out (since it
// is then not detected by clang parsing).
- const auto attributes = cf->attributes();
- if (cf->isVirtual()
- && !attributes.testFlag(AbstractMetaFunction::OverriddenCppMethod)
- && !attributes.testFlag(AbstractMetaFunction::FinalCppMethod)) {
- *f += AbstractMetaFunction::OverriddenCppMethod;
- }
- // Same function, propegate virtual...
- if (!(cmp & AbstractMetaFunction::EqualAttributes)) {
- if (!f->isEmptyFunction()) {
- if (!sf->isFinalInTargetLang() && f->isFinalInTargetLang()) {
- *f -= AbstractMetaFunction::FinalInTargetLang;
- }
-#if 0
- if (!f->isFinalInTargetLang() && f->isPrivate()) {
- f->setFunctionType(AbstractMetaFunction::EmptyFunction);
- f->setVisibility(AbstractMetaAttributes::Protected);
- *f += AbstractMetaAttributes::FinalInTargetLang;
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("private virtual function '%1' in '%2'")
- .arg(f->signature(), f->implementingClass()->name());
- }
-#endif
- }
+ const auto attributes = cf->cppAttributes();
+ if (attributes.testFlag(FunctionAttribute::Virtual)
+ && !attributes.testFlag(FunctionAttribute::Override)
+ && !attributes.testFlag(FunctionAttribute::Final)) {
+ f->setCppAttribute(FunctionAttribute::Override);
}
if (f->access() != sf->access()) {
qCWarning(lcShiboken, "%s",
- qPrintable(msgFunctionVisibilityModified(this, f.data())));
+ qPrintable(msgFunctionVisibilityModified(klass, f.get())));
#if 0
// If new visibility is private, we can't
// do anything. If it isn't, then we
@@ -1543,43 +1531,12 @@ void AbstractMetaClass::fixFunctions()
// Private overrides of abstract functions have to go into the class or
// the subclasses will not compile as non-abstract classes.
// But they don't need to be implemented, since they can never be called.
- if (f->isPrivate()) {
+ if (f->isPrivate())
f->setFunctionType(AbstractMetaFunction::EmptyFunction);
- *f += AbstractMetaFunction::FinalInTargetLang;
- }
}
// Set the class which first declares this function, afawk
f->setDeclaringClass(sf->declaringClass());
-
- if (sf->isFinalInTargetLang() && !sf->isPrivate() && !f->isPrivate() && !sf->isStatic() && !f->isStatic()) {
- // Shadowed funcion, need to make base class
- // function non-virtual
- if (f->implementingClass() != sf->implementingClass() && f->implementingClass()->inheritsFrom(sf->implementingClass())) {
-
- // Check whether the superclass method has been redefined to non-final
-
- bool hasNonFinalModifier = false;
- bool isBaseImplPrivate = false;
- const FunctionModificationList &mods = sf->modifications(sf->implementingClass());
- for (const FunctionModification &mod : mods) {
- if (mod.isNonFinal()) {
- hasNonFinalModifier = true;
- break;
- }
- if (mod.isPrivate()) {
- isBaseImplPrivate = true;
- break;
- }
- }
-
- if (!hasNonFinalModifier && !isBaseImplPrivate) {
- qCWarning(lcShiboken, "%s",
- qPrintable(msgShadowingFunction(sf.data(), f.data())));
- }
- }
- }
-
}
if (cmp & AbstractMetaFunction::EqualDefaultValueOverload) {
@@ -1618,8 +1575,8 @@ void AbstractMetaClass::fixFunctions()
bool hasPublicConstructors = false;
// Apply modifications after the declaring class has been set
for (const auto &func : std::as_const(funcs)) {
- auto ncFunc = qSharedPointerConstCast<AbstractMetaFunction>(func);
- for (const auto &mod : func->modifications(this)) {
+ auto ncFunc = std::const_pointer_cast<AbstractMetaFunction>(func);
+ for (const auto &mod : func->modifications(klass)) {
if (mod.isRenameModifier())
ncFunc->setName(mod.renamedToName());
}
@@ -1627,8 +1584,8 @@ void AbstractMetaClass::fixFunctions()
// Make sure class is abstract if one of the functions is
if (func->isAbstract()) {
- (*this) += AbstractMetaClass::Abstract;
- (*this) -= AbstractMetaClass::FinalInTargetLang;
+ (*klass) += AbstractMetaClass::Abstract;
+ (*klass) -= AbstractMetaClass::FinalInTargetLang;
}
if (func->isConstructor()) {
@@ -1641,15 +1598,15 @@ void AbstractMetaClass::fixFunctions()
// Make sure that we include files for all classes that are in use
- addExtraIncludesForFunction(this, func);
+ addExtraIncludesForFunction(klass, func);
}
if (hasPrivateConstructors && !hasPublicConstructors) {
- (*this) += AbstractMetaClass::Abstract;
- (*this) -= AbstractMetaClass::FinalInTargetLang;
+ (*klass) += AbstractMetaClass::Abstract;
+ (*klass) -= AbstractMetaClass::FinalInTargetLang;
}
- setFunctions(funcs);
+ d->setFunctions(funcs, klass);
}
bool AbstractMetaClass::needsInheritanceSetup() const
@@ -1658,6 +1615,7 @@ bool AbstractMetaClass::needsInheritanceSetup() const
switch (d->m_typeEntry->type()) {
case TypeEntry::NamespaceType:
case TypeEntry::SmartPointerType:
+ case TypeEntry::ContainerType:
return false;
default:
break;
@@ -1689,11 +1647,11 @@ std::optional<AbstractMetaEnumValue>
if (lst.size() > 1) {
const auto &prefixName = lst.at(0);
const auto &enumName = lst.at(1);
- if (auto *cl = findClass(classes, prefixName))
+ if (auto cl = findClass(classes, prefixName))
return cl->findEnumValue(enumName.toString());
}
- for (AbstractMetaClass *metaClass : classes) {
+ for (const auto &metaClass : classes) {
auto enumValue = metaClass->findEnumValue(name);
if (enumValue.has_value())
return enumValue;
@@ -1707,12 +1665,12 @@ std::optional<AbstractMetaEnumValue>
/// Target language base name or complete Target language package.class name.
template <class It>
-static It findClassHelper(It begin, It end, QStringView name)
+static It findClassHelper(It begin, It end, QAnyStringView name)
{
if (name.isEmpty() || begin == end)
return end;
- if (name.contains(u'.')) { // Search target lang name
+ if (asv_contains(name,'.')) { // Search target lang name
for (auto it = begin; it != end; ++it) {
if ((*it)->fullName() == name)
return it;
@@ -1725,7 +1683,7 @@ static It findClassHelper(It begin, It end, QStringView name)
return it;
}
- if (name.contains(u"::")) // Qualified, cannot possibly match name
+ if (asv_contains(name, "::")) // Qualified, cannot possibly match name
return end;
for (auto it = begin; it != end; ++it) {
@@ -1736,31 +1694,31 @@ static It findClassHelper(It begin, It end, QStringView name)
return end;
}
-AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &classes,
- QStringView name)
+AbstractMetaClassPtr AbstractMetaClass::findClass(const AbstractMetaClassList &classes,
+ QAnyStringView name)
{
auto it =findClassHelper(classes.cbegin(), classes.cend(), name);
return it != classes.cend() ? *it : nullptr;
}
-const AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassCList &classes,
- QStringView name)
+AbstractMetaClassCPtr AbstractMetaClass::findClass(const AbstractMetaClassCList &classes,
+ QAnyStringView name)
{
auto it = findClassHelper(classes.cbegin(), classes.cend(), name);
return it != classes.cend() ? *it : nullptr;
}
-AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &classes,
- const TypeEntryCPtr &typeEntry)
+AbstractMetaClassPtr AbstractMetaClass::findClass(const AbstractMetaClassList &classes,
+ const TypeEntryCPtr &typeEntry)
{
- for (AbstractMetaClass *c : classes) {
+ for (AbstractMetaClassPtr c : classes) {
if (c->typeEntry() == typeEntry)
return c;
}
return nullptr;
}
-const AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassCList &classes,
+AbstractMetaClassCPtr AbstractMetaClass::findClass(const AbstractMetaClassCList &classes,
const TypeEntryCPtr &typeEntry)
{
for (auto c : classes) {
@@ -1771,40 +1729,41 @@ const AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassCLi
}
/// Returns true if this class is a subclass of the given class
-bool AbstractMetaClass::inheritsFrom(const AbstractMetaClass *cls) const
+bool inheritsFrom(const AbstractMetaClassCPtr &c, const AbstractMetaClassCPtr &cls)
{
Q_ASSERT(cls != nullptr);
- if (this == cls || d->m_templateBaseClass == cls)
+ if (c == cls || c->templateBaseClass() == cls)
return true;
- return recurseClassHierarchy(this, [cls](const AbstractMetaClass *c) {
- return cls == c;
- }) != nullptr;
+ return bool(recurseClassHierarchy(c, [cls](const AbstractMetaClassCPtr &c) {
+ return cls.get() == c.get();
+ }));
}
-bool AbstractMetaClass::inheritsFrom(const QString &name) const
+bool inheritsFrom(const AbstractMetaClassCPtr &c, QAnyStringView name)
{
- if (this->qualifiedCppName() == name)
+ if (c->qualifiedCppName() == name)
return true;
- if (d->m_templateBaseClass != nullptr
- && d->m_templateBaseClass->qualifiedCppName() == name) {
+ if (c->templateBaseClass() != nullptr
+ && c->templateBaseClass()->qualifiedCppName() == name) {
return true;
}
- return recurseClassHierarchy(this, [&name](const AbstractMetaClass *c) {
+ return bool(recurseClassHierarchy(c, [&name](const AbstractMetaClassCPtr &c) {
return c->qualifiedCppName() == name;
- }) != nullptr;
+ }));
}
-const AbstractMetaClass *AbstractMetaClass::findBaseClass(const QString &qualifiedName) const
+AbstractMetaClassCPtr findBaseClass(const AbstractMetaClassCPtr &c,
+ const QString &qualifiedName)
{
- if (d->m_templateBaseClass != nullptr
- && d->m_templateBaseClass->qualifiedCppName() == qualifiedName) {
- return d->m_templateBaseClass;
- }
- return recurseClassHierarchy(this, [&qualifiedName](const AbstractMetaClass *c) {
+ auto tp = c->templateBaseClass();
+ if (tp && tp->qualifiedCppName() == qualifiedName)
+ return tp;
+
+ return recurseClassHierarchy(c, [&qualifiedName](const AbstractMetaClassCPtr &c) {
return c->qualifiedCppName() == qualifiedName;
});
}
@@ -1834,7 +1793,7 @@ void AbstractMetaClass::setValueTypeWithCopyConstructorOnly(bool v)
d->m_valueTypeWithCopyConstructorOnly = v;
}
-bool AbstractMetaClass::determineValueTypeWithCopyConstructorOnly(const AbstractMetaClass *c,
+bool AbstractMetaClass::determineValueTypeWithCopyConstructorOnly(const AbstractMetaClassCPtr &c,
bool avoidProtectedHack)
{
@@ -1900,7 +1859,7 @@ void AbstractMetaClass::format(QDebug &debug) const
if (!d->m_baseClasses.isEmpty()) {
debug << ", inherits ";
- for (auto b : d->m_baseClasses)
+ for (const auto &b : d->m_baseClasses)
debug << " \"" << b->name() << '"';
}
@@ -1965,6 +1924,18 @@ void AbstractMetaClass::setSourceLocation(const SourceLocation &sourceLocation)
d->m_sourceLocation = sourceLocation;
}
+AbstractMetaClassCList allBaseClasses(const AbstractMetaClassCPtr metaClass)
+{
+ AbstractMetaClassCList result;
+ recurseClassHierarchy(metaClass, [&result] (const AbstractMetaClassCPtr &c) {
+ if (!result.contains(c))
+ result.append(c);
+ return false;
+ });
+ result.removeFirst(); // remove self
+ return result;
+}
+
QDebug operator<<(QDebug debug, const UsingMember &d)
{
QDebugStateSaver saver(debug);
@@ -1975,20 +1946,38 @@ QDebug operator<<(QDebug debug, const UsingMember &d)
return debug;
}
-QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
+void formatMetaClass(QDebug &ddebug, const AbstractMetaClass *ac)
{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "AbstractMetaClass(";
- if (ac) {
- ac->format(d);
- if (d.verbosity() > 2)
- ac->formatMembers(d);
+ QDebugStateSaver saver(ddebug);
+ ddebug.noquote();
+ ddebug.nospace();
+ ddebug << "AbstractMetaClass(";
+ if (ac != nullptr) {
+ ac->format(ddebug);
+ if (ddebug.verbosity() > 2)
+ ac->formatMembers(ddebug);
} else {
- d << '0';
+ ddebug << '0';
}
- d << ')';
+ ddebug << ')';
+}
+
+QDebug operator<<(QDebug d, const AbstractMetaClassCPtr &ac)
+{
+ formatMetaClass(d, ac.get());
+ return d;
+}
+
+QDebug operator<<(QDebug d, const AbstractMetaClassPtr &ac)
+{
+ formatMetaClass(d, ac.get());
return d;
}
+
+QDebug operator<<(QDebug d, const AbstractMetaClass *ac)
+{
+ formatMetaClass(d, ac);
+ return d;
+}
+
#endif // !QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.h b/sources/shiboken6/ApiExtractor/abstractmetalang.h
index 526df69af..3dc876690 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang.h
@@ -66,11 +66,13 @@ public:
~AbstractMetaClass();
const AbstractMetaFunctionCList &functions() const;
+ const AbstractMetaFunctionCList &userAddedPythonOverrides() const;
void setFunctions(const AbstractMetaFunctionCList &functions);
- void addFunction(const AbstractMetaFunctionCPtr &function);
+ static void addFunction(const AbstractMetaClassPtr &klass,
+ const AbstractMetaFunctionCPtr &function);
bool hasFunction(const QString &str) const;
- AbstractMetaFunctionCPtr findFunction(QStringView functionName) const;
- AbstractMetaFunctionCList findFunctions(QStringView functionName) const;
+ AbstractMetaFunctionCPtr findFunction(QAnyStringView functionName) const;
+ AbstractMetaFunctionCList findFunctions(QAnyStringView functionName) const;
AbstractMetaFunctionCPtr findOperatorBool() const;
// Find a Qt-style isNull() method suitable for nb_bool
AbstractMetaFunctionCPtr findQtIsNullMethod() const;
@@ -81,8 +83,8 @@ public:
bool hasCopyConstructor() const;
bool hasPrivateCopyConstructor() const;
- void addDefaultConstructor();
- void addDefaultCopyConstructor();
+ static void addDefaultConstructor(const AbstractMetaClassPtr &klass);
+ static void addDefaultCopyConstructor(const AbstractMetaClassPtr &klass);
bool hasNonPrivateConstructor() const;
void setHasNonPrivateConstructor(bool value);
@@ -113,11 +115,7 @@ public:
bool isImplicitlyCopyConstructible() const;
bool canAddDefaultCopyConstructor() const;
- /// Return type entry of the base class that declares the parent management
- TypeEntryCPtr parentManagementEntry() const;
- bool hasParentManagement() const { return !parentManagementEntry().isNull(); }
-
- void addSynthesizedComparisonOperators();
+ static void addSynthesizedComparisonOperators(const AbstractMetaClassPtr &c);
bool generateExceptionHandling() const;
@@ -125,7 +123,7 @@ public:
const UsingMembers &usingMembers() const;
void addUsingMember(const UsingMember &um);
- bool isUsingMember(const AbstractMetaClass *c, const QString &memberName,
+ bool isUsingMember(const AbstractMetaClassCPtr &c, const QString &memberName,
Access minimumAccess) const;
bool hasUsingMemberFor(const QString &memberName) const;
@@ -190,27 +188,27 @@ public:
QString baseClassName() const;
- const AbstractMetaClass *defaultSuperclass() const; // Attribute "default-superclass"
- void setDefaultSuperclass(AbstractMetaClass *s);
+ AbstractMetaClassCPtr defaultSuperclass() const; // Attribute "default-superclass"
+ void setDefaultSuperclass(const AbstractMetaClassPtr &s);
- const AbstractMetaClass *baseClass() const;
+ AbstractMetaClassCPtr baseClass() const;
const AbstractMetaClassCList &baseClasses() const;
// base classes including defaultSuperclass
AbstractMetaClassCList typeSystemBaseClasses() const;
// Recursive list of all base classes including defaultSuperclass
AbstractMetaClassCList allTypeSystemAncestors() const;
- void addBaseClass(const AbstractMetaClass *base_class);
- void setBaseClass(const AbstractMetaClass *base_class);
+ void addBaseClass(const AbstractMetaClassCPtr &base_class);
+ void setBaseClass(const AbstractMetaClassCPtr &base_class);
/**
* \return the namespace from another package which this namespace extends.
*/
- const AbstractMetaClass *extendedNamespace() const;
- void setExtendedNamespace(const AbstractMetaClass *e);
+ AbstractMetaClassCPtr extendedNamespace() const;
+ void setExtendedNamespace(const AbstractMetaClassCPtr &e);
const AbstractMetaClassCList &innerClasses() const;
- void addInnerClass(AbstractMetaClass *cl);
+ void addInnerClass(const AbstractMetaClassPtr &cl);
void setInnerClasses(const AbstractMetaClassCList &innerClasses);
QString package() const;
@@ -219,14 +217,11 @@ public:
bool isInvisibleNamespace() const;
bool isInlineNamespace() const;
- bool isQObject() const;
bool isQtNamespace() const;
QString qualifiedCppName() const;
bool hasSignals() const;
- bool inheritsFrom(const AbstractMetaClass *other) const;
- bool inheritsFrom(const QString &name) const;
/**
* Says if the class that declares or inherits a virtual function.
@@ -292,8 +287,8 @@ public:
void sortFunctions();
- const AbstractMetaClass *templateBaseClass() const;
- void setTemplateBaseClass(const AbstractMetaClass *cls);
+ AbstractMetaClassCPtr templateBaseClass() const;
+ void setTemplateBaseClass(const AbstractMetaClassCPtr &cls);
bool hasTemplateBaseClassInstantiations() const;
const AbstractMetaTypeList &templateBaseClassInstantiations() const;
@@ -317,18 +312,18 @@ public:
bool isCopyable() const;
bool isValueTypeWithCopyConstructorOnly() const;
void setValueTypeWithCopyConstructorOnly(bool v);
- static bool determineValueTypeWithCopyConstructorOnly(const AbstractMetaClass *c,
+ static bool determineValueTypeWithCopyConstructorOnly(const AbstractMetaClassCPtr &c,
bool avoidProtectedHack);
- static AbstractMetaClass *findClass(const AbstractMetaClassList &classes,
- QStringView name);
- static const AbstractMetaClass *findClass(const AbstractMetaClassCList &classes,
- QStringView name);
- static AbstractMetaClass *findClass(const AbstractMetaClassList &classes,
+ static AbstractMetaClassPtr findClass(const AbstractMetaClassList &classes,
+ QAnyStringView name);
+ static AbstractMetaClassCPtr findClass(const AbstractMetaClassCList &classes,
+ QAnyStringView name);
+ static AbstractMetaClassPtr findClass(const AbstractMetaClassList &classes,
const TypeEntryCPtr &typeEntry);
- static const AbstractMetaClass *findClass(const AbstractMetaClassCList &classes,
+ static AbstractMetaClassCPtr findClass(const AbstractMetaClassCList &classes,
const TypeEntryCPtr &typeEntry);
- const AbstractMetaClass *findBaseClass(const QString &qualifiedName) const;
+ AbstractMetaClassCPtr findBaseClass(const QString &qualifiedName) const;
static std::optional<AbstractMetaEnumValue> findEnumValue(const AbstractMetaClassList &classes,
const QString &string);
@@ -337,7 +332,7 @@ public:
void setSourceLocation(const SourceLocation &sourceLocation);
// For AbstractMetaBuilder
- void fixFunctions();
+ static void fixFunctions(const AbstractMetaClassPtr &klass);
bool needsInheritanceSetup() const;
void setInheritanceDone(bool b);
bool inheritanceDone() const;
@@ -349,17 +344,15 @@ private:
#ifndef QT_NO_DEBUG_STREAM
void format(QDebug &d) const;
void formatMembers(QDebug &d) const;
+ friend QDebug operator<<(QDebug d, const AbstractMetaClassCPtr &ac);
+ friend QDebug operator<<(QDebug d, const AbstractMetaClassPtr &ac);
friend QDebug operator<<(QDebug d, const AbstractMetaClass *ac);
+ friend void formatMetaClass(QDebug &, const AbstractMetaClass *);
#endif
QScopedPointer<AbstractMetaClassPrivate> d;
};
-inline bool AbstractMetaClass::isFinalInTargetLang() const
-{
- return attributes().testFlag(FinalInTargetLang);
-}
-
inline bool AbstractMetaClass::isAbstract() const
{
return attributes().testFlag(Abstract);
@@ -368,7 +361,7 @@ inline bool AbstractMetaClass::isAbstract() const
template <class Function>
void AbstractMetaClass::invisibleNamespaceRecursion(Function f) const
{
- for (auto ic : innerClasses()) {
+ for (const auto &ic : innerClasses()) {
if (ic->isInvisibleNamespace()) {
f(ic);
ic->invisibleNamespaceRecursion(f);
@@ -376,6 +369,23 @@ void AbstractMetaClass::invisibleNamespaceRecursion(Function f) const
}
}
+bool inheritsFrom(const AbstractMetaClassCPtr &c, const AbstractMetaClassCPtr &other);
+bool inheritsFrom(const AbstractMetaClassCPtr &c, QAnyStringView name);
+inline bool isQObject(const AbstractMetaClassCPtr &c)
+{
+ return inheritsFrom(c, "QObject");
+}
+
+AbstractMetaClassCPtr findBaseClass(const AbstractMetaClassCPtr &c,
+ const QString &qualifiedName);
+
+/// Return type entry of the base class that declares the parent management
+TypeEntryCPtr parentManagementEntry(const AbstractMetaClassCPtr &klass);
+inline bool hasParentManagement(const AbstractMetaClassCPtr &c)
+{ return bool(parentManagementEntry(c)); }
+
+AbstractMetaClassCList allBaseClasses(const AbstractMetaClassCPtr metaClass);
+
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaClass::CppWrapper);
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaClass::Attributes);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h b/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h
index 2bdfdb54d..9047c6bcd 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h
@@ -11,18 +11,15 @@ enum class FunctionQueryOption {
Constructors = 0x0000002, // Constructors except copy/move
CopyConstructor = 0x0000004, // Only copy constructors
//Destructors = 0x0000002, // Only destructors. Not included in class.
- FinalInTargetLangFunctions = 0x0000008, // Only functions that are non-virtual in TargetLang
ClassImplements = 0x0000020, // Only functions implemented by the current class
StaticFunctions = 0x0000080, // Only static functions
Signals = 0x0000100, // Only signals
NormalFunctions = 0x0000200, // Only functions that aren't signals
Visible = 0x0000400, // Only public and protected functions
- WasPublic = 0x0001000, // Only functions that were originally public
NonStaticFunctions = 0x0004000, // No static functions
Empty = 0x0008000, // Empty overrides of abstract functions
Invisible = 0x0010000, // Only private functions
VirtualInCppFunctions = 0x0020000, // Only functions that are virtual in C++
- VirtualInTargetLangFunctions = 0x0080000, // Only functions which are virtual in TargetLang
NotRemoved = 0x0400000, // Only functions that have not been removed
OperatorOverloads = 0x2000000, // Only functions that are operator overloads
GenerateExceptionHandling = 0x4000000,
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h b/sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h
index c1deea2c2..2a053ceaf 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h
@@ -4,21 +4,24 @@
#ifndef ABSTRACTMETALANG_HELPERS_H
#define ABSTRACTMETALANG_HELPERS_H
+#include "abstractmetalang_typedefs.h"
+
template <class MetaClass>
-MetaClass *findByName(QList<MetaClass *> haystack, QStringView needle)
+std::shared_ptr<MetaClass> findByName(const QList<std::shared_ptr<MetaClass> > &haystack,
+ QStringView needle)
{
- for (MetaClass *c : haystack) {
+ for (const auto &c : haystack) {
if (c->name() == needle)
return c;
}
- return nullptr;
+ return {};
}
// Helper for recursing the base classes of an AbstractMetaClass.
// Returns the class for which the predicate is true.
template <class Predicate>
-const AbstractMetaClass *recurseClassHierarchy(const AbstractMetaClass *klass,
- Predicate pred)
+AbstractMetaClassCPtr recurseClassHierarchy(const AbstractMetaClassCPtr &klass,
+ Predicate pred)
{
if (pred(klass))
return klass;
@@ -26,7 +29,7 @@ const AbstractMetaClass *recurseClassHierarchy(const AbstractMetaClass *klass,
if (auto r = recurseClassHierarchy(base, pred))
return r;
}
- return nullptr;
+ return {};
}
#endif // ABSTRACTMETALANG_HELPERS_H
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang_typedefs.h b/sources/shiboken6/ApiExtractor/abstractmetalang_typedefs.h
index 3b444197c..802f549cf 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang_typedefs.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang_typedefs.h
@@ -4,9 +4,10 @@
#ifndef ABSTRACTMETALANG_TYPEDEFS_H
#define ABSTRACTMETALANG_TYPEDEFS_H
-#include <QtCore/QSharedPointer>
#include <QtCore/QList>
+#include <memory>
+
class AbstractMetaClass;
class AbstractMetaField;
class AbstractMetaArgument;
@@ -16,12 +17,14 @@ class AbstractMetaFunction;
class AbstractMetaType;
struct UsingMember;
-using AbstractMetaFunctionPtr = QSharedPointer<AbstractMetaFunction>;
-using AbstractMetaFunctionCPtr = QSharedPointer<const AbstractMetaFunction>;
+using AbstractMetaFunctionPtr = std::shared_ptr<AbstractMetaFunction>;
+using AbstractMetaFunctionCPtr = std::shared_ptr<const AbstractMetaFunction>;
+using AbstractMetaClassPtr = std::shared_ptr<AbstractMetaClass>;
+using AbstractMetaClassCPtr = std::shared_ptr<const AbstractMetaClass>;
using AbstractMetaArgumentList = QList<AbstractMetaArgument>;
-using AbstractMetaClassList = QList<AbstractMetaClass *>;
-using AbstractMetaClassCList = QList<const AbstractMetaClass *>;
+using AbstractMetaClassList = QList<AbstractMetaClassPtr>;
+using AbstractMetaClassCList = QList<AbstractMetaClassCPtr>;
using AbstractMetaEnumList = QList<AbstractMetaEnum>;
using AbstractMetaEnumValueList = QList<AbstractMetaEnumValue>;
using AbstractMetaFieldList = QList<AbstractMetaField>;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
index 19e030330..3ec07509d 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
@@ -7,6 +7,8 @@
#include "messages.h"
#include "typedatabase.h"
#include "containertypeentry.h"
+#include "enumtypeentry.h"
+#include "flagstypeentry.h"
#include "qtcompat.h"
#include "typeinfo.h"
@@ -17,12 +19,13 @@
#include <QtCore/QHash>
#include <QtCore/QSharedData>
-#include <QtCore/QSharedPointer>
#include <QtCore/QStack>
+#include <memory>
+
using namespace Qt::StringLiterals;
-using AbstractMetaTypeCPtr = QSharedPointer<const AbstractMetaType>;
+using AbstractMetaTypeCPtr = std::shared_ptr<const AbstractMetaType>;
const QSet<QString> &AbstractMetaType::cppFloatTypes()
{
@@ -116,6 +119,7 @@ public:
QString formatPythonSignature() const;
bool isEquivalent(const AbstractMetaTypeData &rhs) const;
bool equals(const AbstractMetaTypeData &rhs) const;
+ QStringList instantiationCppSignatures() const;
template <class Predicate>
bool generateOpaqueContainer(Predicate p) const;
@@ -151,6 +155,14 @@ AbstractMetaTypeData::AbstractMetaTypeData(const TypeEntryCPtr &t) :
{
}
+QStringList AbstractMetaTypeData::instantiationCppSignatures() const
+{
+ QStringList result;
+ for (const auto &i : m_instantiations)
+ result.append(i.cppSignature());
+ return result;
+}
+
AbstractMetaType::AbstractMetaType(const TypeEntryCPtr &t) :
d(new AbstractMetaTypeData(t))
{
@@ -166,9 +178,9 @@ AbstractMetaType &AbstractMetaType::operator=(const AbstractMetaType &) = defaul
AbstractMetaType::AbstractMetaType(const AbstractMetaType &rhs) = default;
-AbstractMetaType::AbstractMetaType(AbstractMetaType &&) = default;
+AbstractMetaType::AbstractMetaType(AbstractMetaType &&) noexcept = default;
-AbstractMetaType &AbstractMetaType::operator=(AbstractMetaType &&) = default;
+AbstractMetaType &AbstractMetaType::operator=(AbstractMetaType &&) noexcept = default;
AbstractMetaType::~AbstractMetaType() = default;
@@ -219,6 +231,11 @@ const AbstractMetaTypeList &AbstractMetaType::instantiations() const
return d->m_instantiations;
}
+QStringList AbstractMetaType::instantiationCppSignatures() const
+{
+ return d->instantiationCppSignatures();
+}
+
// For applying the <array> function argument modification: change into a type
// where "int *" becomes "int[]".
bool AbstractMetaType::applyArrayModification(QString *errorMessage)
@@ -228,7 +245,7 @@ bool AbstractMetaType::applyArrayModification(QString *errorMessage)
*errorMessage = u"<array> modification already applied."_s;
return false;
}
- if (!d->m_arrayElementType.isNull()) {
+ if (d->m_arrayElementType) {
QTextStream(errorMessage) << "The type \"" << cppSignature()
<< "\" is an array of " << d->m_arrayElementType->name() << '.';
return false;
@@ -276,13 +293,13 @@ QString AbstractMetaType::originalTypeDescription() const
void AbstractMetaType::setOriginalTemplateType(const AbstractMetaType &type)
{
- if (d->m_originalTemplateType.isNull() || *d->m_originalTemplateType != type)
+ if (!d->m_originalTemplateType || *d->m_originalTemplateType != type)
d->m_originalTemplateType.reset(new AbstractMetaType(type));
}
const AbstractMetaType *AbstractMetaType::originalTemplateType() const
{
- return d->m_originalTemplateType.data();
+ return d->m_originalTemplateType.get();
}
AbstractMetaType AbstractMetaType::getSmartPointerInnerType() const
@@ -311,7 +328,7 @@ AbstractMetaTypeList AbstractMetaType::nestedArrayTypes() const
}
break;
case NativePointerAsArrayPattern:
- result.append(*d->m_arrayElementType.data());
+ result.append(*d->m_arrayElementType.get());
break;
default:
break;
@@ -339,6 +356,12 @@ bool AbstractMetaType::passByValue() const
return d->passByValue();
}
+bool AbstractMetaType::useStdMove() const
+{
+ return (isUniquePointer() && d->passByValue())
+ || d->m_referenceType == RValueReference;
+}
+
ReferenceType AbstractMetaType::referenceType() const
{
return d->m_referenceType;
@@ -417,17 +440,28 @@ int AbstractMetaType::arrayElementCount() const
const AbstractMetaType *AbstractMetaType::arrayElementType() const
{
- return d->m_arrayElementType.data();
+ return d->m_arrayElementType.get();
}
void AbstractMetaType::setArrayElementType(const AbstractMetaType &t)
{
- if (d->m_arrayElementType.isNull() || *d->m_arrayElementType != t) {
+ if (!d->m_arrayElementType || *d->m_arrayElementType != t) {
d->m_arrayElementType.reset(new AbstractMetaType(t));
d->m_signaturesDirty = true;
}
}
+AbstractMetaType AbstractMetaType::plainType() const
+{
+ AbstractMetaType result = *this;
+ result.clearIndirections();
+ result.setReferenceType(NoReference);
+ result.setConstant(false);
+ result.setVolatile(false);
+ result.decideUsagePattern();
+ return result;
+}
+
QString AbstractMetaType::cppSignature() const
{
const AbstractMetaTypeData *cd = d.constData();
@@ -509,6 +543,7 @@ void AbstractMetaType::decideUsagePattern()
pattern = ObjectPattern;
}
setTypeUsagePattern(pattern);
+ Q_ASSERT(pattern != ContainerPattern || !d->m_instantiations.isEmpty());
}
bool AbstractMetaTypeData::hasTemplateChildren() const
@@ -542,6 +577,29 @@ static inline QString formatArraySize(int e)
return result;
}
+// Return the number of template parameters; remove the default
+// non template type parameter of std::span from the signature.
+static qsizetype stripDefaultTemplateArgs(const TypeEntryCPtr &te,
+ const AbstractMetaTypeList &instantiations)
+{
+ static const char16_t dynamicExtent64[] = u"18446744073709551615"; // size_t(-1)
+ static const char16_t dynamicExtent32[] = u"4294967295";
+
+ qsizetype result = instantiations.size();
+ if (result == 0 || !te->isContainer())
+ return result;
+ auto cte = std::static_pointer_cast<const ContainerTypeEntry>(te);
+ if (cte->containerKind() != ContainerTypeEntry::SpanContainer)
+ return result;
+ const auto lastTe = instantiations.constLast().typeEntry();
+ if (lastTe->type() == TypeEntry::ConstantValueType) {
+ const QString &name = lastTe->name();
+ if (name == dynamicExtent64 || name == dynamicExtent32)
+ --result;
+ }
+ return result;
+}
+
QString AbstractMetaTypeData::formatSignature(bool minimal) const
{
QString result;
@@ -564,12 +622,13 @@ QString AbstractMetaTypeData::formatSignature(bool minimal) const
result += u'<';
if (minimal)
result += u' ';
- for (qsizetype i = 0, size = m_instantiations.size(); i < size; ++i) {
+ const auto size = stripDefaultTemplateArgs(m_typeEntry, m_instantiations);
+ for (qsizetype i = 0; i < size; ++i) {
if (i > 0)
result += u',';
result += m_instantiations.at(i).minimalSignature();
}
- result += u" >"_s;
+ result += u'>';
}
if (!minimal && (!m_indirections.isEmpty() || m_referenceType != NoReference))
@@ -642,10 +701,12 @@ QString AbstractMetaTypeData::formatPythonSignature() const
if (m_typeEntry->isPrimitive())
for (Indirection i : m_indirections)
result += TypeInfo::indirectionKeyword(i);
- // If it is a flags type, we replace it with the full name:
- // "PySide6.QtCore.Qt.ItemFlags" instead of "PySide6.QtCore.QFlags<Qt.ItemFlag>"
- if (m_typeEntry->isFlags())
- result = m_typeEntry->qualifiedTargetLangName();
+ // If it is a flags type, we replace it with the full name of the enum:
+ // "PySide6.QtCore.Qt.ItemFlag" instead of "PySide6.QtCore.QFlags<Qt.ItemFlag>"
+ if (m_typeEntry->isFlags()) {
+ const auto fte = std::static_pointer_cast<const FlagsTypeEntry>(m_typeEntry);
+ result = fte->originator()->qualifiedTargetLangName();
+ }
result.replace(u"::"_s, u"."_s);
return result;
}
@@ -688,9 +749,9 @@ void AbstractMetaType::setVolatile(bool v)
static bool equalsCPtr(const AbstractMetaTypeCPtr &t1, const AbstractMetaTypeCPtr &t2)
{
- if (t1.isNull() != t2.isNull())
+ if (bool(t1) != bool(t2))
return false;
- return t1.isNull() || *t1 == *t2;
+ return !t1 || *t1 == *t2;
}
bool AbstractMetaTypeData::isEquivalent(const AbstractMetaTypeData &rhs) const
@@ -718,9 +779,9 @@ bool AbstractMetaTypeData::equals(const AbstractMetaTypeData &rhs) const
&& m_referenceType == rhs.m_referenceType && isEquivalent(rhs);
}
-bool AbstractMetaType::equals(const AbstractMetaType &rhs) const
+bool comparesEqual(const AbstractMetaType &lhs, const AbstractMetaType &rhs) noexcept
{
- return d->equals(*rhs.d);
+ return lhs.d->equals(*rhs.d);
}
bool AbstractMetaType::isEquivalent(const AbstractMetaType &rhs) const
@@ -730,12 +791,12 @@ bool AbstractMetaType::isEquivalent(const AbstractMetaType &rhs) const
const AbstractMetaType *AbstractMetaType::viewOn() const
{
- return d->m_viewOn.data();
+ return d->m_viewOn.get();
}
void AbstractMetaType::setViewOn(const AbstractMetaType &v)
{
- if (d->m_viewOn.isNull() || *d->m_viewOn != v)
+ if (!d->m_viewOn || *d->m_viewOn != v)
d->m_viewOn.reset(new AbstractMetaType(v));
}
@@ -744,7 +805,7 @@ AbstractMetaType AbstractMetaType::createVoid()
static QScopedPointer<AbstractMetaType> metaType;
if (metaType.isNull()) {
static TypeEntryCPtr voidTypeEntry = TypeDatabase::instance()->findType(u"void"_s);
- Q_ASSERT(!voidTypeEntry.isNull());
+ Q_ASSERT(voidTypeEntry);
metaType.reset(new AbstractMetaType(voidTypeEntry));
metaType->decideUsagePattern();
}
@@ -871,7 +932,7 @@ bool AbstractMetaType::isValueTypeWithCopyConstructorOnly() const
{
bool result = false;
if (d->m_typeEntry->isComplex()) {
- const auto cte = qSharedPointerCast<const ComplexTypeEntry>(d->m_typeEntry);
+ const auto cte = std::static_pointer_cast<const ComplexTypeEntry>(d->m_typeEntry);
result = cte->isValueTypeWithCopyConstructorOnly();
}
return result;
@@ -888,14 +949,18 @@ using AbstractMetaTypeCache = QHash<QString, AbstractMetaType>;
Q_GLOBAL_STATIC(AbstractMetaTypeCache, metaTypeFromStringCache)
std::optional<AbstractMetaType>
-AbstractMetaType::fromString(QString typeSignature, QString *errorMessage)
+AbstractMetaType::fromString(const QString &typeSignatureIn, QString *errorMessage)
{
- typeSignature = typeSignature.trimmed();
+ auto &cache = *metaTypeFromStringCache();
+ auto it = cache.find(typeSignatureIn);
+ if (it != cache.end())
+ return it.value();
+
+ QString typeSignature = typeSignatureIn.trimmed();
if (typeSignature.startsWith(u"::"))
typeSignature.remove(0, 2);
- auto &cache = *metaTypeFromStringCache();
- auto it = cache.find(typeSignature);
+ it = cache.find(typeSignature);
if (it == cache.end()) {
auto metaType =
AbstractMetaBuilder::translateType(typeSignature, nullptr, {}, errorMessage);
@@ -904,6 +969,8 @@ AbstractMetaType::fromString(QString typeSignature, QString *errorMessage)
errorMessage->prepend(msgCannotBuildMetaType(typeSignature));
return {};
}
+ if (typeSignature != typeSignatureIn)
+ cache.insert(typeSignatureIn, metaType.value());
it = cache.insert(typeSignature, metaType.value());
}
return it.value();
@@ -918,16 +985,12 @@ AbstractMetaType AbstractMetaType::fromTypeEntry(const TypeEntryCPtr &typeEntry)
auto it = cache.find(typeName);
if (it != cache.end())
return it.value();
- AbstractMetaType metaType(typeEntry);
- metaType.clearIndirections();
- metaType.setReferenceType(NoReference);
- metaType.setConstant(false);
- metaType.decideUsagePattern();
+ AbstractMetaType metaType = AbstractMetaType(typeEntry).plainType();
cache.insert(typeName, metaType);
return metaType;
}
-AbstractMetaType AbstractMetaType::fromAbstractMetaClass(const AbstractMetaClass *metaClass)
+AbstractMetaType AbstractMetaType::fromAbstractMetaClass(const AbstractMetaClassCPtr &metaClass)
{
return fromTypeEntry(metaClass->typeEntry());
}
@@ -940,37 +1003,34 @@ bool AbstractMetaTypeData::generateOpaqueContainer(Predicate pred) const
return false;
if (m_indirections.size() > 1)
return false;
- auto containerTypeEntry = qSharedPointerCast<const ContainerTypeEntry>(m_typeEntry);
+ auto containerTypeEntry = std::static_pointer_cast<const ContainerTypeEntry>(m_typeEntry);
auto kind = containerTypeEntry->containerKind();
- if (kind != ContainerTypeEntry::ListContainer)
- return false;
- const auto &instantation = m_instantiations.constFirst();
- if (instantation.referenceType() != NoReference)
+ if (kind != ContainerTypeEntry::ListContainer && kind != ContainerTypeEntry::SpanContainer)
return false;
- const QString signature = instantation.cppSignature();
- bool result = false;
- auto instTypEntry = instantation.typeEntry();
- switch (instTypEntry->type()) {
+ const auto &firstInstantiation = m_instantiations.constFirst();
+ if (firstInstantiation.referenceType() != NoReference)
+ return false;
+ switch (firstInstantiation.typeEntry()->type()) {
case TypeEntry::PrimitiveType:
case TypeEntry::FlagsType:
case TypeEntry::EnumType:
case TypeEntry::BasicValueType:
case TypeEntry::ObjectType:
case TypeEntry::CustomType:
- result = pred(containerTypeEntry, signature);
break;
default:
- break;
+ return false;
}
- return result;
+
+ return pred(containerTypeEntry, instantiationCppSignatures());
}
// Simple predicate for checking whether an opaque container should be generated
static bool opaqueContainerPredicate(const ContainerTypeEntryCPtr &t,
- const QString &signature)
+ const QStringList &instantiations)
{
- return t->generateOpaqueContainer(signature);
+ return t->generateOpaqueContainer(instantiations);
}
bool AbstractMetaType::generateOpaqueContainer() const
@@ -983,8 +1043,9 @@ bool AbstractMetaType::generateOpaqueContainer() const
// (cf AbstractMetaFunction::generateOpaqueContainerReturn())
bool AbstractMetaType::generateOpaqueContainerForGetter(const QString &modifiedType) const
{
- auto predicate = [&modifiedType](const ContainerTypeEntryCPtr &t, const QString &signature) {
- return t->opaqueContainerName(signature) == modifiedType;
+ auto predicate = [&modifiedType](const ContainerTypeEntryCPtr &t,
+ const QStringList &instantiations) {
+ return t->opaqueContainerName(instantiations) == modifiedType;
};
return d->generateOpaqueContainer(predicate);
}
@@ -1008,7 +1069,7 @@ void AbstractMetaType::formatDebug(QDebug &debug) const
for (auto i : indirections)
debug << ' ' << TypeInfo::indirectionKeyword(i);
}
- if (referenceType())
+ if (referenceType() != NoReference)
debug << ", reftype=" << referenceType();
if (isConstant())
debug << ", [const]";
diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.h b/sources/shiboken6/ApiExtractor/abstractmetatype.h
index 237c33d20..8a1ecdf20 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetatype.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetatype.h
@@ -9,7 +9,9 @@
#include "parser/codemodel_enums.h"
#include "typedatabase_typedefs.h"
+#include <QtCore/QtCompare>
#include <QtCore/qobjectdefs.h>
+#include <QtCore/QHashFunctions>
#include <QtCore/QSharedDataPointer>
#include <QtCore/QList>
#include <QtCore/QSet>
@@ -50,8 +52,8 @@ public:
explicit AbstractMetaType(const TypeEntryCPtr &t);
AbstractMetaType(const AbstractMetaType &);
AbstractMetaType &operator=(const AbstractMetaType &);
- AbstractMetaType(AbstractMetaType &&);
- AbstractMetaType &operator=(AbstractMetaType &&);
+ AbstractMetaType(AbstractMetaType &&) noexcept;
+ AbstractMetaType &operator=(AbstractMetaType &&) noexcept;
~AbstractMetaType();
QString package() const;
@@ -67,6 +69,7 @@ public:
const AbstractMetaTypeList &instantiations() const;
void addInstantiation(const AbstractMetaType &inst);
void setInstantiations(const AbstractMetaTypeList &insts);
+ QStringList instantiationCppSignatures() const;
QString minimalSignature() const { return formatSignature(true); }
@@ -118,6 +121,7 @@ public:
bool passByConstRef() const;
bool passByValue() const;
+ bool useStdMove() const;
ReferenceType referenceType() const;
void setReferenceType(ReferenceType ref);
@@ -141,6 +145,9 @@ public:
AbstractMetaTypeList nestedArrayTypes() const;
+ /// Strip const/indirections/reference from the type
+ AbstractMetaType plainType() const;
+
QString cppSignature() const;
QString pythonSignature() const;
@@ -165,7 +172,6 @@ public:
bool hasTemplateChildren() const;
- bool equals(const AbstractMetaType &rhs) const;
/// Is equivalent from the POV of argument passing (differ by const ref)
bool isEquivalent(const AbstractMetaType &rhs) const;
@@ -182,11 +188,11 @@ public:
/// \param typeSignature The string describing the type to be built.
/// \return A new AbstractMetaType object or nullopt in case of failure.
static std::optional<AbstractMetaType>
- fromString(QString typeSignature, QString *errorMessage = nullptr);
+ fromString(const QString &typeSignatureIn, QString *errorMessage = nullptr);
/// Creates an AbstractMetaType object from a TypeEntry.
static AbstractMetaType fromTypeEntry(const TypeEntryCPtr &typeEntry);
/// Creates an AbstractMetaType object from an AbstractMetaClass.
- static AbstractMetaType fromAbstractMetaClass(const AbstractMetaClass *metaClass);
+ static AbstractMetaType fromAbstractMetaClass(const AbstractMetaClassCPtr &metaClass);
static void dereference(QString *type); // "foo" -> "(*foo)"
/// Apply the result of shouldDereferenceArgument()
@@ -248,6 +254,12 @@ public:
#endif
private:
+ friend size_t qHash(const AbstractMetaType &t, size_t seed = 0) noexcept
+ { return qHash(t.typeEntry().get(), seed); }
+ friend bool comparesEqual(const AbstractMetaType &lhs,
+ const AbstractMetaType &rhs) noexcept;
+ Q_DECLARE_EQUALITY_COMPARABLE(AbstractMetaType)
+
friend class AbstractMetaTypeData;
QSharedDataPointer<AbstractMetaTypeData> d;
@@ -256,14 +268,6 @@ private:
QString formatPythonSignature() const;
};
-inline bool operator==(const AbstractMetaType &t1, const AbstractMetaType &t2)
-{ return t1.equals(t2); }
-inline bool operator!=(const AbstractMetaType &t1, const AbstractMetaType &t2)
-{ return !t1.equals(t2); }
-
-inline size_t qHash(const AbstractMetaType &t, size_t seed)
-{ return qHash(t.typeEntry(), seed); }
-
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const AbstractMetaType &at);
QDebug operator<<(QDebug d, const AbstractMetaType *at);
diff --git a/sources/shiboken6/ApiExtractor/addedfunction.cpp b/sources/shiboken6/ApiExtractor/addedfunction.cpp
index 6525c1ed7..9d95b734c 100644
--- a/sources/shiboken6/ApiExtractor/addedfunction.cpp
+++ b/sources/shiboken6/ApiExtractor/addedfunction.cpp
@@ -9,18 +9,13 @@
using namespace Qt::StringLiterals;
-static inline QString callOperator() { return QStringLiteral("operator()"); }
+constexpr auto callOperator = "operator()"_L1;
// Helpers to split a parameter list of <add-function>, <declare-function>
// (@ denoting names), like
// "void foo(QList<X,Y> &@list@ = QList<X,Y>{1,2}, int @b@=5, ...)"
namespace AddedFunctionParser {
-bool Argument::equals(const Argument &rhs) const
-{
- return type == rhs.type && name == rhs.name && defaultValue == rhs.defaultValue;
-}
-
QDebug operator<<(QDebug d, const Argument &a)
{
QDebugStateSaver saver(d);
@@ -87,7 +82,7 @@ Arguments splitParameters(QStringView paramString, QString *errorMessage)
for (const auto &t : tokens) {
Argument argument;
// Check defaultValue, "int @b@=5"
- const int equalPos = t.lastIndexOf(u'=');
+ const auto equalPos = t.lastIndexOf(u'=');
if (equalPos != -1) {
const int defaultValuePos = equalPos + 1;
argument.defaultValue =
@@ -95,7 +90,7 @@ Arguments splitParameters(QStringView paramString, QString *errorMessage)
}
QString typeString = (equalPos != -1 ? t.left(equalPos) : t).trimmed().toString();
// Check @name@
- const int atPos = typeString.indexOf(u'@');
+ const auto atPos = typeString.indexOf(u'@');
if (atPos != -1) {
const int namePos = atPos + 1;
const int nameEndPos = typeString.indexOf(u'@', namePos);
@@ -143,16 +138,16 @@ AddedFunction::AddedFunctionPtr
QStringView signature = QStringView{signatureIn}.trimmed();
// Skip past "operator()(...)"
- const int parenSearchStartPos = signature.startsWith(callOperator())
- ? callOperator().size() : 0;
- const int openParenPos = signature.indexOf(u'(', parenSearchStartPos);
+ const auto parenSearchStartPos = signature.startsWith(callOperator)
+ ? callOperator.size() : 0;
+ const auto openParenPos = signature.indexOf(u'(', parenSearchStartPos);
if (openParenPos < 0) {
return AddedFunctionPtr(new AddedFunction(signature.toString(),
arguments, returnType));
}
const QString name = signature.left(openParenPos).trimmed().toString();
- const int closingParenPos = signature.lastIndexOf(u')');
+ const auto closingParenPos = signature.lastIndexOf(u')');
if (closingParenPos < 0) {
*errorMessage = u"Missing closing parenthesis"_s;
return {};
@@ -160,8 +155,8 @@ AddedFunction::AddedFunctionPtr
// Check for "foo() const"
bool isConst = false;
- const int signatureLength = signature.length();
- const int qualifierLength = signatureLength - closingParenPos - 1;
+ const auto signatureLength = signature.length();
+ const auto qualifierLength = signatureLength - closingParenPos - 1;
if (qualifierLength >= 5
&& signature.right(qualifierLength).contains(u"const")) {
isConst = true;
@@ -182,7 +177,7 @@ AddedFunction::AddedFunctionPtr
arguments.append({type, p.name, p.defaultValue});
}
- AddedFunctionPtr result(new AddedFunction(name, arguments, returnType));
+ auto result = std::make_shared<AddedFunction>(name, arguments, returnType);
result->setConstant(isConst);
return result;
}
diff --git a/sources/shiboken6/ApiExtractor/addedfunction.h b/sources/shiboken6/ApiExtractor/addedfunction.h
index 0f5dc89ef..b8d189b7a 100644
--- a/sources/shiboken6/ApiExtractor/addedfunction.h
+++ b/sources/shiboken6/ApiExtractor/addedfunction.h
@@ -8,9 +8,10 @@
#include "parser/typeinfo.h"
#include <QtCore/QList>
-#include <QtCore/QSharedPointer>
#include <QtCore/QString>
+#include <memory>
+
QT_FORWARD_DECLARE_CLASS(QDebug)
/// \internal
@@ -19,7 +20,7 @@ QT_FORWARD_DECLARE_CLASS(QDebug)
/// will be inserted into the right AbstractMetaClass.
struct AddedFunction
{
- using AddedFunctionPtr = QSharedPointer<AddedFunction>;
+ using AddedFunctionPtr = std::shared_ptr<AddedFunction>;
/// Function access types.
enum Access {
@@ -78,6 +79,9 @@ struct AddedFunction
bool isDeclaration() const { return m_isDeclaration; } // <declare-function>
void setDeclaration(bool value) { m_isDeclaration = value; }
+ bool isPythonOverride() const { return m_isPythonOverride; }
+ void setPythonOverride(bool o) { m_isPythonOverride = o; }
+
const FunctionModificationList &modifications() const { return m_modifications; }
FunctionModificationList &modifications() { return m_modifications; }
@@ -85,17 +89,22 @@ struct AddedFunction
DocModificationList &docModifications() { return m_docModifications; }
void addDocModification(const DocModification &m) { m_docModifications.append(m); }
+ QString targetLangPackage() const { return m_targetLangPackage; }
+ void setTargetLangPackage(const QString &p) { m_targetLangPackage = p; }
+
private:
QString m_name;
QList<Argument> m_arguments;
TypeInfo m_returnType;
FunctionModificationList m_modifications;
DocModificationList m_docModifications;
+ QString m_targetLangPackage;
Access m_access = Public;
bool m_isConst = false;
bool m_isClassMethod = false;
bool m_isStatic = false;
bool m_isDeclaration = false;
+ bool m_isPythonOverride = false;
};
QDebug operator<<(QDebug d, const AddedFunction::Argument &a);
diff --git a/sources/shiboken6/ApiExtractor/addedfunction_p.h b/sources/shiboken6/ApiExtractor/addedfunction_p.h
index 9915871ad..40b69a5df 100644
--- a/sources/shiboken6/ApiExtractor/addedfunction_p.h
+++ b/sources/shiboken6/ApiExtractor/addedfunction_p.h
@@ -4,6 +4,7 @@
#ifndef ADDEDFUNCTION_P_H
#define ADDEDFUNCTION_P_H
+#include <QtCore/QtCompare>
#include <QtCore/QList>
#include <QtCore/QString>
#include <QtCore/QStringView>
@@ -19,18 +20,20 @@ namespace AddedFunctionParser {
struct Argument
{
- bool equals(const Argument &rhs) const;
-
QString type;
QString name;
QString defaultValue;
+
+ friend bool comparesEqual(const Argument &lhs, const Argument &rhs) noexcept
+ {
+ return lhs.type == rhs.type && lhs.name == rhs.name
+ && lhs.defaultValue == rhs.defaultValue;
+ }
+ Q_DECLARE_EQUALITY_COMPARABLE(Argument)
};
using Arguments = QList<Argument>;
-inline bool operator==(const Argument &a1, const Argument &a2) { return a1.equals(a2); }
-inline bool operator!=(const Argument &a1, const Argument &a2) { return !a1.equals(a2); }
-
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const Argument &a);
#endif
diff --git a/sources/shiboken6/ApiExtractor/anystringview_helpers.cpp b/sources/shiboken6/ApiExtractor/anystringview_helpers.cpp
new file mode 100644
index 000000000..35d2d535a
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/anystringview_helpers.cpp
@@ -0,0 +1,56 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "anystringview_helpers.h"
+
+#include <QtCore/QString> // Must go before QAnyStringView for operator<<(QTextStream,QASV)!
+#include <QtCore/QAnyStringView>
+#include <QtCore/QDebug>
+#include <QtCore/QTextStream>
+
+#include <cstring>
+
+QTextStream &operator<<(QTextStream &str, QAnyStringView asv)
+{
+ asv.visit([&str](auto s) { str << s; });
+ return str;
+}
+
+static bool asv_containsImpl(QLatin1StringView v, char c)
+{
+ return v.contains(uint16_t(c));
+}
+
+static bool asv_containsImpl(QUtf8StringView v, char c)
+{
+ return std::strchr(v.data(), c) != nullptr;
+}
+
+static bool asv_containsImpl(QStringView v, char c)
+{
+ return v.contains(uint16_t(c));
+}
+
+bool asv_contains(QAnyStringView asv, char needle)
+{
+ return asv.visit([needle](auto s) { return asv_containsImpl(s, needle); });
+}
+
+static bool asv_containsImpl(QLatin1StringView v, const char *c)
+{
+ return v.contains(QLatin1StringView(c));
+}
+static bool asv_containsImpl(QUtf8StringView v, const char *c)
+{
+ return std::strstr(v.data(), c) != nullptr;
+}
+
+static bool asv_containsImpl(QStringView v, const char *c)
+{
+ return v.contains(QLatin1StringView(c));
+}
+
+bool asv_contains(QAnyStringView asv, const char *needle)
+{
+ return asv.visit([needle](auto s) { return asv_containsImpl(s, needle); });
+}
diff --git a/sources/shiboken6/ApiExtractor/anystringview_helpers.h b/sources/shiboken6/ApiExtractor/anystringview_helpers.h
new file mode 100644
index 000000000..e1e6ab7f0
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/anystringview_helpers.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef ANYSTRINGVIEW_STREAM_H
+#define ANYSTRINGVIEW_STREAM_H
+
+#include <QtCore/QtClassHelperMacros>
+
+QT_FORWARD_DECLARE_CLASS(QAnyStringView)
+QT_FORWARD_DECLARE_CLASS(QTextStream)
+QT_FORWARD_DECLARE_CLASS(QDebug)
+
+QTextStream &operator<<(QTextStream &str, QAnyStringView asv);
+
+bool asv_contains(QAnyStringView asv, char needle);
+bool asv_contains(QAnyStringView asv, const char *needle);
+
+#endif // ANYSTRINGVIEW_STREAM_H
diff --git a/sources/shiboken6/ApiExtractor/apiextractor.cpp b/sources/shiboken6/ApiExtractor/apiextractor.cpp
index 2e22f21e3..a4efaf2f9 100644
--- a/sources/shiboken6/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken6/ApiExtractor/apiextractor.cpp
@@ -3,7 +3,6 @@
#include "apiextractor.h"
#include "apiextractorresult.h"
-#include "apiextractorresultdata_p.h"
#include "abstractmetaargument.h"
#include "abstractmetabuilder.h"
#include "abstractmetaenum.h"
@@ -14,6 +13,7 @@
#include "exception.h"
#include "messages.h"
#include "modifications.h"
+#include "optionsparser.h"
#include "reporthandler.h"
#include "typedatabase.h"
#include "customconversion.h"
@@ -43,7 +43,186 @@ struct InstantiationCollectContext
QStringList instantiatedContainersNames;
};
-struct ApiExtractorPrivate
+struct ApiExtractorOptions
+{
+ QString m_typeSystemFileName;
+ QFileInfoList m_cppFileNames;
+ HeaderPaths m_includePaths;
+ QStringList m_clangOptions;
+ QString m_logDirectory;
+ LanguageLevel m_languageLevel = LanguageLevel::Default;
+ bool m_skipDeprecated = false;
+};
+
+static inline QString languageLevelDescription()
+{
+ return u"C++ Language level (c++11..c++17, default="_s
+ + QLatin1StringView(clang::languageLevelOption(clang::emulatedCompilerLanguageLevel()))
+ + u')';
+}
+
+QList<OptionDescription> ApiExtractor::options()
+{
+ return {
+ {u"use-global-header"_s,
+ u"Use the global headers in generated code."_s},
+ {u"clang-option"_s,
+ u"Option to be passed to clang"_s},
+ {u"clang-options"_s,
+ u"A comma-separated list of options to be passed to clang"_s},
+ {u"skip-deprecated"_s,
+ u"Skip deprecated functions"_s},
+ {u"-F<path>"_s, {} },
+ {u"framework-include-paths="_s + OptionsParser::pathSyntax(),
+ u"Framework include paths used by the C++ parser"_s},
+ {u"-isystem<path>"_s, {} },
+ {u"system-include-paths="_s + OptionsParser::pathSyntax(),
+ u"System include paths used by the C++ parser"_s},
+ {u"language-level=, -std=<level>"_s,
+ languageLevelDescription()},
+ };
+}
+
+class ApiExtractorOptionsParser : public OptionsParser
+{
+public:
+ explicit ApiExtractorOptionsParser(ApiExtractorOptions *o) : m_options(o) {}
+
+ bool handleBoolOption(const QString &key, OptionSource source) override;
+ bool handleOption(const QString &key, const QString &value,
+ OptionSource source) override;
+
+private:
+ void parseIncludePathOption(const QString &value, HeaderType headerType);
+ void parseIncludePathOption(const QStringList &values, HeaderType headerType);
+ void setLanguageLevel(const QString &value);
+
+ ApiExtractorOptions *m_options;
+};
+
+void ApiExtractorOptionsParser::parseIncludePathOption(const QString &value,
+ HeaderType headerType)
+{
+ if (value.isEmpty())
+ throw Exception(u"Empty value passed to include path option"_s);
+ const auto path = QFile::encodeName(QDir::cleanPath(value));
+ m_options->m_includePaths.append(HeaderPath{path, headerType});
+}
+
+void ApiExtractorOptionsParser::parseIncludePathOption(const QStringList &values,
+ HeaderType headerType)
+{
+ for (const auto &value : values)
+ parseIncludePathOption(value, headerType);
+}
+
+void ApiExtractorOptionsParser::setLanguageLevel(const QString &value)
+{
+ const QByteArray languageLevelBA = value.toLatin1();
+ const LanguageLevel level = clang::languageLevelFromOption(languageLevelBA.constData());
+ if (level == LanguageLevel::Default)
+ throw Exception(msgInvalidLanguageLevel(value));
+ m_options->m_languageLevel = level;
+}
+
+bool ApiExtractorOptionsParser::handleBoolOption(const QString &key, OptionSource source)
+{
+ static const auto isystemOption = "isystem"_L1;
+
+ switch (source) {
+ case OptionSource::CommandLine:
+ case OptionSource::ProjectFile:
+ if (key == u"use-global-header") {
+ AbstractMetaBuilder::setUseGlobalHeader(true);
+ return true;
+ }
+ if (key == u"skip-deprecated") {
+ m_options->m_skipDeprecated = true;
+ return true;
+ }
+ break;
+
+ case OptionSource::CommandLineSingleDash:
+ if (key.startsWith(u'I')) { // Shorthand path arguments -I/usr/include...
+ parseIncludePathOption(key.sliced(1), HeaderType::Standard);
+ return true;
+ }
+ if (key.startsWith(u'F')) {
+ parseIncludePathOption(key.sliced(1), HeaderType::Framework);
+ return true;
+ }
+ if (key.startsWith(isystemOption)) {
+ parseIncludePathOption(key.sliced(isystemOption.size()), HeaderType::System);
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+bool ApiExtractorOptionsParser::handleOption(const QString &key, const QString &value,
+ OptionSource source)
+{
+ if (source == OptionSource::CommandLineSingleDash) {
+ if (key == u"std") {
+ setLanguageLevel(value);
+ return true;
+ }
+ return false;
+ }
+
+ if (key == u"clang-option") {
+ m_options->m_clangOptions.append(value);
+ return true;
+ }
+ if (key == u"clang-options") {
+ m_options->m_clangOptions.append(value.split(u',', Qt::SkipEmptyParts));
+ return true;
+ }
+ if (key == u"include-paths") {
+ parseIncludePathOption(value.split(QDir::listSeparator(), Qt::SkipEmptyParts),
+ HeaderType::Standard);
+ return true;
+ }
+ if (key == u"framework-include-paths") {
+ parseIncludePathOption(value.split(QDir::listSeparator(), Qt::SkipEmptyParts),
+ HeaderType::Framework);
+ return true;
+ }
+ if (key == u"system-include-paths") {
+ parseIncludePathOption(value.split(QDir::listSeparator(), Qt::SkipEmptyParts),
+ HeaderType::System);
+ return true;
+ }
+ if (key == u"language-level") {
+ setLanguageLevel(value);
+ return true;
+ }
+
+ if (source == OptionSource::ProjectFile) {
+ if (key == u"include-path") {
+ parseIncludePathOption(value, HeaderType::Standard);
+ return true;
+ }
+ if (key == u"framework-include-path") {
+ parseIncludePathOption(value, HeaderType::Framework);
+ return true;
+ }
+ if (key == u"system-include-path") {
+ parseIncludePathOption(value, HeaderType::System);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+std::shared_ptr<OptionsParser> ApiExtractor::createOptionsParser()
+{
+ return std::make_shared<ApiExtractorOptionsParser>(d);
+}
+
+struct ApiExtractorPrivate : public ApiExtractorOptions
{
bool runHelper(ApiExtractorFlags flags);
@@ -54,7 +233,7 @@ struct ApiExtractorPrivate
void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
const AbstractMetaFunctionCPtr &func);
void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
- const AbstractMetaClass *metaClass);
+ const AbstractMetaClassCPtr &metaClass);
void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context);
void collectInstantiatedOpqaqueContainers(InstantiationCollectContext &context);
void collectContainerTypesFromSnippets(InstantiationCollectContext &context);
@@ -64,23 +243,12 @@ struct ApiExtractorPrivate
void addInstantiatedSmartPointer(InstantiationCollectContext &context,
const AbstractMetaType &type);
- QString m_typeSystemFileName;
- QFileInfoList m_cppFileNames;
- HeaderPaths m_includePaths;
- QStringList m_clangOptions;
AbstractMetaBuilder *m_builder = nullptr;
- QString m_logDirectory;
- LanguageLevel m_languageLevel = LanguageLevel::Default;
- bool m_skipDeprecated = false;
};
ApiExtractor::ApiExtractor() :
d(new ApiExtractorPrivate)
{
- // Environment TYPESYSTEMPATH
- QString envTypesystemPaths = QFile::decodeName(qgetenv("TYPESYSTEMPATH"));
- if (!envTypesystemPaths.isEmpty())
- TypeDatabase::instance()->addTypesystemPath(envTypesystemPaths);
}
ApiExtractor::~ApiExtractor()
@@ -89,32 +257,6 @@ ApiExtractor::~ApiExtractor()
delete d;
}
-void ApiExtractor::addTypesystemSearchPath (const QString& path)
-{
- TypeDatabase::instance()->addTypesystemPath(path);
-}
-
-void ApiExtractor::addTypesystemSearchPath(const QStringList& paths)
-{
- for (const QString &path : paths)
- addTypesystemSearchPath(path);
-}
-
-void ApiExtractor::setTypesystemKeywords(const QStringList &keywords)
-{
- TypeDatabase::instance()->setTypesystemKeywords(keywords);
-}
-
-void ApiExtractor::addIncludePath(const HeaderPath& path)
-{
- d->m_includePaths << path;
-}
-
-void ApiExtractor::addIncludePath(const HeaderPaths& paths)
-{
- d->m_includePaths << paths;
-}
-
HeaderPaths ApiExtractor::includePaths() const
{
return d->m_includePaths;
@@ -145,33 +287,6 @@ QString ApiExtractor::typeSystem() const
return d->m_typeSystemFileName;
}
-void ApiExtractor::setSkipDeprecated(bool value)
-{
- d->m_skipDeprecated = value;
- if (d->m_builder)
- d->m_builder->setSkipDeprecated(d->m_skipDeprecated);
-}
-
-void ApiExtractor::setSuppressWarnings ( bool value )
-{
- TypeDatabase::instance()->setSuppressWarnings(value);
-}
-
-void ApiExtractor::setSilent ( bool value )
-{
- ReportHandler::setSilent(value);
-}
-
-bool ApiExtractor::setApiVersion(const QString& package, const QString &version)
-{
- return TypeDatabase::setApiVersion(package, version);
-}
-
-void ApiExtractor::setDropTypeEntries(const QStringList &dropEntries)
-{
- TypeDatabase::instance()->setDropTypeEntries(dropEntries);
-}
-
const AbstractMetaEnumList &ApiExtractor::globalEnums() const
{
Q_ASSERT(d->m_builder);
@@ -225,8 +340,7 @@ bool ApiExtractorPrivate::runHelper(ApiExtractorFlags flags)
}
const QString pattern = QDir::tempPath() + u'/'
- + m_cppFileNames.constFirst().baseName()
- + QStringLiteral("_XXXXXX.hpp");
+ + m_cppFileNames.constFirst().baseName() + "_XXXXXX.hpp"_L1;
QTemporaryFile ppFile(pattern);
bool autoRemove = !qEnvironmentVariableIsSet("KEEP_TEMP_FILES");
// make sure that a tempfile can be written
@@ -266,16 +380,16 @@ bool ApiExtractorPrivate::runHelper(ApiExtractorFlags flags)
for (const HeaderPath &headerPath : std::as_const(m_includePaths))
arguments.append(HeaderPath::includeOption(headerPath));
+ if (flags.testFlag(ApiExtractorFlag::UsePySideExtensions))
+ addPySideExtensions(&arguments);
arguments.append(QFile::encodeName(preprocessedCppFileName));
+
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
qCInfo(lcShiboken).noquote().nospace()
<< "clang language level: " << int(m_languageLevel)
<< "\nclang arguments: " << arguments;
}
- if (flags.testFlag(ApiExtractorFlag::UsePySideExtensions))
- addPySideExtensions(&arguments);
-
const bool result = m_builder->build(arguments, flags, addCompilerSupportArguments,
m_languageLevel);
if (!result)
@@ -300,18 +414,17 @@ std::optional<ApiExtractorResult> ApiExtractor::run(ApiExtractorFlags flags)
InstantiationCollectContext collectContext;
d->collectInstantiatedContainersAndSmartPointers(collectContext);
- auto *data = new ApiExtractorResultData;
-
- classListToCList(d->m_builder->takeClasses(), &data->m_metaClasses);
- classListToCList(d->m_builder->takeTemplates(), &data->m_templates);
- classListToCList(d->m_builder->takeSmartPointers(), &data->m_smartPointers);
- data->m_globalFunctions = d->m_builder->globalFunctions();
- data->m_globalEnums = d->m_builder->globalEnums();
- data->m_enums = d->m_builder->typeEntryToEnumsHash();
- data->m_flags = flags;
- qSwap(data->m_instantiatedContainers, collectContext.instantiatedContainers);
- qSwap(data->m_instantiatedSmartPointers, collectContext.instantiatedSmartPointers);
- return ApiExtractorResult(data);
+ ApiExtractorResult result;
+ classListToCList(d->m_builder->takeClasses(), &result.m_metaClasses);
+ classListToCList(d->m_builder->takeSmartPointers(), &result.m_smartPointers);
+ result.m_globalFunctions = d->m_builder->globalFunctions();
+ result.m_globalEnums = d->m_builder->globalEnums();
+ result.m_enums = d->m_builder->typeEntryToEnumsHash();
+ result.m_flags = flags;
+ result.m_typedefTargetToName = d->m_builder->typedefTargetToName();
+ qSwap(result.m_instantiatedContainers, collectContext.instantiatedContainers);
+ qSwap(result.m_instantiatedSmartPointers, collectContext.instantiatedSmartPointers);
+ return result;
}
LanguageLevel ApiExtractor::languageLevel() const
@@ -319,26 +432,11 @@ LanguageLevel ApiExtractor::languageLevel() const
return d->m_languageLevel;
}
-void ApiExtractor::setLanguageLevel(LanguageLevel languageLevel)
-{
- d->m_languageLevel = languageLevel;
-}
-
QStringList ApiExtractor::clangOptions() const
{
return d->m_clangOptions;
}
-void ApiExtractor::setClangOptions(const QStringList &co)
-{
- d->m_clangOptions = co;
-}
-
-void ApiExtractor::setUseGlobalHeader(bool h)
-{
- AbstractMetaBuilder::setUseGlobalHeader(h);
-}
-
AbstractMetaFunctionPtr
ApiExtractor::inheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
const AbstractMetaTypeList &templateTypes)
@@ -349,20 +447,19 @@ AbstractMetaFunctionPtr
AbstractMetaFunctionPtr
ApiExtractor::inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
const AbstractMetaTypeList &templateTypes,
- const AbstractMetaClass *templateClass,
- AbstractMetaClass *subclass)
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass)
{
return AbstractMetaBuilder::inheritTemplateMember(function, templateTypes,
templateClass, subclass);
}
-AbstractMetaClass *ApiExtractor::inheritTemplateClass(const ComplexTypeEntryPtr &te,
- const AbstractMetaClass *templateClass,
- const AbstractMetaTypeList &templateTypes,
- InheritTemplateFlags flags)
+AbstractMetaClassPtr ApiExtractor::inheritTemplateClass(const ComplexTypeEntryPtr &te,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes)
{
return AbstractMetaBuilder::inheritTemplateClass(te, templateClass,
- templateTypes, flags);
+ templateTypes);
}
QString ApiExtractorPrivate::getSimplifiedContainerTypeName(const AbstractMetaType &type)
@@ -436,12 +533,12 @@ ApiExtractorPrivate::addInstantiatedContainersAndSmartPointers(InstantiationColl
return;
}
if (type.hasTemplateChildren()) {
- QString piece = isContainer ? QStringLiteral("container") : QStringLiteral("smart pointer");
+ const auto piece = isContainer ? "container"_L1 : "smart pointer"_L1;
QString warning =
QString::fromLatin1("Skipping instantiation of %1 '%2' because it has template"
" arguments.").arg(piece, type.originalTypeDescription());
if (!contextName.isEmpty())
- warning.append(QStringLiteral(" Calling context: ") + contextName);
+ warning.append(" Calling context: "_L1 + contextName);
qCWarning(lcShiboken).noquote().nospace() << warning;
return;
@@ -489,7 +586,7 @@ static void addOwnerModification(const AbstractMetaFunctionCList &functions,
for (const auto &f : functions) {
if (!f->arguments().isEmpty()
&& f->arguments().constFirst().type().indirections() > 0) {
- qSharedPointerConstCast<AbstractMetaFunction>(f)->clearModificationsCache();
+ std::const_pointer_cast<AbstractMetaFunction>(f)->clearModificationsCache();
typeEntry->addFunctionModification(invalidateArgMod(f));
}
}
@@ -505,10 +602,9 @@ void ApiExtractorPrivate::addInstantiatedSmartPointer(InstantiationCollectContex
Q_ASSERT(smp.smartPointer);
const auto &instantiatedType = type.instantiations().constFirst();
- const auto ste = qSharedPointerCast<const SmartPointerTypeEntry>(smp.smartPointer->typeEntry());
+ const auto ste = std::static_pointer_cast<const SmartPointerTypeEntry>(smp.smartPointer->typeEntry());
QString name = ste->getTargetName(smp.type);
auto parentTypeEntry = ste->parent();
- InheritTemplateFlags flags;
auto colonPos = name.lastIndexOf(u"::");
const bool withinNameSpace = colonPos != -1;
@@ -519,22 +615,21 @@ void ApiExtractorPrivate::addInstantiatedSmartPointer(InstantiationCollectContex
if (nameSpaces.isEmpty())
throw Exception(msgNamespaceNotFound(name));
parentTypeEntry = nameSpaces.constFirst();
- } else {
- flags.setFlag(InheritTemplateFlag::SetEnclosingClass);
}
TypedefEntryPtr typedefEntry(new TypedefEntry(name, ste->name(), ste->version(),
parentTypeEntry));
typedefEntry->setTargetLangPackage(ste->targetLangPackage());
auto instantiationEntry = TypeDatabase::initializeTypeDefEntry(typedefEntry, ste);
+ instantiationEntry->setParent(parentTypeEntry);
smp.specialized = ApiExtractor::inheritTemplateClass(instantiationEntry, smp.smartPointer,
- {instantiatedType}, flags);
+ {instantiatedType});
Q_ASSERT(smp.specialized);
- if (withinNameSpace) { // move class to desired namespace
- auto *enclClass = AbstractMetaClass::findClass(m_builder->classes(), parentTypeEntry);
+ if (parentTypeEntry->type() != TypeEntry::TypeSystemType) { // move class to desired namespace
+ const auto enclClass = AbstractMetaClass::findClass(m_builder->classes(), parentTypeEntry);
Q_ASSERT(enclClass);
- auto *specialized = const_cast<AbstractMetaClass *>(smp.specialized);
+ auto specialized = std::const_pointer_cast<AbstractMetaClass>(smp.specialized);
specialized->setEnclosingClass(enclClass);
enclClass->addInnerClass(specialized);
}
@@ -556,26 +651,31 @@ ApiExtractorPrivate::collectInstantiatedContainersAndSmartPointers(Instantiation
const AbstractMetaFunctionCPtr &func)
{
addInstantiatedContainersAndSmartPointers(context, func->type(), func->signature());
- for (const AbstractMetaArgument &arg : func->arguments())
- addInstantiatedContainersAndSmartPointers(context, arg.type(), func->signature());
+ for (const AbstractMetaArgument &arg : func->arguments()) {
+ const auto argType = arg.type();
+ const auto type = argType.viewOn() != nullptr ? *argType.viewOn() : argType;
+ addInstantiatedContainersAndSmartPointers(context, type, func->signature());
+ }
}
void
ApiExtractorPrivate::collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
- const AbstractMetaClass *metaClass)
+ const AbstractMetaClassCPtr &metaClass)
{
if (!metaClass->typeEntry()->generateCode())
return;
for (const auto &func : metaClass->functions())
collectInstantiatedContainersAndSmartPointers(context, func);
+ for (const auto &func : metaClass->userAddedPythonOverrides())
+ collectInstantiatedContainersAndSmartPointers(context, func);
for (const AbstractMetaField &field : metaClass->fields())
addInstantiatedContainersAndSmartPointers(context, field.type(), field.name());
// The list of inner classes might be extended when smart pointer
// instantiations are specified to be in namespaces.
- auto &innerClasses = metaClass->innerClasses();
+ const auto &innerClasses = metaClass->innerClasses();
for (auto i = innerClasses.size() - 1; i >= 0; --i) {
- auto *innerClass = innerClasses.at(i);
+ const auto innerClass = innerClasses.at(i);
if (!innerClass->typeEntry()->isSmartPointer())
collectInstantiatedContainersAndSmartPointers(context, innerClass);
}
@@ -587,7 +687,7 @@ ApiExtractorPrivate::collectInstantiatedContainersAndSmartPointers(Instantiation
collectInstantiatedOpqaqueContainers(context);
for (const auto &func : m_builder->globalFunctions())
collectInstantiatedContainersAndSmartPointers(context, func);
- for (auto metaClass : m_builder->classes())
+ for (const auto &metaClass : m_builder->classes())
collectInstantiatedContainersAndSmartPointers(context, metaClass);
collectContainerTypesFromSnippets(context);
}
@@ -614,8 +714,7 @@ void ApiExtractorPrivate::collectInstantiatedOpqaqueContainers(InstantiationColl
for (const auto &container : containers) {
for (const auto &oc : container->opaqueContainers()) {
QString errorMessage;
- const QString typeName = container->qualifiedCppName() + u'<'
- + oc.instantiation + u'>';
+ const QString typeName = container->qualifiedCppName() + oc.templateParameters();
auto typeOpt = AbstractMetaType::fromString(typeName, &errorMessage);
if (typeOpt.has_value()
&& generateOpaqueContainer(typeOpt.value(), moduleEntry)) {
@@ -635,12 +734,12 @@ static void getCode(QStringList &code, const CodeSnipList &codeSnips)
static void getCode(QStringList &code, const TypeEntryCPtr &type)
{
if (type->isComplex())
- getCode(code, qSharedPointerCast<const ComplexTypeEntry>(type)->codeSnips());
+ getCode(code, std::static_pointer_cast<const ComplexTypeEntry>(type)->codeSnips());
else if (type->isTypeSystem())
- getCode(code, qSharedPointerCast<const TypeSystemTypeEntry>(type)->codeSnips());
+ getCode(code, std::static_pointer_cast<const TypeSystemTypeEntry>(type)->codeSnips());
auto customConversion = CustomConversion::getCustomConversion(type);
- if (customConversion.isNull())
+ if (!customConversion)
return;
if (!customConversion->nativeToTargetConversion().isEmpty())
@@ -664,11 +763,11 @@ void ApiExtractorPrivate::collectContainerTypesFromSnippets(InstantiationCollect
const ContainerTypeEntryCList &containerTypeList = td->containerTypes();
for (const auto &type : containerTypeList)
getCode(snips, type);
- for (auto metaClass : m_builder->classes())
+ for (const auto &metaClass : m_builder->classes())
getCode(snips, metaClass->typeEntry());
const auto moduleEntry = td->defaultTypeSystemType();
- Q_ASSERT(!moduleEntry.isNull());
+ Q_ASSERT(moduleEntry);
getCode(snips, moduleEntry);
for (const auto &func : m_builder->globalFunctions())
@@ -686,8 +785,8 @@ ApiExtractorPrivate::collectContainerTypesFromConverterMacros(InstantiationColle
bool toPythonMacro)
{
QString convMacro = toPythonMacro ? u"%CONVERTTOPYTHON["_s : u"%CONVERTTOCPP["_s;
- int offset = toPythonMacro ? sizeof("%CONVERTTOPYTHON") : sizeof("%CONVERTTOCPP");
- int start = 0;
+ const qsizetype offset = toPythonMacro ? sizeof("%CONVERTTOPYTHON") : sizeof("%CONVERTTOCPP");
+ qsizetype start = 0;
QString errorMessage;
while ((start = code.indexOf(convMacro, start)) != -1) {
int end = code.indexOf(u']', start);
diff --git a/sources/shiboken6/ApiExtractor/apiextractor.h b/sources/shiboken6/ApiExtractor/apiextractor.h
index 51df5e45a..7bff5c252 100644
--- a/sources/shiboken6/ApiExtractor/apiextractor.h
+++ b/sources/shiboken6/ApiExtractor/apiextractor.h
@@ -20,6 +20,8 @@ class AbstractMetaClass;
class AbstractMetaEnum;
class AbstractMetaFunction;
class ComplexTypeEntry;
+struct OptionDescription;
+class OptionsParser;
QT_BEGIN_NAMESPACE
class QDebug;
@@ -36,27 +38,17 @@ public:
ApiExtractor();
~ApiExtractor();
+ static QList<OptionDescription> options();
+ std::shared_ptr<OptionsParser> createOptionsParser();
+
void setTypeSystem(const QString& typeSystemFileName);
QString typeSystem() const;
void setCppFileNames(const QFileInfoList &cppFileNames);
QFileInfoList cppFileNames() const;
- void setSkipDeprecated(bool value);
- static void setSuppressWarnings(bool value);
- static void setSilent(bool value);
- static void addTypesystemSearchPath(const QString &path);
- static void addTypesystemSearchPath(const QStringList& paths);
- static void setTypesystemKeywords(const QStringList& keywords);
- void addIncludePath(const HeaderPath& path);
- void addIncludePath(const HeaderPaths& paths);
HeaderPaths includePaths() const;
void setLogDirectory(const QString& logDir);
- static bool setApiVersion(const QString &package, const QString &version);
- static void setDropTypeEntries(const QStringList &dropEntries);
LanguageLevel languageLevel() const;
- void setLanguageLevel(LanguageLevel languageLevel);
QStringList clangOptions() const;
- void setClangOptions(const QStringList &co);
- static void setUseGlobalHeader(bool h);
const AbstractMetaEnumList &globalEnums() const;
const AbstractMetaFunctionCList &globalFunctions() const;
@@ -74,15 +66,14 @@ public:
static AbstractMetaFunctionPtr
inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
const AbstractMetaTypeList &templateTypes,
- const AbstractMetaClass *templateClass,
- AbstractMetaClass *subclass);
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass);
/// Forwards to AbstractMetaBuilder::inheritTemplateClass()
- static AbstractMetaClass *
+ static AbstractMetaClassPtr
inheritTemplateClass(const ComplexTypeEntryPtr &te,
- const AbstractMetaClass *templateClass,
- const AbstractMetaTypeList &templateTypes,
- InheritTemplateFlags flags = {});
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes);
private:
ApiExtractorPrivate *d;
diff --git a/sources/shiboken6/ApiExtractor/apiextractorflags.h b/sources/shiboken6/ApiExtractor/apiextractorflags.h
index 4fe6ecc1a..6f69b8b77 100644
--- a/sources/shiboken6/ApiExtractor/apiextractorflags.h
+++ b/sources/shiboken6/ApiExtractor/apiextractorflags.h
@@ -15,12 +15,4 @@ enum class ApiExtractorFlag
Q_DECLARE_FLAGS(ApiExtractorFlags, ApiExtractorFlag)
Q_DECLARE_OPERATORS_FOR_FLAGS(ApiExtractorFlags)
-enum class InheritTemplateFlag
-{
- SetEnclosingClass = 0x1
-};
-
-Q_DECLARE_FLAGS(InheritTemplateFlags, InheritTemplateFlag)
-Q_DECLARE_OPERATORS_FOR_FLAGS(InheritTemplateFlags)
-
#endif // APIEXTRACTORFLAGS_H
diff --git a/sources/shiboken6/ApiExtractor/apiextractorresult.cpp b/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
index a0917d64e..b53ffa9b6 100644
--- a/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
+++ b/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
@@ -2,90 +2,88 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "apiextractorresult.h"
-#include "apiextractorresultdata_p.h"
#include "abstractmetalang.h"
#include "abstractmetaenum.h"
#include "enumtypeentry.h"
#include "flagstypeentry.h"
-ApiExtractorResultData::ApiExtractorResultData() = default;
-
-ApiExtractorResultData::~ApiExtractorResultData()
-{
- qDeleteAll(m_smartPointers);
- qDeleteAll(m_metaClasses);
- qDeleteAll(m_templates);
- for (auto &smp : m_instantiatedSmartPointers)
- delete smp.specialized;
-}
-
-ApiExtractorResult::ApiExtractorResult() : d(new ApiExtractorResultData)
-{
-}
-
-ApiExtractorResult::ApiExtractorResult(ApiExtractorResultData *data) :
- d(data)
-{
-}
+ApiExtractorResult::ApiExtractorResult() = default;
ApiExtractorResult::ApiExtractorResult(const ApiExtractorResult &) = default;
ApiExtractorResult &ApiExtractorResult::operator=(const ApiExtractorResult &) = default;
-ApiExtractorResult::ApiExtractorResult(ApiExtractorResult &&) = default;
+ApiExtractorResult::ApiExtractorResult(ApiExtractorResult &&) noexcept = default;
-ApiExtractorResult &ApiExtractorResult::operator=(ApiExtractorResult &&) = default;
+ApiExtractorResult &ApiExtractorResult::operator=(ApiExtractorResult &&) noexcept = default;
ApiExtractorResult::~ApiExtractorResult() = default;
const AbstractMetaEnumList &ApiExtractorResult::globalEnums() const
{
- return d->m_globalEnums;
+ return m_globalEnums;
}
const AbstractMetaFunctionCList &ApiExtractorResult::globalFunctions() const
{
- return d->m_globalFunctions;
+ return m_globalFunctions;
}
const AbstractMetaClassCList &ApiExtractorResult::classes() const
{
- return d->m_metaClasses;
+ return m_metaClasses;
}
const AbstractMetaClassCList &ApiExtractorResult::smartPointers() const
{
- return d->m_smartPointers;
+ return m_smartPointers;
}
const AbstractMetaTypeList &ApiExtractorResult::instantiatedContainers() const
{
- return d->m_instantiatedContainers;
+ return m_instantiatedContainers;
}
const InstantiatedSmartPointers &ApiExtractorResult::instantiatedSmartPointers() const
{
- return d->m_instantiatedSmartPointers;
+ return m_instantiatedSmartPointers;
+}
+
+std::optional<InstantiatedSmartPointer>
+ ApiExtractorResult::findSmartPointerInstantiation(const SmartPointerTypeEntryCPtr &pointer,
+ const TypeEntryCPtr &pointee) const
+{
+ for (const auto &smp : m_instantiatedSmartPointers) {
+ const auto &i = smp.type;
+ if (i.typeEntry() == pointer && i.instantiations().at(0).typeEntry() == pointee)
+ return smp;
+ }
+ return std::nullopt;
+}
+
+const QMultiHash<QString, QString> &ApiExtractorResult::typedefTargetToName() const
+{
+ return m_typedefTargetToName;
}
ApiExtractorFlags ApiExtractorResult::flags() const
{
- return d->m_flags;
+ return m_flags;
}
void ApiExtractorResult::setFlags(ApiExtractorFlags f)
{
- d->m_flags = f;
+ m_flags = f;
}
std::optional<AbstractMetaEnum>
ApiExtractorResult::findAbstractMetaEnum(TypeEntryCPtr typeEntry) const
{
- if (!typeEntry.isNull() && typeEntry->isFlags())
- typeEntry = qSharedPointerCast<const FlagsTypeEntry>(typeEntry)->originator();
- const auto it = d->m_enums.constFind(typeEntry);
- if (it == d->m_enums.constEnd())
+ if (typeEntry && typeEntry->isFlags())
+ typeEntry = std::static_pointer_cast<const FlagsTypeEntry>(typeEntry)->originator();
+ const auto it = m_enums.constFind(typeEntry);
+ if (it == m_enums.constEnd())
return {};
return it.value();
}
@@ -93,7 +91,7 @@ std::optional<AbstractMetaEnum>
AbstractMetaFunctionCList ApiExtractorResult::implicitConversions(const TypeEntryCPtr &type) const
{
if (type->isValue()) {
- if (auto metaClass = AbstractMetaClass::findClass(d->m_metaClasses, type))
+ if (auto metaClass = AbstractMetaClass::findClass(m_metaClasses, type))
return metaClass->implicitConversions();
}
return {};
diff --git a/sources/shiboken6/ApiExtractor/apiextractorresult.h b/sources/shiboken6/ApiExtractor/apiextractorresult.h
index f85fca9f0..b2aae88ed 100644
--- a/sources/shiboken6/ApiExtractor/apiextractorresult.h
+++ b/sources/shiboken6/ApiExtractor/apiextractorresult.h
@@ -9,7 +9,8 @@
#include "abstractmetalang_typedefs.h"
#include "typesystem_typedefs.h"
-#include <QtCore/QExplicitlySharedDataPointer>
+#include <QtCore/QHash>
+#include <QtCore/QMultiHash>
#include <optional>
@@ -17,8 +18,8 @@ class ApiExtractorResultData;
struct InstantiatedSmartPointer
{
- const AbstractMetaClass *smartPointer = nullptr; // Template class
- const AbstractMetaClass *specialized = nullptr; // Specialized for type
+ AbstractMetaClassCPtr smartPointer; // Template class
+ AbstractMetaClassCPtr specialized; // Specialized for type
AbstractMetaType type;
};
@@ -29,11 +30,10 @@ class ApiExtractorResult
{
public:
ApiExtractorResult();
- explicit ApiExtractorResult(ApiExtractorResultData *data);
ApiExtractorResult(const ApiExtractorResult &);
ApiExtractorResult &operator=(const ApiExtractorResult &);
- ApiExtractorResult(ApiExtractorResult &&);
- ApiExtractorResult &operator=(ApiExtractorResult &&);
+ ApiExtractorResult(ApiExtractorResult &&) noexcept;
+ ApiExtractorResult &operator=(ApiExtractorResult &&) noexcept;
~ApiExtractorResult();
const AbstractMetaEnumList &globalEnums() const;
@@ -43,6 +43,11 @@ public:
const AbstractMetaTypeList &instantiatedContainers() const;
const InstantiatedSmartPointers &instantiatedSmartPointers() const;
+ std::optional<InstantiatedSmartPointer>
+ findSmartPointerInstantiation(const SmartPointerTypeEntryCPtr &pointer,
+ const TypeEntryCPtr &pointee) const;
+
+ const QMultiHash<QString, QString> &typedefTargetToName() const;
// Query functions for the generators
std::optional<AbstractMetaEnum>
@@ -60,7 +65,17 @@ public:
void setFlags(ApiExtractorFlags f);
private:
- QExplicitlySharedDataPointer<ApiExtractorResultData> d;
+ AbstractMetaClassCList m_metaClasses;
+ AbstractMetaClassCList m_smartPointers;
+ AbstractMetaFunctionCList m_globalFunctions;
+ AbstractMetaEnumList m_globalEnums;
+ AbstractMetaTypeList m_instantiatedContainers;
+ InstantiatedSmartPointers m_instantiatedSmartPointers;
+ QHash<TypeEntryCPtr, AbstractMetaEnum> m_enums;
+ QMultiHash<QString, QString> m_typedefTargetToName;
+ ApiExtractorFlags m_flags;
+
+ friend class ApiExtractor;
};
#endif // APIEXTRACTORRESULT_H
diff --git a/sources/shiboken6/ApiExtractor/apiextractorresultdata_p.h b/sources/shiboken6/ApiExtractor/apiextractorresultdata_p.h
deleted file mode 100644
index 05d548d6d..000000000
--- a/sources/shiboken6/ApiExtractor/apiextractorresultdata_p.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2022 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#ifndef APIEXTRACTORRESULTDATA_P_H
-#define APIEXTRACTORRESULTDATA_P_H
-
-#include "apiextractorresult.h"
-
-#include <QtCore/QHash>
-#include <QtCore/QSharedData>
-
-class ApiExtractorResultData : public QSharedData
-{
-public:
- ApiExtractorResultData();
- ~ApiExtractorResultData();
-
- AbstractMetaClassCList m_metaClasses;
- AbstractMetaClassCList m_templates; // not exposed, just for ownership
- AbstractMetaClassCList m_smartPointers;
- AbstractMetaFunctionCList m_globalFunctions;
- AbstractMetaEnumList m_globalEnums;
- AbstractMetaTypeList m_instantiatedContainers;
- InstantiatedSmartPointers m_instantiatedSmartPointers;
- QHash<TypeEntryCPtr, AbstractMetaEnum> m_enums;
- ApiExtractorFlags m_flags;
-};
-
-#endif // APIEXTRACTORRESULTDATA_P_H
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
index 512f1a879..31e7efb05 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
@@ -4,6 +4,7 @@
#include "clangbuilder.h"
#include "compilersupport.h"
#include "clangutils.h"
+#include "clangdebugutils.h"
#include <codemodel.h>
#include <reporthandler.h>
@@ -25,9 +26,6 @@ using namespace Qt::StringLiterals;
namespace clang {
-static inline QString colonColon() { return QStringLiteral("::"); }
-static inline QString templateBrackets() { return QStringLiteral("<>"); }
-
static inline bool isClassCursor(const CXCursor &c)
{
return c.kind == CXCursor_ClassDecl || c.kind == CXCursor_StructDecl
@@ -115,8 +113,17 @@ static bool isSigned(CXTypeKind kind)
class BuilderPrivate {
public:
+ Q_DISABLE_COPY_MOVE(BuilderPrivate)
+
+ enum class SpecialSystemHeader {
+ None,
+ Types,
+ OpenGL,
+ WhiteListed,
+ WhiteListedPath
+ };
+
using CursorClassHash = QHash<CXCursor, ClassModelItem>;
- using CursorTypedefHash = QHash<CXCursor, TypeDefModelItem>;
using TypeInfoHash = QHash<CXType, TypeInfo>;
explicit BuilderPrivate(BaseVisitor *bv) : m_baseVisitor(bv), m_model(new CodeModel)
@@ -182,10 +189,9 @@ public:
std::pair<QString, ClassModelItem> getBaseClass(CXType type) const;
void addBaseClass(const CXCursor &cursor);
- template <class Item>
- void qualifyTypeDef(const CXCursor &typeRefCursor, const QSharedPointer<Item> &item) const;
-
+ SpecialSystemHeader specialSystemHeader(const QString &fileName) const;
bool visitHeader(const QString &fileName) const;
+ static const char *specialSystemHeaderReason(SpecialSystemHeader sh);
void setFileName(const CXCursor &cursor, _CodeModelItem *item);
@@ -198,7 +204,6 @@ public:
// classes can be correctly parented in case of forward-declared inner classes
// (QMetaObject::Connection)
CursorClassHash m_cursorClassHash;
- CursorTypedefHash m_cursorTypedefHash;
mutable TypeInfoHash m_typeInfoHash; // Cache type information
mutable QHash<QString, TemplateTypeAliasModelItem> m_templateTypeAliases;
@@ -209,21 +214,22 @@ public:
ArgumentModelItem m_currentArgument;
VariableModelItem m_currentField;
TemplateTypeAliasModelItem m_currentTemplateTypeAlias;
- QStringList m_systemIncludes; // files, like "memory"
- QStringList m_systemIncludePaths; // paths, like "/usr/include/Qt/"
+ QStringList m_forceProcessSystemIncludes; // files, like "memory"
+ QStringList m_forceProcessSystemIncludePaths; // paths, like "/usr/include/Qt/"
QString m_usingTypeRef; // Base classes in "using Base::member;"
bool m_withinUsingDeclaration = false;
int m_anonymousEnumCount = 0;
CodeModel::FunctionType m_currentFunctionType = CodeModel::Normal;
bool m_withinFriendDecl = false;
+ mutable QHash<QString, SpecialSystemHeader> m_systemHeaders;
};
bool BuilderPrivate::addClass(const CXCursor &cursor, CodeModel::ClassType t)
{
QString className = getCursorSpelling(cursor);
m_currentClass.reset(new _ClassModelItem(m_model, className));
- setFileName(cursor, m_currentClass.data());
+ setFileName(cursor, m_currentClass.get());
m_currentClass->setClassType(t);
// Some inner class? Note that it does not need to be (lexically) contained in a
// class since it is possible to forward declare an inner class:
@@ -266,7 +272,7 @@ static QString msgCannotDetermineException(const std::string_view &snippetV)
const qsizetype length = qsizetype(truncate ? newLine : snippetV.size());
QString snippet = QString::fromUtf8(snippetV.data(), length);
if (truncate)
- snippet += QStringLiteral("...");
+ snippet += "..."_L1;
return u"Cannot determine exception specification: \""_s + snippet + u'"';
}
@@ -327,9 +333,11 @@ FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor,
// Apply type fixes to "operator X &" -> "operator X&"
if (name.startsWith(u"operator "))
name = fixTypeName(name);
- FunctionModelItem result(new _FunctionModelItem(m_model, name));
- setFileName(cursor, result.data());
- result->setType(createTypeInfo(clang_getCursorResultType(cursor)));
+ auto result = std::make_shared<_FunctionModelItem>(m_model, name);
+ setFileName(cursor, result.get());
+ const auto type = clang_getCursorResultType(cursor);
+ result->setType(createTypeInfo(type));
+ result->setScopeResolution(hasScopeResolution(type));
result->setFunctionType(t);
result->setScope(m_scope);
result->setStatic(clang_Cursor_getStorageClass(cursor) == CX_SC_Static);
@@ -338,7 +346,7 @@ FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor,
case CXAvailability_Available:
break;
case CXAvailability_Deprecated:
- result->setDeprecated(true);
+ result->setAttribute(FunctionAttribute::Deprecated);
break;
case CXAvailability_NotAvailable: // "Foo(const Foo&) = delete;"
result->setDeleted(true);
@@ -381,9 +389,9 @@ FunctionModelItem BuilderPrivate::createMemberFunction(const CXCursor &cursor,
auto result = createFunction(cursor, functionType, isTemplateCode);
result->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor)));
result->setConstant(clang_CXXMethod_isConst(cursor) != 0);
- result->setStatic(clang_CXXMethod_isStatic(cursor) != 0);
- result->setVirtual(clang_CXXMethod_isVirtual(cursor) != 0);
- result->setAbstract(clang_CXXMethod_isPureVirtual(cursor) != 0);
+ result->setAttribute(FunctionAttribute::Static, clang_CXXMethod_isStatic(cursor) != 0);
+ result->setAttribute(FunctionAttribute::Virtual, clang_CXXMethod_isVirtual(cursor) != 0);
+ result->setAttribute(FunctionAttribute::Abstract, clang_CXXMethod_isPureVirtual(cursor) != 0);
return result;
}
@@ -399,13 +407,14 @@ void BuilderPrivate::qualifyConstructor(const CXCursor &cursor)
&& m_currentFunction->arguments().size() == 1
&& clang_CXXConstructor_isCopyConstructor(cursor) == 0
&& clang_CXXConstructor_isMoveConstructor(cursor) == 0) {
- m_currentFunction->setExplicit(clang_CXXConstructor_isConvertingConstructor(cursor) == 0);
+ m_currentFunction->setAttribute(FunctionAttribute::Explicit,
+ clang_CXXConstructor_isConvertingConstructor(cursor) == 0);
}
}
TemplateParameterModelItem BuilderPrivate::createTemplateParameter(const CXCursor &cursor) const
{
- return TemplateParameterModelItem(new _TemplateParameterModelItem(m_model, getCursorSpelling(cursor)));
+ return std::make_shared<_TemplateParameterModelItem>(m_model, getCursorSpelling(cursor));
}
TemplateParameterModelItem BuilderPrivate::createNonTypeTemplateParameter(const CXCursor &cursor) const
@@ -418,11 +427,12 @@ TemplateParameterModelItem BuilderPrivate::createNonTypeTemplateParameter(const
// CXCursor_VarDecl, CXCursor_FieldDecl cursors
void BuilderPrivate::addField(const CXCursor &cursor)
{
- VariableModelItem field(new _VariableModelItem(m_model, getCursorSpelling(cursor)));
+ auto field = std::make_shared<_VariableModelItem>(m_model, getCursorSpelling(cursor));
field->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor)));
field->setScope(m_scope);
field->setType(createTypeInfo(cursor));
field->setMutable(clang_CXXField_isMutable(cursor) != 0);
+ setFileName(cursor, field.get());
m_currentField = field;
m_scopeStack.back()->addVariable(field);
}
@@ -438,7 +448,7 @@ static QStringList qualifiedName(const QString &t)
end = t.size();
int lastPos = 0;
while (true) {
- const int nextPos = t.indexOf(colonColon(), lastPos);
+ const int nextPos = t.indexOf(u"::"_s, lastPos);
if (nextPos < 0 || nextPos >= end)
break;
result.append(t.mid(lastPos, nextPos - lastPos));
@@ -556,7 +566,7 @@ TypeInfo BuilderPrivate::createTypeInfoUncached(const CXType &type,
typeInfo.setConstant(clang_isConstQualifiedType(nestedType) != 0);
typeInfo.setVolatile(clang_isVolatileQualifiedType(nestedType) != 0);
- QString typeName = getTypeName(nestedType);
+ QString typeName = getResolvedTypeName(nestedType);
while (TypeInfo::stripLeadingConst(&typeName)
|| TypeInfo::stripLeadingVolatile(&typeName)) {
}
@@ -566,14 +576,14 @@ TypeInfo BuilderPrivate::createTypeInfoUncached(const CXType &type,
// the typedef source is named "type-parameter-0-0". Convert it back to the
// template parameter name. The CXTypes are the same for all templates and
// must not be cached.
- if (!m_currentClass.isNull() && typeName.startsWith(u"type-parameter-0-")) {
+ if (m_currentClass && typeName.startsWith(u"type-parameter-0-")) {
if (cacheable != nullptr)
*cacheable = false;
bool ok;
const int n = QStringView{typeName}.mid(17).toInt(&ok);
if (ok) {
auto currentTemplate = currentTemplateClass();
- if (!currentTemplate.isNull() && n < currentTemplate->templateParameters().size())
+ if (currentTemplate && n < currentTemplate->templateParameters().size())
typeName = currentTemplate->templateParameters().at(n)->name();
}
}
@@ -604,19 +614,18 @@ TypeInfo BuilderPrivate::createTypeInfo(const CXType &type) const
void BuilderPrivate::addTypeDef(const CXCursor &cursor, const CXType &cxType)
{
const QString target = getCursorSpelling(cursor);
- TypeDefModelItem item(new _TypeDefModelItem(m_model, target));
- setFileName(cursor, item.data());
+ auto item = std::make_shared<_TypeDefModelItem>(m_model, target);
+ setFileName(cursor, item.get());
item->setType(createTypeInfo(cxType));
item->setScope(m_scope);
m_scopeStack.back()->addTypeDef(item);
- m_cursorTypedefHash.insert(cursor, item);
}
ClassModelItem BuilderPrivate::currentTemplateClass() const
{
for (auto i = m_scopeStack.size() - 1; i >= 0; --i) {
- auto klass = qSharedPointerDynamicCast<_ClassModelItem>(m_scopeStack.at(i));
- if (!klass.isNull() && klass->isTemplate())
+ auto klass = std::dynamic_pointer_cast<_ClassModelItem>(m_scopeStack.at(i));
+ if (klass && klass->isTemplate())
return klass;
}
return {};
@@ -626,7 +635,7 @@ void BuilderPrivate::startTemplateTypeAlias(const CXCursor &cursor)
{
const QString target = getCursorSpelling(cursor);
m_currentTemplateTypeAlias.reset(new _TemplateTypeAliasModelItem(m_model, target));
- setFileName(cursor, m_currentTemplateTypeAlias.data());
+ setFileName(cursor, m_currentTemplateTypeAlias.get());
m_currentTemplateTypeAlias->setScope(m_scope);
}
@@ -659,6 +668,9 @@ QString BuilderPrivate::cursorValueExpression(BaseVisitor *bv, const CXCursor &c
}
// Resolve a type (loop over aliases/typedefs), for example for base classes
+// Note: TypeAliasTemplateDecl ("using QVector<T>=QList<T>") is automatically
+// resolved by clang_getTypeDeclaration(), but it stops at
+// TypeAliasDecl / TypedefDecl.
struct TypeDeclaration
{
@@ -666,17 +678,21 @@ struct TypeDeclaration
CXCursor declaration;
};
-static TypeDeclaration resolveType(CXType type)
+static inline bool isTypeAliasDecl(const CXCursor &cursor)
+{
+ const auto kind = clang_getCursorKind(cursor);
+ return kind == CXCursor_TypeAliasDecl || kind == CXCursor_TypedefDecl;
+}
+
+static TypeDeclaration resolveBaseClassType(CXType type)
{
CXCursor decl = clang_getTypeDeclaration(type);
- if (type.kind != CXType_Unexposed) {
- while (true) {
- auto kind = clang_getCursorKind(decl);
- if (kind != CXCursor_TypeAliasDecl && kind != CXCursor_TypedefDecl)
- break;
- type = clang_getTypedefDeclUnderlyingType(decl);
- decl = clang_getTypeDeclaration(type);
- }
+ auto resolvedType = clang_getCursorType(decl);
+ if (resolvedType.kind != CXType_Invalid && resolvedType.kind != type.kind)
+ type = resolvedType;
+ while (isTypeAliasDecl(decl)) {
+ type = clang_getTypedefDeclUnderlyingType(decl);
+ decl = clang_getTypeDeclaration(type);
}
return {type, decl};
}
@@ -685,21 +701,11 @@ static TypeDeclaration resolveType(CXType type)
// where the cursor spelling has "struct baseClass".
std::pair<QString, ClassModelItem> BuilderPrivate::getBaseClass(CXType type) const
{
- const auto decl = resolveType(type);
+ const auto decl = resolveBaseClassType(type);
// Note: spelling has "struct baseClass", use type
- QString baseClassName;
- if (decl.type.kind == CXType_Unexposed) {
- // The type is unexposed when the base class is a template type alias:
- // "class QItemSelection : public QList<X>" where QList is aliased to QVector.
- // Try to resolve via code model.
- TypeInfo info = createTypeInfo(decl.type);
- auto parentScope = m_scopeStack.at(m_scopeStack.size() - 2); // Current is class.
- auto resolved = TypeInfo::resolveType(info, parentScope);
- if (resolved != info)
- baseClassName = resolved.toString();
- }
- if (baseClassName.isEmpty())
- baseClassName = getTypeName(decl.type);
+ QString baseClassName = getTypeName(decl.type);
+ if (baseClassName.startsWith(u"std::")) // Simplify "std::" types
+ baseClassName = createTypeInfo(decl.type).toString();
auto it = m_cursorClassHash.constFind(decl.declaration);
// Not found: Set unqualified name. This happens in cases like
@@ -720,11 +726,11 @@ std::pair<QString, ClassModelItem> BuilderPrivate::getBaseClass(CXType type) con
// "std::vector<T>").
const QStringList &baseScope = it.value()->scope();
if (!baseScope.isEmpty()) {
- const int lastSep = baseClassName.lastIndexOf(colonColon());
+ const int lastSep = baseClassName.lastIndexOf(u"::"_s);
if (lastSep >= 0)
- baseClassName.remove(0, lastSep + colonColon().size());
- baseClassName.prepend(colonColon());
- baseClassName.prepend(baseScope.join(colonColon()));
+ baseClassName.remove(0, lastSep + u"::"_s.size());
+ baseClassName.prepend(u"::"_s);
+ baseClassName.prepend(baseScope.join(u"::"_s));
}
return {baseClassName, it.value()};
}
@@ -738,37 +744,6 @@ void BuilderPrivate::addBaseClass(const CXCursor &cursor)
m_currentClass->addBaseClass({baseClass.first, baseClass.second, access});
}
-static inline CXCursor definitionFromTypeRef(const CXCursor &typeRefCursor)
-{
- Q_ASSERT(typeRefCursor.kind == CXCursor_TypeRef);
- return clang_getTypeDeclaration(clang_getCursorType(typeRefCursor));
-}
-
-// Qualify function arguments or fields that are typedef'ed from another scope:
-// enum ConversionFlag {};
-// typedef QFlags<ConversionFlag> ConversionFlags;
-// class QTextCodec {
-// enum ConversionFlag {};
-// typedef QFlags<ConversionFlag> ConversionFlags;
-// struct ConverterState {
-// explicit ConverterState(ConversionFlags);
-// ^^ qualify to QTextCodec::ConversionFlags
-// ConversionFlags m_flags;
-// ^^ ditto
-
-template <class Item> // ArgumentModelItem, VariableModelItem
-void BuilderPrivate::qualifyTypeDef(const CXCursor &typeRefCursor, const QSharedPointer<Item> &item) const
-{
- TypeInfo type = item->type();
- if (type.qualifiedName().size() == 1) { // item's type is unqualified.
- const auto it = m_cursorTypedefHash.constFind(definitionFromTypeRef(typeRefCursor));
- if (it != m_cursorTypedefHash.constEnd() && !it.value()->scope().isEmpty()) {
- type.setQualifiedName(it.value()->scope() + type.qualifiedName());
- item->setType(type);
- }
- }
-}
-
void BuilderPrivate::setFileName(const CXCursor &cursor, _CodeModelItem *item)
{
const SourceRange range = getCursorRange(cursor);
@@ -802,8 +777,38 @@ static QString baseName(QString path)
return path;
}
+const char * BuilderPrivate::specialSystemHeaderReason(BuilderPrivate::SpecialSystemHeader sh)
+{
+ static const QHash<SpecialSystemHeader, const char *> mapping {
+ {SpecialSystemHeader::OpenGL, "OpenGL"},
+ {SpecialSystemHeader::Types, "types"},
+ {SpecialSystemHeader::WhiteListed, "white listed"},
+ {SpecialSystemHeader::WhiteListedPath, "white listed path"}
+ };
+ return mapping.value(sh, "");
+}
+
bool BuilderPrivate::visitHeader(const QString &fileName) const
{
+ auto it = m_systemHeaders.find(fileName);
+ if (it == m_systemHeaders.end()) {
+ it = m_systemHeaders.insert(fileName, specialSystemHeader(fileName));
+ if (ReportHandler::isDebug(ReportHandler::MediumDebug)) {
+ const QString &name = QDir::toNativeSeparators(fileName);
+ if (it.value() == SpecialSystemHeader::None) {
+ qCInfo(lcShiboken, "Skipping system header %s", qPrintable(name));
+ } else {
+ qCInfo(lcShiboken, "Parsing system header %s (%s)",
+ qPrintable(name), specialSystemHeaderReason(it.value()));
+ }
+ }
+ }
+ return it.value() != SpecialSystemHeader::None;
+}
+
+BuilderPrivate::SpecialSystemHeader
+ BuilderPrivate::specialSystemHeader(const QString &fileName) const
+{
// Resolve OpenGL typedefs although the header is considered a system header.
const QString baseName = clang::baseName(fileName);
if (baseName == u"gl.h"
@@ -812,8 +817,8 @@ bool BuilderPrivate::visitHeader(const QString &fileName) const
|| baseName == u"gl31.h"
|| baseName == u"gl32.h"
|| baseName == u"stdint.h" // Windows: int32_t, uint32_t
- || baseName == u"stddef.h") { // size_t
- return true;
+ || baseName == u"stddef.h") { // size_t`
+ return SpecialSystemHeader::OpenGL;
}
switch (clang::platform()) {
@@ -822,7 +827,7 @@ bool BuilderPrivate::visitHeader(const QString &fileName) const
|| baseName == u"types.h"
|| baseName == u"stdint-intn.h" // int32_t
|| baseName == u"stdint-uintn.h") { // uint32_t
- return true;
+ return SpecialSystemHeader::Types;
}
break;
case Platform::macOS:
@@ -832,22 +837,28 @@ bool BuilderPrivate::visitHeader(const QString &fileName) const
if (baseName == u"gltypes.h"
|| fileName.contains(u"/usr/include/_types")
|| fileName.contains(u"/usr/include/sys/_types")) {
- return true;
+ return SpecialSystemHeader::Types;
}
break;
default:
break;
}
- for (const auto &systemInclude : m_systemIncludes) {
- if (systemInclude == baseName)
- return true;
- }
- for (const auto &systemIncludePath : m_systemIncludePaths) {
- if (fileName.startsWith(systemIncludePath))
- return true;
+ // When building against system Qt (as it happens with yocto / Boot2Qt), the Qt headers are
+ // considered system headers by clang_Location_isInSystemHeader, and shiboken will not
+ // process them. We need to explicitly process them by checking against the list of
+ // include paths that were passed to shiboken's --force-process-system-include-paths option
+ // or specified via the <system-include> xml tag.
+ if (m_forceProcessSystemIncludes.contains(baseName))
+ return SpecialSystemHeader::WhiteListed;
+
+ if (std::any_of(m_forceProcessSystemIncludePaths.cbegin(),
+ m_forceProcessSystemIncludePaths.cend(),
+ [fileName](const QString &p) { return fileName.startsWith(p); })) {
+ return SpecialSystemHeader::WhiteListedPath;
}
- return false;
+
+ return SpecialSystemHeader::None;
}
bool Builder::visitLocation(const QString &fileName, LocationType locationType) const
@@ -855,13 +866,14 @@ bool Builder::visitLocation(const QString &fileName, LocationType locationType)
return locationType != LocationType::System || d->visitHeader(fileName);
}
-void Builder::setSystemIncludes(const QStringList &systemIncludes)
+void Builder::setForceProcessSystemIncludes(const QStringList &systemIncludes)
{
for (const auto &i : systemIncludes) {
- if (i.endsWith(u'/'))
- d->m_systemIncludePaths.append(i);
+ QFileInfo fi(i);
+ if (fi.exists() && fi.isDir())
+ d->m_forceProcessSystemIncludePaths.append(i);
else
- d->m_systemIncludes.append(i);
+ d->m_forceProcessSystemIncludes.append(i);
}
}
@@ -870,7 +882,7 @@ FileModelItem Builder::dom() const
Q_ASSERT(!d->m_scopeStack.isEmpty());
auto rootScope = d->m_scopeStack.constFirst();
rootScope->purgeClassDeclarations();
- return qSharedPointerDynamicCast<_FileModelItem>(rootScope);
+ return std::dynamic_pointer_cast<_FileModelItem>(rootScope);
}
static QString msgOutOfOrder(const CXCursor &cursor, const char *expectedScope)
@@ -904,6 +916,8 @@ static NamespaceType namespaceType(const CXCursor &cursor)
static QString enumType(const CXCursor &cursor)
{
QString name = getCursorSpelling(cursor); // "enum Foo { v1, v2 };"
+ if (name.contains(u"unnamed enum")) // Clang 16.0
+ return {};
if (name.isEmpty()) {
// PYSIDE-1228: For "typedef enum { v1, v2 } Foo;", type will return
// "Foo" as expected. Care must be taken to exclude real anonymous enums.
@@ -933,7 +947,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
}
break;
case CXCursor_CXXBaseSpecifier:
- if (d->m_currentClass.isNull()) {
+ if (!d->m_currentClass) {
const Diagnostic d(msgOutOfOrder(cursor, "class"), cursor, CXDiagnostic_Error);
qWarning() << d;
appendDiagnostic(d);
@@ -955,15 +969,15 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
|| !d->addClass(cursor, CodeModel::Class)) {
return Skip;
}
- d->m_currentClass->setName(d->m_currentClass->name() + templateBrackets());
- d->m_scope.back() += templateBrackets();
+ d->m_currentClass->setName(d->m_currentClass->name() + "<>"_L1);
+ d->m_scope.back() += "<>"_L1;
break;
case CXCursor_EnumDecl: {
QString name = enumType(cursor);
EnumKind kind = CEnum;
if (name.isEmpty()) {
kind = AnonymousEnum;
- name = QStringLiteral("enum_") + QString::number(++d->m_anonymousEnumCount);
+ name = "enum_"_L1 + QString::number(++d->m_anonymousEnumCount);
#if !CLANG_NO_ENUMDECL_ISSCOPED
} else if (clang_EnumDecl_isScoped(cursor) != 0) {
#else
@@ -972,19 +986,21 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
kind = EnumClass;
}
d->m_currentEnum.reset(new _EnumModelItem(d->m_model, name));
- d->setFileName(cursor, d->m_currentEnum.data());
+ d->setFileName(cursor, d->m_currentEnum.get());
d->m_currentEnum->setScope(d->m_scope);
d->m_currentEnum->setEnumKind(kind);
if (clang_getCursorAvailability(cursor) == CXAvailability_Deprecated)
d->m_currentEnum->setDeprecated(true);
- d->m_currentEnum->setSigned(isSigned(clang_getEnumDeclIntegerType(cursor).kind));
- if (!qSharedPointerDynamicCast<_ClassModelItem>(d->m_scopeStack.back()).isNull())
+ const auto enumType = fullyResolveType(clang_getEnumDeclIntegerType(cursor));
+ d->m_currentEnum->setSigned(isSigned(enumType.kind));
+ d->m_currentEnum->setUnderlyingType(getTypeName(enumType));
+ if (std::dynamic_pointer_cast<_ClassModelItem>(d->m_scopeStack.back()))
d->m_currentEnum->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor)));
}
break;
case CXCursor_EnumConstantDecl: {
const QString name = getCursorSpelling(cursor);
- if (d->m_currentEnum.isNull()) {
+ if (!d->m_currentEnum) {
const Diagnostic d(msgOutOfOrder(cursor, "enum"), cursor, CXDiagnostic_Error);
qWarning() << d;
appendDiagnostic(d);
@@ -995,7 +1011,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
enumValue.setValue(clang_getEnumConstantDeclValue(cursor));
else
enumValue.setUnsignedValue(clang_getEnumConstantDeclUnsignedValue(cursor));
- EnumeratorModelItem enumConstant(new _EnumeratorModelItem(d->m_model, name));
+ auto enumConstant = std::make_shared<_EnumeratorModelItem>(d->m_model, name);
enumConstant->setStringValue(d->cursorValueExpression(this, cursor));
enumConstant->setValue(enumValue);
if (clang_getCursorAvailability(cursor) == CXAvailability_Deprecated)
@@ -1043,6 +1059,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
}
}
d->m_currentFunction = d->createFunction(cursor, CodeModel::Normal, true);
+ d->setFileName(cursor, d->m_currentFunction.get());
d->m_scopeStack.back()->addFunction(d->m_currentFunction);
break;
case CXCursor_FunctionDecl:
@@ -1066,8 +1083,8 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
if (type == NamespaceType::Anonymous)
return Skip;
const QString name = getCursorSpelling(cursor);
- const NamespaceModelItem parentNamespaceItem = qSharedPointerDynamicCast<_NamespaceModelItem>(d->m_scopeStack.back());
- if (parentNamespaceItem.isNull()) {
+ const auto parentNamespaceItem = std::dynamic_pointer_cast<_NamespaceModelItem>(d->m_scopeStack.back());
+ if (!parentNamespaceItem) {
const QString message = msgOutOfOrder(cursor, "namespace")
+ u" (current scope: "_s + d->m_scopeStack.back()->name() + u')';
const Diagnostic d(message, cursor, CXDiagnostic_Error);
@@ -1079,7 +1096,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
// in subsequent modules.
NamespaceModelItem namespaceItem = parentNamespaceItem->findNamespace(name);
namespaceItem.reset(new _NamespaceModelItem(d->m_model, name));
- d->setFileName(cursor, namespaceItem.data());
+ d->setFileName(cursor, namespaceItem.get());
namespaceItem->setScope(d->m_scope);
namespaceItem->setType(type);
parentNamespaceItem->addNamespace(namespaceItem);
@@ -1089,10 +1106,12 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
case CXCursor_ParmDecl:
// Skip in case of nested CXCursor_ParmDecls in case one parameter is a function pointer
// and function pointer typedefs.
- if (d->m_currentArgument.isNull() && !d->m_currentFunction.isNull()) {
+ if (!d->m_currentArgument && d->m_currentFunction) {
const QString name = getCursorSpelling(cursor);
d->m_currentArgument.reset(new _ArgumentModelItem(d->m_model, name));
- d->m_currentArgument->setType(d->createTypeInfo(cursor));
+ const auto type = clang_getCursorType(cursor);
+ d->m_currentArgument->setScopeResolution(hasScopeResolution(type));
+ d->m_currentArgument->setType(d->createTypeInfo(type));
d->m_currentFunction->addArgument(d->m_currentArgument);
QString defaultValueExpression = d->cursorValueExpression(this, cursor);
if (!defaultValueExpression.isEmpty()) {
@@ -1108,16 +1127,16 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
const TemplateParameterModelItem tItem = cursor.kind == CXCursor_TemplateTemplateParameter
? d->createTemplateParameter(cursor) : d->createNonTypeTemplateParameter(cursor);
// Apply to function/member template?
- if (!d->m_currentFunction.isNull()) {
+ if (d->m_currentFunction) {
d->m_currentFunction->setTemplateParameters(d->m_currentFunction->templateParameters() << tItem);
- } else if (!d->m_currentTemplateTypeAlias.isNull()) {
+ } else if (d->m_currentTemplateTypeAlias) {
d->m_currentTemplateTypeAlias->addTemplateParameter(tItem);
- } else if (!d->m_currentClass.isNull()) { // Apply to class
+ } else if (d->m_currentClass) { // Apply to class
const QString &tplParmName = tItem->name();
if (Q_UNLIKELY(!insertTemplateParameterIntoClassName(tplParmName, d->m_currentClass)
|| !insertTemplateParameterIntoClassName(tplParmName, &d->m_scope.back()))) {
- const QString message = QStringLiteral("Error inserting template parameter \"") + tplParmName
- + QStringLiteral("\" into ") + d->m_currentClass->name();
+ const QString message = "Error inserting template parameter \""_L1 + tplParmName
+ + "\" into "_L1 + d->m_currentClass->name();
const Diagnostic d(message, cursor, CXDiagnostic_Error);
qWarning() << d;
appendDiagnostic(d);
@@ -1131,7 +1150,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
d->startTemplateTypeAlias(cursor);
break;
case CXCursor_TypeAliasDecl: // May contain nested CXCursor_TemplateTypeParameter
- if (d->m_currentTemplateTypeAlias.isNull()) {
+ if (!d->m_currentTemplateTypeAlias) {
const CXType type = clang_getCanonicalType(clang_getCursorType(cursor));
if (type.kind > CXType_Unexposed)
d->addTypeDef(cursor, type);
@@ -1159,31 +1178,23 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
d->m_usingTypeRef = getCursorSpelling(cursor);
break;
case CXCursor_TypeRef:
- if (!d->m_currentFunction.isNull()) {
- if (d->m_currentArgument.isNull())
- d->qualifyTypeDef(cursor, d->m_currentFunction); // return type
- else
- d->qualifyTypeDef(cursor, d->m_currentArgument);
- } else if (!d->m_currentField.isNull()) {
- d->qualifyTypeDef(cursor, d->m_currentField);
- } else if (d->m_withinUsingDeclaration && d->m_usingTypeRef.isEmpty()) {
+ if (d->m_withinUsingDeclaration && d->m_usingTypeRef.isEmpty())
d->m_usingTypeRef = d->getBaseClass(clang_getCursorType(cursor)).first;
- }
break;
case CXCursor_CXXFinalAttr:
- if (!d->m_currentFunction.isNull())
- d->m_currentFunction->setFinal(true);
- else if (!d->m_currentClass.isNull())
+ if (d->m_currentFunction)
+ d->m_currentFunction->setAttribute(FunctionAttribute::Final);
+ else if (d->m_currentClass)
d->m_currentClass->setFinal(true);
break;
case CXCursor_CXXOverrideAttr:
- if (!d->m_currentFunction.isNull())
- d->m_currentFunction->setOverride(true);
+ if (d->m_currentFunction)
+ d->m_currentFunction->setAttribute(FunctionAttribute::Override);
break;
case CXCursor_StaticAssert:
// Check for Q_PROPERTY() (see PySide6/global.h.in for an explanation
// how it is defined, and qdoc).
- if (clang_isDeclaration(cursor.kind) && !d->m_currentClass.isNull()) {
+ if (clang_isDeclaration(cursor.kind) && d->m_currentClass) {
auto snippet = getCodeSnippet(cursor);
const auto length = snippet.size();
if (length > 12 && *snippet.rbegin() == ')'
@@ -1195,7 +1206,7 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
break;
// UsingDeclaration: consists of a TypeRef (base) and OverloadedDeclRef (member name)
case CXCursor_UsingDeclaration:
- if (!d->m_currentClass.isNull())
+ if (d->m_currentClass)
d->m_withinUsingDeclaration = true;
break;
case CXCursor_OverloadedDeclRef:
@@ -1223,51 +1234,51 @@ bool Builder::endToken(const CXCursor &cursor)
case CXCursor_ClassTemplatePartialSpecialization:
d->popScope();
// Continue in outer class after leaving inner class?
- if (ClassModelItem lastClass = qSharedPointerDynamicCast<_ClassModelItem>(d->m_scopeStack.back()))
+ if (auto lastClass = std::dynamic_pointer_cast<_ClassModelItem>(d->m_scopeStack.back()))
d->m_currentClass = lastClass;
else
- d->m_currentClass.clear();
+ d->m_currentClass.reset();
d->m_currentFunctionType = CodeModel::Normal;
break;
case CXCursor_EnumDecl:
- if (!d->m_currentEnum.isNull())
+ if (d->m_currentEnum)
d->m_scopeStack.back()->addEnum(d->m_currentEnum);
- d->m_currentEnum.clear();
+ d->m_currentEnum.reset();
break;
case CXCursor_FriendDecl:
d->m_withinFriendDecl = false;
break;
case CXCursor_VarDecl:
case CXCursor_FieldDecl:
- d->m_currentField.clear();
+ d->m_currentField.reset();
break;
case CXCursor_Constructor:
d->qualifyConstructor(cursor);
- if (!d->m_currentFunction.isNull()) {
+ if (d->m_currentFunction) {
d->m_currentFunction->_determineType();
- d->m_currentFunction.clear();
+ d->m_currentFunction.reset();
}
break;
case CXCursor_Destructor:
case CXCursor_CXXMethod:
case CXCursor_FunctionDecl:
case CXCursor_FunctionTemplate:
- if (!d->m_currentFunction.isNull()) {
+ if (d->m_currentFunction) {
d->m_currentFunction->_determineType();
- d->m_currentFunction.clear();
+ d->m_currentFunction.reset();
}
break;
case CXCursor_ConversionFunction:
- if (!d->m_currentFunction.isNull()) {
+ if (d->m_currentFunction) {
d->m_currentFunction->setFunctionType(CodeModel::ConversionOperator);
- d->m_currentFunction.clear();
+ d->m_currentFunction.reset();
}
break;
case CXCursor_Namespace:
d->popScope();
break;
case CXCursor_ParmDecl:
- d->m_currentArgument.clear();
+ d->m_currentArgument.reset();
break;
case CXCursor_TypeAliasTemplateDecl:
d->m_currentTemplateTypeAlias.reset();
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h
index 56b6347d5..b2ec6d304 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h
@@ -14,12 +14,12 @@ class BuilderPrivate;
class Builder : public BaseVisitor {
public:
- Q_DISABLE_COPY(Builder)
+ Q_DISABLE_COPY_MOVE(Builder)
Builder();
~Builder();
- void setSystemIncludes(const QStringList &systemIncludes);
+ void setForceProcessSystemIncludes(const QStringList &systemIncludes);
bool visitLocation(const QString &fileName, LocationType locationType) const override;
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.cpp b/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.cpp
index 93618cf0f..3c002da9c 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.cpp
@@ -7,8 +7,6 @@
#include <QtCore/QDebug>
#include <QtCore/QString>
-#include <string.h>
-
#ifndef QT_NO_DEBUG_STREAM
#ifdef Q_OS_WIN
@@ -19,7 +17,7 @@ const char pathSep = '/';
static const char *baseName(const char *fileName)
{
- const char *b = strrchr(fileName, pathSep);
+ const char *b = std::strrchr(fileName, pathSep);
return b ? b + 1 : fileName;
}
@@ -49,59 +47,99 @@ QDebug operator<<(QDebug s, CX_CXXAccessSpecifier ac)
return s;
}
-QDebug operator<<(QDebug s, const CXType &t)
+struct formatCXTypeName
+{
+ explicit formatCXTypeName(const CXType &type) : m_type(type) {}
+
+ const CXType &m_type;
+};
+
+QDebug operator<<(QDebug debug, const formatCXTypeName &ft)
{
- CXString typeSpelling = clang_getTypeSpelling(t);
- s << typeSpelling;
+ CXString typeSpelling = clang_getTypeSpelling(ft.m_type);
+ debug << typeSpelling;
clang_disposeString(typeSpelling);
- return s;
+ return debug;
}
-QDebug operator<<(QDebug s, const CXCursor &cursor)
+QDebug operator<<(QDebug debug, const CXType &type)
{
- QDebugStateSaver saver(s);
- s.nospace();
- s.noquote();
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug.noquote();
+ debug << "CXType(";
+ if (type.kind == CXType_Invalid) {
+ debug << "invalid)";
+ return debug;
+ }
+
+ debug << type.kind;
+ switch (type.kind) {
+ case CXType_Unexposed:
+ debug << " [unexposed]";
+ break;
+ case CXType_Elaborated:
+ debug << " [elaborated]";
+ break;
+ default:
+ break;
+ }
+ debug << ", " << formatCXTypeName(type) << ')';
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const CXCursor &cursor)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug.noquote();
const CXCursorKind kind = clang_getCursorKind(cursor);
- s << kind;
- if (kind >= CXCursor_FirstInvalid && kind <= CXCursor_LastInvalid)
- return s;
+ debug << "CXCursor(";
+ if (kind >= CXCursor_FirstInvalid && kind <= CXCursor_LastInvalid) {
+ debug << "invalid)";
+ return debug;
+ }
+
+ const QString cursorSpelling = clang::getCursorSpelling(cursor);
+ debug << '"' << cursorSpelling << '"';
+ CXString cursorDisplay = clang_getCursorDisplayName(cursor);
+ if (const char *dpy = clang_getCString(cursorDisplay)) {
+ const QString display = QString::fromUtf8(dpy);
+ if (display != cursorSpelling)
+ debug << ", display=\"" << dpy << '"';
+ }
+ clang_disposeString(cursorDisplay);
+
+ debug << ", kind=" << kind;
+
const CXType type = clang_getCursorType(cursor);
switch (kind) {
case CXCursor_CXXAccessSpecifier:
- s << ' ' << clang_getCXXAccessSpecifier(cursor);
+ debug << ", " << clang_getCXXAccessSpecifier(cursor);
break;
case CXCursor_CXXBaseSpecifier:
- s << ", inherits=\"" << clang::getCursorSpelling(clang_getTypeDeclaration(type)) << '"';
+ debug << ", inherits=\"" << clang::getCursorSpelling(clang_getTypeDeclaration(type)) << '"';
break;
case CXCursor_CXXMethod:
case CXCursor_FunctionDecl:
case CXCursor_ConversionFunction:
- s << ", result type=\"" << clang_getCursorResultType(cursor) << '"';
+ debug << ", result type=\""
+ << formatCXTypeName(clang_getCursorResultType(cursor)) << '"';
break;
case CXCursor_TypedefDecl:
- s << ", underlyingType=\"" << clang_getTypedefDeclUnderlyingType(cursor) << '"';
+ debug << ", underlyingType=\""
+ << formatCXTypeName(clang_getTypedefDeclUnderlyingType(cursor)) << '"';
break;
default:
break;
}
- if (type.kind != CXType_Invalid)
- s << ", type=\"" << type << '"';
+ debug << ", type=\"" << formatCXTypeName(type) << '"';
if (clang_Cursor_hasAttrs(cursor))
- s << ", [attrs]";
+ debug << ", [attrs]";
- const QString cursorSpelling = clang::getCursorSpelling(cursor);
- if (!cursorSpelling.isEmpty())
- s << ", spelling=\"" << cursorSpelling << '"';
- CXString cursorDisplay = clang_getCursorDisplayName(cursor);
- if (const char *dpy = clang_getCString(cursorDisplay)) {
- const QString display = QString::fromUtf8(dpy);
- if (display != cursorSpelling)
- s << ", display=\"" << dpy << '"';
- }
- clang_disposeString(cursorDisplay);
- return s;
+ debug << ')';
+ return debug;
}
QDebug operator<<(QDebug s, const CXSourceLocation &location)
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.h b/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.h
index 3a1b91e1a..7aac8a575 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.h
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.h
@@ -4,7 +4,7 @@
#ifndef CLANGDEBUGUTILS_H
#define CLANGDEBUGUTILS_H
-#include <QtCore/QtGlobal>
+#include <QtCore/qtclasshelpermacros.h>
#include <clang-c/Index.h>
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp b/sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp
index 9762b352f..6c0cf3ae2 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp
@@ -13,6 +13,8 @@
#include <QtCore/QScopedArrayPointer>
#include <QtCore/QString>
+using namespace Qt::StringLiterals;
+
namespace clang {
QString SourceFileCache::getFileName(CXFile file)
@@ -39,7 +41,7 @@ std::string_view SourceFileCache::getCodeSnippet(const CXCursor &cursor,
if (range.first.file != range.second.file) {
if (errorMessage)
- *errorMessage = QStringLiteral("Range spans several files");
+ *errorMessage = "Range spans several files"_L1;
return std::string_view(empty, 0);
}
@@ -48,7 +50,7 @@ std::string_view SourceFileCache::getCodeSnippet(const CXCursor &cursor,
const QString fileName = getFileName(range.first.file);
if (fileName.isEmpty()) {
if (errorMessage)
- *errorMessage = QStringLiteral("Range has no file");
+ *errorMessage = "Range has no file"_L1;
return std::string_view(empty, 0);
}
QFile file(fileName);
@@ -233,6 +235,7 @@ static QByteArray msgCreateTranslationUnit(const QByteArrayList &clangArgs, unsi
static CXTranslationUnit createTranslationUnit(CXIndex index,
const QByteArrayList &args,
bool addCompilerSupportArguments,
+ LanguageLevel level,
unsigned flags = 0)
{
// courtesy qdoc
@@ -253,7 +256,7 @@ static CXTranslationUnit createTranslationUnit(CXIndex index,
QByteArrayList clangArgs;
if (addCompilerSupportArguments) {
- clangArgs += emulatedCompilerOptions();
+ clangArgs += emulatedCompilerOptions(level);
clangArgs += defaultArgs;
}
clangArgs += detectVulkan();
@@ -278,7 +281,7 @@ static CXTranslationUnit createTranslationUnit(CXIndex index,
*/
bool parse(const QByteArrayList &clangArgs, bool addCompilerSupportArguments,
- unsigned clangFlags, BaseVisitor &bv)
+ LanguageLevel level, unsigned clangFlags, BaseVisitor &bv)
{
CXIndex index = clang_createIndex(0 /* excludeDeclarationsFromPCH */,
1 /* displayDiagnostics */);
@@ -289,7 +292,7 @@ bool parse(const QByteArrayList &clangArgs, bool addCompilerSupportArguments,
CXTranslationUnit translationUnit =
createTranslationUnit(index, clangArgs, addCompilerSupportArguments,
- clangFlags);
+ level, clangFlags);
if (!translationUnit)
return false;
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangparser.h b/sources/shiboken6/ApiExtractor/clangparser/clangparser.h
index 3abbece24..22e0a50cd 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangparser.h
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangparser.h
@@ -8,11 +8,13 @@
#include <QtCore/QByteArrayList>
#include <QtCore/QHash>
-#include <QtCore/QPair>
#include <QtCore/QString>
#include <QtCore/QList>
#include <string_view>
+#include <utility>
+
+enum class LanguageLevel;
namespace clang {
@@ -40,7 +42,7 @@ enum class LocationType
};
class BaseVisitor {
- Q_DISABLE_COPY(BaseVisitor)
+ Q_DISABLE_COPY_MOVE(BaseVisitor)
public:
using Diagnostics = QList<Diagnostic>;
@@ -79,7 +81,7 @@ private:
bool parse(const QByteArrayList &clangArgs,
bool addCompilerSupportArguments,
- unsigned clangFlags, BaseVisitor &ctx);
+ LanguageLevel level, unsigned clangFlags, BaseVisitor &ctx);
} // namespace clang
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangutils.cpp b/sources/shiboken6/ApiExtractor/clangparser/clangutils.cpp
index 6955e4ec2..1651e09ec 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangutils.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangutils.cpp
@@ -8,38 +8,33 @@
#include <QtCore/QHashFunctions>
#include <QtCore/QProcess>
-bool operator==(const CXCursor &c1, const CXCursor &c2)
+#include <string_view>
+
+bool operator==(const CXCursor &c1, const CXCursor &c2) noexcept
{
return c1.kind == c2.kind
&& c1.xdata == c2.xdata
&& std::equal(c1.data, c1.data + sizeof(c1.data) / sizeof(c1.data[0]), c2.data);
}
-size_t qHash(const CXCursor &c, size_t seed)
+size_t qHash(const CXCursor &c, size_t seed) noexcept
{
- return qHash(c.kind) ^ qHash(c.xdata) ^ qHash(c.data[0])
- ^ qHash(c.data[1]) ^ qHash(c.data[2]) ^ seed;
+ return qHashMulti(seed, c.kind, c.xdata, c.data[0], c.data[1], c.data[2]);
}
-bool operator==(const CXType &t1, const CXType &t2)
+bool operator==(const CXType &t1, const CXType &t2) noexcept
{
return t1.kind == t2.kind && t1.data[0] == t2.data[0]
&& t1.data[1] == t2.data[1];
}
-size_t qHash(const CXType &ct, size_t seed)
+size_t qHash(const CXType &ct, size_t seed) noexcept
{
- return size_t(ct.kind) ^ size_t(0xFFFFFFFF & quintptr(ct.data[0]))
- ^ size_t(0xFFFFFFFF & quintptr(ct.data[1])) ^ seed;
+ return qHashMulti(seed, ct.kind, ct.data[0], ct.data[1]);
}
namespace clang {
-bool SourceLocation::equals(const SourceLocation &rhs) const
-{
- return file == rhs.file && offset == rhs.offset;
-}
-
SourceLocation getExpansionLocation(const CXSourceLocation &location)
{
SourceLocation result;
@@ -77,8 +72,8 @@ CXString getFileNameFromLocation(const CXSourceLocation &location)
SourceRange getCursorRange(const CXCursor &cursor)
{
const CXSourceRange extent = clang_getCursorExtent(cursor);
- return qMakePair(getExpansionLocation(clang_getRangeStart(extent)),
- getExpansionLocation(clang_getRangeEnd(extent)));
+ return std::make_pair(getExpansionLocation(clang_getRangeStart(extent)),
+ getExpansionLocation(clang_getRangeEnd(extent)));
}
QString getCursorKindName(CXCursorKind cursorKind)
@@ -105,6 +100,43 @@ QString getCursorDisplayName(const CXCursor &cursor)
return result;
}
+static inline bool isBuiltinType(CXTypeKind kind)
+{
+ return kind >= CXType_FirstBuiltin && kind <= CXType_LastBuiltin;
+}
+
+// Resolve elaborated types occurring with clang 16
+static CXType resolveElaboratedType(const CXType &type)
+{
+ if (!isBuiltinType(type.kind)) {
+ CXCursor decl = clang_getTypeDeclaration(type);
+ auto resolvedType = clang_getCursorType(decl);
+ if (resolvedType.kind != CXType_Invalid && resolvedType.kind != type.kind)
+ return resolvedType;
+ }
+ return type;
+}
+
+// Resolve typedefs
+static CXType resolveTypedef(const CXType &type)
+{
+ auto result = type;
+ while (result.kind == CXType_Typedef) {
+ auto decl = clang_getTypeDeclaration(result);
+ auto resolved = clang_getTypedefDeclUnderlyingType(decl);
+ if (resolved.kind == CXType_Invalid)
+ break;
+ result = resolved;
+ }
+ return result;
+}
+
+// Fully resolve a type from elaborated & typedefs
+CXType fullyResolveType(const CXType &type)
+{
+ return resolveTypedef(resolveElaboratedType(type));
+}
+
QString getTypeName(const CXType &type)
{
CXString typeSpelling = clang_getTypeSpelling(type);
@@ -113,6 +145,23 @@ QString getTypeName(const CXType &type)
return result;
}
+// Quick check for "::Type"
+bool hasScopeResolution(const CXType &type)
+{
+ CXString typeSpelling = clang_getTypeSpelling(type);
+ std::string_view spelling = clang_getCString(typeSpelling);
+ const bool result = spelling.compare(0, 2, "::") == 0
+ || spelling.find(" ::") != std::string::npos;
+ clang_disposeString(typeSpelling);
+ return result;
+}
+
+// Resolve elaborated types occurring with clang 16
+QString getResolvedTypeName(const CXType &type)
+{
+ return getTypeName(resolveElaboratedType(type));
+}
+
Diagnostic::Diagnostic(const QString &m, const CXCursor &c, CXDiagnosticSeverity s)
: message(m), source(Other), severity(s)
{
@@ -166,14 +215,14 @@ QList<Diagnostic> getDiagnostics(CXTranslationUnit tu)
return result;
}
-QPair<qsizetype, qsizetype>
+std::pair<qsizetype, qsizetype>
parseTemplateArgumentList(const QString &l,
const TemplateArgumentHandler &handler,
qsizetype from)
{
const auto ltPos = l.indexOf(u'<', from);
if (ltPos == - 1)
- return qMakePair(-1, -1);
+ return std::make_pair(-1, -1);
auto startPos = ltPos + 1;
int level = 1;
for (qsizetype p = startPos, end = l.size(); p < end; ) {
@@ -185,7 +234,7 @@ QPair<qsizetype, qsizetype>
++p;
if (c == '>') {
if (--level == 0)
- return qMakePair(ltPos, p);
+ return std::make_pair(ltPos, p);
// Skip over next ',': "a<b<c,d>,e>"
for (; p < end && (l.at(p).isSpace() || l.at(p) == u','); ++p) {}
}
@@ -201,7 +250,7 @@ QPair<qsizetype, qsizetype>
break;
}
}
- return qMakePair(-1, -1);
+ return std::make_pair(-1, -1);
}
CXDiagnosticSeverity maxSeverity(const QList<Diagnostic> &ds)
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangutils.h b/sources/shiboken6/ApiExtractor/clangparser/clangutils.h
index 9ad0cbc57..fbbf95f1b 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangutils.h
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangutils.h
@@ -5,20 +5,21 @@
#define CLANGUTILS_H
#include <clang-c/Index.h>
-#include <QtCore/QPair>
#include <QtCore/QString>
#include <QtCore/QStringList>
+#include <QtCore/QtCompare>
#include <QtCore/QList>
#include <functional>
+#include <utility>
QT_FORWARD_DECLARE_CLASS(QDebug)
-bool operator==(const CXCursor &c1, const CXCursor &c2);
-size_t qHash(const CXCursor &c, size_t seed = 0);
+bool operator==(const CXCursor &c1, const CXCursor &c2) noexcept;
+size_t qHash(const CXCursor &c, size_t seed = 0) noexcept;
-bool operator==(const CXType &t1, const CXType &t2);
-size_t qHash(const CXType &ct, size_t seed);
+bool operator==(const CXType &t1, const CXType &t2) noexcept;
+size_t qHash(const CXType &ct, size_t seed = 0) noexcept;
namespace clang {
@@ -26,6 +27,9 @@ QString getCursorKindName(CXCursorKind cursorKind);
QString getCursorSpelling(const CXCursor &cursor);
QString getCursorDisplayName(const CXCursor &cursor);
QString getTypeName(const CXType &type);
+bool hasScopeResolution(const CXType &type);
+CXType fullyResolveType(const CXType &type);
+QString getResolvedTypeName(const CXType &type);
inline QString getCursorTypeName(const CXCursor &cursor)
{ return getTypeName(clang_getCursorType(cursor)); }
inline QString getCursorResultTypeName(const CXCursor &cursor)
@@ -46,17 +50,18 @@ struct SourceLocation
unsigned line = 0;
unsigned column = 0;
unsigned offset = 0;
-};
-
-inline bool operator==(const SourceLocation &l1, const SourceLocation &l2)
-{ return l1.equals(l2); }
-inline bool operator!=(const SourceLocation &l1, const SourceLocation &l2)
-{ return !l1.equals(l2); }
+ friend constexpr bool comparesEqual(const SourceLocation &lhs,
+ const SourceLocation &rhs) noexcept
+ {
+ return lhs.file == rhs.file && lhs.offset == rhs.offset;
+ }
+ Q_DECLARE_EQUALITY_COMPARABLE_LITERAL_TYPE(SourceLocation)
+};
SourceLocation getExpansionLocation(const CXSourceLocation &location);
-using SourceRange =QPair<SourceLocation, SourceLocation>;
+using SourceRange = std::pair<SourceLocation, SourceLocation>;
SourceLocation getCursorLocation(const CXCursor &cursor);
CXString getFileNameFromLocation(const CXSourceLocation &location);
@@ -89,7 +94,7 @@ CXDiagnosticSeverity maxSeverity(const QList<Diagnostic> &ds);
// with each match (level and string). Return begin and end of the list.
using TemplateArgumentHandler = std::function<void (int, QStringView)>;
-QPair<qsizetype, qsizetype>
+std::pair<qsizetype, qsizetype>
parseTemplateArgumentList(const QString &l,
const TemplateArgumentHandler &handler,
qsizetype from = 0);
diff --git a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp
index 4145c8dec..20224020b 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp
@@ -3,6 +3,7 @@
#include "compilersupport.h"
#include "header_paths.h"
+#include "clangutils.h"
#include <reporthandler.h>
@@ -19,7 +20,6 @@
#include <clang-c/Index.h>
-#include <string.h>
#include <algorithm>
#include <iterator>
@@ -94,13 +94,19 @@ bool setPlatform(const QString &name)
return result;
}
+// 3/2024: Use a recent MSVC2022 for libclang 18.X
+static QByteArray msvcCompatVersion()
+{
+ return libClangVersion() >= QVersionNumber(0, 64) ? "19.39"_ba : "19.26"_ba;
+}
+
static bool runProcess(const QString &program, const QStringList &arguments,
QByteArray *stdOutIn = nullptr, QByteArray *stdErrIn = nullptr)
{
QProcess process;
process.start(program, arguments, QProcess::ReadWrite);
if (!process.waitForStarted()) {
- qWarning().noquote().nospace() << "Unable to start "
+ qCWarning(lcShiboken).noquote().nospace() << "Unable to start "
<< process.program() << ": " << process.errorString();
return false;
}
@@ -113,18 +119,18 @@ static bool runProcess(const QString &program, const QStringList &arguments,
*stdOutIn = process.readAllStandardOutput();
if (!finished) {
- qWarning().noquote().nospace() << process.program() << " timed out: " << stdErr;
+ qCWarning(lcShiboken).noquote().nospace() << process.program() << " timed out: " << stdErr;
process.kill();
return false;
}
if (process.exitStatus() != QProcess::NormalExit) {
- qWarning().noquote().nospace() << process.program() << " crashed: " << stdErr;
+ qCWarning(lcShiboken).noquote().nospace() << process.program() << " crashed: " << stdErr;
return false;
}
if (process.exitCode() != 0) {
- qWarning().noquote().nospace() << process.program() << " exited "
+ qCWarning(lcShiboken).noquote().nospace() << process.program() << " exited "
<< process.exitCode() << ": " << stdErr;
return false;
}
@@ -179,6 +185,13 @@ static HeaderPaths gppInternalIncludePaths(const QString &compiler)
return result;
const QByteArrayList stdErrLines = stdErr.split('\n');
bool isIncludeDir = false;
+
+ if (ReportHandler::isDebug(ReportHandler::MediumDebug))
+ qCInfo(lcShiboken()).noquote().nospace()
+ << "gppInternalIncludePaths:\n compiler: " << compiler
+ << "\n stdOut: " << stdOut
+ << "\n stdErr: " << stdErr;
+
for (const QByteArray &line : stdErrLines) {
if (isIncludeDir) {
if (line.startsWith(QByteArrayLiteral("End of search list"))) {
@@ -240,6 +253,23 @@ static bool needsClangBuiltinIncludes()
return platform() != Platform::macOS;
}
+static QString queryLlvmConfigDir(const QString &arg)
+{
+ static const QString llvmConfig = QStandardPaths::findExecutable(u"llvm-config"_s);
+ if (llvmConfig.isEmpty())
+ return {};
+ QByteArray stdOut;
+ if (!runProcess(llvmConfig, QStringList{arg}, &stdOut))
+ return {};
+ const QString path = QFile::decodeName(stdOut.trimmed());
+ if (!QFileInfo::exists(path)) {
+ qCWarning(lcShiboken, R"(%s: "%s" as returned by llvm-config "%s" does not exist.)",
+ __FUNCTION__, qPrintable(QDir::toNativeSeparators(path)), qPrintable(arg));
+ return {};
+ }
+ return path;
+}
+
static QString findClangLibDir()
{
for (const char *envVar : {"LLVM_INSTALL_DIR", "CLANG_INSTALL_DIR"}) {
@@ -247,21 +277,11 @@ static QString findClangLibDir()
const QString path = QFile::decodeName(qgetenv(envVar)) + u"/lib"_s;
if (QFileInfo::exists(path))
return path;
- qWarning("%s: %s as pointed to by %s does not exist.", __FUNCTION__, qPrintable(path), envVar);
- }
- }
- const QString llvmConfig =
- QStandardPaths::findExecutable(u"llvm-config"_s);
- if (!llvmConfig.isEmpty()) {
- QByteArray stdOut;
- if (runProcess(llvmConfig, QStringList{u"--libdir"_s}, &stdOut)) {
- const QString path = QFile::decodeName(stdOut.trimmed());
- if (QFileInfo::exists(path))
- return path;
- qWarning("%s: %s as returned by llvm-config does not exist.", __FUNCTION__, qPrintable(path));
+ qCWarning(lcShiboken, "%s: %s as pointed to by %s does not exist.",
+ __FUNCTION__, qPrintable(path), envVar);
}
}
- return QString();
+ return queryLlvmConfigDir(u"--libdir"_s);
}
static QString findClangBuiltInIncludesDir()
@@ -270,13 +290,23 @@ static QString findClangBuiltInIncludesDir()
const QString clangPathLibDir = findClangLibDir();
if (!clangPathLibDir.isEmpty()) {
QString candidate;
+ QString clangDirName = clangPathLibDir + u"/clang"_s;
+ // PYSIDE-2769: llvm-config --libdir may report /usr/lib64 on manylinux_2_28_x86_64
+ // whereas the includes are under /usr/lib/clang/../include.
+ if (!QFileInfo::exists(clangDirName) && clangPathLibDir.endsWith("64"_L1)) {
+ const QString fallback = clangPathLibDir.sliced(0, clangPathLibDir.size() - 2);
+ clangDirName = fallback + u"/clang"_s;
+ qCWarning(lcShiboken, "%s: Falling back from %s to %s.",
+ __FUNCTION__, qPrintable(clangPathLibDir), qPrintable(fallback));
+ }
+
QVersionNumber lastVersionNumber(1, 0, 0);
- const QString clangDirName = clangPathLibDir + u"/clang"_s;
QDir clangDir(clangDirName);
const QFileInfoList versionDirs =
clangDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
if (versionDirs.isEmpty())
- qWarning("%s: No subdirectories found in %s.", __FUNCTION__, qPrintable(clangDirName));
+ qCWarning(lcShiboken, "%s: No subdirectories found in %s.",
+ __FUNCTION__, qPrintable(clangDirName));
for (const QFileInfo &fi : versionDirs) {
const QString fileName = fi.fileName();
if (fileName.at(0).isDigit()) {
@@ -288,22 +318,44 @@ static QString findClangBuiltInIncludesDir()
}
}
if (!candidate.isEmpty())
- return candidate + QStringLiteral("/include");
+ return candidate + "/include"_L1;
}
- return QString();
+ return queryLlvmConfigDir(u"--includedir"_s);
}
+QString compilerFromCMake()
+{
+#ifdef CMAKE_CXX_COMPILER
+ return QString::fromLocal8Bit(CMAKE_CXX_COMPILER);
+#else
+ return {};
+#endif
+}
+
+// Return a compiler suitable for determining the internal include paths
static QString compilerFromCMake(const QString &defaultCompiler)
{
if (!compilerPath().isEmpty())
return compilerPath();
-// Added !defined(Q_OS_DARWIN) due to PYSIDE-1032
- QString result = defaultCompiler;
-#ifdef CMAKE_CXX_COMPILER
- if (platform() != Platform::macOS)
- result = QString::fromLocal8Bit(CMAKE_CXX_COMPILER);
-#endif
- return result;
+ // Exclude macOS since cmakeCompiler returns the full path instead of the
+ // /usr/bin/clang shim, which results in the default SDK sysroot path
+ // missing (PYSIDE-1032)
+ if (platform() == Platform::macOS)
+ return defaultCompiler;
+ QString cmakeCompiler = compilerFromCMake();
+ if (cmakeCompiler.isEmpty())
+ return defaultCompiler;
+ QFileInfo fi(cmakeCompiler);
+ // Should be absolute by default, but a user may specify -DCMAKE_CXX_COMPILER=cl.exe
+ if (fi.isRelative())
+ return cmakeCompiler;
+ if (fi.exists())
+ return fi.absoluteFilePath();
+ // The compiler may not exist in case something like icecream or
+ // a non-standard-path was used on the build machine. Check
+ // the executable.
+ cmakeCompiler = QStandardPaths::findExecutable(fi.fileName());
+ return cmakeCompiler.isEmpty() ? defaultCompiler : cmakeCompiler;
}
static void appendClangBuiltinIncludes(HeaderPaths *p)
@@ -315,7 +367,8 @@ static void appendClangBuiltinIncludes(HeaderPaths *p)
"(neither by checking the environment variables LLVM_INSTALL_DIR, CLANG_INSTALL_DIR "
" nor running llvm-config). This may lead to parse errors.");
} else {
- qCInfo(lcShiboken, "CLANG builtins includes directory: %s",
+ qCInfo(lcShiboken, "CLANG v%d.%d, builtins includes directory: %s",
+ CINDEX_VERSION_MAJOR, CINDEX_VERSION_MINOR,
qPrintable(clangBuiltinIncludesDir));
p->append(HeaderPath{QFile::encodeName(clangBuiltinIncludesDir),
HeaderType::System});
@@ -323,15 +376,17 @@ static void appendClangBuiltinIncludes(HeaderPaths *p)
}
// Returns clang options needed for emulating the host compiler
-QByteArrayList emulatedCompilerOptions()
+QByteArrayList emulatedCompilerOptions(LanguageLevel level)
{
QByteArrayList result;
HeaderPaths headerPaths;
switch (compiler()) {
case Compiler::Msvc:
- result.append(QByteArrayLiteral("-fms-compatibility-version=19.26.28806"));
- result.append(QByteArrayLiteral("-fdelayed-template-parsing"));
+ result.append("-fms-compatibility-version="_ba + msvcCompatVersion());
+ if (level < LanguageLevel::Cpp20)
+ result.append("-fdelayed-template-parsing"_ba);
result.append(QByteArrayLiteral("-Wno-microsoft-enum-value"));
+ result.append("/Zc:__cplusplus"_ba);
// Fix yvals_core.h: STL1000: Unexpected compiler version, expected Clang 7 or newer (MSVC2017 update)
result.append(QByteArrayLiteral("-D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH"));
if (needsClangBuiltinIncludes())
@@ -347,7 +402,7 @@ QByteArrayList emulatedCompilerOptions()
// Append the c++ include paths since Clang is unable to find
// <type_traits> etc (g++ 11.3).
- const HeaderPaths gppPaths = gppInternalIncludePaths(compilerFromCMake(u"g++"_qs));
+ const HeaderPaths gppPaths = gppInternalIncludePaths(compilerFromCMake(u"g++"_s));
for (const HeaderPath &h : gppPaths) {
if (h.path.contains("c++") || h.path.contains("sysroot"))
headerPaths.append(h);
diff --git a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h
index 18e87c495..f1d63b7c3 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h
+++ b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h
@@ -33,7 +33,7 @@ enum class Platform {
namespace clang {
QVersionNumber libClangVersion();
-QByteArrayList emulatedCompilerOptions();
+QByteArrayList emulatedCompilerOptions(LanguageLevel level);
LanguageLevel emulatedCompilerLanguageLevel();
const char *languageLevelOption(LanguageLevel l);
@@ -44,6 +44,8 @@ QByteArrayList detectVulkan();
Compiler compiler();
bool setCompiler(const QString &name);
+QString compilerFromCMake();
+
const QString &compilerPath();
void setCompilerPath(const QString &name);
diff --git a/sources/shiboken6/ApiExtractor/classdocumentation.cpp b/sources/shiboken6/ApiExtractor/classdocumentation.cpp
index 3d4abb87d..637e4a422 100644
--- a/sources/shiboken6/ApiExtractor/classdocumentation.cpp
+++ b/sources/shiboken6/ApiExtractor/classdocumentation.cpp
@@ -3,6 +3,7 @@
#include "classdocumentation.h"
#include "messages.h"
+#include "debughelpers_p.h"
#include <QtCore/QDebug>
#include <QtCore/QBuffer>
@@ -82,44 +83,51 @@ qsizetype ClassDocumentation::indexOfProperty(const QString &name) const
return -1;
}
-enum class WebXmlTag
+enum class WebXmlCodeTag
{
- Class, Description, Enum, Function, Parameter, Property, Typedef, Other
+ Class, Description, Enum, Function, Header, Parameter, Property, Typedef, Other
};
-static WebXmlTag tag(QStringView name)
+static WebXmlCodeTag tag(QStringView name)
{
if (name == u"class" || name == u"namespace")
- return WebXmlTag::Class;
+ return WebXmlCodeTag::Class;
if (name == u"enum")
- return WebXmlTag::Enum;
+ return WebXmlCodeTag::Enum;
if (name == u"function")
- return WebXmlTag::Function;
+ return WebXmlCodeTag::Function;
if (name == u"description")
- return WebXmlTag::Description;
+ return WebXmlCodeTag::Description;
+ if (name == u"header")
+ return WebXmlCodeTag::Header;
if (name == u"parameter")
- return WebXmlTag::Parameter;
+ return WebXmlCodeTag::Parameter;
if (name == u"property")
- return WebXmlTag::Property;
+ return WebXmlCodeTag::Property;
if (name == u"typedef")
- return WebXmlTag::Typedef;
- return WebXmlTag::Other;
+ return WebXmlCodeTag::Typedef;
+ return WebXmlCodeTag::Other;
}
-static void parseWebXmlElement(WebXmlTag tag, const QXmlStreamAttributes &attributes,
+static void parseWebXmlElement(WebXmlCodeTag tag, const QXmlStreamAttributes &attributes,
ClassDocumentation *cd)
{
switch (tag) {
- case WebXmlTag::Class:
+ case WebXmlCodeTag::Class:
cd->name = attributes.value(u"name"_s).toString();
+ cd->type = ClassDocumentation::Class;
break;
- case WebXmlTag::Enum: {
+ case WebXmlCodeTag::Header:
+ cd->name = attributes.value(u"name"_s).toString();
+ cd->type = ClassDocumentation::Header;
+ break;
+ case WebXmlCodeTag::Enum: {
EnumDocumentation ed;
ed.name = attributes.value(u"name"_s).toString();
cd->enums.append(ed);
}
break;
- case WebXmlTag::Function: {
+ case WebXmlCodeTag::Function: {
FunctionDocumentation fd;
fd.name = attributes.value(u"name"_s).toString();
fd.signature = attributes.value(u"signature"_s).toString();
@@ -128,11 +136,11 @@ static void parseWebXmlElement(WebXmlTag tag, const QXmlStreamAttributes &attrib
cd->functions.append(fd);
}
break;
- case WebXmlTag::Parameter:
+ case WebXmlCodeTag::Parameter:
Q_ASSERT(!cd->functions.isEmpty());
cd->functions.last().parameters.append(attributes.value(u"type"_s).toString());
break;
- case WebXmlTag::Property: {
+ case WebXmlCodeTag::Property: {
PropertyDocumentation pd;
pd.name = attributes.value(u"name"_s).toString();
pd.brief = attributes.value(u"brief"_s).toString();
@@ -184,17 +192,17 @@ static QString msgXmlError(const QString &fileName, const QXmlStreamReader &read
return result;
}
-ClassDocumentation parseWebXml(const QString &fileName, QString *errorMessage)
+std::optional<ClassDocumentation> parseWebXml(const QString &fileName, QString *errorMessage)
{
ClassDocumentation result;
QFile file(fileName);
if (!file.open(QIODevice::Text | QIODevice::ReadOnly)) {
*errorMessage = msgCannotOpenForReading(file);
- return result;
+ return std::nullopt;
}
- WebXmlTag lastTag = WebXmlTag::Other;
+ WebXmlCodeTag lastTag = WebXmlCodeTag::Other;
QXmlStreamReader reader(&file);
while (!reader.atEnd()) {
switch (reader.readNext()) {
@@ -202,26 +210,27 @@ ClassDocumentation parseWebXml(const QString &fileName, QString *errorMessage)
const auto currentTag = tag(reader.name());
parseWebXmlElement(currentTag, reader.attributes(), &result);
switch (currentTag) { // Store relevant tags in lastTag
- case WebXmlTag::Class:
- case WebXmlTag::Function:
- case WebXmlTag::Enum:
- case WebXmlTag::Property:
- case WebXmlTag::Typedef:
+ case WebXmlCodeTag::Class:
+ case WebXmlCodeTag::Function:
+ case WebXmlCodeTag::Enum:
+ case WebXmlCodeTag::Header:
+ case WebXmlCodeTag::Property:
+ case WebXmlCodeTag::Typedef:
lastTag = currentTag;
break;
- case WebXmlTag::Description: { // Append the description to the element
+ case WebXmlCodeTag::Description: { // Append the description to the element
QString *target = nullptr;
switch (lastTag) {
- case WebXmlTag::Class:
+ case WebXmlCodeTag::Class:
target = &result.description;
break;
- case WebXmlTag::Function:
+ case WebXmlCodeTag::Function:
target = &result.functions.last().description;
break;
- case WebXmlTag::Enum:
+ case WebXmlCodeTag::Enum:
target = &result.enums.last().description;
break;
- case WebXmlTag::Property:
+ case WebXmlCodeTag::Property:
target = &result.properties.last().description;
default:
break;
@@ -241,7 +250,7 @@ ClassDocumentation parseWebXml(const QString &fileName, QString *errorMessage)
if (reader.error() != QXmlStreamReader::NoError) {
*errorMessage= msgXmlError(fileName, reader);
- return {};
+ return std::nullopt;
}
sortDocumentation(&result);
@@ -277,21 +286,6 @@ QString webXmlModuleDescription(const QString &fileName, QString *errorMessage)
return result;
}
-// Debug helpers
-template <class T>
-static void formatList(QDebug &debug, const char *title, const QList<T> &l)
-{
- if (const qsizetype size = l.size()) {
- debug << title << '[' << size << "]=(";
- for (qsizetype i = 0; i < size; ++i) {
- if (i)
- debug << ", ";
- debug << l.at(i);
- }
- debug << ')';
- }
-}
-
static void formatDescription(QDebug &debug, const QString &desc)
{
debug << "description=";
@@ -351,7 +345,7 @@ QDebug operator<<(QDebug debug, const FunctionDocumentation &f)
debug << ", returns " << f.returnType;
if (f.constant)
debug << ", const";
- formatList(debug, ", parameters", f.parameters);
+ formatList(debug, ", parameters", f.parameters, ", ");
debug << ", signature=\"" << f.signature << "\", ";
formatDescription(debug, f.description);
}
@@ -377,16 +371,11 @@ QDebug operator<<(QDebug debug, const ClassDocumentation &c)
QDebugStateSaver saver(debug);
debug.noquote();
debug.nospace();
- debug << "Class(";
- if (c) {
- debug << c.name << ", ";
- formatDescription(debug, c.description);
- formatList(debug, ", enums", c.enums);
- formatList(debug, ", properties", c.properties);
- formatList(debug, ", functions", c.functions);
- } else {
- debug << "invalid";
- }
+ debug << "Class(" << c.name << ", ";
+ formatDescription(debug, c.description);
+ formatList(debug, ", enums", c.enums);
+ formatList(debug, ", properties", c.properties);
+ formatList(debug, ", functions", c.functions);
debug << ')';
return debug;
}
diff --git a/sources/shiboken6/ApiExtractor/classdocumentation.h b/sources/shiboken6/ApiExtractor/classdocumentation.h
index ef66912f8..d47101389 100644
--- a/sources/shiboken6/ApiExtractor/classdocumentation.h
+++ b/sources/shiboken6/ApiExtractor/classdocumentation.h
@@ -6,6 +6,8 @@
#include <QtCore/QStringList>
+#include <optional>
+
QT_FORWARD_DECLARE_CLASS(QDebug)
/// An enumeration in a WebXML/doxygen document
@@ -41,9 +43,14 @@ struct FunctionDocumentation : public FunctionDocumentationQuery
using FunctionDocumentationList = QList<FunctionDocumentation>;
-/// A class/namespace in a WebXML/doxygen document
+/// A WebXML/doxygen document
struct ClassDocumentation
{
+ enum Type {
+ Class, // <class>, class/namespace
+ Header // <header>, grouped global functions/enums
+ };
+
qsizetype indexOfEnum(const QString &name) const;
FunctionDocumentationList findFunctionCandidates(const QString &name,
bool constant) const;
@@ -51,18 +58,17 @@ struct ClassDocumentation
const FunctionDocumentationQuery &q);
qsizetype indexOfProperty(const QString &name) const;
+ Type type = Type::Class;
QString name;
QString description;
QList<EnumDocumentation> enums;
QList<PropertyDocumentation> properties;
FunctionDocumentationList functions;
-
- operator bool() const { return !name.isEmpty(); }
};
/// Parse a WebXML class/namespace document
-ClassDocumentation parseWebXml(const QString &fileName, QString *errorMessage);
+std::optional<ClassDocumentation> parseWebXml(const QString &fileName, QString *errorMessage);
/// Extract the module description from a WebXML module document
QString webXmlModuleDescription(const QString &fileName, QString *errorMessage);
diff --git a/sources/shiboken6/ApiExtractor/cmake_uninstall.cmake b/sources/shiboken6/ApiExtractor/cmake_uninstall.cmake
index df95fb9d8..4031b4e1a 100644
--- a/sources/shiboken6/ApiExtractor/cmake_uninstall.cmake
+++ b/sources/shiboken6/ApiExtractor/cmake_uninstall.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
diff --git a/sources/shiboken6/ApiExtractor/codesnip.cpp b/sources/shiboken6/ApiExtractor/codesnip.cpp
index 81977ceb1..e2cd5eb35 100644
--- a/sources/shiboken6/ApiExtractor/codesnip.cpp
+++ b/sources/shiboken6/ApiExtractor/codesnip.cpp
@@ -14,7 +14,7 @@ using namespace Qt::StringLiterals;
QString TemplateInstance::expandCode() const
{
const auto templateEntry = TypeDatabase::instance()->findTemplate(m_name);
- if (templateEntry.isNull()) {
+ if (!templateEntry) {
const QString m = u"<insert-template> referring to non-existing template '"_s
+ m_name + u"'."_s;
throw Exception(m);
@@ -63,7 +63,7 @@ void CodeSnipAbstract::purgeEmptyFragments()
QRegularExpression CodeSnipAbstract::placeHolderRegex(int index)
{
- return QRegularExpression(u'%' + QString::number(index) + QStringLiteral("\\b"));
+ return QRegularExpression(u'%' + QString::number(index) + "\\b"_L1);
}
void purgeEmptyCodeSnips(QList<CodeSnip> *list)
diff --git a/sources/shiboken6/ApiExtractor/codesnip.h b/sources/shiboken6/ApiExtractor/codesnip.h
index 7a1ab0624..86834a1db 100644
--- a/sources/shiboken6/ApiExtractor/codesnip.h
+++ b/sources/shiboken6/ApiExtractor/codesnip.h
@@ -9,9 +9,10 @@
#include <QtCore/QList>
#include <QtCore/QHash>
-#include <QtCore/QSharedPointer>
#include <QtCore/QString>
+#include <memory>
+
class TemplateInstance
{
public:
@@ -34,7 +35,7 @@ private:
QHash<QString, QString> replaceRules;
};
-using TemplateInstancePtr = QSharedPointer<TemplateInstance>;
+using TemplateInstancePtr = std::shared_ptr<TemplateInstance>;
class CodeSnipFragment
{
@@ -43,7 +44,7 @@ public:
explicit CodeSnipFragment(const QString &code) : m_code(code) {}
explicit CodeSnipFragment(const TemplateInstancePtr &instance) : m_instance(instance) {}
- bool isEmpty() const { return m_code.isEmpty() && m_instance.isNull(); }
+ bool isEmpty() const { return m_code.isEmpty() && !m_instance; }
QString code() const;
@@ -51,7 +52,7 @@ public:
private:
QString m_code;
- QSharedPointer<TemplateInstance> m_instance;
+ std::shared_ptr<TemplateInstance> m_instance;
};
class CodeSnipAbstract : public CodeSnipHelpers
diff --git a/sources/shiboken6/ApiExtractor/complextypeentry.h b/sources/shiboken6/ApiExtractor/complextypeentry.h
index bdbd7fa22..5b884f2cc 100644
--- a/sources/shiboken6/ApiExtractor/complextypeentry.h
+++ b/sources/shiboken6/ApiExtractor/complextypeentry.h
@@ -4,7 +4,7 @@
#ifndef COMPLEXTYPEENTRY_H
#define COMPLEXTYPEENTRY_H
-#include "typesystem.h"
+#include "configurabletypeentry.h"
#include "typesystem_enums.h"
#include "modifications_typedefs.h"
#include "pymethoddefentry.h"
@@ -33,7 +33,7 @@ struct TypeSystemProperty
bool generateGetSetDef = false;
};
-class ComplexTypeEntry : public TypeEntry
+class ComplexTypeEntry : public ConfigurableTypeEntry
{
public:
enum TypeFlag {
@@ -42,7 +42,9 @@ public:
ForceAbstract = 0x8,
// Indicates that the instances are used to create hierarchies
// like widgets; parent ownership heuristics are enabled for them.
- ParentManagement = 0x10
+ ParentManagement = 0x10,
+ DisableQtMetaObjectFunctions = 0x20,
+ Typedef = 0x40 // Result of a <typedef-type>
};
Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
diff --git a/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp b/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp
index c02a95777..b6eda651c 100644
--- a/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp
+++ b/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp
@@ -165,15 +165,15 @@ QStringList ConditionalStreamReader::platformConditions()
{
QStringList result;
#if defined (Q_OS_UNIX)
- result << QStringLiteral("unix");
+ result << "unix"_L1;
#endif
#if defined (Q_OS_LINUX)
- result << QStringLiteral("linux");
+ result << "linux"_L1;
#elif defined (Q_OS_MACOS)
- result << QStringLiteral("darwin");
+ result << "darwin"_L1;
#elif defined (Q_OS_WINDOWS)
- result << QStringLiteral("windows");
+ result << "windows"_L1;
#endif
return result;
}
diff --git a/sources/shiboken6/ApiExtractor/conditionalstreamreader.h b/sources/shiboken6/ApiExtractor/conditionalstreamreader.h
index a273fd0ca..730697525 100644
--- a/sources/shiboken6/ApiExtractor/conditionalstreamreader.h
+++ b/sources/shiboken6/ApiExtractor/conditionalstreamreader.h
@@ -26,6 +26,8 @@ class ProxyEntityResolver;
class ConditionalStreamReader
{
public:
+ Q_DISABLE_COPY_MOVE(ConditionalStreamReader)
+
using TokenType = QXmlStreamReader::TokenType;
explicit ConditionalStreamReader(QIODevice *iod);
explicit ConditionalStreamReader(const QString &s);
diff --git a/sources/shiboken6/ApiExtractor/configurabletypeentry.h b/sources/shiboken6/ApiExtractor/configurabletypeentry.h
new file mode 100644
index 000000000..59522e16c
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/configurabletypeentry.h
@@ -0,0 +1,28 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef CONFIGURABLETYPEENTRY_H
+#define CONFIGURABLETYPEENTRY_H
+
+#include "typesystem.h"
+
+class ConfigurableTypeEntryPrivate;
+
+class ConfigurableTypeEntry : public TypeEntry
+{
+public:
+ explicit ConfigurableTypeEntry(const QString &entryName, Type t,
+ const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ TypeEntry *clone() const override;
+
+ QString configCondition() const;
+ void setConfigCondition(const QString &c);
+ bool hasConfigCondition() const;
+
+protected:
+ explicit ConfigurableTypeEntry(ConfigurableTypeEntryPrivate *d);
+};
+
+#endif // CONFIGURABLETYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/containertypeentry.h b/sources/shiboken6/ApiExtractor/containertypeentry.h
index 8acf038fd..b2003816b 100644
--- a/sources/shiboken6/ApiExtractor/containertypeentry.h
+++ b/sources/shiboken6/ApiExtractor/containertypeentry.h
@@ -9,15 +9,19 @@
class ContainerTypeEntryPrivate;
+struct OpaqueContainer // Generate an opaque container for an instantiation under name
+{
+ QStringList instantiations;
+ QString name;
+
+ QString templateParameters() const;
+};
+
+using OpaqueContainers = QList<OpaqueContainer>;
+
class ContainerTypeEntry : public ComplexTypeEntry
{
public:
- struct OpaqueContainer // Generate an opaque container for an instantiation under name
- {
- QString instantiation;
- QString name;
- };
- using OpaqueContainers = QList<OpaqueContainer>;
enum ContainerKind {
ListContainer,
@@ -25,6 +29,7 @@ public:
MapContainer,
MultiMapContainer,
PairContainer,
+ SpanContainer, // Fixed size
};
explicit ContainerTypeEntry(const QString &entryName, ContainerKind containerKind,
@@ -32,10 +37,13 @@ public:
ContainerKind containerKind() const;
+ /// Number of template parameters (except allocators)
+ qsizetype templateParameterCount() const;
+
const OpaqueContainers &opaqueContainers() const;
- void addOpaqueContainer(OpaqueContainer r);
- bool generateOpaqueContainer(const QString &instantiation) const;
- QString opaqueContainerName(const QString &instantiation) const;
+ void appendOpaqueContainers(const OpaqueContainers &l);
+ bool generateOpaqueContainer(const QStringList &instantiations) const;
+ QString opaqueContainerName(const QStringList &instantiations) const;
bool hasCustomConversion() const;
void setCustomConversion(const CustomConversionPtr &customConversion);
@@ -50,4 +58,6 @@ protected:
explicit ContainerTypeEntry(ContainerTypeEntryPrivate *d);
};
+QDebug operator<<(QDebug d, const OpaqueContainer &oc);
+
#endif // CONTAINERTYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/customconversion.cpp b/sources/shiboken6/ApiExtractor/customconversion.cpp
index 4632e4e76..4cfd1b974 100644
--- a/sources/shiboken6/ApiExtractor/customconversion.cpp
+++ b/sources/shiboken6/ApiExtractor/customconversion.cpp
@@ -99,7 +99,7 @@ QString TargetToNativeConversion::sourceTypeCheck() const
return m_sourceTypeCheck;
if (m_sourceType != nullptr && m_sourceType->isCustom()) {
- const auto cte = qSharedPointerCast<const CustomTypeEntry>(m_sourceType);
+ const auto cte = std::static_pointer_cast<const CustomTypeEntry>(m_sourceType);
if (cte->hasCheckFunction()) {
QString result = cte->checkFunction();
if (result != u"true") // For PyObject, which is always true
@@ -134,11 +134,11 @@ void TargetToNativeConversion::formatDebug(QDebug &debug) const
CustomConversionPtr CustomConversion::getCustomConversion(const TypeEntryCPtr &type)
{
if (type->isPrimitive())
- return qSharedPointerCast<const PrimitiveTypeEntry>(type)->customConversion();
+ return std::static_pointer_cast<const PrimitiveTypeEntry>(type)->customConversion();
if (type->isContainer())
- return qSharedPointerCast<const ContainerTypeEntry>(type)->customConversion();
+ return std::static_pointer_cast<const ContainerTypeEntry>(type)->customConversion();
if (type->isValue())
- return qSharedPointerCast<const ValueTypeEntry>(type)->customConversion();
+ return std::static_pointer_cast<const ValueTypeEntry>(type)->customConversion();
return {};
}
@@ -188,7 +188,7 @@ QDebug operator<<(QDebug debug, const CustomConversionPtr &cptr)
debug.noquote();
debug.nospace();
debug << "CustomConversionPtr";
- if (auto *c = cptr.data()) {
+ if (auto *c = cptr.get()) {
c->formatDebug(debug);
} else {
debug << "(0)";
diff --git a/sources/shiboken6/ApiExtractor/customconversion_typedefs.h b/sources/shiboken6/ApiExtractor/customconversion_typedefs.h
index a928378b7..6528f7d7b 100644
--- a/sources/shiboken6/ApiExtractor/customconversion_typedefs.h
+++ b/sources/shiboken6/ApiExtractor/customconversion_typedefs.h
@@ -5,9 +5,10 @@
#define CUSTOMCONVERSION_TYPEDEFS_H
#include <QtCore/QList>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
class CustomConversion;
-using CustomConversionPtr = QSharedPointer<CustomConversion>;
+using CustomConversionPtr = std::shared_ptr<CustomConversion>;
#endif // CUSTOMCONVERSION_TYPEDEFS_H
diff --git a/sources/shiboken6/ApiExtractor/debughelpers_p.h b/sources/shiboken6/ApiExtractor/debughelpers_p.h
new file mode 100644
index 000000000..81ebbb3b9
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/debughelpers_p.h
@@ -0,0 +1,56 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef DEBUGHELPERS_P_H
+#define DEBUGHELPERS_P_H
+
+#include <QtCore/QDebug>
+#include <memory>
+
+template <class T>
+inline QDebug operator<<(QDebug debug, const std::shared_ptr<T> &ptr)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace();
+ debug << "std::shared_ptr(" << ptr.get() << ")";
+ return debug;
+}
+
+template <class It>
+inline void formatSequence(QDebug &d, It i1, It i2,
+ const char *separator=", ")
+{
+ for (It i = i1; i != i2; ++i) {
+ if (i != i1)
+ d << separator;
+ d << *i;
+ }
+}
+
+template <class It>
+inline static void formatPtrSequence(QDebug &d, It i1, It i2,
+ const char *separator=", ")
+{
+ for (It i = i1; i != i2; ++i) {
+ if (i != i1)
+ d << separator;
+ d << i->get();
+ }
+}
+
+template <class Container>
+static void formatList(QDebug &d, const char *name, const Container &c,
+ const char *separator=", ")
+{
+ if (const auto size = c.size()) {
+ d << ", " << name << '[' << size << "]=(";
+ for (qsizetype i = 0; i < size; ++i) {
+ if (i)
+ d << separator;
+ d << c.at(i);
+ }
+ d << ')';
+ }
+}
+
+#endif // DEBUGHELPERS_P_H
diff --git a/sources/shiboken6/ApiExtractor/dependency.h b/sources/shiboken6/ApiExtractor/dependency.h
index f0e525e26..aa280de03 100644
--- a/sources/shiboken6/ApiExtractor/dependency.h
+++ b/sources/shiboken6/ApiExtractor/dependency.h
@@ -13,8 +13,8 @@
class AbstractMetaClass;
struct Dependency {
- AbstractMetaClass *parent;
- AbstractMetaClass *child;
+ AbstractMetaClassPtr parent;
+ AbstractMetaClassPtr child;
};
using Dependencies = QList<Dependency>;
diff --git a/sources/shiboken6/ApiExtractor/docparser.cpp b/sources/shiboken6/ApiExtractor/docparser.cpp
index 908e8576b..468fe1098 100644
--- a/sources/shiboken6/ApiExtractor/docparser.cpp
+++ b/sources/shiboken6/ApiExtractor/docparser.cpp
@@ -31,15 +31,37 @@
using namespace Qt::StringLiterals;
-DocParser::DocParser()
+static inline bool isXpathDocModification(const DocModification &mod)
{
-#ifdef HAVE_LIBXSLT
- xmlSubstituteEntitiesDefault(1);
-#endif
+ return mod.mode() == TypeSystem::DocModificationXPathReplace;
}
+static inline bool isNotXpathDocModification(const DocModification &mod)
+{
+ return mod.mode() != TypeSystem::DocModificationXPathReplace;
+}
+
+static void removeXpathDocModifications(DocModificationList *l)
+{
+ l->erase(std::remove_if(l->begin(), l->end(), isXpathDocModification), l->end());
+}
+
+static void removeNonXpathDocModifications(DocModificationList *l)
+{
+ l->erase(std::remove_if(l->begin(), l->end(), isNotXpathDocModification), l->end());
+}
+
+DocParser::DocParser() = default;
DocParser::~DocParser() = default;
+void DocParser::fillGlobalFunctionDocumentation(const AbstractMetaFunctionPtr &)
+{
+}
+
+void DocParser::fillGlobalEnumDocumentation(AbstractMetaEnum &)
+{
+}
+
QString DocParser::getDocumentation(const XQueryPtr &xquery, const QString& query,
const DocModificationList& mods)
{
@@ -86,22 +108,59 @@ bool DocParser::skipForQuery(const AbstractMetaFunctionCPtr &func)
usesRValueReference);
}
-DocModificationList DocParser::getDocModifications(const AbstractMetaClass *cppClass,
- const AbstractMetaFunctionCPtr &func)
+DocModificationList DocParser::getDocModifications(const AbstractMetaClassCPtr &cppClass)
+
+{
+ auto result = cppClass->typeEntry()->docModifications();
+ removeXpathDocModifications(&result);
+ return result;
+}
+
+static void filterBySignature(const AbstractMetaFunctionCPtr &func, DocModificationList *l)
{
- auto te = cppClass->typeEntry();
- if (func.isNull())
- return te->docModifications();
+ if (!l->isEmpty()) {
+ const QString minimalSignature = func->minimalSignature();
+ const auto filter = [&minimalSignature](const DocModification &mod) {
+ return mod.signature() != minimalSignature;
+ };
+ l->erase(std::remove_if(l->begin(), l->end(), filter), l->end());
+ }
+}
- if (func->isUserAdded())
- return func->addedFunctionDocModifications();
+DocModificationList DocParser::getDocModifications(const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaClassCPtr &cppClass)
+{
+ DocModificationList result;
+ if (func->isUserAdded()) {
+ result = func->addedFunctionDocModifications();
+ removeXpathDocModifications(&result);
+ } else if (cppClass != nullptr) {
+ result = cppClass->typeEntry()->functionDocModifications();
+ removeXpathDocModifications(&result);
+ filterBySignature(func, &result);
+ }
+ return result;
+}
- DocModificationList result = te->functionDocModifications();
- const QString minimalSignature = func->minimalSignature();
- const auto filter = [&minimalSignature](const DocModification &mod) {
- return mod.signature() != minimalSignature;
- };
- result.erase(std::remove_if(result.begin(), result.end(), filter), result.end());
+DocModificationList DocParser::getXpathDocModifications(const AbstractMetaClassCPtr &cppClass)
+{
+ auto result = cppClass->typeEntry()->docModifications();
+ removeNonXpathDocModifications(&result);
+ return result;
+}
+
+DocModificationList DocParser::getXpathDocModifications(const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaClassCPtr &cppClass)
+{
+ DocModificationList result;
+ if (func->isUserAdded()) {
+ result = func->addedFunctionDocModifications();
+ removeNonXpathDocModifications(&result);
+ } else if (cppClass != nullptr) {
+ result = cppClass->typeEntry()->functionDocModifications();
+ removeNonXpathDocModifications(&result);
+ filterBySignature(func, &result);
+ }
return result;
}
@@ -120,7 +179,7 @@ QString DocParser::enumBaseClass(const AbstractMetaEnum &e)
return e.typeEntry()->flags() != nullptr ? u"Flag"_s : u"Enum"_s;
}
-AbstractMetaFunctionCList DocParser::documentableFunctions(const AbstractMetaClass *metaClass)
+AbstractMetaFunctionCList DocParser::documentableFunctions(const AbstractMetaClassCPtr &metaClass)
{
auto result = metaClass->functionsInTargetLang();
for (auto i = result.size() - 1; i >= 0; --i) {
@@ -131,12 +190,8 @@ AbstractMetaFunctionCList DocParser::documentableFunctions(const AbstractMetaCla
return result;
}
-static inline bool isXpathDocModification(const DocModification &mod)
-{
- return mod.mode() == TypeSystem::DocModificationXPathReplace;
-}
-
-QString DocParser::applyDocModifications(const DocModificationList& mods, const QString& xml)
+QString DocParser::applyDocModifications(const DocModificationList& xpathMods,
+ const QString& xml)
{
const char xslPrefix[] =
R"(<xsl:template match="/">
@@ -150,32 +205,28 @@ R"(<xsl:template match="/">
</xsl:template>
)";
- if (mods.isEmpty() || xml.isEmpty()
- || !std::any_of(mods.cbegin(), mods.cend(), isXpathDocModification)) {
+ if (xpathMods.isEmpty() || xml.isEmpty())
return xml;
- }
QString xsl = QLatin1StringView(xslPrefix);
- for (const DocModification &mod : mods) {
- if (isXpathDocModification(mod)) {
- QString xpath = mod.xpath();
- xpath.replace(u'"', u"&quot;"_s);
- xsl += u"<xsl:template match=\""_s
- + xpath + u"\">"_s
- + mod.code() + u"</xsl:template>\n"_s;
- }
+ for (const DocModification &mod : xpathMods) {
+ Q_ASSERT(isXpathDocModification(mod));
+ QString xpath = mod.xpath();
+ xpath.replace(u'"', u"&quot;"_s);
+ xsl += "<xsl:template match=\""_L1 + xpath + "\">"_L1
+ + mod.code() + "</xsl:template>\n"_L1;
}
QString errorMessage;
const QString result = xsl_transform(xml, xsl, &errorMessage);
if (!errorMessage.isEmpty())
qCWarning(lcShibokenDoc, "%s",
- qPrintable(msgXpathDocModificationError(mods, errorMessage)));
+ qPrintable(msgXpathDocModificationError(xpathMods, errorMessage)));
if (result == xml) {
const QString message = u"Query did not result in any modifications to \""_s
+ xml + u'"';
qCWarning(lcShibokenDoc, "%s",
- qPrintable(msgXpathDocModificationError(mods, message)));
+ qPrintable(msgXpathDocModificationError(xpathMods, message)));
}
return result;
}
diff --git a/sources/shiboken6/ApiExtractor/docparser.h b/sources/shiboken6/ApiExtractor/docparser.h
index 88643b7bf..6d458b25a 100644
--- a/sources/shiboken6/ApiExtractor/docparser.h
+++ b/sources/shiboken6/ApiExtractor/docparser.h
@@ -7,7 +7,8 @@
#include "modifications_typedefs.h"
#include <QtCore/QString>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
class AbstractMetaClass;
class DocModification;
@@ -20,13 +21,15 @@ struct FunctionDocumentation;
class DocParser
{
public:
- Q_DISABLE_COPY(DocParser)
+ Q_DISABLE_COPY_MOVE(DocParser)
- using XQueryPtr = QSharedPointer<XQuery>;
+ using XQueryPtr = std::shared_ptr<XQuery>;
DocParser();
virtual ~DocParser();
- virtual void fillDocumentation(AbstractMetaClass *metaClass) = 0;
+ virtual void fillDocumentation(const AbstractMetaClassPtr &metaClass) = 0;
+ virtual void fillGlobalFunctionDocumentation(const AbstractMetaFunctionPtr &f);
+ virtual void fillGlobalEnumDocumentation(AbstractMetaEnum &e);
/**
* Process and retrieves documentation concerning the entire
@@ -93,8 +96,12 @@ public:
/// Helper to return the documentation modifications for a class
/// or a member function.
- static DocModificationList getDocModifications(const AbstractMetaClass *cppClass,
- const AbstractMetaFunctionCPtr &func = {});
+ static DocModificationList getDocModifications(const AbstractMetaClassCPtr &cppClass);
+ static DocModificationList getDocModifications(const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaClassCPtr &cppClass = {});
+ static DocModificationList getXpathDocModifications(const AbstractMetaClassCPtr &cppClass);
+ static DocModificationList getXpathDocModifications(const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaClassCPtr &cppClass = {});
static QString enumBaseClass(const AbstractMetaEnum &e);
@@ -103,9 +110,9 @@ protected:
const QString &query,
const DocModificationList &mods);
- static AbstractMetaFunctionCList documentableFunctions(const AbstractMetaClass *metaClass);
+ static AbstractMetaFunctionCList documentableFunctions(const AbstractMetaClassCPtr &metaClass);
- static QString applyDocModifications(const DocModificationList &mods, const QString &xml);
+ static QString applyDocModifications(const DocModificationList &xpathMods, const QString &xml);
private:
QString m_packageName;
diff --git a/sources/shiboken6/ApiExtractor/documentation.cpp b/sources/shiboken6/ApiExtractor/documentation.cpp
index 6c4d7166e..33cf0e9fb 100644
--- a/sources/shiboken6/ApiExtractor/documentation.cpp
+++ b/sources/shiboken6/ApiExtractor/documentation.cpp
@@ -35,12 +35,6 @@ void Documentation::setFormat(Documentation::Format f)
m_format = f;
}
-bool Documentation::equals(const Documentation &rhs) const
-{
- return m_format == rhs.m_format && m_detailed == rhs.m_detailed
- && m_brief == rhs.m_brief;
-}
-
void Documentation::setDetailed(const QString &detailed)
{
m_detailed = detailed.trimmed();
diff --git a/sources/shiboken6/ApiExtractor/documentation.h b/sources/shiboken6/ApiExtractor/documentation.h
index a18bb1a13..df9d5d614 100644
--- a/sources/shiboken6/ApiExtractor/documentation.h
+++ b/sources/shiboken6/ApiExtractor/documentation.h
@@ -5,6 +5,7 @@
#define DOCUMENTATION_H
#include <QtCore/QString>
+#include <QtCore/QtCompare>
QT_FORWARD_DECLARE_CLASS(QDebug)
@@ -44,16 +45,19 @@ public:
void setBrief(const QString &brief);
private:
+ friend bool comparesEqual(const Documentation &lhs,
+ const Documentation &rhs) noexcept
+ {
+ return lhs.m_format == rhs.m_format && lhs.m_detailed == rhs.m_detailed
+ && lhs.m_brief == rhs.m_brief;
+ }
+ Q_DECLARE_EQUALITY_COMPARABLE(Documentation)
+
QString m_detailed;
QString m_brief;
Format m_format = Documentation::Native;
};
-inline bool operator==(const Documentation &d1, const Documentation &d2)
-{ return d1.equals(d2); }
-inline bool operator!=(const Documentation &d1, const Documentation &d2)
-{ return !d1.equals(d2); }
-
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const Documentation &);
#endif
diff --git a/sources/shiboken6/ApiExtractor/dotview.cpp b/sources/shiboken6/ApiExtractor/dotview.cpp
index da94f5e7f..0bd192257 100644
--- a/sources/shiboken6/ApiExtractor/dotview.cpp
+++ b/sources/shiboken6/ApiExtractor/dotview.cpp
@@ -13,7 +13,7 @@ using namespace Qt::StringLiterals;
bool showDotGraph(const QString &name, const QString &graph)
{
- const QString imageType = u"jpg"_s;
+ constexpr auto imageType = "jpg"_L1;
// Write out the graph to a temporary file
QTemporaryFile dotFile(QDir::tempPath() + u'/' + name + u"_XXXXXX.dot"_s);
@@ -43,9 +43,9 @@ bool showDotGraph(const QString &name, const QString &graph)
// Launch image. Should use QDesktopServices::openUrl(),
// but we don't link against QtGui
#ifdef Q_OS_UNIX
- const QString imageViewer = u"gwenview"_s;
+ constexpr auto imageViewer = "gwenview"_L1;
#else
- const QString imageViewer = u"mspaint"_s;
+ constexpr auto imageViewer = "mspaint"_L1;
#endif
if (!QProcess::startDetached(imageViewer, {imageFile})) {
qWarning("Failed to launch viewer: %s", qPrintable(imageViewer));
diff --git a/sources/shiboken6/ApiExtractor/doxygenparser.cpp b/sources/shiboken6/ApiExtractor/doxygenparser.cpp
index 8f608cbc8..da790015f 100644
--- a/sources/shiboken6/ApiExtractor/doxygenparser.cpp
+++ b/sources/shiboken6/ApiExtractor/doxygenparser.cpp
@@ -41,7 +41,7 @@ Documentation DoxygenParser::retrieveModuleDocumentation()
return retrieveModuleDocumentation(packageName());
}
-void DoxygenParser::fillDocumentation(AbstractMetaClass *metaClass)
+void DoxygenParser::fillDocumentation(const AbstractMetaClassPtr &metaClass)
{
if (!metaClass)
return;
@@ -54,13 +54,12 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass *metaClass)
doxyFileSuffix += metaClass->name();
doxyFileSuffix += u".xml"_s;
- const char* prefixes[] = { "class", "struct", "namespace" };
+ static constexpr QLatin1StringView prefixes[] = { "class"_L1, "struct"_L1, "namespace"_L1 };
bool isProperty = false;
QString doxyFilePath;
- for (const char *prefix : prefixes) {
- doxyFilePath = documentationDataDirectory() + u'/'
- + QLatin1StringView(prefix) + doxyFileSuffix;
+ for (const auto &prefix : prefixes) {
+ doxyFilePath = documentationDataDirectory() + u'/' + prefix + doxyFileSuffix;
if (QFile::exists(doxyFilePath))
break;
doxyFilePath.clear();
@@ -76,12 +75,12 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass *metaClass)
QString errorMessage;
XQueryPtr xquery = XQuery::create(doxyFilePath, &errorMessage);
- if (xquery.isNull()) {
+ if (!xquery) {
qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
return;
}
- static const QList<QPair<Documentation::Type, QString>> docTags = {
+ static const QList<std::pair<Documentation::Type, QString>> docTags = {
{ Documentation::Brief, u"briefdescription"_s },
{ Documentation::Detailed, u"detaileddescription"_s }
};
@@ -119,7 +118,7 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass *metaClass)
+ func->originalName() + u"\"]"_s;
if (func->arguments().isEmpty()) {
- QString args = func->isConstant() ? u"() const "_s : u"()"_s;
+ QString args = func->isConstant() ? u"() const"_s : u"()"_s;
query += u"/../argsstring[text()=\""_s + args + u"\"]"_s;
} else {
int i = 1;
@@ -151,16 +150,16 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass *metaClass)
}
QString doc = getDocumentation(xquery, funcQuery,
- DocParser::getDocModifications(metaClass, func));
+ DocParser::getXpathDocModifications(func, metaClass));
if (doc.isEmpty()) {
qCWarning(lcShibokenDoc, "%s",
- qPrintable(msgCannotFindDocumentation(doxyFilePath, func.data(),
+ qPrintable(msgCannotFindDocumentation(doxyFilePath, func.get(),
funcQuery)));
} else {
funcDoc.setValue(doc, tag.first);
}
}
- qSharedPointerConstCast<AbstractMetaFunction>(func)->setDocumentation(funcDoc);
+ std::const_pointer_cast<AbstractMetaFunction>(func)->setDocumentation(funcDoc);
isProperty = false;
}
@@ -207,12 +206,12 @@ Documentation DoxygenParser::retrieveModuleDocumentation(const QString& name){
qCWarning(lcShibokenDoc).noquote().nospace()
<< "Can't find doxygen XML file for module " << name << ", tried: "
<< QDir::toNativeSeparators(sourceFile);
- return Documentation();
+ return {};
}
QString errorMessage;
XQueryPtr xquery = XQuery::create(sourceFile, &errorMessage);
- if (xquery.isNull()) {
+ if (!xquery) {
qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
return {};
}
diff --git a/sources/shiboken6/ApiExtractor/doxygenparser.h b/sources/shiboken6/ApiExtractor/doxygenparser.h
index ea1883d12..4f6a9e53c 100644
--- a/sources/shiboken6/ApiExtractor/doxygenparser.h
+++ b/sources/shiboken6/ApiExtractor/doxygenparser.h
@@ -10,7 +10,7 @@ class DoxygenParser : public DocParser
{
public:
DoxygenParser() = default;
- void fillDocumentation(AbstractMetaClass *metaClass) override;
+ void fillDocumentation(const AbstractMetaClassPtr &metaClass) override;
Documentation retrieveModuleDocumentation() override;
Documentation retrieveModuleDocumentation(const QString& name) override;
};
diff --git a/sources/shiboken6/ApiExtractor/enclosingclassmixin.cpp b/sources/shiboken6/ApiExtractor/enclosingclassmixin.cpp
index f2d5074b7..2421ae527 100644
--- a/sources/shiboken6/ApiExtractor/enclosingclassmixin.cpp
+++ b/sources/shiboken6/ApiExtractor/enclosingclassmixin.cpp
@@ -5,9 +5,9 @@
#include "abstractmetalang.h"
#include "namespacetypeentry.h"
-const AbstractMetaClass *EnclosingClassMixin::targetLangEnclosingClass() const
+AbstractMetaClassCPtr EnclosingClassMixin::targetLangEnclosingClass() const
{
- auto result = m_enclosingClass;
+ auto result = m_enclosingClass.lock();
while (result && !NamespaceTypeEntry::isVisibleScope(result->typeEntry()))
result = result->enclosingClass();
return result;
diff --git a/sources/shiboken6/ApiExtractor/enclosingclassmixin.h b/sources/shiboken6/ApiExtractor/enclosingclassmixin.h
index 31aeb9285..8d735d5ec 100644
--- a/sources/shiboken6/ApiExtractor/enclosingclassmixin.h
+++ b/sources/shiboken6/ApiExtractor/enclosingclassmixin.h
@@ -4,16 +4,21 @@
#ifndef ENCLOSINGCLASSMIXIN_H
#define ENCLOSINGCLASSMIXIN_H
+#include "abstractmetalang_typedefs.h"
+
class AbstractMetaClass;
class EnclosingClassMixin {
public:
- const AbstractMetaClass *enclosingClass() const { return m_enclosingClass; }
- void setEnclosingClass(const AbstractMetaClass *cls) { m_enclosingClass = cls; }
- const AbstractMetaClass *targetLangEnclosingClass() const;
+
+ const AbstractMetaClassCPtr enclosingClass() const
+ { return m_enclosingClass.lock(); }
+ void setEnclosingClass(const AbstractMetaClassCPtr &cls)
+ { m_enclosingClass = cls; }
+ AbstractMetaClassCPtr targetLangEnclosingClass() const;
private:
- const AbstractMetaClass *m_enclosingClass = nullptr;
+ std::weak_ptr<const AbstractMetaClass> m_enclosingClass;
};
#endif // ENCLOSINGCLASSMIXIN_H
diff --git a/sources/shiboken6/ApiExtractor/enumtypeentry.h b/sources/shiboken6/ApiExtractor/enumtypeentry.h
index 14bab50cf..3360d7db5 100644
--- a/sources/shiboken6/ApiExtractor/enumtypeentry.h
+++ b/sources/shiboken6/ApiExtractor/enumtypeentry.h
@@ -4,12 +4,13 @@
#ifndef ENUMTYPEENTRY_H
#define ENUMTYPEENTRY_H
-#include "typesystem.h"
+#include "configurabletypeentry.h"
#include "typesystem_enums.h"
class EnumTypeEntryPrivate;
-class EnumTypeEntry : public TypeEntry
+// EnumTypeEntry is configurable for global enums only
+class EnumTypeEntry : public ConfigurableTypeEntry
{
public:
explicit EnumTypeEntry(const QString &entryName,
@@ -36,6 +37,9 @@ public:
void addEnumValueRejection(const QString &name);
QStringList enumValueRejections() const;
+ QString docFile() const;
+ void setDocFile(const QString &df);
+
TypeEntry *clone() const override;
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
diff --git a/sources/shiboken6/ApiExtractor/fileout.cpp b/sources/shiboken6/ApiExtractor/fileout.cpp
index da81f5a1b..6f9ec4d8a 100644
--- a/sources/shiboken6/ApiExtractor/fileout.cpp
+++ b/sources/shiboken6/ApiExtractor/fileout.cpp
@@ -175,7 +175,7 @@ FileOut::State FileOut::done()
if (!FileOut::m_dryRun) {
QDir dir(info.absolutePath());
if (!dir.mkpath(dir.absolutePath())) {
- const QString message = QStringLiteral("Unable to create directory '%1'")
+ const QString message = QString::fromLatin1("Unable to create directory '%1'")
.arg(QDir::toNativeSeparators(dir.absolutePath()));
throw Exception(message);
}
diff --git a/sources/shiboken6/ApiExtractor/fileout.h b/sources/shiboken6/ApiExtractor/fileout.h
index d3f1b7b1f..b11ad1e20 100644
--- a/sources/shiboken6/ApiExtractor/fileout.h
+++ b/sources/shiboken6/ApiExtractor/fileout.h
@@ -14,7 +14,7 @@ class FileOut
{
QByteArray m_buffer;
public:
- Q_DISABLE_COPY(FileOut)
+ Q_DISABLE_COPY_MOVE(FileOut)
enum State { Unchanged, Success };
diff --git a/sources/shiboken6/ApiExtractor/flagstypeentry.h b/sources/shiboken6/ApiExtractor/flagstypeentry.h
index b784b64e6..6eddcd12b 100644
--- a/sources/shiboken6/ApiExtractor/flagstypeentry.h
+++ b/sources/shiboken6/ApiExtractor/flagstypeentry.h
@@ -9,6 +9,7 @@
class EnumTypeEntry;
class FlagsTypeEntryPrivate;
+// FlagsTypeEntry is configurable for global flags only
class FlagsTypeEntry : public TypeEntry
{
public:
diff --git a/sources/shiboken6/ApiExtractor/functiontypeentry.h b/sources/shiboken6/ApiExtractor/functiontypeentry.h
index 0901ff017..53aa1fad6 100644
--- a/sources/shiboken6/ApiExtractor/functiontypeentry.h
+++ b/sources/shiboken6/ApiExtractor/functiontypeentry.h
@@ -5,7 +5,6 @@
#define FUNCTIONTYPEENTRY_H
#include "typesystem.h"
-#include "typesystem_enums.h"
class FunctionTypeEntryPrivate;
@@ -20,8 +19,8 @@ public:
bool hasSignature(const QString& signature) const;
void addSignature(const QString& signature);
- TypeSystem::SnakeCase snakeCase() const;
- void setSnakeCase(TypeSystem::SnakeCase sc);
+ QString docFile() const;
+ void setDocFile(const QString &df);
TypeEntry *clone() const override;
diff --git a/sources/shiboken6/ApiExtractor/icecc.cmake b/sources/shiboken6/ApiExtractor/icecc.cmake
index b2bf071aa..fa8d3b7cf 100644
--- a/sources/shiboken6/ApiExtractor/icecc.cmake
+++ b/sources/shiboken6/ApiExtractor/icecc.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include (CMakeForceCompiler)
option(ENABLE_ICECC "Enable icecc checking, for distributed compilation")
if (ENABLE_ICECC)
diff --git a/sources/shiboken6/ApiExtractor/include.cpp b/sources/shiboken6/ApiExtractor/include.cpp
index d2d577817..aee6b7337 100644
--- a/sources/shiboken6/ApiExtractor/include.cpp
+++ b/sources/shiboken6/ApiExtractor/include.cpp
@@ -24,18 +24,15 @@ QString Include::toString() const
return u"import "_s + m_name + u';';
}
-int Include::compare(const Include &rhs) const
+Qt::strong_ordering compareThreeWay(const Include &lhs, const Include &rhs) noexcept
{
- if (m_type < rhs.m_type)
- return -1;
- if (m_type > rhs.m_type)
- return 1;
- return m_name.compare(rhs.m_name);
-}
-
-size_t qHash(const Include& inc)
-{
- return qHash(inc.m_name);
+ if (lhs.m_type < rhs.m_type)
+ return Qt::strong_ordering::less;
+ if (lhs.m_type > rhs.m_type)
+ return Qt::strong_ordering::greater;
+ if (auto c = lhs.m_name.compare(rhs.m_name))
+ return c < 0 ? Qt::strong_ordering::less : Qt::strong_ordering::greater;
+ return Qt::strong_ordering::equal;
}
QTextStream& operator<<(QTextStream& out, const Include& g)
diff --git a/sources/shiboken6/ApiExtractor/include.h b/sources/shiboken6/ApiExtractor/include.h
index 7fd7d3b36..875a941f9 100644
--- a/sources/shiboken6/ApiExtractor/include.h
+++ b/sources/shiboken6/ApiExtractor/include.h
@@ -4,6 +4,8 @@
#ifndef INCLUDE_H
#define INCLUDE_H
+#include <QtCore/QtCompare>
+#include <QtCore/QHashFunctions>
#include <QtCore/QString>
#include <QtCore/QList>
@@ -42,45 +44,24 @@ public:
QString toString() const;
- friend size_t qHash(const Include &);
int compare(const Include &rhs) const;
- private:
- IncludeType m_type = IncludePath;
- QString m_name;
-};
-
-size_t qHash(const Include& inc);
-
-inline bool operator<(const Include &lhs, const Include &rhs)
-{
- return lhs.compare(rhs) < 0;
-}
-
-inline bool operator<=(const Include &lhs, const Include &rhs)
-{
- return lhs.compare(rhs) <= 0;
-}
-
-inline bool operator==(const Include &lhs, const Include &rhs)
-{
- return lhs.compare(rhs) == 0;
-}
-
-inline bool operator!=(const Include &lhs, const Include &rhs)
-{
- return lhs.compare(rhs) != 0;
-}
-
-inline bool operator>=(const Include &lhs, const Include &rhs)
-{
- return lhs.compare(rhs) >= 0;
-}
+private:
+ friend size_t qHash(Include &inc, size_t seed = 0) noexcept
+ {
+ return qHashMulti(seed, inc.m_type, inc.m_name);
+ }
+ friend bool comparesEqual(const Include &lhs, const Include &rhs) noexcept
+ {
+ return lhs.m_type == rhs.m_type && lhs.m_name == rhs.m_name;
+ }
+ friend Qt::strong_ordering compareThreeWay(const Include &lhs,
+ const Include &rhs) noexcept;
+ Q_DECLARE_STRONGLY_ORDERED(Include)
-inline bool operator>(const Include &lhs, const Include &rhs)
-{
- return lhs.compare(rhs) > 0;
-}
+ IncludeType m_type = IncludePath;
+ QString m_name;
+};
QTextStream& operator<<(QTextStream& out, const Include& include);
TextStream& operator<<(TextStream& out, const Include& include);
diff --git a/sources/shiboken6/ApiExtractor/messages.cpp b/sources/shiboken6/ApiExtractor/messages.cpp
index 247bb7db0..b1f0b240e 100644
--- a/sources/shiboken6/ApiExtractor/messages.cpp
+++ b/sources/shiboken6/ApiExtractor/messages.cpp
@@ -16,7 +16,6 @@
#include "qtcompat.h"
-#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
@@ -25,11 +24,25 @@
using namespace Qt::StringLiterals;
-static inline QString colonColon() { return QStringLiteral("::"); }
-
// abstractmetabuilder.cpp
-QString msgNoFunctionForModification(const AbstractMetaClass *klass,
+static QTextStream &operator<<(QTextStream &s, Access a)
+{
+ switch (a) {
+ case Access::Public:
+ s << "public";
+ break;
+ case Access::Protected:
+ s << "protected";
+ break;
+ case Access::Private:
+ s << "private";
+ break;
+ }
+ return s;
+}
+
+QString msgNoFunctionForModification(const AbstractMetaClassCPtr &klass,
const QString &signature,
const QString &originalSignature,
const QStringList &possibleSignatures,
@@ -79,7 +92,7 @@ QString msgTypeModificationFailed(const QString &type, int n,
str << "type of argument " << n;
str << " of ";
- if (auto *c = func->ownerClass())
+ if (auto c = func->ownerClass())
str << c->name() << "::";
str << func->signature() << " to \"" << type << "\": " << why;
return result;
@@ -113,7 +126,7 @@ QString msgArgumentRemovalFailed(const AbstractMetaFunction *func, int n,
QString result;
QTextStream str(&result);
str << "Unable to remove argument " << n << " of ";
- if (auto *c = func->ownerClass())
+ if (auto c = func->ownerClass())
str << c->name() << "::";
str << func->signature() << ": " << why;
return result;
@@ -126,7 +139,7 @@ static void msgFormatEnumType(Stream &str,
{
switch (enumItem->enumKind()) {
case CEnum:
- str << "Enum '" << enumItem->qualifiedName().join(colonColon()) << '\'';
+ str << "Enum '" << enumItem->qualifiedName().join(u"::"_s) << '\'';
break;
case AnonymousEnum: {
const EnumeratorList &values = enumItem->enumerators();
@@ -149,7 +162,7 @@ static void msgFormatEnumType(Stream &str,
}
break;
case EnumClass:
- str << "Scoped enum '" << enumItem->qualifiedName().join(colonColon()) << '\'';
+ str << "Scoped enum '" << enumItem->qualifiedName().join(u"::"_s) << '\'';
break;
}
if (!className.isEmpty())
@@ -157,7 +170,7 @@ static void msgFormatEnumType(Stream &str,
}
static void formatAddedFuncError(const QString &addedFuncName,
- const AbstractMetaClass *context,
+ const AbstractMetaClassCPtr &context,
QTextStream &str)
{
if (context) {
@@ -173,12 +186,12 @@ static void formatAddedFuncError(const QString &addedFuncName,
QString msgAddedFunctionInvalidArgType(const QString &addedFuncName,
const QStringList &typeName,
int pos, const QString &why,
- const AbstractMetaClass *context)
+ const AbstractMetaClassCPtr &context)
{
QString result;
QTextStream str(&result);
formatAddedFuncError(addedFuncName, context, str);
- str << "Unable to translate type \"" << typeName.join(colonColon())
+ str << "Unable to translate type \"" << typeName.join(u"::"_s)
<< "\" of argument " << pos << " of added function \""
<< addedFuncName << "\": " << why;
return result;
@@ -186,18 +199,18 @@ QString msgAddedFunctionInvalidArgType(const QString &addedFuncName,
QString msgAddedFunctionInvalidReturnType(const QString &addedFuncName,
const QStringList &typeName, const QString &why,
- const AbstractMetaClass *context)
+ const AbstractMetaClassCPtr &context)
{
QString result;
QTextStream str(&result);
formatAddedFuncError(addedFuncName, context, str);
- str << "Unable to translate return type \"" << typeName.join(colonColon())
+ str << "Unable to translate return type \"" << typeName.join(u"::"_s)
<< "\" of added function \"" << addedFuncName << "\": "
<< why;
return result;
}
-QString msgUnnamedArgumentDefaultExpression(const AbstractMetaClass *context,
+QString msgUnnamedArgumentDefaultExpression(const AbstractMetaClassCPtr &context,
int n, const QString &className,
const AbstractMetaFunction *f)
{
@@ -227,7 +240,8 @@ QString msgNoEnumTypeEntry(const EnumModelItem &enumItem,
QTextStream str(&result);
str << enumItem->sourceLocation();
msgFormatEnumType(str, enumItem, className);
- str << " does not have a type entry";
+ str << " does not have a type entry (type systems: "
+ << TypeDatabase::instance()->loadedTypeSystemNames() << ')';
return result;
}
@@ -251,7 +265,8 @@ QString msgNamespaceNoTypeEntry(const NamespaceModelItem &item,
QString result;
QTextStream str(&result);
str << item->sourceLocation() << "namespace '" << fullName
- << "' does not have a type entry";
+ << "' does not have a type entry (type systems: "
+ << TypeDatabase::instance()->loadedTypeSystemNames() << ')';
return result;
}
@@ -302,11 +317,13 @@ QString msgSkippingFunction(const FunctionModelItem &functionItem,
{
QString result;
QTextStream str(&result);
- str << functionItem->sourceLocation() << "skipping ";
- if (functionItem->isAbstract())
+ str << functionItem->sourceLocation() << "skipping "
+ << functionItem->accessPolicy() << ' ';
+ const bool isAbstract = functionItem->attributes().testFlag(FunctionAttribute::Abstract);
+ if (isAbstract)
str << "abstract ";
str << "function '" << signature << "', " << why;
- if (functionItem->isAbstract()) {
+ if (isAbstract) {
str << "\nThis will lead to compilation errors due to not "
"being able to instantiate the wrapper.";
}
@@ -324,7 +341,7 @@ QString msgShadowingFunction(const AbstractMetaFunction *f1,
return result;
}
-QString msgSignalOverloaded(const AbstractMetaClass *c,
+QString msgSignalOverloaded(const AbstractMetaClassCPtr &c,
const AbstractMetaFunction *f)
{
QString result;
@@ -339,8 +356,9 @@ QString msgSkippingField(const VariableModelItem &field, const QString &classNam
{
QString result;
QTextStream str(&result);
- str << field->sourceLocation() << "skipping field '" << className
- << "::" << field->name() << "' with unmatched type '" << type << '\'';
+ str << field->sourceLocation() << "skipping " << field->accessPolicy()
+ << " field '" << className << "::" << field->name()
+ << "' with unmatched type '" << type << '\'';
return result;
}
@@ -351,8 +369,14 @@ QString msgTypeNotDefined(const TypeEntryCPtr &entry)
{
QString result;
QTextStream str(&result);
+ const bool hasConfigCondition = entry->isComplex()
+ && std::static_pointer_cast<const ConfigurableTypeEntry>(entry)->hasConfigCondition();
str << entry->sourceLocation() << "type '" <<entry->qualifiedCppName()
- << "' is specified in typesystem, but not defined. " << msgCompilationError;
+ << "' is specified in typesystem, but not defined";
+ if (hasConfigCondition)
+ str << " (disabled by configuration?).";
+ else
+ str << ". " << msgCompilationError;
return result;
}
@@ -372,14 +396,15 @@ QString msgGlobalFunctionNotDefined(const FunctionTypeEntryCPtr &fte,
QString msgStrippingArgument(const FunctionModelItem &f, int i,
const QString &originalSignature,
- const ArgumentModelItem &arg)
+ const ArgumentModelItem &arg,
+ const QString &reason)
{
QString result;
QTextStream str(&result);
str << f->sourceLocation() << "Stripping argument #" << (i + 1) << " of "
<< originalSignature << " due to unmatched type \""
<< arg->type().toString() << "\" with default expression \""
- << arg->defaultValueExpression() << "\".";
+ << arg->defaultValueExpression() << "\": " << reason;
return result;
}
@@ -392,7 +417,7 @@ QString msgEnumNotDefined(const EnumTypeEntryCPtr &t)
return result;
}
-QString msgUnknownBase(const AbstractMetaClass *metaClass,
+QString msgUnknownBase(const AbstractMetaClassCPtr &metaClass,
const QString &baseClassName)
{
QString result;
@@ -402,7 +427,7 @@ QString msgUnknownBase(const AbstractMetaClass *metaClass,
return result;
}
-QString msgBaseNotInTypeSystem(const AbstractMetaClass *metaClass,
+QString msgBaseNotInTypeSystem(const AbstractMetaClassCPtr &metaClass,
const QString &baseClassName)
{
QString result;
@@ -456,6 +481,21 @@ QString msgCannotFindTypeEntryForSmartPointer(const QString &t, const QString &s
+ u"\" for instantiation of \""_s +smartPointerType + u"\"."_s;
}
+QString msgInheritTemplateIssue(const AbstractMetaClassPtr &subclass,
+ const TypeInfo &info,
+ const QString &what)
+{
+ return "While inheriting template "_L1 + subclass->name()
+ + " from "_L1 + info.toString() + ": "_L1 + what;
+}
+
+QString msgIgnoringTemplateParameter(const QString &typeName,
+ const char *why)
+{
+ return "Ignoring template parameter "_L1 + typeName +
+ ": "_L1 + QLatin1StringView(why);
+}
+
QString msgInvalidSmartPointerType(const TypeInfo &i)
{
return u"Invalid smart pointer type \""_s +i.toString() + u"\"."_s;
@@ -511,7 +551,7 @@ QString msgPropertyExists(const QString &className, const QString &name)
+ name + u"\" (defined by Q_PROPERTY)."_s;
}
-QString msgFunctionVisibilityModified(const AbstractMetaClass *c,
+QString msgFunctionVisibilityModified(const AbstractMetaClassCPtr &c,
const AbstractMetaFunction *f)
{
QString result;
@@ -521,7 +561,7 @@ QString msgFunctionVisibilityModified(const AbstractMetaClass *c,
return result;
}
-QString msgUsingMemberClassNotFound(const AbstractMetaClass *c,
+QString msgUsingMemberClassNotFound(const AbstractMetaClassCPtr &c,
const QString &baseClassName,
const QString &memberName)
{
@@ -587,23 +627,25 @@ QString msgFallbackForDocumentation(const QString &fileName,
}
QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaEnum &e,
const QString &query)
{
- return msgCannotFindDocumentation(fileName, "enum",
- metaClass->name() + u"::"_s + e.name(),
- query);
+ QString name = e.name();
+ if (metaClass != nullptr)
+ name.prepend(metaClass->name() + "::"_L1);
+ return msgCannotFindDocumentation(fileName, "enum", name, query);
}
QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaField &f,
const QString &query)
{
- return msgCannotFindDocumentation(fileName, "field",
- metaClass->name() + u"::"_s + f.name(),
- query);
+ QString name = f.name();
+ if (metaClass != nullptr)
+ name.prepend(metaClass->name() + "::"_L1);
+ return msgCannotFindDocumentation(fileName, "field", name, query);
}
QString msgXpathDocModificationError(const DocModificationList& mods,
@@ -631,13 +673,13 @@ QString msgXpathDocModificationError(const DocModificationList& mods,
QString msgCannotOpenForReading(const QFile &f)
{
- return QStringLiteral("Failed to open file '%1' for reading: %2")
+ return QString::fromLatin1("Failed to open file '%1' for reading: %2")
.arg(QDir::toNativeSeparators(f.fileName()), f.errorString());
}
QString msgCannotOpenForWriting(const QFile &f)
{
- return QStringLiteral("Failed to open file '%1' for writing: %2")
+ return QString::fromLatin1("Failed to open file '%1' for writing: %2")
.arg(QDir::toNativeSeparators(f.fileName()), f.errorString());
}
@@ -659,23 +701,6 @@ QString msgCannotUseEnumAsInt(const QString &name)
"Compilation errors may occur when used as a function argument."_s;
}
-QString msgConversionTypesDiffer(const QString &varType, const QString &conversionType)
-{
- QString result;
- QTextStream str(&result);
- str << "Types of receiver variable ('" << varType
- << "') and %%CONVERTTOCPP type system variable ('" << conversionType
- << "') differ";
- QString strippedVarType = varType;
- QString strippedConversionType = conversionType;
- TypeInfo::stripQualifiers(&strippedVarType);
- TypeInfo::stripQualifiers(&strippedConversionType);
- if (strippedVarType == strippedConversionType)
- str << " in qualifiers. Please make sure the type is a distinct token";
- str << '.';
- return result;
-}
-
QString msgCannotFindSmartPointerGetter(const SmartPointerTypeEntryCPtr &te)
{
return u"Getter \""_s + te->getter() + u"()\" of smart pointer \""_s
@@ -688,7 +713,7 @@ QString msgCannotFindSmartPointerMethod(const SmartPointerTypeEntryCPtr &te, con
+ te->name() + u"\" not found."_s;
}
-QString msgMethodNotFound(const AbstractMetaClass *klass, const QString &name)
+QString msgMethodNotFound(const AbstractMetaClassCPtr &klass, const QString &name)
{
return u"Method \""_s + name + u"\" not found in class "_s
+ klass->name() + u'.';
@@ -696,18 +721,12 @@ QString msgMethodNotFound(const AbstractMetaClass *klass, const QString &name)
// main.cpp
-QString msgLeftOverArguments(const QVariantMap &remainingArgs)
+QString msgLeftOverArguments(const QString &remainingArgs, const QStringList &argV)
{
QString message;
QTextStream str(&message);
- str << "shiboken: Called with wrong arguments:";
- for (auto it = remainingArgs.cbegin(), end = remainingArgs.cend(); it != end; ++it) {
- str << ' ' << it.key();
- const QString value = it.value().toString();
- if (!value.isEmpty())
- str << ' ' << value;
- }
- str << "\nCommand line: " << QCoreApplication::arguments().join(u' ');
+ str << "shiboken: Unprocessed arguments: " << remainingArgs
+ << "\nCommand line: " << argV.join(u' ');
return message;
}
@@ -734,7 +753,7 @@ QString msgCyclicDependency(const QString &funcName, const QString &graphName,
if (i)
str << ", \"";
str << involvedConversions.at(i)->signature() << '"';
- if (const AbstractMetaClass *c = involvedConversions.at(i)->implementingClass())
+ if (const auto c = involvedConversions.at(i)->implementingClass())
str << '(' << c->name() << ')';
}
}
@@ -763,7 +782,7 @@ QString msgUnknownOperator(const AbstractMetaFunction *func)
{
QString result = u"Unknown operator: \""_s + func->originalName()
+ u'"';
- if (const AbstractMetaClass *c = func->implementingClass())
+ if (const auto c = func->implementingClass())
result += u" in class: "_s + c->name();
return result;
}
@@ -774,7 +793,7 @@ QString msgWrongIndex(const char *varName, const QString &capture,
QString result;
QTextStream str(&result);
str << "Wrong index for " << varName << " variable (" << capture << ") on ";
- if (const AbstractMetaClass *c = func->implementingClass())
+ if (const auto c = func->implementingClass())
str << c->name() << "::";
str << func->signature();
return result;
@@ -816,17 +835,17 @@ QString msgRejectReason(const TypeRejection &r, const QString &needle)
QTextStream str(&result);
switch (r.matchType) {
case TypeRejection::ExcludeClass:
- str << " matches class exclusion \"" << r.className.pattern() << '"';
+ str << "matches class exclusion \"" << r.className.pattern() << '"';
break;
case TypeRejection::Function:
case TypeRejection::Field:
case TypeRejection::Enum:
- str << " matches class \"" << r.className.pattern() << "\" and \""
+ str << "matches class \"" << r.className.pattern() << "\" and \""
<< r.pattern.pattern() << '"';
break;
case TypeRejection::ArgumentType:
case TypeRejection::ReturnType:
- str << " matches class \"" << r.className.pattern() << "\" and \""
+ str << "matches class \"" << r.className.pattern() << "\" and \""
<< needle << "\" matches \"" << r.pattern.pattern() << '"';
break;
}
@@ -879,6 +898,21 @@ QString msgCannotFindSnippet(const QString &file, const QString &snippetLabel)
return result;
}
+QString msgSnippetError(const QString &context, const char *what)
+{
+ return "Error processing code snippet of "_L1 + context
+ + ": "_L1 + QString::fromUtf8(what);
+}
+
+QString msgUnableToResolveTypedef(const QString &sourceType, const QString &sourceName)
+{
+ QString result;
+ QTextStream(&result) << "Unable to resolve typedef \"" << sourceType
+ << "\": Could not find a value, container, object or smart pointer type named \""
+ << sourceName << "\".";
+ return result;
+}
+
// cppgenerator.cpp
QString msgPureVirtualFunctionRemoved(const AbstractMetaFunction *f)
@@ -950,3 +984,14 @@ QString msgUnknownArrayPointerConversion(const QString &s)
return u"Warning: Falling back to pointer conversion for unknown array type \""_s
+ s + u"\""_s;
}
+
+QString msgMissingProjectFileMarker(const QString &name, const QByteArray &startMarker)
+{
+ return u"First line of project file \""_s + QDir::toNativeSeparators(name)
+ + u"\" must be the string \""_s + QString::fromLatin1(startMarker) + u"\"."_s;
+}
+
+QString msgInvalidLanguageLevel(const QString &l)
+{
+ return u"Invalid argument for language level: \""_s + l + u"\"."_s;
+}
diff --git a/sources/shiboken6/ApiExtractor/messages.h b/sources/shiboken6/ApiExtractor/messages.h
index 17255f717..e3f582b49 100644
--- a/sources/shiboken6/ApiExtractor/messages.h
+++ b/sources/shiboken6/ApiExtractor/messages.h
@@ -25,19 +25,19 @@ QT_FORWARD_DECLARE_CLASS(QXmlStreamReader)
QString msgAddedFunctionInvalidArgType(const QString &addedFuncName,
const QStringList &typeName,
int pos, const QString &why,
- const AbstractMetaClass *context = nullptr);
+ const AbstractMetaClassCPtr &context = {});
QString msgAddedFunctionInvalidReturnType(const QString &addedFuncName,
const QStringList &typeName, const QString &why,
- const AbstractMetaClass *context = nullptr);
+ const AbstractMetaClassCPtr &context = {});
-QString msgUnnamedArgumentDefaultExpression(const AbstractMetaClass *context,
+QString msgUnnamedArgumentDefaultExpression(const AbstractMetaClassCPtr &context,
int n, const QString &className,
const AbstractMetaFunction *f);
QString msgArgumentIndexOutOfRange(const AbstractMetaFunction *func, int index);
-QString msgNoFunctionForModification(const AbstractMetaClass *klass,
+QString msgNoFunctionForModification(const AbstractMetaClassCPtr &klass,
const QString &signature,
const QString &originalSignature,
const QStringList &possibleSignatures,
@@ -82,7 +82,7 @@ QString msgUnmatchedReturnType(const FunctionModelItem &functionItem,
QString msgShadowingFunction(const AbstractMetaFunction *f1,
const AbstractMetaFunction *f2);
-QString msgSignalOverloaded(const AbstractMetaClass *c,
+QString msgSignalOverloaded(const AbstractMetaClassCPtr &c,
const AbstractMetaFunction *f);
QString msgSkippingFunction(const FunctionModelItem &functionItem,
@@ -99,14 +99,15 @@ QString msgGlobalFunctionNotDefined(const FunctionTypeEntryCPtr &fte,
QString msgStrippingArgument(const FunctionModelItem &f, int i,
const QString &originalSignature,
- const ArgumentModelItem &arg);
+ const ArgumentModelItem &arg,
+ const QString &reason);
QString msgEnumNotDefined(const EnumTypeEntryCPtr &t);
-QString msgUnknownBase(const AbstractMetaClass *metaClass,
+QString msgUnknownBase(const AbstractMetaClassCPtr &metaClass,
const QString &baseClassName);
-QString msgBaseNotInTypeSystem(const AbstractMetaClass *metaClass,
+QString msgBaseNotInTypeSystem(const AbstractMetaClassCPtr &metaClass,
const QString &baseClassName);
QString msgArrayModificationFailed(const FunctionModelItem &functionItem,
@@ -125,6 +126,10 @@ QString msgUnableToTranslateType(const TypeInfo &typeInfo,
QString msgCannotFindTypeEntry(const QString &t);
QString msgCannotFindTypeEntryForSmartPointer(const QString &t, const QString &smartPointerType);
+QString msgInheritTemplateIssue(const AbstractMetaClassPtr &subclass,
+ const TypeInfo &info, const QString &what);
+QString msgIgnoringTemplateParameter(const QString &typeName,
+ const char *why);
QString msgInvalidSmartPointerType(const TypeInfo &i);
QString msgCannotFindSmartPointerInstantion(const TypeInfo &i);
@@ -140,10 +145,10 @@ QString msgPropertyTypeParsingFailed(const QString &name, const QString &typeNam
const QString &why);
QString msgPropertyExists(const QString &className, const QString &name);
-QString msgFunctionVisibilityModified(const AbstractMetaClass *c,
+QString msgFunctionVisibilityModified(const AbstractMetaClassCPtr &c,
const AbstractMetaFunction *f);
-QString msgUsingMemberClassNotFound(const AbstractMetaClass *c,
+QString msgUsingMemberClassNotFound(const AbstractMetaClassCPtr &c,
const QString &baseClassName,
const QString &memberName);
@@ -164,12 +169,12 @@ QString msgFallbackForDocumentation(const QString &fileName,
const QString &query = {});
QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaEnum &e,
const QString &query = {});
QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaField &f,
const QString &query);
@@ -184,15 +189,13 @@ QString msgWriteFailed(const QFile &f, qsizetype size);
QString msgCannotUseEnumAsInt(const QString &name);
-QString msgConversionTypesDiffer(const QString &varType, const QString &conversionType);
-
QString msgCannotFindSmartPointerGetter(const SmartPointerTypeEntryCPtr &);
QString msgCannotFindSmartPointerMethod(const SmartPointerTypeEntryCPtr &te, const QString &m);
-QString msgMethodNotFound(const AbstractMetaClass *klass, const QString &name);
+QString msgMethodNotFound(const AbstractMetaClassCPtr &klass, const QString &name);
-QString msgLeftOverArguments(const QVariantMap &remainingArgs);
+QString msgLeftOverArguments(const QString &remainingArgs, const QStringList &argV);
QString msgInvalidVersion(const QString &package, const QString &version);
@@ -210,6 +213,8 @@ QString msgIncorrectlyNestedName(const QString &name);
QString msgCannotFindView(const QString &viewedName, const QString &name);
QString msgCannotFindSnippet(const QString &file, const QString &snippetLabel);
+QString msgSnippetError(const QString &context, const char *what);
+QString msgUnableToResolveTypedef(const QString &sourceType, const QString &sourceName);
QString msgCyclicDependency(const QString &funcName, const QString &graphName,
const AbstractMetaFunctionCList &cyclic,
@@ -252,4 +257,8 @@ QString msgMissingCustomConversion(const TypeEntryCPtr &t);
QString msgUnknownArrayPointerConversion(const QString &s);
+QString msgMissingProjectFileMarker(const QString &name, const QByteArray &startMarker);
+
+QString msgInvalidLanguageLevel(const QString &l);
+
#endif // MESSAGES_H
diff --git a/sources/shiboken6/ApiExtractor/modifications.cpp b/sources/shiboken6/ApiExtractor/modifications.cpp
index d42cfb460..d876e8035 100644
--- a/sources/shiboken6/ApiExtractor/modifications.cpp
+++ b/sources/shiboken6/ApiExtractor/modifications.cpp
@@ -14,20 +14,6 @@
using namespace Qt::StringLiterals;
-// ---------------------- Modification
-QString FunctionModification::accessModifierString() const
-{
- if (isPrivate())
- return u"private"_s;
- if (isProtected())
- return u"protected"_s;
- if (isPublic())
- return u"public"_s;
- if (isFriendly())
- return u"friendly"_s;
- return QString();
-}
-
// ---------------------- FieldModification
class FieldModificationData : public QSharedData
@@ -48,8 +34,8 @@ FieldModification::FieldModification() : d(new FieldModificationData)
FieldModification::FieldModification(const FieldModification &) = default;
FieldModification &FieldModification::operator=(const FieldModification &) = default;
-FieldModification::FieldModification(FieldModification &&) = default;
-FieldModification &FieldModification::operator=(FieldModification &&) = default;
+FieldModification::FieldModification(FieldModification &&) noexcept = default;
+FieldModification &FieldModification::operator=(FieldModification &&) noexcept = default;
FieldModification::~FieldModification() = default;
QString FieldModification::name() const
@@ -188,7 +174,7 @@ QDebug operator<<(QDebug d, const CodeSnip &s)
if (i)
d << ", ";
d << '#' << i << ' ';
- if (f.instance().isNull()) {
+ if (!f.instance()) {
d << '"';
const QString &code = f.code();
const auto lines = QStringView{code}.split(u'\n');
@@ -241,8 +227,8 @@ ArgumentModification::ArgumentModification(int idx) : d(new ArgumentModification
ArgumentModification::ArgumentModification(const ArgumentModification &) = default;
ArgumentModification &ArgumentModification::operator=(const ArgumentModification &) = default;
-ArgumentModification::ArgumentModification(ArgumentModification &&) = default;
-ArgumentModification &ArgumentModification::operator=(ArgumentModification &&) = default;
+ArgumentModification::ArgumentModification(ArgumentModification &&) noexcept = default;
+ArgumentModification &ArgumentModification::operator=(ArgumentModification &&) noexcept = default;
ArgumentModification::~ArgumentModification() = default;
const QString &ArgumentModification::modifiedType() const
@@ -423,7 +409,6 @@ public:
QString m_originalSignature;
QRegularExpression m_signaturePattern;
int m_overloadNumber = TypeSystem::OverloadNumberUnset;
- bool m_thread = false;
bool removed = false;
TypeSystem::AllowThread m_allowThread = TypeSystem::AllowThread::Unspecified;
TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
@@ -436,8 +421,8 @@ FunctionModification::FunctionModification() : d(new FunctionModificationData)
FunctionModification::FunctionModification(const FunctionModification &) = default;
FunctionModification &FunctionModification::operator=(const FunctionModification &) = default;
-FunctionModification::FunctionModification(FunctionModification &&) = default;
-FunctionModification &FunctionModification::operator=(FunctionModification &&) = default;
+FunctionModification::FunctionModification(FunctionModification &&) noexcept = default;
+FunctionModification &FunctionModification::operator=(FunctionModification &&) noexcept = default;
FunctionModification::~FunctionModification() = default;
void FunctionModification::formatDebug(QDebug &debug) const
@@ -453,8 +438,6 @@ void FunctionModification::formatDebug(QDebug &debug) const
debug << ", renamedToName=\"" << d->renamedToName << '"';
if (d->m_allowThread != TypeSystem::AllowThread::Unspecified)
debug << ", allowThread=" << int(d->m_allowThread);
- if (d->m_thread)
- debug << ", thread";
if (d->m_exceptionHandling != TypeSystem::ExceptionHandling::Unspecified)
debug << ", exceptionHandling=" << int(d->m_exceptionHandling);
if (!d->m_snips.isEmpty())
@@ -557,17 +540,6 @@ void FunctionModification::setSnips(const CodeSnipList &snips)
}
// ---------------------- FunctionModification
-void FunctionModification::setIsThread(bool flag)
-{
- if (d->m_thread != flag)
- d->m_thread = flag;
-}
-
-bool FunctionModification::isThread() const
-{
- return d->m_thread;
-}
-
FunctionModification::AllowThread FunctionModification::allowThread() const
{
return d->m_allowThread;
diff --git a/sources/shiboken6/ApiExtractor/modifications.h b/sources/shiboken6/ApiExtractor/modifications.h
index 65ed81ff8..27a38f1aa 100644
--- a/sources/shiboken6/ApiExtractor/modifications.h
+++ b/sources/shiboken6/ApiExtractor/modifications.h
@@ -64,8 +64,8 @@ public:
explicit ArgumentModification(int idx);
ArgumentModification(const ArgumentModification &);
ArgumentModification &operator=(const ArgumentModification &);
- ArgumentModification(ArgumentModification &&);
- ArgumentModification &operator=(ArgumentModification &&);
+ ArgumentModification(ArgumentModification &&) noexcept;
+ ArgumentModification &operator=(ArgumentModification &&) noexcept;
~ArgumentModification();
// Reference count flags for this argument
@@ -134,15 +134,14 @@ public:
FunctionModification();
FunctionModification(const FunctionModification &);
FunctionModification &operator=(const FunctionModification &);
- FunctionModification(FunctionModification &&);
- FunctionModification &operator=(FunctionModification &&);
+ FunctionModification(FunctionModification &&) noexcept;
+ FunctionModification &operator=(FunctionModification &&) noexcept;
~FunctionModification();
enum ModifierFlag {
Private = 0x0001,
Protected = 0x0002,
- Public = 0x0003,
- Friendly = 0x0004,
+ Public = 0x0004,
AccessModifierMask = 0x000f,
Final = 0x0010,
@@ -155,7 +154,8 @@ public:
CodeInjection = 0x1000,
Rename = 0x2000,
Deprecated = 0x4000,
- ReplaceExpression = 0x8000
+ Undeprecated = 0x8000,
+ ReplaceExpression = 0x10000
};
Q_DECLARE_FLAGS(Modifiers, ModifierFlag);
@@ -190,10 +190,6 @@ public:
{
return accessModifier() == Public;
}
- bool isFriendly() const
- {
- return accessModifier() == Friendly;
- }
bool isFinal() const
{
return modifiers().testFlag(Final);
@@ -202,7 +198,6 @@ public:
{
return modifiers().testFlag(NonFinal);
}
- QString accessModifierString() const;
bool isDeprecated() const
{
@@ -222,8 +217,6 @@ public:
{
return modifiers().testFlag(CodeInjection);
}
- void setIsThread(bool flag);
- bool isThread() const;
AllowThread allowThread() const;
void setAllowThread(AllowThread allow);
@@ -278,8 +271,8 @@ public:
FieldModification();
FieldModification(const FieldModification &);
FieldModification &operator=(const FieldModification &);
- FieldModification(FieldModification &&);
- FieldModification &operator=(FieldModification &&);
+ FieldModification(FieldModification &&) noexcept;
+ FieldModification &operator=(FieldModification &&) noexcept;
~FieldModification();
QString name() const;
diff --git a/sources/shiboken6/ApiExtractor/modifications_typedefs.h b/sources/shiboken6/ApiExtractor/modifications_typedefs.h
index c827335ab..3b86c55d3 100644
--- a/sources/shiboken6/ApiExtractor/modifications_typedefs.h
+++ b/sources/shiboken6/ApiExtractor/modifications_typedefs.h
@@ -5,7 +5,8 @@
#define MODIFICATIONS_TYPEDEFS_H
#include <QtCore/QList>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
class CodeSnip;
class DocModification;
@@ -14,7 +15,7 @@ struct AddedFunction;
class FieldModification;
class FunctionModification;
-using AddedFunctionPtr = QSharedPointer<AddedFunction>;
+using AddedFunctionPtr = std::shared_ptr<AddedFunction>;
using AddedFunctionList = QList<AddedFunctionPtr>;
using CodeSnipList = QList<CodeSnip>;
using DocModificationList = QList<DocModification>;
diff --git a/sources/shiboken6/ApiExtractor/optionsparser.cpp b/sources/shiboken6/ApiExtractor/optionsparser.cpp
new file mode 100644
index 000000000..f2e64c7e4
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/optionsparser.cpp
@@ -0,0 +1,232 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "optionsparser.h"
+#include "messages.h"
+#include "exception.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QTextStream>
+
+using namespace Qt::StringLiterals;
+
+template <class Stream> void formatBoolOption(Stream &s, const BoolOption &bo)
+{
+ switch (bo.source) {
+ case OptionSource::CommandLine:
+ s << "--";
+ break;
+ case OptionSource::CommandLineSingleDash:
+ s << '-';
+ break;
+ default:
+ break;
+ }
+ s << bo.option;
+ if (bo.source == OptionSource::ProjectFile)
+ s << " (project)";
+}
+
+template <class Stream> void formatOptionValue(Stream &s, const OptionValue &ov)
+{
+ switch (ov.source) {
+ case OptionSource::CommandLine:
+ s << "--";
+ break;
+ case OptionSource::CommandLineSingleDash:
+ s << '-';
+ break;
+ default:
+ break;
+ }
+ s << ov.option << '=' << ov.value;
+ if (ov.source == OptionSource::ProjectFile)
+ s << " (project)";
+}
+
+QTextStream &operator<<(QTextStream &s, const BoolOption &bo)
+{
+ formatBoolOption(s, bo);
+ return s;
+}
+
+QTextStream &operator<<(QTextStream &s, const OptionValue &ov)
+{
+ formatOptionValue(s, ov);
+ return s;
+}
+
+QDebug operator<<(QDebug debug, const BoolOption &bo)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ formatBoolOption(debug, bo);
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const OptionValue &v)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ formatOptionValue(debug, v);
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const Options &v)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "Options(";
+ if (!v.boolOptions.isEmpty())
+ debug << "bools=" << v.boolOptions;
+ if (!v.valueOptions.isEmpty())
+ debug << ", option values=" << v.valueOptions;
+ if (!v.positionalArguments.isEmpty())
+ debug << ", pos=" << v.positionalArguments;
+ debug << ')';
+ return debug;
+}
+
+QTextStream &operator<<(QTextStream &s, const OptionDescription &od)
+{
+ if (!od.name.startsWith(u'-'))
+ s << "--";
+ s << od.name;
+ if (od.description.isEmpty()) { // For formatting {{"-s", ""}, {"--short", "descr"}}
+ s << ", ";
+ } else {
+ s << '\n';
+ const auto lines = QStringView{od.description}.split(u'\n');
+ for (const auto &line : lines)
+ s << " " << line << '\n';
+ s << '\n';
+ }
+ return s;
+}
+
+QTextStream &operator<<(QTextStream &s, const OptionDescriptions &options)
+{
+ s.setFieldAlignment(QTextStream::AlignLeft);
+ for (const auto &od : options)
+ s << od;
+ return s;
+}
+
+OptionsParser::OptionsParser() noexcept = default;
+OptionsParser::~OptionsParser() = default;
+
+const QString &OptionsParser::pathSyntax()
+{
+ static const QString result =
+ u"<path>["_s + QDir::listSeparator() + u"<path>"_s
+ + QDir::listSeparator() + u"...]"_s;
+ return result;
+}
+
+bool OptionsParser::handleBoolOption(const QString &, OptionSource)
+{
+ return false;
+}
+
+bool OptionsParser::handleOption(const QString &, const QString &, OptionSource)
+{
+ return false;
+}
+
+void OptionsParser::process(Options *o)
+{
+ for (auto i = o->boolOptions.size() - 1; i >= 0; --i) {
+ const auto &opt = o->boolOptions.at(i);
+ if (handleBoolOption(opt.option, opt.source))
+ o->boolOptions.removeAt(i);
+ }
+ for (auto i = o->valueOptions.size() - 1; i >= 0; --i) {
+ const auto &opt = o->valueOptions.at(i);
+ if (handleOption(opt.option, opt.value, opt.source))
+ o->valueOptions.removeAt(i);
+ }
+}
+
+bool OptionsParserList::handleBoolOption(const QString &key, OptionSource source)
+{
+ for (const auto &p : std::as_const(m_parsers)) {
+ if (p->handleBoolOption(key, source))
+ return true;
+ }
+ return false;
+}
+
+bool OptionsParserList::handleOption(const QString &key, const QString &value, OptionSource source)
+{
+ for (const auto &p : std::as_const(m_parsers)) {
+ if (p->handleOption(key, value, source))
+ return true;
+ }
+ return false;
+}
+
+static void processOption(const QString &o, OptionSource source,
+ BoolOptions *bools, OptionValues *values)
+{
+ const auto equals = o.indexOf(u'=');
+ if (equals == -1) {
+ bools->append({o.trimmed(), source});
+ } else {
+ QString key = o.left(equals).trimmed();
+ QString value = o.mid(equals + 1).trimmed();
+ if (!value.isEmpty())
+ values->append({key, value, source});
+ }
+}
+
+static void readProjectFile(const QString &name, Options *o)
+{
+ const auto startMarker = "[generator-project]"_ba;
+
+ QFile file(name);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
+ throw Exception(msgCannotOpenForReading(file));
+
+ if (file.atEnd() || file.readLine().trimmed() != startMarker)
+ throw Exception(msgMissingProjectFileMarker(name, startMarker));
+
+ while (!file.atEnd()) {
+ const QByteArray lineB = file.readLine().trimmed();
+ if (!lineB.isEmpty() && !lineB.startsWith('#')) {
+ processOption(QString::fromUtf8(lineB), OptionSource::ProjectFile,
+ &o->boolOptions, &o->valueOptions);
+ }
+ }
+}
+
+void Options::setOptions(const QStringList &argv)
+{
+ const auto projectFileOption = "--project-file="_L1;
+ for (const auto &o : argv) {
+ if (o.startsWith(projectFileOption)) {
+ readProjectFile(o.sliced(projectFileOption.size()), this);
+ } else if (o.startsWith(u"--")) {
+ processOption(o.sliced(2), OptionSource::CommandLine,
+ &boolOptions, &valueOptions);
+ } else if (o.startsWith(u'-')) {
+ processOption(o.sliced(1), OptionSource::CommandLineSingleDash,
+ &boolOptions, &valueOptions);
+ } else {
+ positionalArguments.append(o);
+ }
+ }
+}
+
+QString Options::msgUnprocessedOptions() const
+{
+ QString result;
+ QTextStream str(&result);
+ for (const auto &b : boolOptions)
+ str << b << ' ';
+ for (const auto &v : valueOptions)
+ str << v << ' ';
+ return result.trimmed();
+}
diff --git a/sources/shiboken6/ApiExtractor/optionsparser.h b/sources/shiboken6/ApiExtractor/optionsparser.h
new file mode 100644
index 000000000..d5557dc15
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/optionsparser.h
@@ -0,0 +1,98 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef OPTIONSPARSER_H
+#define OPTIONSPARSER_H
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+#include <memory>
+
+QT_FORWARD_DECLARE_CLASS(QTextStream)
+
+enum class OptionSource
+{
+ CommandLine, // "--option"
+ CommandLineSingleDash, // "-o"
+ ProjectFile
+};
+
+struct BoolOption
+{
+ QString option;
+ OptionSource source = OptionSource::CommandLine;
+};
+
+struct OptionValue // --option=value pair
+{
+ QString option;
+ QString value;
+ OptionSource source = OptionSource::CommandLine;
+};
+
+using BoolOptions = QList<BoolOption>;
+using OptionValues = QList<OptionValue>;
+
+struct Options // Options from command line and project file
+{
+ void setOptions(const QStringList &argv);
+ QString msgUnprocessedOptions() const;
+
+ BoolOptions boolOptions;
+ OptionValues valueOptions;
+ QStringList positionalArguments;
+};
+
+struct OptionDescription // For help formatting
+{
+ QString name;
+ QString description;
+};
+
+using OptionDescriptions = QList<OptionDescription>;
+
+QTextStream &operator<<(QTextStream &s, const BoolOption &bo);
+QTextStream &operator<<(QTextStream &s, const OptionValue &ov);
+QTextStream &operator<<(QTextStream &s, const OptionDescription &od);
+QTextStream &operator<<(QTextStream &s, const OptionDescriptions &options);
+
+class OptionsParser
+{
+public:
+ Q_DISABLE_COPY_MOVE(OptionsParser)
+
+ virtual ~OptionsParser();
+
+ // Return true to indicate the option was processed.
+ virtual bool handleBoolOption(const QString &key, OptionSource source);
+ virtual bool handleOption(const QString &key, const QString &value, OptionSource source);
+
+ void process(Options *);
+
+ static const QString &pathSyntax();
+
+protected:
+ OptionsParser() noexcept;
+};
+
+class OptionsParserList : public OptionsParser
+{
+public:
+ using OptionsParserPtr = std::shared_ptr<OptionsParser>;
+
+ void append(const OptionsParserPtr &parser) { m_parsers.append(parser); }
+ void clear() { m_parsers.clear(); }
+
+ bool handleBoolOption(const QString &key, OptionSource source) override;
+ bool handleOption(const QString &key, const QString &value, OptionSource source) override;
+
+private:
+ QList<OptionsParserPtr> m_parsers;
+};
+
+QDebug operator<<(QDebug debug, const BoolOption &bo);
+QDebug operator<<(QDebug debug, const OptionValue &v);
+QDebug operator<<(QDebug debug, const Options &v);
+
+#endif // OPTIONSPARSER_H
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
index 8c6279ee6..259a706dc 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
@@ -6,33 +6,24 @@
#include "codemodel.h"
#include <sourcelocation.h>
+#include <debughelpers_p.h>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QRegularExpression>
#include <algorithm>
-#include <functional>
-#include <iostream>
using namespace Qt::StringLiterals;
-// Predicate to find an item by name in a list of QSharedPointer<Item>
-template <class T> class ModelItemNamePredicate
-{
-public:
- explicit ModelItemNamePredicate(const QString &name) : m_name(name) {}
- bool operator()(const QSharedPointer<T> &item) const { return item->name() == m_name; }
-
-private:
- const QString m_name;
-};
-
template <class T>
-static QSharedPointer<T> findModelItem(const QList<QSharedPointer<T> > &list, const QString &name)
+static std::shared_ptr<T> findModelItem(const QList<std::shared_ptr<T> > &list,
+ QAnyStringView name)
{
- const auto it = std::find_if(list.cbegin(), list.cend(), ModelItemNamePredicate<T>(name));
- return it != list.cend() ? *it : QSharedPointer<T>();
+ using ItemPtr = std::shared_ptr<T>;
+ auto pred = [name](const ItemPtr &item) { return item->name() == name; };
+ const auto it = std::find_if(list.cbegin(), list.cend(), pred);
+ return it != list.cend() ? *it : ItemPtr{};
}
// ---------------------------------------------------------------------------
@@ -53,7 +44,7 @@ void CodeModel::addFile(const FileModelItem &item)
m_files.append(item);
}
-FileModelItem CodeModel::findFile(const QString &name) const
+FileModelItem CodeModel::findFile(QAnyStringView name) const
{
return findModelItem(m_files, name);
}
@@ -71,11 +62,11 @@ static CodeModelItem findRecursion(const ScopeModelItem &scope,
return tp;
if (TemplateTypeAliasModelItem tta = scope->findTemplateTypeAlias(nameSegment))
return tta;
- return CodeModelItem();
+ return {};
}
if (auto nestedClass = scope->findClass(nameSegment))
return findRecursion(nestedClass, qualifiedName, segment + 1);
- if (auto namespaceItem = qSharedPointerDynamicCast<_NamespaceModelItem>(scope)) {
+ if (auto namespaceItem = std::dynamic_pointer_cast<_NamespaceModelItem>(scope)) {
for (const auto &nestedNamespace : namespaceItem->namespaces()) {
if (nestedNamespace->name() == nameSegment) {
if (auto item = findRecursion(nestedNamespace, qualifiedName, segment + 1))
@@ -83,7 +74,7 @@ static CodeModelItem findRecursion(const ScopeModelItem &scope,
}
}
}
- return CodeModelItem();
+ return {};
}
CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, const ScopeModelItem &scope)
@@ -120,7 +111,7 @@ QDebug operator<<(QDebug d, const CodeModel *m)
d << "CodeModel(";
if (m) {
const NamespaceModelItem globalNamespaceP = m->globalNamespace();
- if (globalNamespaceP.data())
+ if (globalNamespaceP)
globalNamespaceP->formatDebug(d);
} else {
d << '0';
@@ -243,27 +234,17 @@ void _CodeModelItem::setEnclosingScope(const _ScopeModelItem *s)
m_enclosingScope = s;
}
-#ifndef QT_NO_DEBUG_STREAM
-template <class It>
-void formatSequence(QDebug &d, It i1, It i2, const char *separator=", ")
+_ScopeModelItem::_ScopeModelItem(CodeModel *model, int kind)
+ : _CodeModelItem(model, kind)
{
- for (It i = i1; i != i2; ++i) {
- if (i != i1)
- d << separator;
- d << *i;
- }
}
-template <class It>
-static void formatPtrSequence(QDebug &d, It i1, It i2, const char *separator=", ")
+_ScopeModelItem::_ScopeModelItem(CodeModel *model, const QString &name, int kind)
+ : _CodeModelItem(model, name, kind)
{
- for (It i = i1; i != i2; ++i) {
- if (i != i1)
- d << separator;
- d << i->data();
- }
}
+#ifndef QT_NO_DEBUG_STREAM
void _CodeModelItem::formatKind(QDebug &d, int k)
{
switch (k) {
@@ -373,6 +354,16 @@ bool _ClassModelItem::extendsClass(const QString &name) const
return false;
}
+_ClassModelItem::_ClassModelItem(CodeModel *model, int kind)
+ : _ScopeModelItem(model, kind)
+{
+}
+
+_ClassModelItem::_ClassModelItem(CodeModel *model, const QString &name, int kind)
+ : _ScopeModelItem(model, name, kind)
+{
+}
+
const QList<_ClassModelItem::UsingMember> &_ClassModelItem::usingMembers() const
{
return m_usingMembers;
@@ -458,7 +449,7 @@ FunctionModelItem _ScopeModelItem::declaredFunction(const FunctionModelItem &ite
return fun;
}
- return FunctionModelItem();
+ return {};
}
_ScopeModelItem::~_ScopeModelItem() = default;
@@ -627,52 +618,46 @@ void _ScopeModelItem::formatDebug(QDebug &d) const
}
#endif // !QT_NO_DEBUG_STREAM
-namespace {
// Predicate to match a non-template class name against the class list.
// "Vector" should match "Vector" as well as "Vector<T>" (as seen for methods
// from within the class "Vector").
-class ClassNamePredicate
+static bool matchClassNameNonTemplatePart(const ClassModelItem &item, const QString &name)
{
-public:
- explicit ClassNamePredicate(const QString &name) : m_name(name) {}
- bool operator()(const ClassModelItem &item) const
- {
- const QString &itemName = item->name();
- if (!itemName.startsWith(m_name))
- return false;
- return itemName.size() == m_name.size() || itemName.at(m_name.size()) == u'<';
- }
-
-private:
- const QString m_name;
-};
-} // namespace
+ const QString &itemName = item->name();
+ if (!itemName.startsWith(name))
+ return false;
+ return itemName.size() == name.size() || itemName.at(name.size()) == u'<';
+}
ClassModelItem _ScopeModelItem::findClass(const QString &name) const
{
// A fully qualified template is matched by name only
const ClassList::const_iterator it = name.contains(u'<')
- ? std::find_if(m_classes.begin(), m_classes.end(), ModelItemNamePredicate<_ClassModelItem>(name))
- : std::find_if(m_classes.begin(), m_classes.end(), ClassNamePredicate(name));
+ ? std::find_if(m_classes.begin(), m_classes.end(),
+ [&name](const ClassModelItem &item) {
+ return item->name() == name; })
+ : std::find_if(m_classes.begin(), m_classes.end(),
+ [&name](const ClassModelItem &item) {
+ return matchClassNameNonTemplatePart(item, name); });
return it != m_classes.end() ? *it : ClassModelItem();
}
-VariableModelItem _ScopeModelItem::findVariable(const QString &name) const
+VariableModelItem _ScopeModelItem::findVariable(QAnyStringView name) const
{
return findModelItem(m_variables, name);
}
-TypeDefModelItem _ScopeModelItem::findTypeDef(const QString &name) const
+TypeDefModelItem _ScopeModelItem::findTypeDef(QAnyStringView name) const
{
return findModelItem(m_typeDefs, name);
}
-TemplateTypeAliasModelItem _ScopeModelItem::findTemplateTypeAlias(const QString &name) const
+TemplateTypeAliasModelItem _ScopeModelItem::findTemplateTypeAlias(QAnyStringView name) const
{
return findModelItem(m_templateTypeAliases, name);
}
-EnumModelItem _ScopeModelItem::findEnum(const QString &name) const
+EnumModelItem _ScopeModelItem::findEnum(QAnyStringView name) const
{
return findModelItem(m_enums, name);
}
@@ -724,8 +709,8 @@ _ScopeModelItem::FindEnumByValueReturn
if (searchSiblingNamespaces && scope->kind() == Kind_Namespace) {
if (auto *enclosingNamespace = dynamic_cast<const _NamespaceModelItem *>(enclosingScope)) {
for (const auto &sibling : enclosingNamespace->namespaces()) {
- if (sibling.data() != scope && sibling->name() == scope->name()) {
- if (const auto e = findEnumByValueRecursion(sibling.data(),
+ if (sibling.get() != scope && sibling->name() == scope->name()) {
+ if (const auto e = findEnumByValueRecursion(sibling.get(),
fullValue, enumValue, false)) {
return e;
}
@@ -741,8 +726,8 @@ _ScopeModelItem::FindEnumByValueReturn
// PYSIDE-331: We need to also search the base classes.
if (auto *classItem = dynamic_cast<const _ClassModelItem *>(scope)) {
for (const auto &base : classItem->baseClasses()) {
- if (!base.klass.isNull()) {
- auto *c = base.klass.data();
+ if (base.klass) {
+ auto *c = base.klass.get();
if (const auto e = findEnumByValueRecursion(c, fullValue, enumValue))
return e;
}
@@ -761,7 +746,7 @@ _ScopeModelItem::FindEnumByValueReturn
return findEnumByValueRecursion(this, value, enumValue);
}
-FunctionList _ScopeModelItem::findFunctions(const QString &name) const
+FunctionList _ScopeModelItem::findFunctions(QAnyStringView name) const
{
FunctionList result;
for (const FunctionModelItem &func : m_functions) {
@@ -772,17 +757,25 @@ FunctionList _ScopeModelItem::findFunctions(const QString &name) const
}
// ---------------------------------------------------------------------------
-_NamespaceModelItem::~_NamespaceModelItem()
+_NamespaceModelItem::_NamespaceModelItem(CodeModel *model, int kind)
+ : _ScopeModelItem(model, kind)
{
}
+_NamespaceModelItem::_NamespaceModelItem(CodeModel *model, const QString &name, int kind)
+ : _ScopeModelItem(model, name, kind)
+{
+}
+
+_NamespaceModelItem::~_NamespaceModelItem() = default;
+
void _NamespaceModelItem::addNamespace(NamespaceModelItem item)
{
item->setEnclosingScope(this);
m_namespaces.append(item);
}
-NamespaceModelItem _NamespaceModelItem::findNamespace(const QString &name) const
+NamespaceModelItem _NamespaceModelItem::findNamespace(QAnyStringView name) const
{
return findModelItem(m_namespaces, name);
}
@@ -814,10 +807,18 @@ void _NamespaceModelItem::formatDebug(QDebug &d) const
#endif // !QT_NO_DEBUG_STREAM
// ---------------------------------------------------------------------------
-_ArgumentModelItem::~_ArgumentModelItem()
+_ArgumentModelItem::_ArgumentModelItem(CodeModel *model, int kind)
+ : _CodeModelItem(model, kind)
{
}
+_ArgumentModelItem::_ArgumentModelItem(CodeModel *model, const QString &name, int kind)
+ : _CodeModelItem(model, name, kind)
+{
+}
+
+_ArgumentModelItem::~_ArgumentModelItem() = default;
+
TypeInfo _ArgumentModelItem::type() const
{
return m_type;
@@ -838,11 +839,23 @@ void _ArgumentModelItem::setDefaultValue(bool defaultValue)
m_defaultValue = defaultValue;
}
+bool _ArgumentModelItem::scopeResolution() const
+{
+ return m_scopeResolution;
+}
+
+void _ArgumentModelItem::setScopeResolution(bool v)
+{
+ m_scopeResolution = v;
+}
+
#ifndef QT_NO_DEBUG_STREAM
void _ArgumentModelItem::formatDebug(QDebug &d) const
{
_CodeModelItem::formatDebug(d);
d << ", type=" << m_type;
+ if (m_scopeResolution)
+ d << ", [m_scope resolution]";
if (m_defaultValue)
d << ", defaultValue=\"" << m_defaultValueExpression << '"';
}
@@ -877,6 +890,16 @@ bool _FunctionModelItem::isSimilar(const FunctionModelItem &other) const
return true;
}
+_FunctionModelItem::_FunctionModelItem(CodeModel *model, int kind)
+ : _MemberModelItem(model, kind), m_flags(0)
+{
+}
+
+_FunctionModelItem::_FunctionModelItem(CodeModel *model, const QString &name, int kind)
+ : _MemberModelItem(model, name, kind), m_flags(0)
+{
+}
+
ArgumentList _FunctionModelItem::arguments() const
{
return m_arguments;
@@ -907,6 +930,16 @@ void _FunctionModelItem::setVariadics(bool isVariadics)
m_isVariadics = isVariadics;
}
+bool _FunctionModelItem::scopeResolution() const
+{
+ return m_scopeResolution;
+}
+
+void _FunctionModelItem::setScopeResolution(bool v)
+{
+ m_scopeResolution = v;
+}
+
bool _FunctionModelItem::isDefaultConstructor() const
{
return m_functionType == CodeModel::Constructor
@@ -969,66 +1002,16 @@ void _FunctionModelItem::setDeleted(bool d)
m_isDeleted = d;
}
-bool _FunctionModelItem::isDeprecated() const
-{
- return m_isDeprecated;
-}
-
-void _FunctionModelItem::setDeprecated(bool d)
-{
- m_isDeprecated = d;
-}
-
-bool _FunctionModelItem::isVirtual() const
-{
- return m_isVirtual;
-}
-
-void _FunctionModelItem::setVirtual(bool isVirtual)
-{
- m_isVirtual = isVirtual;
-}
-
bool _FunctionModelItem::isInline() const
{
return m_isInline;
}
-bool _FunctionModelItem::isOverride() const
-{
- return m_isOverride;
-}
-
-void _FunctionModelItem::setOverride(bool o)
-{
- m_isOverride = o;
-}
-
-bool _FunctionModelItem::isFinal() const
-{
- return m_isFinal;
-}
-
-void _FunctionModelItem::setFinal(bool f)
-{
- m_isFinal = f;
-}
-
void _FunctionModelItem::setInline(bool isInline)
{
m_isInline = isInline;
}
-bool _FunctionModelItem::isExplicit() const
-{
- return m_isExplicit;
-}
-
-void _FunctionModelItem::setExplicit(bool isExplicit)
-{
- m_isExplicit = isExplicit;
-}
-
bool _FunctionModelItem::isHiddenFriend() const
{
return m_isHiddenFriend;
@@ -1039,27 +1022,6 @@ void _FunctionModelItem::setHiddenFriend(bool f)
m_isHiddenFriend = f;
}
-bool _FunctionModelItem::isAbstract() const
-{
- return m_isAbstract;
-}
-
-void _FunctionModelItem::setAbstract(bool isAbstract)
-{
- m_isAbstract = isAbstract;
-}
-
-// Qt
-bool _FunctionModelItem::isInvokable() const
-{
- return m_isInvokable;
-}
-
-void _FunctionModelItem::setInvokable(bool isInvokable)
-{
- m_isInvokable = isInvokable;
-}
-
QString _FunctionModelItem::typeSystemSignature() const // For dumping out type system files
{
QString result;
@@ -1184,20 +1146,22 @@ void _FunctionModelItem::formatDebug(QDebug &d) const
d << " [deleted!]";
if (m_isInline)
d << " [inline]";
- if (m_isVirtual)
+ if (m_attributes.testFlag(FunctionAttribute::Virtual))
d << " [virtual]";
- if (m_isOverride)
+ if (m_attributes.testFlag(FunctionAttribute::Override))
d << " [override]";
- if (m_isDeprecated)
+ if (m_attributes.testFlag(FunctionAttribute::Deprecated))
d << " [deprecated]";
- if (m_isFinal)
+ if (m_attributes.testFlag(FunctionAttribute::Final))
d << " [final]";
- if (m_isAbstract)
+ if (m_attributes.testFlag(FunctionAttribute::Abstract))
d << " [abstract]";
- if (m_isExplicit)
+ if (m_attributes.testFlag(FunctionAttribute::Explicit))
d << " [explicit]";
if (m_isInvokable)
d << " [invokable]";
+ if (m_scopeResolution)
+ d << " [scope resolution]";
formatModelItemList(d, ", arguments=", m_arguments);
if (m_isVariadics)
d << ",...";
@@ -1205,6 +1169,16 @@ void _FunctionModelItem::formatDebug(QDebug &d) const
#endif // !QT_NO_DEBUG_STREAM
// ---------------------------------------------------------------------------
+_TypeDefModelItem::_TypeDefModelItem(CodeModel *model, int kind)
+ : _CodeModelItem(model, kind)
+{
+}
+
+_TypeDefModelItem::_TypeDefModelItem(CodeModel *model, const QString &name, int kind)
+ : _CodeModelItem(model, name, kind)
+{
+}
+
TypeInfo _TypeDefModelItem::type() const
{
return m_type;
@@ -1266,6 +1240,16 @@ void _TemplateTypeAliasModelItem::formatDebug(QDebug &d) const
#endif // !QT_NO_DEBUG_STREAM
// ---------------------------------------------------------------------------
+_EnumModelItem::_EnumModelItem(CodeModel *model, const QString &name, int kind)
+ : _CodeModelItem(model, name, kind)
+{
+}
+
+_EnumModelItem::_EnumModelItem(CodeModel *model, int kind)
+ : _CodeModelItem(model, kind)
+{
+}
+
Access _EnumModelItem::accessPolicy() const
{
return m_accessPolicy;
@@ -1307,6 +1291,16 @@ void _EnumModelItem::setSigned(bool s)
m_signed = s;
}
+QString _EnumModelItem::underlyingType() const
+{
+ return m_underlyingType;
+}
+
+void _EnumModelItem::setUnderlyingType(const QString &underlyingType)
+{
+ m_underlyingType = underlyingType;
+}
+
bool _EnumModelItem::isDeprecated() const
{
return m_deprecated;
@@ -1342,6 +1336,16 @@ void _EnumModelItem::formatDebug(QDebug &d) const
// ---------------------------------------------------------------------------
_EnumeratorModelItem::~_EnumeratorModelItem() = default;
+_EnumeratorModelItem::_EnumeratorModelItem(CodeModel *model, int kind)
+ : _CodeModelItem(model, kind)
+{
+}
+
+_EnumeratorModelItem::_EnumeratorModelItem(CodeModel *model, const QString &name, int kind)
+ : _CodeModelItem(model, name, kind)
+{
+}
+
QString _EnumeratorModelItem::stringValue() const
{
return m_stringValue;
@@ -1375,6 +1379,17 @@ void _EnumeratorModelItem::formatDebug(QDebug &d) const
// ---------------------------------------------------------------------------
_TemplateParameterModelItem::~_TemplateParameterModelItem() = default;
+_TemplateParameterModelItem::_TemplateParameterModelItem(CodeModel *model, int kind)
+ : _CodeModelItem(model, kind)
+{
+}
+
+_TemplateParameterModelItem::_TemplateParameterModelItem(CodeModel *model,
+ const QString &name, int kind)
+ : _CodeModelItem(model, name, kind)
+{
+}
+
TypeInfo _TemplateParameterModelItem::type() const
{
return m_type;
@@ -1438,6 +1453,16 @@ void _MemberModelItem::setStatic(bool isStatic)
m_isStatic = isStatic;
}
+_MemberModelItem::_MemberModelItem(CodeModel *model, int kind)
+ : _CodeModelItem(model, kind), m_flags(0)
+{
+}
+
+_MemberModelItem::_MemberModelItem(CodeModel *model, const QString &name, int kind)
+ : _CodeModelItem(model, name, kind), m_flags(0)
+{
+}
+
bool _MemberModelItem::isConstant() const
{
return m_isConstant;
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel.h b/sources/shiboken6/ApiExtractor/parser/codemodel.h
index 97a851995..b31c09163 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel.h
@@ -12,7 +12,6 @@
#include "typeinfo.h"
#include <QtCore/QHash>
-#include <QtCore/QPair>
#include <QtCore/QSet>
#include <QtCore/QString>
#include <QtCore/QStringList>
@@ -20,6 +19,7 @@
#include <QtCore/QWeakPointer>
#include <optional>
+#include <utility>
QT_FORWARD_DECLARE_CLASS(QDebug)
@@ -32,7 +32,7 @@ class CodeModel
{
Q_GADGET
public:
- Q_DISABLE_COPY(CodeModel)
+ Q_DISABLE_COPY_MOVE(CodeModel)
enum FunctionType {
Normal,
@@ -74,7 +74,7 @@ public:
NamespaceModelItem globalNamespace() const;
void addFile(const FileModelItem &item);
- FileModelItem findFile(const QString &name) const;
+ FileModelItem findFile(QAnyStringView name) const;
static CodeModelItem findItem(const QStringList &qualifiedName,
const ScopeModelItem &scope);
@@ -91,8 +91,9 @@ QDebug operator<<(QDebug d, const CodeModel *m);
class _CodeModelItem
{
- Q_DISABLE_COPY(_CodeModelItem)
public:
+ Q_DISABLE_COPY_MOVE(_CodeModelItem)
+
enum Kind {
/* These are bit-flags resembling inheritance */
Kind_Scope = 0x1,
@@ -175,6 +176,7 @@ QDebug operator<<(QDebug d, const _CodeModelItem *t);
class _ScopeModelItem: public _CodeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_ScopeModelItem)
DECLARE_MODEL_NODE(Scope)
~_ScopeModelItem();
@@ -194,21 +196,21 @@ public:
void addVariable(const VariableModelItem &item);
ClassModelItem findClass(const QString &name) const;
- EnumModelItem findEnum(const QString &name) const;
+ EnumModelItem findEnum(QAnyStringView name) const;
struct FindEnumByValueReturn
{
- operator bool() const { return !item.isNull(); }
+ operator bool() const { return bool(item); }
EnumModelItem item;
QString qualifiedName;
};
FindEnumByValueReturn findEnumByValue(QStringView value) const;
- FunctionList findFunctions(const QString &name) const;
- TypeDefModelItem findTypeDef(const QString &name) const;
- TemplateTypeAliasModelItem findTemplateTypeAlias(const QString &name) const;
- VariableModelItem findVariable(const QString &name) const;
+ FunctionList findFunctions(QAnyStringView name) const;
+ TypeDefModelItem findTypeDef(QAnyStringView name) const;
+ TemplateTypeAliasModelItem findTemplateTypeAlias(QAnyStringView name) const;
+ VariableModelItem findVariable(QAnyStringView name) const;
void addEnumsDeclaration(const QString &enumsDeclaration);
QStringList enumsDeclarations() const { return m_enumsDeclarations; }
@@ -223,10 +225,9 @@ public:
#endif
protected:
- explicit _ScopeModelItem(CodeModel *model, int kind = __node_kind)
- : _CodeModelItem(model, kind) {}
- explicit _ScopeModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _CodeModelItem(model, name, kind) {}
+ explicit _ScopeModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _ScopeModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
void appendScope(const _ScopeModelItem &other);
@@ -258,6 +259,7 @@ private:
class _ClassModelItem: public _ScopeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_ClassModelItem)
DECLARE_MODEL_NODE(Class)
struct BaseClass
@@ -274,10 +276,9 @@ public:
Access access = Access::Public;
};
- explicit _ClassModelItem(CodeModel *model, int kind = __node_kind)
- : _ScopeModelItem(model, kind), m_classType(CodeModel::Class) {}
- explicit _ClassModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _ScopeModelItem(model, name, kind), m_classType(CodeModel::Class) {}
+ explicit _ClassModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _ClassModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
~_ClassModelItem();
const QList<BaseClass> &baseClasses() const { return m_baseClasses; }
@@ -313,7 +314,7 @@ private:
QList<BaseClass> m_baseClasses;
QList<UsingMember> m_usingMembers;
TemplateParameterList m_templateParameters;
- CodeModel::ClassType m_classType;
+ CodeModel::ClassType m_classType = CodeModel::Class;
QStringList m_propertyDeclarations;
bool m_final = false;
@@ -322,12 +323,12 @@ private:
class _NamespaceModelItem: public _ScopeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_NamespaceModelItem)
DECLARE_MODEL_NODE(Namespace)
- explicit _NamespaceModelItem(CodeModel *model, int kind = __node_kind)
- : _ScopeModelItem(model, kind) {}
- explicit _NamespaceModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _ScopeModelItem(model, name, kind) {}
+ explicit _NamespaceModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _NamespaceModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
~_NamespaceModelItem();
const NamespaceList &namespaces() const { return m_namespaces; }
@@ -337,7 +338,7 @@ public:
void addNamespace(NamespaceModelItem item);
- NamespaceModelItem findNamespace(const QString &name) const;
+ NamespaceModelItem findNamespace(QAnyStringView name) const;
void appendNamespace(const _NamespaceModelItem &other);
@@ -353,24 +354,23 @@ private:
class _FileModelItem: public _NamespaceModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_FileModelItem)
DECLARE_MODEL_NODE(File)
- explicit _FileModelItem(CodeModel *model, int kind = __node_kind)
- : _NamespaceModelItem(model, kind) {}
- explicit _FileModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _NamespaceModelItem(model, name, kind) {}
+ using _NamespaceModelItem::_NamespaceModelItem;
+
~_FileModelItem();
};
class _ArgumentModelItem: public _CodeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_ArgumentModelItem)
DECLARE_MODEL_NODE(Argument)
- explicit _ArgumentModelItem(CodeModel *model, int kind = __node_kind)
- : _CodeModelItem(model, kind), m_defaultValue(false) {}
- explicit _ArgumentModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _CodeModelItem(model, name, kind), m_defaultValue(false) {}
+ explicit _ArgumentModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _ArgumentModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
~_ArgumentModelItem();
TypeInfo type() const;
@@ -382,6 +382,10 @@ public:
QString defaultValueExpression() const { return m_defaultValueExpression; }
void setDefaultValueExpression(const QString &expr) { m_defaultValueExpression = expr; }
+ // Argument type has scope resolution "::ArgumentType"
+ bool scopeResolution() const;
+ void setScopeResolution(bool v);
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
#endif
@@ -389,18 +393,19 @@ public:
private:
TypeInfo m_type;
QString m_defaultValueExpression;
- bool m_defaultValue;
+ bool m_defaultValue = false;
+ bool m_scopeResolution = false;
};
class _MemberModelItem: public _CodeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_MemberModelItem)
DECLARE_MODEL_NODE(Member)
- explicit _MemberModelItem(CodeModel *model, int kind = __node_kind)
- : _CodeModelItem(model, kind), m_accessPolicy(Access::Public), m_flags(0) {}
- explicit _MemberModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _CodeModelItem(model, name, kind), m_accessPolicy(Access::Public), m_flags(0) {}
+ explicit _MemberModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _MemberModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
~_MemberModelItem();
bool isConstant() const;
@@ -443,7 +448,7 @@ public:
private:
TemplateParameterList m_templateParameters;
TypeInfo m_type;
- Access m_accessPolicy;
+ Access m_accessPolicy = Access::Public;
union {
struct {
uint m_isConstant: 1;
@@ -463,12 +468,12 @@ private:
class _FunctionModelItem: public _MemberModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_FunctionModelItem)
DECLARE_MODEL_NODE(Function)
- explicit _FunctionModelItem(CodeModel *model, int kind = __node_kind)
- : _MemberModelItem(model, kind), m_functionType(CodeModel::Normal), m_flags(0) {}
- explicit _FunctionModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _MemberModelItem(model, name, kind), m_functionType(CodeModel::Normal), m_flags(0) {}
+ explicit _FunctionModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _FunctionModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
~_FunctionModelItem();
ArgumentList arguments() const;
@@ -480,39 +485,25 @@ public:
static std::optional<CodeModel::FunctionType> functionTypeFromName(QStringView name);
+ FunctionAttributes attributes() const { return m_attributes; }
+ void setAttributes(FunctionAttributes a) { m_attributes = a; }
+ void setAttribute(FunctionAttribute a, bool on = true) { m_attributes.setFlag(a, on); }
+
bool isDeleted() const;
void setDeleted(bool d);
- bool isDeprecated() const;
- void setDeprecated(bool d);
-
- bool isVirtual() const;
- void setVirtual(bool isVirtual);
-
- bool isOverride() const;
- void setOverride(bool o);
-
- bool isFinal() const;
- void setFinal(bool f);
-
bool isInline() const;
void setInline(bool isInline);
- bool isExplicit() const;
- void setExplicit(bool isExplicit);
-
bool isHiddenFriend() const;
void setHiddenFriend(bool f);
- bool isInvokable() const; // Qt
- void setInvokable(bool isInvokable); // Qt
-
- bool isAbstract() const;
- void setAbstract(bool isAbstract);
-
bool isVariadics() const;
void setVariadics(bool isVariadics);
+ bool scopeResolution() const; // Return type has scope resolution "::ReturnType"
+ void setScopeResolution(bool v);
+
bool isDefaultConstructor() const;
bool isSpaceshipOperator() const;
@@ -538,20 +529,16 @@ private:
CodeModel::FunctionType _determineTypeHelper() const;
ArgumentList m_arguments;
- CodeModel::FunctionType m_functionType;
+ FunctionAttributes m_attributes;
+ CodeModel::FunctionType m_functionType = CodeModel::Normal;
union {
struct {
uint m_isDeleted: 1;
- uint m_isVirtual: 1;
- uint m_isOverride: 1;
- uint m_isFinal: 1;
- uint m_isDeprecated: 1;
uint m_isInline: 1;
- uint m_isAbstract: 1;
- uint m_isExplicit: 1;
uint m_isVariadics: 1;
uint m_isHiddenFriend: 1;
uint m_isInvokable : 1; // Qt
+ uint m_scopeResolution: 1;
};
uint m_flags;
};
@@ -563,10 +550,7 @@ class _VariableModelItem: public _MemberModelItem
public:
DECLARE_MODEL_NODE(Variable)
- explicit _VariableModelItem(CodeModel *model, int kind = __node_kind)
- : _MemberModelItem(model, kind) {}
- explicit _VariableModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _MemberModelItem(model, name, kind) {}
+ using _MemberModelItem::_MemberModelItem;
};
class _TypeDefModelItem: public _CodeModelItem
@@ -574,10 +558,9 @@ class _TypeDefModelItem: public _CodeModelItem
public:
DECLARE_MODEL_NODE(TypeDef)
- explicit _TypeDefModelItem(CodeModel *model, int kind = __node_kind)
- : _CodeModelItem(model, kind) {}
- explicit _TypeDefModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _CodeModelItem(model, name, kind) {}
+ explicit _TypeDefModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _TypeDefModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
TypeInfo type() const;
void setType(const TypeInfo &type);
@@ -617,12 +600,11 @@ private:
class _EnumModelItem: public _CodeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_EnumModelItem)
DECLARE_MODEL_NODE(Enum)
- explicit _EnumModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _CodeModelItem(model, name, kind) {}
- explicit _EnumModelItem(CodeModel *model, int kind = __node_kind)
- : _CodeModelItem(model, kind) {}
+ explicit _EnumModelItem(CodeModel *model, const QString &name, int kind = __node_kind);
+ explicit _EnumModelItem(CodeModel *model, int kind = __node_kind);
~_EnumModelItem();
Access accessPolicy() const;
@@ -647,7 +629,11 @@ public:
bool isSigned() const;
void setSigned(bool s);
+ QString underlyingType() const;
+ void setUnderlyingType(const QString &underlyingType);
+
private:
+ QString m_underlyingType;
Access m_accessPolicy = Access::Public;
EnumeratorList m_enumerators;
EnumKind m_enumKind = CEnum;
@@ -658,12 +644,12 @@ private:
class _EnumeratorModelItem: public _CodeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_EnumeratorModelItem)
DECLARE_MODEL_NODE(Enumerator)
- explicit _EnumeratorModelItem(CodeModel *model, int kind = __node_kind)
- : _CodeModelItem(model, kind) {}
- explicit _EnumeratorModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _CodeModelItem(model, name, kind) {}
+ explicit _EnumeratorModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _EnumeratorModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
~_EnumeratorModelItem();
QString stringValue() const;
@@ -688,12 +674,12 @@ private:
class _TemplateParameterModelItem: public _CodeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_TemplateParameterModelItem)
DECLARE_MODEL_NODE(TemplateParameter)
- explicit _TemplateParameterModelItem(CodeModel *model, int kind = __node_kind)
- : _CodeModelItem(model, kind), m_defaultValue(false) {}
- explicit _TemplateParameterModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _CodeModelItem(model, name, kind), m_defaultValue(false) {}
+ explicit _TemplateParameterModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _TemplateParameterModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
~_TemplateParameterModelItem();
TypeInfo type() const;
@@ -708,9 +694,7 @@ public:
private:
TypeInfo m_type;
- bool m_defaultValue;
+ bool m_defaultValue = false;
};
#endif // CODEMODEL_H
-
-// kate: space-indent on; indent-width 2; replace-tabs on;
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h b/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h
index 1a058bdfe..e5c429bd0 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h
@@ -4,6 +4,8 @@
#ifndef CODEMODEL_ENUMS_H
#define CODEMODEL_ENUMS_H
+#include <QtCore/qflags.h>
+
enum ReferenceType {
NoReference,
LValueReference,
@@ -43,4 +45,17 @@ enum class Access
Public
};
+enum class FunctionAttribute {
+ Abstract = 0x00000001,
+ Static = 0x00000002,
+ Virtual = 0x00000004,
+ Override = 0x00000008,
+ Final = 0x00000010,
+ Deprecated = 0x00000020, // Code annotation
+ Explicit = 0x00000040, // Constructor
+};
+
+Q_DECLARE_FLAGS(FunctionAttributes, FunctionAttribute)
+Q_DECLARE_OPERATORS_FOR_FLAGS(FunctionAttributes)
+
#endif // CODEMODEL_ENUMS_H
diff --git a/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h b/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h
index a3adf6678..f0a25c9db 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h
@@ -7,7 +7,8 @@
#define CODEMODEL_FWD_H
#include <QtCore/QList>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
// forward declarations
class CodeModel;
@@ -27,20 +28,20 @@ class _VariableModelItem;
class _MemberModelItem;
class TypeInfo;
-using ArgumentModelItem = QSharedPointer<_ArgumentModelItem>;
-using ClassModelItem = QSharedPointer<_ClassModelItem>;
-using CodeModelItem = QSharedPointer<_CodeModelItem>;
-using EnumModelItem = QSharedPointer<_EnumModelItem>;
-using EnumeratorModelItem = QSharedPointer<_EnumeratorModelItem>;
-using FileModelItem = QSharedPointer<_FileModelItem>;
-using FunctionModelItem = QSharedPointer<_FunctionModelItem>;
-using NamespaceModelItem = QSharedPointer<_NamespaceModelItem>;
-using ScopeModelItem = QSharedPointer<_ScopeModelItem>;
-using TemplateParameterModelItem = QSharedPointer<_TemplateParameterModelItem>;
-using TypeDefModelItem = QSharedPointer<_TypeDefModelItem>;
-using TemplateTypeAliasModelItem = QSharedPointer<_TemplateTypeAliasModelItem>;
-using VariableModelItem = QSharedPointer<_VariableModelItem>;
-using MemberModelItem = QSharedPointer<_MemberModelItem>;
+using ArgumentModelItem = std::shared_ptr<_ArgumentModelItem>;
+using ClassModelItem = std::shared_ptr<_ClassModelItem>;
+using CodeModelItem = std::shared_ptr<_CodeModelItem>;
+using EnumModelItem = std::shared_ptr<_EnumModelItem>;
+using EnumeratorModelItem = std::shared_ptr<_EnumeratorModelItem>;
+using FileModelItem = std::shared_ptr<_FileModelItem>;
+using FunctionModelItem = std::shared_ptr<_FunctionModelItem>;
+using NamespaceModelItem = std::shared_ptr<_NamespaceModelItem>;
+using ScopeModelItem = std::shared_ptr<_ScopeModelItem>;
+using TemplateParameterModelItem = std::shared_ptr<_TemplateParameterModelItem>;
+using TypeDefModelItem = std::shared_ptr<_TypeDefModelItem>;
+using TemplateTypeAliasModelItem = std::shared_ptr<_TemplateTypeAliasModelItem>;
+using VariableModelItem = std::shared_ptr<_VariableModelItem>;
+using MemberModelItem = std::shared_ptr<_MemberModelItem>;
using ArgumentList = QList<ArgumentModelItem>;
using ClassList = QList<ClassModelItem>;
diff --git a/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp b/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp
index 165b52101..3749e16a8 100644
--- a/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp
+++ b/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp
@@ -7,12 +7,34 @@
#include <QtCore/QString>
#include <QtCore/QTextStream>
+using namespace Qt::StringLiterals;
+
QString EnumValue::toString() const
{
return m_type == EnumValue::Signed
? QString::number(m_value) : QString::number(m_unsignedValue);
}
+QString EnumValue::toHex(int fieldWidth) const
+{
+ QString result;
+ QTextStream str(&result);
+ // Note: Qt goofes up formatting of negative padded hex numbers, it ends up
+ // with "0x00-1". Write '-' before.
+ if (isNegative())
+ str << '-';
+ str << "0x" << Qt::hex;
+ if (fieldWidth) {
+ str.setFieldWidth(fieldWidth);
+ str.setPadChar(u'0');
+ }
+ if (m_type == EnumValue::Signed)
+ str << qAbs(m_value);
+ else
+ str << m_unsignedValue;
+ return result;
+}
+
void EnumValue::setValue(qint64 v)
{
m_value = v;
@@ -25,15 +47,33 @@ void EnumValue::setUnsignedValue(quint64 v)
m_type = Unsigned;
}
-bool EnumValue::equals(const EnumValue &rhs) const
+EnumValue EnumValue::toUnsigned() const
{
- if (m_type != rhs.m_type)
+ if (m_type == Unsigned)
+ return *this;
+ EnumValue result;
+ result.setUnsignedValue(m_value < 0 ? quint64(-m_value) : quint64(m_value));
+ return result;
+}
+
+bool comparesEqual(const EnumValue &lhs, const EnumValue &rhs) noexcept
+{
+ if (lhs.m_type != rhs.m_type)
return false;
- return m_type == Signed ? m_value == rhs.m_value : m_unsignedValue == rhs.m_unsignedValue;
+ return lhs.m_type == EnumValue::Signed
+ ? lhs.m_value == rhs.m_value : lhs.m_unsignedValue == rhs.m_unsignedValue;
+}
+
+void EnumValue::formatDebugHex(QDebug &d) const
+{
+ d << "0x" << Qt::hex;
+ formatDebug(d);
+ d << Qt::dec;
}
void EnumValue::formatDebug(QDebug &d) const
{
+
if (m_type == EnumValue::Signed)
d << m_value;
else
diff --git a/sources/shiboken6/ApiExtractor/parser/enumvalue.h b/sources/shiboken6/ApiExtractor/parser/enumvalue.h
index 3aaed2b73..bbd5a712d 100644
--- a/sources/shiboken6/ApiExtractor/parser/enumvalue.h
+++ b/sources/shiboken6/ApiExtractor/parser/enumvalue.h
@@ -4,7 +4,9 @@
#ifndef ENUMVALUE_H
#define ENUMVALUE_H
-#include <QtCore/QtGlobal>
+#include <QtCore/qtypes.h>
+#include <QtCore/qtclasshelpermacros.h>
+#include <QtCore/QtCompare>
QT_FORWARD_DECLARE_CLASS(QDebug)
QT_FORWARD_DECLARE_CLASS(QString)
@@ -20,20 +22,29 @@ public:
};
QString toString() const;
+ QString toHex(int fieldWidth = 0) const;
Type type() { return m_type; }
qint64 value() const { return m_value; }
quint64 unsignedValue() const { return m_unsignedValue; }
bool isNullValue() const { return m_type == Signed ? m_value == 0 : m_unsignedValue == 0u; }
+ bool isNegative() const { return m_type == Signed && m_value < 0; }
void setValue(qint64 v);
void setUnsignedValue(quint64 v);
+ EnumValue toUnsigned() const;
+
bool equals(const EnumValue &rhs) const;
void formatDebug(QDebug &d) const;
+ void formatDebugHex(QDebug &d) const;
private:
+ friend bool comparesEqual(const EnumValue &lhs,
+ const EnumValue &rhs) noexcept;
+ Q_DECLARE_EQUALITY_COMPARABLE(EnumValue)
+
#ifndef QT_NO_DEBUG_STREAM
friend QDebug operator<<(QDebug, const EnumValue &);
#endif
@@ -47,9 +58,4 @@ private:
Type m_type = Signed;
};
-inline bool operator==(const EnumValue &e1, const EnumValue &e2)
-{ return e1.equals(e2); }
-inline bool operator!=(const EnumValue &e1, const EnumValue &e2)
-{ return !e1.equals(e2); }
-
#endif // ENUMVALUE_H
diff --git a/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp b/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp
index 205f01de8..f8c5c31d8 100644
--- a/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp
+++ b/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp
@@ -7,6 +7,7 @@
#include "codemodel.h"
#include <clangparser/clangutils.h>
+#include <debughelpers_p.h>
#include "qtcompat.h"
@@ -46,10 +47,10 @@ public:
};
};
- ReferenceType m_referenceType;
+ ReferenceType m_referenceType = NoReference;
};
-TypeInfoData::TypeInfoData() : flags(0), m_referenceType(NoReference)
+TypeInfoData::TypeInfoData() : flags(0)
{
}
@@ -60,9 +61,8 @@ TypeInfo::TypeInfo() : d(new TypeInfoData)
TypeInfo::~TypeInfo() = default;
TypeInfo::TypeInfo(const TypeInfo &) = default;
TypeInfo& TypeInfo::operator=(const TypeInfo &) = default;
-TypeInfo::TypeInfo(TypeInfo &&) = default;
-TypeInfo& TypeInfo::operator=(TypeInfo &&) = default;
-
+TypeInfo::TypeInfo(TypeInfo &&) noexcept = default;
+TypeInfo &TypeInfo::operator=(TypeInfo &&) noexcept = default;
static inline TypeInfo createType(const QString &name)
{
@@ -98,7 +98,7 @@ TypeInfo TypeInfo::combine(const TypeInfo &__lhs, const TypeInfo &__rhs)
__result.setArrayElements(__result.arrayElements() + __rhs.arrayElements());
- const auto instantiations = __rhs.instantiations();
+ const auto &instantiations = __rhs.instantiations();
for (const auto &i : instantiations)
__result.addInstantiation(i);
@@ -266,6 +266,12 @@ void TypeInfo::clearInstantiations()
d->m_instantiations.clear();
}
+bool TypeInfo::isPlain() const
+{
+ return d->m_constant == 0 && d->m_volatile == 0 && d->m_referenceType == NoReference
+ && d->m_indirections.isEmpty() && d->m_arrayElements.isEmpty();
+}
+
TypeInfo TypeInfo::resolveType(TypeInfo const &__type, const ScopeModelItem &__scope)
{
CodeModel *__model = __scope->model();
@@ -286,14 +292,14 @@ TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, con
otherType.setQualifiedName(__item->qualifiedName());
}
- if (TypeDefModelItem __typedef = qSharedPointerDynamicCast<_TypeDefModelItem>(__item)) {
+ if (TypeDefModelItem __typedef = std::dynamic_pointer_cast<_TypeDefModelItem>(__item)) {
const TypeInfo combined = TypeInfo::combine(__typedef->type(), otherType);
const CodeModelItem nextItem = __scope->model()->findItem(combined.qualifiedName(), __scope);
if (!nextItem)
return combined;
// PYSIDE-362, prevent recursion on opaque structs like
// typedef struct xcb_connection_t xcb_connection_t;
- if (nextItem.data() ==__item.data()) {
+ if (nextItem.get() ==__item.get()) {
std::cerr << "** WARNING Bailing out recursion of " << __FUNCTION__
<< "() on " << qPrintable(__type.qualifiedName().join(u"::"_s))
<< std::endl;
@@ -302,7 +308,7 @@ TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, con
return resolveType(nextItem, combined, __scope);
}
- if (TemplateTypeAliasModelItem templateTypeAlias = qSharedPointerDynamicCast<_TemplateTypeAliasModelItem>(__item)) {
+ if (TemplateTypeAliasModelItem templateTypeAlias = std::dynamic_pointer_cast<_TemplateTypeAliasModelItem>(__item)) {
TypeInfo combined = TypeInfo::combine(templateTypeAlias->type(), otherType);
// For the alias "template<typename T> using QList = QVector<T>" with
@@ -313,7 +319,7 @@ TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, con
for (qsizetype i = 0; i < count; ++i)
aliasInstantiations[i] = concreteInstantiations.at(i);
combined.setInstantiations(aliasInstantiations);
- const CodeModelItem nextItem = __scope->model()->findItem(combined.qualifiedName(), __scope);
+ const CodeModelItem nextItem = CodeModel::findItem(combined.qualifiedName(), __scope);
if (!nextItem)
return combined;
return resolveType(nextItem, combined, __scope);
@@ -341,6 +347,10 @@ public:
while (level < m_parseStack.size())
m_parseStack.pop();
TypeInfo instantiation;
+ if (name.startsWith(u"const ")) {
+ instantiation.setConstant(true);
+ name = name.mid(6);
+ }
instantiation.setQualifiedName(qualifiedName(name));
top()->addInstantiation(instantiation);
}
@@ -361,7 +371,8 @@ private:
QStack<TypeInfo *> m_parseStack;
};
-QPair<qsizetype, qsizetype> TypeInfo::parseTemplateArgumentList(const QString &l, qsizetype from)
+std::pair<qsizetype, qsizetype>
+ TypeInfo::parseTemplateArgumentList(const QString &l, qsizetype from)
{
return clang::parseTemplateArgumentList(l, clang::TemplateArgumentHandler(TypeInfoTemplateArgumentHandler(this)), from);
}
@@ -441,31 +452,28 @@ bool TypeInfoData::equals(const TypeInfoData &other) const
&& m_instantiations == other.m_instantiations;
}
-bool TypeInfo::equals(const TypeInfo &other) const
+
+bool comparesEqual(const TypeInfo &lhs, const TypeInfo &rhs) noexcept
{
- return d.data() == other.d.data() || d->equals(*other.d);
+ return lhs.d.data() == rhs.d.data() || lhs.d->equals(*rhs.d);
}
QString TypeInfo::indirectionKeyword(Indirection i)
{
- return i == Indirection::Pointer
- ? QStringLiteral("*") : QStringLiteral("*const");
+ return i == Indirection::Pointer ? "*"_L1 : "*const"_L1;
}
-static inline QString constQualifier() { return QStringLiteral("const"); }
-static inline QString volatileQualifier() { return QStringLiteral("volatile"); }
-
bool TypeInfo::stripLeadingConst(QString *s)
{
- return stripLeadingQualifier(constQualifier(), s);
+ return stripLeadingQualifier("const"_L1, s);
}
bool TypeInfo::stripLeadingVolatile(QString *s)
{
- return stripLeadingQualifier(volatileQualifier(), s);
+ return stripLeadingQualifier("volatile"_L1, s);
}
-bool TypeInfo::stripLeadingQualifier(const QString &qualifier, QString *s)
+bool TypeInfo::stripLeadingQualifier(QLatin1StringView qualifier, QString *s)
{
// "const int x"
const auto qualifierSize = qualifier.size();
@@ -558,16 +566,6 @@ void TypeInfo::formatTypeSystemSignature(QTextStream &str) const
}
#ifndef QT_NO_DEBUG_STREAM
-template <class It>
-void formatSequence(QDebug &d, It i1, It i2, const char *separator=", ")
-{
- for (It i = i1; i != i2; ++i) {
- if (i != i1)
- d << separator;
- d << *i;
- }
-}
-
void TypeInfo::formatDebug(QDebug &debug) const
{
debug << '"';
diff --git a/sources/shiboken6/ApiExtractor/parser/typeinfo.h b/sources/shiboken6/ApiExtractor/parser/typeinfo.h
index cf3576eb6..e4f363b67 100644
--- a/sources/shiboken6/ApiExtractor/parser/typeinfo.h
+++ b/sources/shiboken6/ApiExtractor/parser/typeinfo.h
@@ -10,8 +10,11 @@
#include <QtCore/QString>
#include <QtCore/QSharedDataPointer>
+#include <QtCore/QtCompare>
#include <QtCore/QStringList>
+#include <utility>
+
QT_FORWARD_DECLARE_CLASS(QDebug)
QT_FORWARD_DECLARE_CLASS(QTextStream)
@@ -28,8 +31,8 @@ public:
~TypeInfo();
TypeInfo(const TypeInfo &);
TypeInfo& operator=(const TypeInfo &);
- TypeInfo(TypeInfo &&);
- TypeInfo& operator=(TypeInfo &&);
+ TypeInfo(TypeInfo &&) noexcept;
+ TypeInfo &operator=(TypeInfo &&) noexcept;
static TypeInfo voidType();
static TypeInfo varArgsType();
@@ -77,11 +80,12 @@ public:
void addInstantiation(const TypeInfo &i);
void clearInstantiations();
- bool isStdType() const;
+ bool isPlain() const; // neither const,volatile, no indirections/references, array
- QPair<qsizetype, qsizetype> parseTemplateArgumentList(const QString &l, qsizetype from = 0);
+ bool isStdType() const;
- bool equals(const TypeInfo &other) const;
+ std::pair<qsizetype, qsizetype>
+ parseTemplateArgumentList(const QString &l, qsizetype from = 0);
// ### arrays and templates??
@@ -100,12 +104,16 @@ public:
static bool stripLeadingConst(QString *s);
static bool stripLeadingVolatile(QString *s);
- static bool stripLeadingQualifier(const QString &qualifier, QString *s);
+ static bool stripLeadingQualifier(QLatin1StringView qualifier, QString *s);
static void stripQualifiers(QString *s);
void simplifyStdType();
private:
+ friend bool comparesEqual(const TypeInfo &lhs,
+ const TypeInfo &rhs) noexcept;
+ Q_DECLARE_EQUALITY_COMPARABLE(TypeInfo)
+
QSharedDataPointer<TypeInfoData> d;
friend class TypeInfoTemplateArgumentHandler;
@@ -113,12 +121,6 @@ private:
static TypeInfo resolveType(CodeModelItem item, TypeInfo const &__type, const ScopeModelItem &__scope);
};
-inline bool operator==(const TypeInfo &t1, const TypeInfo &t2)
-{ return t1.equals(t2); }
-
-inline bool operator!=(const TypeInfo &t1, const TypeInfo &t2)
-{ return !t1.equals(t2); }
-
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const TypeInfo &t);
#endif
diff --git a/sources/shiboken6/ApiExtractor/predefined_templates.cpp b/sources/shiboken6/ApiExtractor/predefined_templates.cpp
index be3dd9319..992f735ac 100644
--- a/sources/shiboken6/ApiExtractor/predefined_templates.cpp
+++ b/sources/shiboken6/ApiExtractor/predefined_templates.cpp
@@ -39,20 +39,37 @@ while (true) {
return result;
}
-static const char stlMapKeyAccessor[] = "->first";
-static const char stlMapValueAccessor[] = "->second";
-static const char qtMapKeyAccessor[] = ".key()";
-static const char qtMapValueAccessor[] = ".value()";
+// Convert a sequence to a limited/fixed array
+static QString pySequenceToCppArray()
+{
+ return uR"(Shiboken::AutoDecRef it(PyObject_GetIter(%in));
+for (auto oit = std::begin(%out), oend = std::end(%out); oit != oend; ++oit) {
+ Shiboken::AutoDecRef pyItem(PyIter_Next(it.object()));
+ if (pyItem.isNull()) {
+ if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_StopIteration))
+ PyErr_Clear();
+ break;
+ }
+ %OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
+ *oit = cppItem;
+}
+)"_s;
+}
+
+static constexpr auto stlMapKeyAccessor = "->first"_L1;
+static constexpr auto stlMapValueAccessor = "->second"_L1;
+static constexpr auto qtMapKeyAccessor = ".key()"_L1;
+static constexpr auto qtMapValueAccessor = ".value()"_L1;
static QString cppMapToPyDict(bool isQMap)
{
return uR"(PyObject *%out = PyDict_New();
-for (auto it = %in.cbegin(), end = %in.cend(); it != end; ++it) {
+for (auto it = std::cbegin(%in), end = std::cend(%in); it != end; ++it) {
const auto &key = it)"_s
- + QLatin1StringView(isQMap ? qtMapKeyAccessor : stlMapKeyAccessor)
+ + (isQMap ? qtMapKeyAccessor : stlMapKeyAccessor)
+ uR"(;
const auto &value = it)"_s
- + QLatin1StringView(isQMap ? qtMapValueAccessor : stlMapValueAccessor)
+ + (isQMap ? qtMapValueAccessor : stlMapValueAccessor)
+ uR"(;
PyObject *pyKey = %CONVERTTOPYTHON[%INTYPE_0](key);
PyObject *pyValue = %CONVERTTOPYTHON[%INTYPE_1](value);
@@ -84,9 +101,9 @@ while (PyDict_Next(%in, &pos, &key, &value)) {
static QString cppMultiMapToPyDict(bool isQMultiMap)
{
return uR"(PyObject *%out = PyDict_New();
- for (auto it = %in.cbegin(), end = %in.cend(); it != end; ) {
+ for (auto it = std::cbegin(%in), end = std::cend(%in); it != end; ) {
const auto &key = it)"_s
- + QLatin1StringView(isQMultiMap ? qtMapKeyAccessor : stlMapKeyAccessor)
+ + (isQMultiMap ? qtMapKeyAccessor : stlMapKeyAccessor)
+ uR"(;
PyObject *pyKey = %CONVERTTOPYTHON[%INTYPE_0](key);
auto upper = %in.)"_s
@@ -110,9 +127,9 @@ static QString cppMultiMapToPyDict(bool isQMultiMap)
static QString cppMultiHashToPyDict(bool isQMultiHash)
{
return uR"(PyObject *%out = PyDict_New();
- for (auto it = %in.cbegin(), end = %in.cend(); it != end; ) {
+ for (auto it = std::cbegin(%in), end = std::cend(%in); it != end; ) {
const auto &key = it)"_s
- + QLatin1StringView(isQMultiHash ? qtMapKeyAccessor : stlMapKeyAccessor)
+ + (isQMultiHash ? qtMapKeyAccessor : stlMapKeyAccessor)
+ uR"(;
PyObject *pyKey = %CONVERTTOPYTHON[%INTYPE_0](key);
auto range = %in.equal_range(key);
@@ -174,7 +191,7 @@ return %out;
{u"shiboken_conversion_cppsequence_to_pylist"_s,
uR"(PyObject *%out = PyList_New(Py_ssize_t(%in.size()));
Py_ssize_t idx = 0;
-for (auto it = %in.cbegin(), end = %in.cend(); it != end; ++it, ++idx) {
+for (auto it = std::cbegin(%in), end = std::cend(%in); it != end; ++it, ++idx) {
const auto &cppItem = *it;
PyList_SET_ITEM(%out, idx, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
}
@@ -192,6 +209,8 @@ return %out;)"_s},
pySequenceToCppContainer(u"push_back"_s, false)},
{u"shiboken_conversion_pyiterable_to_cppsequentialcontainer_reserve"_s,
pySequenceToCppContainer(u"push_back"_s, true)},
+ {u"shiboken_conversion_pyiterable_to_cpparray"_s,
+ pySequenceToCppArray()},
{u"shiboken_conversion_pyiterable_to_cppsetcontainer"_s,
pySequenceToCppContainer(u"insert"_s, false)},
@@ -233,19 +252,25 @@ QByteArray containerTypeSystemSnippet(const char *name, const char *type,
const char *targetToNativeType,
const char *targetToNative)
{
- return QByteArrayLiteral("<container-type name=\"")
+ QByteArray result = QByteArrayLiteral("<container-type name=\"")
+ name + QByteArrayLiteral("\" type=\"") + type + R"(">
<include file-name=")" + include + R"(" location="global"/>
<conversion-rule>
<native-to-target>
<insert-template name=")" + nativeToTarget + R"("/>
</native-to-target>
- <target-to-native>
- <add-conversion type=")" + targetToNativeType + R"(">
- <insert-template name=")" + targetToNative + R"("/>
+)";
+ if (targetToNativeType != nullptr) {
+ result += QByteArrayLiteral(R"( <target-to-native>
+ <add-conversion type=")") + targetToNativeType
+ + QByteArrayLiteral(R"(">
+ <insert-template name=")") + targetToNative + QByteArrayLiteral(R"("/>
</add-conversion>
</target-to-native>
- </conversion-rule>
+)");
+ }
+result += QByteArrayLiteral(R"( </conversion-rule>
</container-type>
-)";
+)");
+ return result;
}
diff --git a/sources/shiboken6/ApiExtractor/predefined_templates.h b/sources/shiboken6/ApiExtractor/predefined_templates.h
index 2519f65d9..0cc2c7f32 100644
--- a/sources/shiboken6/ApiExtractor/predefined_templates.h
+++ b/sources/shiboken6/ApiExtractor/predefined_templates.h
@@ -21,7 +21,7 @@ const PredefinedTemplates &predefinedTemplates();
QByteArray containerTypeSystemSnippet(const char *name, const char *type,
const char *include,
const char *nativeToTarget,
- const char *targetToNativeType,
- const char *targetToNative);
+ const char *targetToNativeType = nullptr,
+ const char *targetToNative = nullptr);
#endif // PREDEFINED_TEMPLATES_H
diff --git a/sources/shiboken6/ApiExtractor/propertyspec.cpp b/sources/shiboken6/ApiExtractor/propertyspec.cpp
index 1c86cacf6..32b756fad 100644
--- a/sources/shiboken6/ApiExtractor/propertyspec.cpp
+++ b/sources/shiboken6/ApiExtractor/propertyspec.cpp
@@ -59,8 +59,8 @@ QPropertySpec::QPropertySpec(const TypeSystemProperty &ts,
QPropertySpec::QPropertySpec(const QPropertySpec &) = default;
QPropertySpec &QPropertySpec::operator=(const QPropertySpec &) = default;
-QPropertySpec::QPropertySpec(QPropertySpec &&) = default;
-QPropertySpec &QPropertySpec::operator=(QPropertySpec &&) = default;
+QPropertySpec::QPropertySpec(QPropertySpec &&) noexcept = default;
+QPropertySpec &QPropertySpec::operator=(QPropertySpec &&) noexcept = default;
QPropertySpec::~QPropertySpec() = default;
const AbstractMetaType &QPropertySpec::type() const
@@ -189,14 +189,15 @@ void QPropertySpec::setGenerateGetSetDef(bool generateGetSetDef)
TypeSystemProperty QPropertySpec::typeSystemPropertyFromQ_Property(const QString &declarationIn,
QString *errorMessage)
{
- enum class PropertyToken { None, Read, Write, Designable, Reset, Notify };
+ enum class PropertyToken { None, Read, Write, Designable, Reset, Notify, Member };
static const QHash<QString, PropertyToken> tokenLookup = {
- {QStringLiteral("READ"), PropertyToken::Read},
- {QStringLiteral("WRITE"), PropertyToken::Write},
- {QStringLiteral("DESIGNABLE"), PropertyToken::Designable},
- {QStringLiteral("RESET"), PropertyToken::Reset},
- {QStringLiteral("NOTIFY"), PropertyToken::Notify}
+ {"READ"_L1, PropertyToken::Read},
+ {"WRITE"_L1, PropertyToken::Write},
+ {"DESIGNABLE"_L1, PropertyToken::Designable},
+ {"RESET"_L1, PropertyToken::Reset},
+ {"NOTIFY"_L1, PropertyToken::Notify},
+ {"MEMBER"_L1, PropertyToken::Member}
};
errorMessage->clear();
@@ -242,17 +243,21 @@ TypeSystemProperty QPropertySpec::typeSystemPropertyFromQ_Property(const QString
case PropertyToken::Notify:
result.notify = propertyTokens.at(pos + 1);
break;
+ case PropertyToken::Member:
+ // Ignore MEMBER tokens introduced by QTBUG-16852 as Python
+ // properties are anyways generated for fields.
+ return {};
case PropertyToken::None:
break;
}
}
- const int namePos = firstToken - 1;
+ const auto namePos = firstToken - 1;
result.name = propertyTokens.at(namePos);
result.type = propertyTokens.constFirst();
- for (int pos = 1; pos < namePos; ++pos)
+ for (qsizetype pos = 1; pos < namePos; ++pos)
result.type += u' ' + propertyTokens.at(pos);
// Fix errors like "Q_PROPERTY(QXYSeries *series .." to be of type "QXYSeries*"
@@ -269,7 +274,7 @@ TypeSystemProperty QPropertySpec::typeSystemPropertyFromQ_Property(const QString
// the AbstractMetaType from the type string.
std::optional<QPropertySpec>
QPropertySpec::fromTypeSystemProperty(AbstractMetaBuilderPrivate *b,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
const TypeSystemProperty &ts,
const QStringList &scopes,
QString *errorMessage)
@@ -302,7 +307,7 @@ std::optional<QPropertySpec>
// via TypeSystemProperty.
std::optional<QPropertySpec>
QPropertySpec::parseQ_Property(AbstractMetaBuilderPrivate *b,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
const QString &declarationIn,
const QStringList &scopes,
QString *errorMessage)
diff --git a/sources/shiboken6/ApiExtractor/propertyspec.h b/sources/shiboken6/ApiExtractor/propertyspec.h
index 907668cb1..9e2e0f3d4 100644
--- a/sources/shiboken6/ApiExtractor/propertyspec.h
+++ b/sources/shiboken6/ApiExtractor/propertyspec.h
@@ -6,6 +6,7 @@
class AbstractMetaType;
+#include "abstractmetalang_typedefs.h"
#include "typesystem_typedefs.h"
#include <QtCore/QStringList>
@@ -32,8 +33,8 @@ public:
const AbstractMetaType &type);
QPropertySpec(const QPropertySpec &);
QPropertySpec &operator=(const QPropertySpec &);
- QPropertySpec(QPropertySpec &&);
- QPropertySpec &operator=(QPropertySpec &&);
+ QPropertySpec(QPropertySpec &&) noexcept;
+ QPropertySpec &operator=(QPropertySpec &&) noexcept;
~QPropertySpec();
static TypeSystemProperty typeSystemPropertyFromQ_Property(const QString &declarationIn,
@@ -42,14 +43,14 @@ public:
static std::optional<QPropertySpec>
fromTypeSystemProperty(AbstractMetaBuilderPrivate *b,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
const TypeSystemProperty &ts,
const QStringList &scopes,
QString *errorMessage);
static std::optional<QPropertySpec>
parseQ_Property(AbstractMetaBuilderPrivate *b,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
const QString &declarationIn,
const QStringList &scopes,
QString *errorMessage);
diff --git a/sources/shiboken6/ApiExtractor/pymethoddefentry.cpp b/sources/shiboken6/ApiExtractor/pymethoddefentry.cpp
index 75ac227b8..64d44378b 100644
--- a/sources/shiboken6/ApiExtractor/pymethoddefentry.cpp
+++ b/sources/shiboken6/ApiExtractor/pymethoddefentry.cpp
@@ -6,10 +6,15 @@
#include <QtCore/QDebug>
+TextStream &operator<<(TextStream &str, const castToPyCFunction &c)
+{
+ str << "reinterpret_cast<PyCFunction>(" << c.m_function << ')';
+ return str;
+}
+
TextStream &operator<<(TextStream &s, const PyMethodDefEntry &e)
{
- s << "{\"" << e.name << "\", reinterpret_cast<PyCFunction>("
- << e.function << "), ";
+ s << "{\"" << e.name << "\", " << castToPyCFunction(e.function) <<", ";
if (e.methFlags.isEmpty()) {
s << '0';
} else {
diff --git a/sources/shiboken6/ApiExtractor/pymethoddefentry.h b/sources/shiboken6/ApiExtractor/pymethoddefentry.h
index 54eaa4ce1..a8694eb30 100644
--- a/sources/shiboken6/ApiExtractor/pymethoddefentry.h
+++ b/sources/shiboken6/ApiExtractor/pymethoddefentry.h
@@ -11,6 +11,14 @@ QT_FORWARD_DECLARE_CLASS(QDebug)
class TextStream;
+struct castToPyCFunction
+{
+ explicit castToPyCFunction(QAnyStringView function) noexcept :
+ m_function(function) {}
+
+ QAnyStringView m_function;
+};
+
struct PyMethodDefEntry
{
QString name;
@@ -21,6 +29,7 @@ struct PyMethodDefEntry
using PyMethodDefEntries = QList<PyMethodDefEntry>;
+TextStream &operator<<(TextStream &str, const castToPyCFunction &e);
TextStream &operator<<(TextStream &s, const PyMethodDefEntry &e);
TextStream &operator<<(TextStream &s, const PyMethodDefEntries &e);
diff --git a/sources/shiboken6/ApiExtractor/qtcompat.h b/sources/shiboken6/ApiExtractor/qtcompat.h
index 9627bb76c..3837dcfd2 100644
--- a/sources/shiboken6/ApiExtractor/qtcompat.h
+++ b/sources/shiboken6/ApiExtractor/qtcompat.h
@@ -4,7 +4,7 @@
#ifndef QTCOMPAT_H
#define QTCOMPAT_H
-#include <QtCore/QtGlobal>
+#include <QtCore/qtconfigmacros.h>
#if QT_VERSION < 0x060400
diff --git a/sources/shiboken6/ApiExtractor/qtdocparser.cpp b/sources/shiboken6/ApiExtractor/qtdocparser.cpp
index 8daf1ad85..5bd99bbd8 100644
--- a/sources/shiboken6/ApiExtractor/qtdocparser.cpp
+++ b/sources/shiboken6/ApiExtractor/qtdocparser.cpp
@@ -15,6 +15,8 @@
#include "reporthandler.h"
#include "flagstypeentry.h"
#include "complextypeentry.h"
+#include "functiontypeentry.h"
+#include "enumtypeentry.h"
#include "qtcompat.h"
@@ -26,8 +28,9 @@ using namespace Qt::StringLiterals;
enum { debugFunctionSearch = 0 };
-static inline QString briefStartElement() { return QStringLiteral("<brief>"); }
-static inline QString briefEndElement() { return QStringLiteral("</brief>"); }
+constexpr auto briefStartElement = "<brief>"_L1;
+constexpr auto briefEndElement = "</brief>"_L1;
+constexpr auto webxmlSuffix = ".webxml"_L1;
Documentation QtDocParser::retrieveModuleDocumentation()
{
@@ -57,7 +60,7 @@ static void formatFunctionUnqualifiedArgTypeQuery(QTextStream &str,
case AbstractMetaType::FlagsPattern: {
// Modify qualified name "QFlags<Qt::AlignmentFlag>" with name "Alignment"
// to "Qt::Alignment" as seen by qdoc.
- const auto flagsEntry = qSharedPointerCast<const FlagsTypeEntry>(metaType.typeEntry());
+ const auto flagsEntry = std::static_pointer_cast<const FlagsTypeEntry>(metaType.typeEntry());
QString name = flagsEntry->qualifiedCppName();
if (name.endsWith(u'>') && name.startsWith(u"QFlags<")) {
const int lastColon = name.lastIndexOf(u':');
@@ -102,7 +105,7 @@ static QString formatFunctionArgTypeQuery(const AbstractMetaType &metaType)
QString QtDocParser::functionDocumentation(const QString &sourceFileName,
const ClassDocumentation &classDocumentation,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaFunctionCPtr &func,
QString *errorMessage)
{
@@ -112,14 +115,14 @@ QString QtDocParser::functionDocumentation(const QString &sourceFileName,
queryFunctionDocumentation(sourceFileName, classDocumentation, metaClass,
func, errorMessage);
- const auto funcModifs = DocParser::getDocModifications(metaClass, func);
+ const auto funcModifs = DocParser::getXpathDocModifications(func, metaClass);
return docString.isEmpty() || funcModifs.isEmpty()
? docString : applyDocModifications(funcModifs, docString);
}
QString QtDocParser::queryFunctionDocumentation(const QString &sourceFileName,
const ClassDocumentation &classDocumentation,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaFunctionCPtr &func,
QString *errorMessage)
{
@@ -127,7 +130,7 @@ QString QtDocParser::queryFunctionDocumentation(const QString &sourceFileName,
FunctionDocumentationList candidates =
classDocumentation.findFunctionCandidates(func->name(), func->isConstant());
if (candidates.isEmpty()) {
- *errorMessage = msgCannotFindDocumentation(sourceFileName, func.data())
+ *errorMessage = msgCannotFindDocumentation(sourceFileName, func.get())
+ u" (no matches)"_s;
return {};
}
@@ -172,13 +175,13 @@ QString QtDocParser::queryFunctionDocumentation(const QString &sourceFileName,
candidates.erase(pend, candidates.end());
if (candidates.size() == 1) {
const auto &match = candidates.constFirst();
- QTextStream(errorMessage) << msgFallbackForDocumentation(sourceFileName, func.data())
+ QTextStream(errorMessage) << msgFallbackForDocumentation(sourceFileName, func.get())
<< "\n Falling back to \"" << match.signature
<< "\" obtained by matching the argument count only.";
return candidates.constFirst().description;
}
- QTextStream(errorMessage) << msgCannotFindDocumentation(sourceFileName, func.data())
+ QTextStream(errorMessage) << msgCannotFindDocumentation(sourceFileName, func.get())
<< " (" << candidates.size() << " candidates matching the argument count)";
return {};
}
@@ -187,29 +190,100 @@ QString QtDocParser::queryFunctionDocumentation(const QString &sourceFileName,
// from the source.
static QString extractBrief(QString *value)
{
- const auto briefStart = value->indexOf(briefStartElement());
+ const auto briefStart = value->indexOf(briefStartElement);
if (briefStart < 0)
return {};
- const auto briefEnd = value->indexOf(briefEndElement(),
- briefStart + briefStartElement().size());
+ const auto briefEnd = value->indexOf(briefEndElement,
+ briefStart + briefStartElement.size());
if (briefEnd < briefStart)
return {};
- const auto briefLength = briefEnd + briefEndElement().size() - briefStart;
+ const auto briefLength = briefEnd + briefEndElement.size() - briefStart;
QString briefValue = value->mid(briefStart, briefLength);
- briefValue.insert(briefValue.size() - briefEndElement().size(),
+ briefValue.insert(briefValue.size() - briefEndElement.size(),
u"<rst> More_...</rst>"_s);
value->remove(briefStart, briefLength);
return briefValue;
}
-void QtDocParser::fillDocumentation(AbstractMetaClass *metaClass)
+// Find the webxml file for global functions/enums
+// by the doc-file typesystem attribute or via include file.
+static QString findGlobalWebXmLFile(const QString &documentationDataDirectory,
+ const QString &docFile,
+ const Include &include)
+{
+ QString result;
+ if (!docFile.isEmpty()) {
+ result = documentationDataDirectory + u'/' + docFile;
+ if (!result.endsWith(webxmlSuffix))
+ result += webxmlSuffix;
+ return QFileInfo::exists(result) ? result : QString{};
+ }
+ if (include.name().isEmpty())
+ return {};
+ // qdoc "\headerfile <QtLogging>" directive produces "qtlogging.webxml"
+ result = documentationDataDirectory + u'/' +
+ QFileInfo(include.name()).baseName() + webxmlSuffix;
+ if (QFileInfo::exists(result))
+ return result;
+ // qdoc "\headerfile <qdrawutil.h>" produces "qdrawutil-h.webxml"
+ result.insert(result.size() - webxmlSuffix.size(), "-h"_L1);
+ return QFileInfo::exists(result) ? result : QString{};
+}
+
+void QtDocParser::fillGlobalFunctionDocumentation(const AbstractMetaFunctionPtr &f)
+{
+ auto te = f->typeEntry();
+ if (te == nullptr)
+ return;
+
+ const QString sourceFileName =
+ findGlobalWebXmLFile(documentationDataDirectory(), te->docFile(), te->include());
+ if (sourceFileName.isEmpty())
+ return;
+
+ QString errorMessage;
+ auto classDocumentationO = parseWebXml(sourceFileName, &errorMessage);
+ if (!classDocumentationO.has_value()) {
+ qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
+ return;
+ }
+ const QString detailed =
+ functionDocumentation(sourceFileName, classDocumentationO.value(),
+ {}, f, &errorMessage);
+ if (!errorMessage.isEmpty())
+ qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
+ const Documentation documentation(detailed, {});
+ f->setDocumentation(documentation);
+}
+
+void QtDocParser::fillGlobalEnumDocumentation(AbstractMetaEnum &e)
+{
+ auto te = e.typeEntry();
+ const QString sourceFileName =
+ findGlobalWebXmLFile(documentationDataDirectory(), te->docFile(), te->include());
+ if (sourceFileName.isEmpty())
+ return;
+
+ QString errorMessage;
+ auto classDocumentationO = parseWebXml(sourceFileName, &errorMessage);
+ if (!classDocumentationO.has_value()) {
+ qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
+ return;
+ }
+ if (!extractEnumDocumentation(classDocumentationO.value(), e)) {
+ qCWarning(lcShibokenDoc, "%s",
+ qPrintable(msgCannotFindDocumentation(sourceFileName, {}, e, {})));
+ }
+}
+
+void QtDocParser::fillDocumentation(const AbstractMetaClassPtr &metaClass)
{
if (!metaClass)
return;
- auto *context = metaClass->enclosingClass();
- while(context) {
- if (context->enclosingClass() == nullptr)
+ auto context = metaClass->enclosingClass();
+ while (context) {
+ if (!context->enclosingClass())
break;
context = context->enclosingClass();
}
@@ -218,9 +292,9 @@ void QtDocParser::fillDocumentation(AbstractMetaClass *metaClass)
+ metaClass->qualifiedCppName().toLower();
sourceFileRoot.replace(u"::"_s, u"-"_s);
- QFileInfo sourceFile(sourceFileRoot + QStringLiteral(".webxml"));
+ QFileInfo sourceFile(sourceFileRoot + webxmlSuffix);
if (!sourceFile.exists())
- sourceFile.setFile(sourceFileRoot + QStringLiteral(".xml"));
+ sourceFile.setFile(sourceFileRoot + ".xml"_L1);
if (!sourceFile.exists()) {
qCWarning(lcShibokenDoc).noquote().nospace()
<< "Can't find qdoc file for class " << metaClass->name() << ", tried: "
@@ -231,18 +305,19 @@ void QtDocParser::fillDocumentation(AbstractMetaClass *metaClass)
const QString sourceFileName = sourceFile.absoluteFilePath();
QString errorMessage;
- const ClassDocumentation classDocumentation = parseWebXml(sourceFileName, &errorMessage);
- if (!classDocumentation) {
+ const auto classDocumentationO = parseWebXml(sourceFileName, &errorMessage);
+ if (!classDocumentationO.has_value()) {
qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
return;
}
+ const auto &classDocumentation = classDocumentationO.value();
for (const auto &p : classDocumentation.properties) {
Documentation doc(p.description, p.brief);
metaClass->setPropertyDocumentation(p.name, doc);
}
- QString docString = applyDocModifications(metaClass->typeEntry()->docModifications(),
+ QString docString = applyDocModifications(DocParser::getXpathDocModifications(metaClass),
classDocumentation.description);
if (docString.isEmpty()) {
@@ -267,7 +342,7 @@ void QtDocParser::fillDocumentation(AbstractMetaClass *metaClass)
if (!errorMessage.isEmpty())
qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
const Documentation documentation(detailed, {});
- qSharedPointerConstCast<AbstractMetaFunction>(func)->setDocumentation(documentation);
+ std::const_pointer_cast<AbstractMetaFunction>(func)->setDocumentation(documentation);
}
#if 0
// Fields
@@ -283,28 +358,35 @@ void QtDocParser::fillDocumentation(AbstractMetaClass *metaClass)
#endif
// Enums
for (AbstractMetaEnum &meta_enum : metaClass->enums()) {
- Documentation enumDoc;
- const auto index = classDocumentation.indexOfEnum(meta_enum.name());
- if (index != -1) {
- QString doc = classDocumentation.enums.at(index).description;
- const auto firstPara = doc.indexOf(u"<para>");
- if (firstPara != -1) {
- const QString baseClass = QtDocParser::enumBaseClass(meta_enum);
- if (baseClass != u"Enum") {
- const QString note = u"(inherits <teletype>enum."_s + baseClass
- + u"</teletype>) "_s;
- doc.insert(firstPara + 6, note);
- }
- }
- enumDoc.setValue(doc);
- meta_enum.setDocumentation(enumDoc);
- } else {
+ if (!extractEnumDocumentation(classDocumentation, meta_enum)) {
qCWarning(lcShibokenDoc, "%s",
qPrintable(msgCannotFindDocumentation(sourceFileName, metaClass, meta_enum, {})));
}
}
}
+bool QtDocParser::extractEnumDocumentation(const ClassDocumentation &classDocumentation,
+ AbstractMetaEnum &meta_enum)
+{
+ Documentation enumDoc;
+ const auto index = classDocumentation.indexOfEnum(meta_enum.name());
+ if (index == -1)
+ return false;
+ QString doc = classDocumentation.enums.at(index).description;
+ const auto firstPara = doc.indexOf(u"<para>");
+ if (firstPara != -1) {
+ const QString baseClass = QtDocParser::enumBaseClass(meta_enum);
+ if (baseClass != "Enum"_L1) {
+ const QString note = "(inherits <teletype>enum."_L1 + baseClass
+ + "</teletype>) "_L1;
+ doc.insert(firstPara + 6, note);
+ }
+ }
+ enumDoc.setValue(doc);
+ meta_enum.setDocumentation(enumDoc);
+ return true;
+}
+
static QString qmlReferenceLink(const QFileInfo &qmlModuleFi)
{
QString result;
diff --git a/sources/shiboken6/ApiExtractor/qtdocparser.h b/sources/shiboken6/ApiExtractor/qtdocparser.h
index 402664217..f6ba5e47a 100644
--- a/sources/shiboken6/ApiExtractor/qtdocparser.h
+++ b/sources/shiboken6/ApiExtractor/qtdocparser.h
@@ -12,22 +12,28 @@ class QtDocParser : public DocParser
{
public:
QtDocParser() = default;
- void fillDocumentation(AbstractMetaClass *metaClass) override;
+ void fillDocumentation(const AbstractMetaClassPtr &metaClass) override;
+ void fillGlobalFunctionDocumentation(const AbstractMetaFunctionPtr &f) override;
+ void fillGlobalEnumDocumentation(AbstractMetaEnum &e) override;
+
Documentation retrieveModuleDocumentation() override;
Documentation retrieveModuleDocumentation(const QString& name) override;
private:
static QString functionDocumentation(const QString &sourceFileName,
const ClassDocumentation &classDocumentation,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaFunctionCPtr &func,
QString *errorMessage);
static QString queryFunctionDocumentation(const QString &sourceFileName,
const ClassDocumentation &classDocumentation,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaFunctionCPtr &func,
QString *errorMessage);
+ static bool extractEnumDocumentation(const ClassDocumentation &classDocumentation,
+ AbstractMetaEnum &meta_enum);
+
};
#endif // QTDOCPARSER_H
diff --git a/sources/shiboken6/ApiExtractor/reporthandler.cpp b/sources/shiboken6/ApiExtractor/reporthandler.cpp
index 2fc7b47b7..23066ba21 100644
--- a/sources/shiboken6/ApiExtractor/reporthandler.cpp
+++ b/sources/shiboken6/ApiExtractor/reporthandler.cpp
@@ -33,6 +33,7 @@ static ReportHandler::DebugLevel m_debugLevel = ReportHandler::NoDebug;
static QSet<QString> m_reportedWarnings;
static QString m_prefix;
static bool m_withinProgress = false;
+static QByteArray m_progressMessage;
static int m_step_warning = 0;
static QElapsedTimer m_timer;
@@ -147,9 +148,13 @@ void ReportHandler::startProgress(const QByteArray& str)
endProgress();
m_withinProgress = true;
- const auto ts = '[' + timeStamp() + ']';
- std::printf("%s %8s %-60s", qPrintable(m_prefix), ts.constData(), str.constData());
- std::fflush(stdout);
+ m_progressMessage = str;
+}
+
+static void indentStdout(qsizetype n)
+{
+ for (qsizetype i = 0; i < n; ++i)
+ fputc(' ', stdout);
}
void ReportHandler::endProgress()
@@ -158,11 +163,23 @@ void ReportHandler::endProgress()
return;
m_withinProgress = false;
+
+ std::fputs(m_prefix.toUtf8().constData(), stdout);
+ const auto ts = timeStamp();
+ if (ts.size() < 6)
+ indentStdout(6 - ts.size());
+ std::fputs(" [", stdout);
+ std::fputs(ts.constData(), stdout);
+ std::fputs("] ", stdout);
+ std::fputs(m_progressMessage.constData(), stdout);
+ if (m_progressMessage.size() < 60)
+ indentStdout(60 - m_progressMessage.size());
const char *endMessage = m_step_warning == 0
? "[" COLOR_GREEN "OK" COLOR_END "]\n"
: "[" COLOR_YELLOW "WARNING" COLOR_END "]\n";
std::fputs(endMessage, stdout);
std::fflush(stdout);
+ m_progressMessage.clear();
m_step_warning = 0;
}
diff --git a/sources/shiboken6/ApiExtractor/tests/CMakeLists.txt b/sources/shiboken6/ApiExtractor/tests/CMakeLists.txt
index 8abc88d6f..76c014fbb 100644
--- a/sources/shiboken6/ApiExtractor/tests/CMakeLists.txt
+++ b/sources/shiboken6/ApiExtractor/tests/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
set(CMAKE_AUTORCC ON)
macro(declare_test testname)
diff --git a/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp
index 8021810b3..4b5da0c3a 100644
--- a/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp
@@ -23,7 +23,7 @@ void TestAbstractMetaClass::testClassName()
<value-type name="ClassName"/>
</typesystem>)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
QCOMPARE(classes[0]->name(), u"ClassName");
@@ -39,7 +39,7 @@ void TestAbstractMetaClass::testClassNameUnderNamespace()
</namespace-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2); // 1 namespace + 1 class
if (classes.constFirst()->name() != u"ClassName")
@@ -71,7 +71,7 @@ void TestAbstractMetaClass::testClassNameUnderNamespace()
// QVERIFY(classes[0]->hasNonPrivateConstructor());
}
-static AbstractMetaFunctionCList virtualFunctions(const AbstractMetaClass *c)
+static AbstractMetaFunctionCList virtualFunctions(const AbstractMetaClassCPtr &c)
{
AbstractMetaFunctionCList result;
const auto &functions = c->functions();
@@ -110,13 +110,13 @@ public:
</typesystem>
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 4);
- auto *a = AbstractMetaClass::findClass(classes, u"A");
- auto *b = AbstractMetaClass::findClass(classes, u"B");
- auto *c = AbstractMetaClass::findClass(classes, u"C");
- const AbstractMetaClass *f = AbstractMetaClass::findClass(classes, u"F");
+ const auto a = AbstractMetaClass::findClass(classes, "A");
+ const auto b = AbstractMetaClass::findClass(classes, "B");
+ const auto c = AbstractMetaClass::findClass(classes, "C");
+ const auto f = AbstractMetaClass::findClass(classes, "F");
QVERIFY(f);
QCOMPARE(a->baseClass(), nullptr);
@@ -159,11 +159,11 @@ public:
const auto funcF = virtualFunctionsF.constFirst();
QCOMPARE(funcA->ownerClass(), a);
- QVERIFY(funcC->attributes().testFlag(AbstractMetaFunction::VirtualCppMethod));
+ QVERIFY(funcC->isVirtual());
QCOMPARE(funcB->ownerClass(), b);
QCOMPARE(funcC->ownerClass(), c);
- QVERIFY(funcC->attributes().testFlag(AbstractMetaFunction::OverriddenCppMethod));
- QVERIFY(funcF->attributes().testFlag(AbstractMetaFunction::FinalCppMethod));
+ QVERIFY(funcC->cppAttributes().testFlag(FunctionAttribute::Override));
+ QVERIFY(funcF->cppAttributes().testFlag(FunctionAttribute::Final));
QCOMPARE(funcA->declaringClass(), a);
QCOMPARE(funcB->declaringClass(), a);
@@ -194,12 +194,12 @@ class Derived : public Base {};
</typesystem>
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto base = AbstractMetaClass::findClass(classes, u"Base");
+ const auto base = AbstractMetaClass::findClass(classes, "Base");
QVERIFY(base);
QVERIFY(base->isPolymorphic());
- auto derived = AbstractMetaClass::findClass(classes, u"Derived");
+ const auto derived = AbstractMetaClass::findClass(classes, "Derived");
QVERIFY(derived);
QVERIFY(derived->isPolymorphic());
}
@@ -218,10 +218,10 @@ void TestAbstractMetaClass::testDefaultValues()
</value-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
const auto candidates = classA->queryFunctionsByName(u"method"_s);
QCOMPARE(candidates.size(), 1);
const auto &method = candidates.constFirst();
@@ -248,10 +248,10 @@ void TestAbstractMetaClass::testModifiedDefaultValues()
</value-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
const auto methodMatches = classA->queryFunctionsByName(u"method"_s);
QCOMPARE(methodMatches.size(), 1);
const auto method = methodMatches.constFirst();
@@ -274,13 +274,13 @@ void TestAbstractMetaClass::testInnerClassOfAPolymorphicOne()
</object-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QVERIFY(classA->isPolymorphic());
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"A::B");
+ const auto classB = AbstractMetaClass::findClass(classes, "A::B");
QVERIFY(classB);
QVERIFY(!classB->isPolymorphic());
}
@@ -302,15 +302,15 @@ void TestAbstractMetaClass::testForwardDeclaredInnerClass()
</value-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"A::B");
+ const auto classB = AbstractMetaClass::findClass(classes, "A::B");
QVERIFY(classB);
- const auto fooF = classB->findFunction(u"foo");
- QVERIFY(!fooF.isNull());
+ const auto fooF = classB->findFunction("foo");
+ QVERIFY(fooF);
}
void TestAbstractMetaClass::testSpecialFunctions()
@@ -333,11 +333,11 @@ void TestAbstractMetaClass::testSpecialFunctions()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
auto ctors = classA->queryFunctions(FunctionQueryOption::AnyConstructor);
QCOMPARE(ctors.size(), 2);
@@ -348,7 +348,7 @@ void TestAbstractMetaClass::testSpecialFunctions()
QCOMPARE(assigmentOps.constFirst()->functionType(),
AbstractMetaFunction::AssignmentOperatorFunction);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
ctors = classB->queryFunctions(FunctionQueryOption::AnyConstructor);
QCOMPARE(ctors.size(), 2);
@@ -399,11 +399,11 @@ void TestAbstractMetaClass::testClassDefaultConstructors()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 6);
- auto *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->functions().size(), 2);
@@ -417,28 +417,28 @@ void TestAbstractMetaClass::testClassDefaultConstructors()
QCOMPARE(ctors[1]->arguments().size(), 1);
QCOMPARE(ctors[1]->minimalSignature(), u"A(A)");
- auto *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
QCOMPARE(classB->functions().size(), 2);
QCOMPARE(classB->functions().constFirst()->minimalSignature(), u"B()");
- auto *classC = AbstractMetaClass::findClass(classes, u"C");
+ const auto classC = AbstractMetaClass::findClass(classes, "C");
QVERIFY(classC);
QCOMPARE(classC->functions().size(), 1);
QCOMPARE(classC->functions().constFirst()->minimalSignature(), u"C(C)");
- auto *classD = AbstractMetaClass::findClass(classes, u"D");
+ const auto classD = AbstractMetaClass::findClass(classes, "D");
QVERIFY(classD);
QCOMPARE(classD->functions().size(), 1);
QCOMPARE(classD->functions().constFirst()->minimalSignature(), u"D(D)");
QVERIFY(classD->functions().constFirst()->isPrivate());
- auto *classE = AbstractMetaClass::findClass(classes, u"E");
+ const auto classE = AbstractMetaClass::findClass(classes, "E");
QVERIFY(classE);
QVERIFY(classE->hasPrivateDestructor());
QCOMPARE(classE->functions().size(), 0);
- auto *classF = AbstractMetaClass::findClass(classes, u"F");
+ const auto classF = AbstractMetaClass::findClass(classes, "F");
QVERIFY(classF);
ctors = classF->queryFunctions(FunctionQueryOption::AnyConstructor);
@@ -468,10 +468,10 @@ void TestAbstractMetaClass::testClassInheritedDefaultConstructors()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
auto ctors = classA->queryFunctions(FunctionQueryOption::AnyConstructor);
@@ -485,7 +485,7 @@ void TestAbstractMetaClass::testClassInheritedDefaultConstructors()
QCOMPARE(ctors[1]->minimalSignature(), u"A(A)");
QVERIFY(ctors[1]->isPrivate());
- auto *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
ctors = classB->queryFunctions(FunctionQueryOption::Constructors);
@@ -506,10 +506,10 @@ void TestAbstractMetaClass::testAbstractClassDefaultConstructors()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
- auto *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
const auto ctors = classA->queryFunctions(FunctionQueryOption::Constructors);
@@ -527,10 +527,10 @@ void TestAbstractMetaClass::testObjectTypesMustNotHaveCopyConstructors()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
- auto *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
const auto ctors = classA->queryFunctions(FunctionQueryOption::Constructors);
@@ -563,13 +563,13 @@ void TestAbstractMetaClass::testIsPolymorphic()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto *b = AbstractMetaClass::findClass(classes, u"A");
+ const auto b = AbstractMetaClass::findClass(classes, "A");
QVERIFY(!b->isPolymorphic());
- auto *a = AbstractMetaClass::findClass(classes, u"B");
+ const auto a = AbstractMetaClass::findClass(classes, "B");
QVERIFY(!a->isPolymorphic());
}
@@ -593,12 +593,12 @@ class Derived : public BaseAlias2 {
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto base = AbstractMetaClass::findClass(classes, u"Base");
+ const auto base = AbstractMetaClass::findClass(classes, "Base");
QVERIFY(base);
- auto derived = AbstractMetaClass::findClass(classes, u"Derived");
+ const auto derived = AbstractMetaClass::findClass(classes, "Derived");
QVERIFY(derived);
QCOMPARE(derived->baseClasses().value(0), base);
}
@@ -644,7 +644,7 @@ void TestAbstractMetaClass::testFreeOperators()
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(code.constData(), xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
const auto classes = builder->classes();
QCOMPARE(classes.size(), 1);
QVERIFY(classes.constFirst()->hasArithmeticOperatorOverload());
@@ -678,12 +678,12 @@ public:
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto base = AbstractMetaClass::findClass(classes, u"Base");
+ const auto base = AbstractMetaClass::findClass(classes, "Base");
QVERIFY(base);
- auto derived = AbstractMetaClass::findClass(classes, u"Derived");
+ const auto derived = AbstractMetaClass::findClass(classes, "Derived");
QVERIFY(derived);
const auto usingMembers = derived->usingMembers();
QCOMPARE(usingMembers.size(), 2);
@@ -733,9 +733,9 @@ void TestAbstractMetaClass::testUsingTemplateMembers()
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(code.constData(), xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto valueList = AbstractMetaClass::findClass(classes, u"ValueList");
+ const auto valueList = AbstractMetaClass::findClass(classes, "ValueList");
QVERIFY(valueList);
auto list = valueList->templateBaseClass();
QVERIFY(valueList->isUsingMember(list, u"append"_s, Access::Public));
@@ -763,9 +763,9 @@ public:
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto *tc = AbstractMetaClass::findClass(classes, u"TestClass");
+ const auto tc = AbstractMetaClass::findClass(classes, "TestClass");
// Verify that the constructor and 2 functions are generated.
const auto &functions = tc->functions();
QCOMPARE(functions.size(), 5);
diff --git a/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
index 072764155..2c320c874 100644
--- a/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
@@ -54,7 +54,7 @@ void TestAbstractMetaType::testConstCharPtrType()
<function signature='justAtest()' />\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
QCOMPARE(builder->globalFunctions().size(), 1);
const auto func = builder->globalFunctions().constFirst();
AbstractMetaType rtype = func->type();
@@ -87,7 +87,7 @@ void TestAbstractMetaType::testApiVersionSupported()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
false, u"1.0"_s));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
@@ -105,7 +105,7 @@ void TestAbstractMetaType::testApiVersionNotSupported()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
true, u"0.1"_s));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
@@ -120,7 +120,7 @@ void TestAbstractMetaType::testCharType()
<function signature='justAtest()'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
@@ -157,11 +157,11 @@ void TestAbstractMetaType::testTypedef()
<value-type name='C' />\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
- const AbstractMetaClass *c = AbstractMetaClass::findClass(classes, u"C");
+ const auto c = AbstractMetaClass::findClass(classes, "C");
QVERIFY(c);
QVERIFY(c->isTypeDef());
}
@@ -182,7 +182,7 @@ void TestAbstractMetaType::testTypedefWithTemplates()
<function signature='func(A&lt;B&gt;)'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
@@ -193,7 +193,7 @@ void TestAbstractMetaType::testTypedefWithTemplates()
QCOMPARE(args.size(), 1);
const AbstractMetaArgument &arg = args.constFirst();
AbstractMetaType metaType = arg.type();
- QCOMPARE(metaType.cppSignature(), u"A<B >");
+ QCOMPARE(metaType.cppSignature(), u"A<B>");
}
@@ -207,11 +207,11 @@ void TestAbstractMetaType::testObjectTypeUsedAsValue()
<object-type name='A'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
const auto overloads = classA->queryFunctionsByName(u"method"_s);
QCOMPARE(overloads.size(), 1);
diff --git a/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp
index 72cf34693..a891e1e28 100644
--- a/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp
@@ -19,28 +19,31 @@
using namespace Qt::StringLiterals;
+static constexpr auto voidT = "void"_L1;
+
void TestAddFunction::testParsingFuncNameAndConstness()
{
// generic test...
- const char sig1[] = "func(type1, const type2, const type3* const)";
+ static constexpr auto sig1 = "func(type1, const type2, const type3* const)"_L1;
QString errorMessage;
- auto f1 = AddedFunction::createAddedFunction(QLatin1StringView(sig1), u"void"_s,
- &errorMessage);
- QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
+ auto f1 = AddedFunction::createAddedFunction(sig1, voidT, &errorMessage);
+ QVERIFY2(f1, qPrintable(errorMessage));
QCOMPARE(f1->name(), u"func");
QCOMPARE(f1->arguments().size(), 3);
TypeInfo retval = f1->returnType();
- QCOMPARE(retval.qualifiedName(), QStringList{u"void"_s});
+ QCOMPARE(retval.qualifiedName(), QStringList{voidT});
QCOMPARE(retval.indirections(), 0);
QCOMPARE(retval.isConstant(), false);
QCOMPARE(retval.referenceType(), NoReference);
// test with a ugly template as argument and other ugly stuff
- const char sig2[] = " _fu__nc_ ( type1, const type2, const Abc<int& , C<char*> * > * *@my_name@, const type3* const ) const ";
- auto f2 = AddedFunction::createAddedFunction(QLatin1StringView(sig2),
+ static constexpr auto sig2 =
+ " _fu__nc_ ( type1, const type2, const Abc<int& , C<char*> * >"
+ " * *@my_name@, const type3* const ) const "_L1;
+ auto f2 = AddedFunction::createAddedFunction(sig2,
u"const Abc<int& , C<char*> * > * *"_s,
&errorMessage);
- QVERIFY2(!f2.isNull(), qPrintable(errorMessage));
+ QVERIFY2(f2, qPrintable(errorMessage));
QCOMPARE(f2->name(), u"_fu__nc_");
const auto &args = f2->arguments();
QCOMPARE(args.size(), 4);
@@ -66,18 +69,15 @@ void TestAddFunction::testParsingFuncNameAndConstness()
QVERIFY(args.at(3).name.isEmpty());
// function with no args.
- const char sig3[] = "func()";
- auto f3 = AddedFunction::createAddedFunction(QLatin1StringView(sig3), u"void"_s,
- &errorMessage);
- QVERIFY2(!f3.isNull(), qPrintable(errorMessage));
+ auto f3 = AddedFunction::createAddedFunction("func()"_L1, voidT, &errorMessage);
+ QVERIFY2(f3, qPrintable(errorMessage));
QCOMPARE(f3->name(), u"func");
QCOMPARE(f3->arguments().size(), 0);
// const call operator
- const char sig4[] = "operator()(int)const";
- auto f4 = AddedFunction::createAddedFunction(QLatin1StringView(sig4), u"int"_s,
- &errorMessage);
- QVERIFY2(!f4.isNull(), qPrintable(errorMessage));
+ auto f4 = AddedFunction::createAddedFunction("operator()(int)const"_L1,
+ "int"_L1, &errorMessage);
+ QVERIFY2(f4, qPrintable(errorMessage));
QCOMPARE(f4->name(), u"operator()");
QCOMPARE(f4->arguments().size(), 1);
QVERIFY(f4->isConstant());
@@ -102,15 +102,15 @@ struct A {
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
auto *typeDb = TypeDatabase::instance();
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
// default ctor, default copy ctor, func a() and the added functions
QCOMPARE(classA->functions().size(), 5);
- auto addedFunc = classA->findFunction(u"b");
+ auto addedFunc = classA->findFunction("b");
QVERIFY(addedFunc);
QCOMPARE(addedFunc->access(), Access::Protected);
QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction);
@@ -131,7 +131,7 @@ struct A {
QCOMPARE(args.at(1).defaultValueExpression(), u"4.6");
QCOMPARE(args.at(2).type().typeEntry(), typeDb->findType(u"B"_s));
- auto addedCallOperator = classA->findFunction(u"operator()");
+ auto addedCallOperator = classA->findFunction("operator()");
QVERIFY(addedCallOperator);
}
@@ -146,9 +146,9 @@ void TestAddFunction::testAddFunctionConstructor()
</value-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->functions().size(), 3); // default and added ctors
const auto addedFunc = classA->functions().constLast();
@@ -169,9 +169,9 @@ void TestAddFunction::testAddFunctionTagDefaultValues()
</value-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
// default ctor, default copy ctor and the added function
QCOMPARE(classA->functions().size(), 3);
@@ -195,9 +195,9 @@ void TestAddFunction::testAddFunctionCodeSnippets()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
const auto addedFunc = classA->functions().constLast();
QVERIFY(addedFunc->hasInjectedCode());
@@ -205,11 +205,10 @@ void TestAddFunction::testAddFunctionCodeSnippets()
void TestAddFunction::testAddFunctionWithoutParenteses()
{
- const char sig1[] = "func";
+ static constexpr auto sig1 = "func"_L1;
QString errorMessage;
- auto f1 = AddedFunction::createAddedFunction(QLatin1StringView(sig1), u"void"_s,
- &errorMessage);
- QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
+ auto f1 = AddedFunction::createAddedFunction(sig1, voidT, &errorMessage);
+ QVERIFY2(f1, qPrintable(errorMessage));
QCOMPARE(f1->name(), u"func");
QCOMPARE(f1->arguments().size(), 0);
QCOMPARE(f1->isConstant(), false);
@@ -225,12 +224,12 @@ void TestAddFunction::testAddFunctionWithoutParenteses()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(u"func");
- QVERIFY(!addedFunc.isNull());
+ const auto addedFunc = classA->findFunction(sig1);
+ QVERIFY(addedFunc);
QVERIFY(addedFunc->hasInjectedCode());
const auto snips = addedFunc->injectedCodeSnips(TypeSystem::CodeSnipPositionAny,
TypeSystem::TargetLangCode);
@@ -239,11 +238,10 @@ void TestAddFunction::testAddFunctionWithoutParenteses()
void TestAddFunction::testAddFunctionWithDefaultArgs()
{
- const char sig1[] = "func";
+ static constexpr auto sig1 = "func"_L1;
QString errorMessage;
- auto f1 = AddedFunction::createAddedFunction(QLatin1StringView(sig1), u"void"_s,
- &errorMessage);
- QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
+ auto f1 = AddedFunction::createAddedFunction(sig1, voidT, &errorMessage);
+ QVERIFY2(f1, qPrintable(errorMessage));
QCOMPARE(f1->name(), u"func");
QCOMPARE(f1->arguments().size(), 0);
QCOMPARE(f1->isConstant(), false);
@@ -262,12 +260,12 @@ void TestAddFunction::testAddFunctionWithDefaultArgs()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(u"func");
- QVERIFY(!addedFunc.isNull());
+ const auto addedFunc = classA->findFunction(sig1);
+ QVERIFY(addedFunc);
const AbstractMetaArgument &arg = addedFunc->arguments().at(1);
QCOMPARE(arg.defaultValueExpression(), u"2");
}
@@ -285,9 +283,9 @@ void TestAddFunction::testAddFunctionAtModuleLevel()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
auto *typeDb = TypeDatabase::instance();
@@ -306,11 +304,10 @@ void TestAddFunction::testAddFunctionAtModuleLevel()
void TestAddFunction::testAddFunctionWithVarargs()
{
- const char sig1[] = "func(int,char,...)";
QString errorMessage;
- auto f1 = AddedFunction::createAddedFunction(QLatin1StringView(sig1), u"void"_s,
+ auto f1 = AddedFunction::createAddedFunction("func(int,char,...)"_L1, voidT,
&errorMessage);
- QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
+ QVERIFY2(f1, qPrintable(errorMessage));
QCOMPARE(f1->name(), u"func");
QCOMPARE(f1->arguments().size(), 3);
QVERIFY(!f1->isConstant());
@@ -326,12 +323,12 @@ void TestAddFunction::testAddFunctionWithVarargs()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(u"func");
- QVERIFY(!addedFunc.isNull());
+ const auto addedFunc = classA->findFunction("func");
+ QVERIFY(addedFunc);
const AbstractMetaArgument &arg = addedFunc->arguments().constLast();
QVERIFY(arg.type().isVarargs());
QVERIFY(arg.type().typeEntry()->isVarargs());
@@ -350,12 +347,12 @@ void TestAddFunction::testAddStaticFunction()
</value-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(u"func");
- QVERIFY(!addedFunc.isNull());
+ const auto addedFunc = classA->findFunction("func");
+ QVERIFY(addedFunc);
QVERIFY(addedFunc->isStatic());
}
@@ -375,13 +372,13 @@ void TestAddFunction::testAddGlobalFunction()
<value-type name='B'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
const auto globalFuncs = builder->globalFunctions();
QCOMPARE(globalFuncs.size(), 2);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(builder->classes(), u"B");
+ const auto classB = AbstractMetaClass::findClass(builder->classes(), "B");
QVERIFY(classB);
- QVERIFY(!classB->findFunction(u"globalFunc"));
- QVERIFY(!classB->findFunction(u"globalFunc2"));
+ QVERIFY(!classB->findFunction("globalFunc"));
+ QVERIFY(!classB->findFunction("globalFunc2"));
QVERIFY(!globalFuncs[0]->injectedCodeSnips().isEmpty());
QVERIFY(!globalFuncs[1]->injectedCodeSnips().isEmpty());
}
@@ -401,7 +398,7 @@ void TestAddFunction::testAddFunctionWithApiVersion()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
true, u"0.1"_s));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
const auto globalFuncs = builder->globalFunctions();
QCOMPARE(globalFuncs.size(), 1);
}
@@ -424,11 +421,11 @@ void TestAddFunction::testModifyAddedFunction()
</typesystem>
)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto *foo = AbstractMetaClass::findClass(classes, u"Foo");
- const auto method = foo->findFunction(u"method");
- QVERIFY(!method.isNull());
+ const auto foo = AbstractMetaClass::findClass(classes, "Foo");
+ const auto method = foo->findFunction("method");
+ QVERIFY(method);
QCOMPARE(method->arguments().size(), 2);
const AbstractMetaArgument &arg = method->arguments().at(1);
QCOMPARE(arg.defaultValueExpression(), u"0");
@@ -451,17 +448,17 @@ void TestAddFunction::testAddFunctionOnTypedef()
</value-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto *foo = AbstractMetaClass::findClass(classes, u"FooInt");
+ const auto foo = AbstractMetaClass::findClass(classes, "FooInt");
QVERIFY(foo);
QVERIFY(foo->hasNonPrivateConstructor());
const auto &lst = foo->queryFunctions(FunctionQueryOption::AnyConstructor);
for (const auto &f : lst)
QVERIFY(f->signature().startsWith(f->name()));
QCOMPARE(lst.size(), 2);
- const auto method = foo->findFunction(u"method");
- QVERIFY(!method.isNull());
+ const auto method = foo->findFunction("method");
+ QVERIFY(method);
}
void TestAddFunction::testAddFunctionWithTemplateArg()
@@ -475,7 +472,7 @@ void TestAddFunction::testAddFunctionWithTemplateArg()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
QCOMPARE(builder->globalFunctions().size(), 1);
const auto func = builder->globalFunctions().constFirst();
const AbstractMetaArgument &arg = func->arguments().constFirst();
diff --git a/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp b/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp
index e7c3a0106..6e1820bed 100644
--- a/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp
@@ -34,7 +34,7 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByInteger()
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
QVERIFY(!builder.isNull());
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), u"A");
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
const AbstractMetaArgument &arg = classA->functions().constLast()->arguments().constFirst();
@@ -43,10 +43,10 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByInteger()
QCOMPARE(arg.type().arrayElementType()->name(), u"double");
}
-static QString functionMinimalSignature(const AbstractMetaClass *c, const QString &name)
+static QString functionMinimalSignature(const AbstractMetaClassCPtr &c, const QString &name)
{
const auto f = c->findFunction(name);
- return f.isNull() ? QString() : f->minimalSignature();
+ return f ? f->minimalSignature() : QString();
}
void TestArrayArgument::testArraySignature()
@@ -72,7 +72,7 @@ void TestArrayArgument::testArraySignature()
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
QVERIFY(!builder.isNull());
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), u"A");
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
QCOMPARE(functionMinimalSignature(classA, u"mi1"_s),
u"mi1(int[5])");
QCOMPARE(functionMinimalSignature(classA, u"mi1c"_s),
@@ -108,7 +108,7 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValue()
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
QVERIFY(!builder.isNull());
- AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), u"A");
+ AbstractMetaClassPtr classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
auto someEnum = classA->findEnum(u"SomeEnum"_s);
@@ -138,8 +138,8 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnu
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), u"A");
+ QVERIFY(builder);
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
AbstractMetaEnum someEnum = builder->globalEnums().constFirst();
diff --git a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp
index bb8c6882b..4829e6c33 100644
--- a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp
@@ -59,14 +59,14 @@ void TestCodeInjections::testReadFile()
</value-type>\n\
</typesystem>\n"_s;
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode.toLocal8Bit().constData()));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QCOMPARE(classA->typeEntry()->codeSnips().size(), 1);
QString code = classA->typeEntry()->codeSnips().constFirst().code();
QVERIFY(code.indexOf(expected) != -1);
QVERIFY(classA->typeEntry()->isValue());
- auto vte = qSharedPointerCast<const ValueTypeEntry>(classA->typeEntry());
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(classA->typeEntry());
code = vte->targetConversionRule();
QVERIFY(code.indexOf(expected) != -1);
}
@@ -85,9 +85,9 @@ void TestCodeInjections::testInjectWithValidApiVersion()
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
true, u"1.0"_s));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QCOMPARE(classA->typeEntry()->codeSnips().size(), 1);
}
@@ -105,10 +105,10 @@ void TestCodeInjections::testInjectWithInvalidApiVersion()
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
true, u"0.1"_s));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QCOMPARE(classA->typeEntry()->codeSnips().size(), 0);
}
@@ -125,7 +125,7 @@ void TestCodeInjections::testTextStream()
str << "\n2nd table\n|" << AlignedField("bla", 3, QTextStream::AlignLeft)
<< '|' << AlignedField(QString{}, 0, QTextStream::AlignLeft) << "|\n";
-static const char expected[] = R"(void foo(int a, int b) {
+constexpr auto expected = R"(void foo(int a, int b) {
if (a == b)
return a;
#if Q_OS_WIN
@@ -141,9 +141,9 @@ static const char expected[] = R"(void foo(int a, int b) {
2nd table
|bla||
-)";
+)"_L1;
- QCOMPARE(str.toString(), QLatin1String(expected));
+ QCOMPARE(str.toString(), expected);
}
void TestCodeInjections::testTextStreamRst()
diff --git a/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp b/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp
index 4f8dcd4b7..0bb72b3c1 100644
--- a/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp
@@ -28,15 +28,15 @@ void TestContainer::testContainerType()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
//search for class A
- auto *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
auto baseContainer = classA->typeEntry()->baseContainerType();
QVERIFY(baseContainer);
- QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer.data())->containerKind(),
+ QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer.get())->containerKind(),
ContainerTypeEntry::ListContainer);
}
@@ -61,11 +61,11 @@ void TestContainer::testListOfValueType()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 3);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->templateBaseClassInstantiations().size(), 1);
const AbstractMetaType templateInstanceType =
diff --git a/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp b/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp
index f7d4b0673..8f2b277af 100644
--- a/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp
@@ -33,11 +33,11 @@ void TestConversionOperator::testConversionOperator()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
- const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, u"C");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
+ const auto classC = AbstractMetaClass::findClass(classes, "C");
QVERIFY(classA);
QVERIFY(classB);
QVERIFY(classC);
@@ -53,7 +53,7 @@ void TestConversionOperator::testConversionOperator()
break;
}
}
- QVERIFY(!convOp.isNull());
+ QVERIFY(convOp);
QVERIFY(classA->externalConversionOperators().contains(convOp));
}
@@ -71,9 +71,9 @@ void TestConversionOperator::testConversionOperatorOfDiscardedClass()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->externalConversionOperators().size(), 0);
}
@@ -95,10 +95,10 @@ void TestConversionOperator::testRemovedConversionOperator()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classA);
QVERIFY(classB);
QCOMPARE(classA->functions().size(), 2);
@@ -121,10 +121,10 @@ void TestConversionOperator::testConversionOperatorReturningReference()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classA);
QVERIFY(classB);
QCOMPARE(classA->functions().size(), 2);
@@ -155,10 +155,10 @@ void TestConversionOperator::testConversionOperatorReturningConstReference()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classA);
QVERIFY(classB);
QCOMPARE(classA->functions().size(), 2);
diff --git a/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp b/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp
index 0f3edcfe5..b5efd92a6 100644
--- a/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp
@@ -21,10 +21,10 @@ void TestConversionRuleTag::testConversionRuleTagWithFile()
{
// FIXME PYSIDE7 remove
// temp file used later
- const char conversionData[] = "Hi! I'm a conversion rule.";
+ constexpr auto conversionData = "Hi! I'm a conversion rule."_L1;
QTemporaryFile file;
- file.open();
- QCOMPARE(file.write(conversionData), qint64(sizeof(conversionData)-1));
+ QVERIFY(file.open());
+ QCOMPARE(file.write(conversionData.constData()), conversionData.size());
file.close();
const char cppCode[] = "struct A {};\n";
@@ -35,15 +35,15 @@ void TestConversionRuleTag::testConversionRuleTagWithFile()
</value-type>\n\
</typesystem>\n"_s;
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode.toLocal8Bit().data()));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
const auto typeEntry = classA->typeEntry();
QVERIFY(typeEntry->isValue());
- auto vte = qSharedPointerCast<const ValueTypeEntry>(typeEntry);
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(typeEntry);
QVERIFY(vte->hasTargetConversionRule());
- QCOMPARE(vte->targetConversionRule(), QLatin1String(conversionData));
+ QCOMPARE(vte->targetConversionRule(), conversionData);
}
void TestConversionRuleTag::testConversionRuleTagReplace()
@@ -85,10 +85,10 @@ void TestConversionRuleTag::testConversionRuleTagReplace()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
auto *typeDb = TypeDatabase::instance();
auto typeA = typeDb->findPrimitiveType(u"A"_s);
- QVERIFY(!typeA.isNull());
+ QVERIFY(typeA);
QVERIFY(typeA->hasCustomConversion());
auto conversion = typeA->customConversion();
@@ -115,7 +115,7 @@ void TestConversionRuleTag::testConversionRuleTagReplace()
QCOMPARE(toNative.sourceTypeName(), u"B");
QVERIFY(!toNative.isCustomType());
auto typeB = typeDb->findType(u"B"_s);
- QVERIFY(!typeB.isNull());
+ QVERIFY(typeB);
QCOMPARE(toNative.sourceType(), typeB);
QCOMPARE(toNative.sourceTypeCheck(), u"CheckIfInputObjectIsB(%IN)");
QCOMPARE(toNative.conversion().trimmed(), u"%OUT = %IN.createA();");
@@ -153,12 +153,12 @@ if (!TargetDateTimeAPI) TargetDateTime_IMPORT;\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
- auto *classA = AbstractMetaClass::findClass(builder->classes(), u"Date");
+ QVERIFY(builder);
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "Date");
QVERIFY(classA);
QVERIFY(classA->typeEntry()->isValue());
- auto vte = qSharedPointerCast<const ValueTypeEntry>(classA->typeEntry());
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(classA->typeEntry());
QVERIFY(vte->hasCustomConversion());
auto conversion = vte->customConversion();
@@ -216,10 +216,10 @@ void TestConversionRuleTag::testConversionRuleTagWithInsertTemplate()
"// TEMPLATE - target_to_native - END";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
auto *typeDb = TypeDatabase::instance();
auto typeA = typeDb->findPrimitiveType(u"A"_s);
- QVERIFY(!typeA.isNull());
+ QVERIFY(typeA);
QVERIFY(typeA->hasCustomConversion());
auto conversion = typeA->customConversion();
diff --git a/sources/shiboken6/ApiExtractor/tests/testctorinformation.cpp b/sources/shiboken6/ApiExtractor/tests/testctorinformation.cpp
index 7579509ff..c3a3ebef0 100644
--- a/sources/shiboken6/ApiExtractor/tests/testctorinformation.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testctorinformation.cpp
@@ -19,16 +19,16 @@ void TestCtorInformation::testCtorIsPrivate()
<value-type name='CtorLess'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 3);
- auto *klass = AbstractMetaClass::findClass(classes, u"Control");
+ auto klass = AbstractMetaClass::findClass(classes, "Control");
QVERIFY(klass);
QVERIFY(klass->hasNonPrivateConstructor());
- klass = AbstractMetaClass::findClass(classes, u"Subject");
+ klass = AbstractMetaClass::findClass(classes, "Subject");
QVERIFY(klass);
QVERIFY(!klass->hasNonPrivateConstructor());
- klass = AbstractMetaClass::findClass(classes, u"CtorLess");
+ klass = AbstractMetaClass::findClass(classes, "CtorLess");
QVERIFY(klass);
QVERIFY(klass->hasNonPrivateConstructor());
}
@@ -45,12 +45,12 @@ void TestCtorInformation::testHasNonPrivateCtor()
<object-type name='Derived'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- const AbstractMetaClass *base = AbstractMetaClass::findClass(classes, u"Base");
+ const auto base = AbstractMetaClass::findClass(classes, "Base");
QCOMPARE(base->hasNonPrivateConstructor(), true);
- const AbstractMetaClass *derived = AbstractMetaClass::findClass(classes, u"Derived");
+ const auto derived = AbstractMetaClass::findClass(classes, "Derived");
QCOMPARE(derived->hasNonPrivateConstructor(), true);
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp
index 2e07b8cba..16f50e69d 100644
--- a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp
@@ -56,16 +56,16 @@ void TestDropTypeEntries::testDropEntries()
u"Foo.NamespaceA.InnerNamespaceA"_s};
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false,
QString(), droppedEntries));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QVERIFY(AbstractMetaClass::findClass(classes, u"ValueA"));
- QVERIFY(!AbstractMetaClass::findClass(classes, u"ValueB"));
- QVERIFY(AbstractMetaClass::findClass(classes, u"ObjectA"));
- QVERIFY(!AbstractMetaClass::findClass(classes, u"ObjectB"));
- QVERIFY(AbstractMetaClass::findClass(classes, u"NamespaceA"));
- QVERIFY(!AbstractMetaClass::findClass(classes, u"NamespaceA::InnerClassA"));
- QVERIFY(!AbstractMetaClass::findClass(classes, u"NamespaceB"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "ValueA"));
+ QVERIFY(!AbstractMetaClass::findClass(classes, "ValueB"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "ObjectA"));
+ QVERIFY(!AbstractMetaClass::findClass(classes, "ObjectB"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "NamespaceA"));
+ QVERIFY(!AbstractMetaClass::findClass(classes, "NamespaceA::InnerClassA"));
+ QVERIFY(!AbstractMetaClass::findClass(classes, "NamespaceB"));
AbstractMetaEnumList globalEnums = builder->globalEnums();
QCOMPARE(globalEnums.size(), 1);
@@ -79,16 +79,16 @@ void TestDropTypeEntries::testDropEntries()
void TestDropTypeEntries::testDontDropEntries()
{
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QVERIFY(AbstractMetaClass::findClass(classes, u"ValueA"));
- QVERIFY(AbstractMetaClass::findClass(classes, u"ValueB"));
- QVERIFY(AbstractMetaClass::findClass(classes, u"ObjectA"));
- QVERIFY(AbstractMetaClass::findClass(classes, u"ObjectB"));
- QVERIFY(AbstractMetaClass::findClass(classes, u"NamespaceA"));
- QVERIFY(AbstractMetaClass::findClass(classes, u"NamespaceA::InnerClassA"));
- QVERIFY(AbstractMetaClass::findClass(classes, u"NamespaceB"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "ValueA"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "ValueB"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "ObjectA"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "ObjectB"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "NamespaceA"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "NamespaceA::InnerClassA"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "NamespaceB"));
QCOMPARE(builder->globalEnums().size(), 2);
@@ -115,21 +115,21 @@ void TestDropTypeEntries::testDropEntryWithChildTags()
QStringList droppedEntries(u"Foo.ValueA"_s);
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false,
QString(), droppedEntries));
- QVERIFY(!builder.isNull());
- QVERIFY(!AbstractMetaClass::findClass(builder->classes(), u"ValueA"));
+ QVERIFY(builder);
+ QVERIFY(!AbstractMetaClass::findClass(builder->classes(), "ValueA"));
}
void TestDropTypeEntries::testDontDropEntryWithChildTags()
{
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false));
- QVERIFY(!builder.isNull());
- QVERIFY(AbstractMetaClass::findClass(builder->classes(), u"ValueA"));
+ QVERIFY(builder);
+ QVERIFY(AbstractMetaClass::findClass(builder->classes(), "ValueA"));
}
void TestDropTypeEntries::testConditionalParsing_data()
{
- const QString xml = QStringLiteral(R"(<?xml version="1.0" encoding="UTF-8"?>
+ const QString xml = R"(<?xml version="1.0" encoding="UTF-8"?>
<root>
<tag1>text</tag1>
<?if keyword1?>
@@ -145,17 +145,17 @@ void TestDropTypeEntries::testConditionalParsing_data()
<?if !keyword99?> <!-- Exclusion only -->
<tag6>text</tag6>
<?endif?>
-</root>)");
-
- const QString root = QStringLiteral("root");
- const QString tag1 = QStringLiteral("tag1");
- const QString tag2 = QStringLiteral("tag2");
- const QString tag3 = QStringLiteral("tag3");
- const QString tag4 = QStringLiteral("tag4");
- const QString tag5 = QStringLiteral("tag5");
- const QString tag6 = QStringLiteral("tag6");
- const QString keyword1 = QStringLiteral("keyword1");
- const QString keyword2 = QStringLiteral("keyword2");
+</root>)"_L1;
+
+ constexpr auto root = "root"_L1;
+ constexpr auto tag1 = "tag1"_L1;
+ constexpr auto tag2 = "tag2"_L1;
+ constexpr auto tag3 = "tag3"_L1;
+ constexpr auto tag4 = "tag4"_L1;
+ constexpr auto tag5 = "tag5"_L1;
+ constexpr auto tag6 = "tag6"_L1;
+ constexpr auto keyword1 = "keyword1"_L1;
+ constexpr auto keyword2 = "keyword2"_L1;
QTest::addColumn<QString>("xml");
QTest::addColumn<QStringList>("keywords");
@@ -204,11 +204,11 @@ void TestDropTypeEntries::testConditionalParsing()
void TestDropTypeEntries::testEntityParsing()
{
- const QString xml = QStringLiteral(R"(<?xml version="1.0" encoding="UTF-8"?>
+ const QString xml = R"(<?xml version="1.0" encoding="UTF-8"?>
<root>
<?entity testentity word1 word2?>
<text>bla &testentity;</text>
-</root>)");
+</root>)"_L1;
QString actual;
ConditionalStreamReader reader(xml);
diff --git a/sources/shiboken6/ApiExtractor/tests/testdtorinformation.cpp b/sources/shiboken6/ApiExtractor/tests/testdtorinformation.cpp
index 95b33243e..2152d39de 100644
--- a/sources/shiboken6/ApiExtractor/tests/testdtorinformation.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testdtorinformation.cpp
@@ -25,13 +25,13 @@ private:
</typesystem>)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto *klass = AbstractMetaClass::findClass(classes, u"Control");
+ auto klass = AbstractMetaClass::findClass(classes, "Control");
QVERIFY(klass);
QVERIFY(!klass->hasPrivateDestructor());
- klass = AbstractMetaClass::findClass(classes, u"Subject");
+ klass = AbstractMetaClass::findClass(classes, "Subject");
QVERIFY(klass);
QVERIFY(klass->hasPrivateDestructor());
}
@@ -53,13 +53,13 @@ protected:
</typesystem>)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto *klass = AbstractMetaClass::findClass(classes, u"Control");
+ auto klass = AbstractMetaClass::findClass(classes, "Control");
QVERIFY(klass);
QVERIFY(!klass->hasProtectedDestructor());
- klass = AbstractMetaClass::findClass(classes, u"Subject");
+ klass = AbstractMetaClass::findClass(classes, "Subject");
QVERIFY(klass);
QVERIFY(klass->hasProtectedDestructor());
}
@@ -81,13 +81,13 @@ protected:
</typesystem>)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto *klass = AbstractMetaClass::findClass(classes, u"Control");
+ auto klass = AbstractMetaClass::findClass(classes, "Control");
QVERIFY(klass);
QVERIFY(!klass->hasVirtualDestructor());
- klass = AbstractMetaClass::findClass(classes, u"Subject");
+ klass = AbstractMetaClass::findClass(classes, "Subject");
QVERIFY(klass);
QVERIFY(klass->hasVirtualDestructor());
}
@@ -106,21 +106,21 @@ class Subject : public SubjectBase {};
</typesystem>
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 4);
- auto klass = AbstractMetaClass::findClass(classes, u"ControlBase");
+ auto klass = AbstractMetaClass::findClass(classes, "ControlBase");
QVERIFY(klass);
QVERIFY(!klass->hasVirtualDestructor());
- klass = AbstractMetaClass::findClass(classes, u"Control");
+ klass = AbstractMetaClass::findClass(classes, "Control");
QVERIFY(klass);
QVERIFY(!klass->hasVirtualDestructor());
- klass = AbstractMetaClass::findClass(classes, u"SubjectBase");
+ klass = AbstractMetaClass::findClass(classes, "SubjectBase");
QVERIFY(klass);
QVERIFY(klass->hasVirtualDestructor());
- klass = AbstractMetaClass::findClass(classes, u"Subject");
+ klass = AbstractMetaClass::findClass(classes, "Subject");
QVERIFY(klass);
QVERIFY(klass->hasVirtualDestructor());
}
@@ -142,13 +142,13 @@ protected:
</typesystem>)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto *klass = AbstractMetaClass::findClass(classes, u"Control");
+ auto klass = AbstractMetaClass::findClass(classes, "Control");
QVERIFY(klass);
QVERIFY(klass->isPolymorphic());
- klass = AbstractMetaClass::findClass(classes, u"Subject");
+ klass = AbstractMetaClass::findClass(classes, "Subject");
QVERIFY(klass);
QVERIFY(klass->isPolymorphic());
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testenum.cpp b/sources/shiboken6/ApiExtractor/tests/testenum.cpp
index e45da9e70..c7c2b8b3b 100644
--- a/sources/shiboken6/ApiExtractor/tests/testenum.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testenum.cpp
@@ -38,7 +38,7 @@ void TestEnum::testEnumCppSignature()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
@@ -54,7 +54,7 @@ void TestEnum::testEnumCppSignature()
u"A::ClassEnum");
// enum as parameter of a method
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QCOMPARE(classA->enums().size(), 1);
const auto funcs = classA->queryFunctionsByName(u"method"_s);
QVERIFY(!funcs.isEmpty());
@@ -93,7 +93,7 @@ void TestEnum::testEnumWithApiVersion()
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
true, u"0.1"_s));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
QCOMPARE(classes[0]->enums().size(), 1);
@@ -119,7 +119,7 @@ void TestEnum::testAnonymousEnum()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaEnumList globalEnums = builder->globalEnums();
QCOMPARE(globalEnums.size(), 1);
@@ -174,7 +174,7 @@ void TestEnum::testGlobalEnums()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaEnumList globalEnums = builder->globalEnums();
QCOMPARE(globalEnums.size(), 2);
@@ -222,7 +222,7 @@ void TestEnum::testEnumValueFromNeighbourEnum()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
@@ -284,9 +284,9 @@ void TestEnum::testEnumValueFromExpression()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
- AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), u"A");
+ AbstractMetaClassPtr classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
auto enumA = classA->findEnum(u"EnumA"_s);
@@ -362,9 +362,9 @@ void TestEnum::testPrivateEnum()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
- AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), u"A");
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
QCOMPARE(classA->enums().size(), 2);
@@ -401,7 +401,7 @@ void TestEnum::testTypedefEnum()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaEnumList globalEnums = builder->globalEnums();
QCOMPARE(globalEnums.size(), 1);
@@ -426,7 +426,7 @@ void TestEnum::testTypedefEnum()
struct EnumDefaultValuesFixture
{
- QSharedPointer<AbstractMetaBuilder> builder;
+ std::shared_ptr<AbstractMetaBuilder> builder;
AbstractMetaType globalEnum;
AbstractMetaType testEnum;
@@ -462,7 +462,7 @@ namespace Test2
)";
fixture->builder.reset(TestUtil::parse(cppCode, xmlCode, false));
- if (fixture->builder.isNull())
+ if (!fixture->builder)
return -1;
const auto globalEnums = fixture->builder->globalEnums();
@@ -472,8 +472,8 @@ namespace Test2
fixture->globalEnum = AbstractMetaType(globalEnums.constFirst().typeEntry());
fixture->globalEnum.decideUsagePattern();
- const AbstractMetaClass *testNamespace = nullptr;
- for (auto *c : fixture->builder->classes()) {
+ AbstractMetaClassCPtr testNamespace;
+ for (const auto &c : fixture->builder->classes()) {
if (c->name() == u"Test2") {
testNamespace = c;
break;
@@ -486,8 +486,8 @@ namespace Test2
if (namespaceEnums.size() != 2)
return -4;
QList<EnumTypeEntryCPtr > enumTypeEntries{
- qSharedPointerCast<const EnumTypeEntry>(namespaceEnums.at(0).typeEntry()),
- qSharedPointerCast<const EnumTypeEntry>(namespaceEnums.at(1).typeEntry())};
+ std::static_pointer_cast<const EnumTypeEntry>(namespaceEnums.at(0).typeEntry()),
+ std::static_pointer_cast<const EnumTypeEntry>(namespaceEnums.at(1).typeEntry())};
if (enumTypeEntries.constFirst()->flags())
std::swap(enumTypeEntries[0], enumTypeEntries[1]);
fixture->testEnum = AbstractMetaType(enumTypeEntries.at(0));
diff --git a/sources/shiboken6/ApiExtractor/tests/testextrainclude.cpp b/sources/shiboken6/ApiExtractor/tests/testextrainclude.cpp
index 048626d2a..fcc409a42 100644
--- a/sources/shiboken6/ApiExtractor/tests/testextrainclude.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testextrainclude.cpp
@@ -21,9 +21,9 @@ void TestExtraInclude::testClassExtraInclude()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QList<Include> includes = classA->typeEntry()->extraIncludes();
@@ -44,13 +44,13 @@ void TestExtraInclude::testGlobalExtraIncludes()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QVERIFY(AbstractMetaClass::findClass(classes, u"A"));
+ QVERIFY(AbstractMetaClass::findClass(classes, "A"));
auto *td = TypeDatabase::instance();
TypeSystemTypeEntryCPtr module = td->defaultTypeSystemType();
- QVERIFY(!module.isNull());
+ QVERIFY(module);
QCOMPARE(module->name(), u"Foo");
QList<Include> includes = module->extraIncludes();
diff --git a/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp b/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp
index 4a98047f1..18eaf5774 100644
--- a/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp
@@ -23,7 +23,7 @@ void TestFunctionTag::testFunctionTagForSpecificSignature()
<function signature='globalFunction(int)'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
TypeEntryCPtr func = TypeDatabase::instance()->findType(u"globalFunction"_s);
QVERIFY(func);
@@ -41,10 +41,10 @@ void TestFunctionTag::testFunctionTagForAllSignatures()
<function signature='globalFunction(float)'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
TypeEntryCPtr func = TypeDatabase::instance()->findType(u"globalFunction"_s);
- QVERIFY(!func.isNull());
+ QVERIFY(func);
QCOMPARE(builder->globalFunctions().size(), 2);
}
@@ -56,10 +56,10 @@ void TestFunctionTag::testRenameGlobalFunction()
<function signature='global_function_with_ugly_name()' rename='smooth'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
TypeEntryCPtr func = TypeDatabase::instance()->findType(u"global_function_with_ugly_name"_s);
- QVERIFY(!func.isNull());
+ QVERIFY(func);
QCOMPARE(builder->globalFunctions().size(), 1);
const auto metaFunc = builder->globalFunctions().constFirst();
diff --git a/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp b/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp
index eabd8b046..899d00ad4 100644
--- a/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp
@@ -29,12 +29,12 @@ void TestImplicitConversions::testWithPrivateCtors()
<value-type name='C'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 3);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
- const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, u"C");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classC = AbstractMetaClass::findClass(classes, "C");
const auto implicitConvs = classA->implicitConversions();
QCOMPARE(implicitConvs.size(), 1);
QCOMPARE(implicitConvs.constFirst()->arguments().constFirst().type().typeEntry(),
@@ -59,11 +59,11 @@ void TestImplicitConversions::testWithModifiedVisibility()
</typesystem>
)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
const auto implicitConvs = classA->implicitConversions();
QCOMPARE(implicitConvs.size(), 1);
QCOMPARE(implicitConvs.constFirst()->arguments().constFirst().type().typeEntry(),
@@ -93,16 +93,16 @@ void TestImplicitConversions::testWithAddedCtor()
<value-type name='C'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 3);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
auto implicitConvs = classA->implicitConversions();
QCOMPARE(implicitConvs.size(), 2);
// Added constructors with custom types should never result in implicit converters.
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
implicitConvs = classB->implicitConversions();
QCOMPARE(implicitConvs.size(), 0);
}
@@ -120,11 +120,11 @@ void TestImplicitConversions::testWithExternalConversionOperator()
<value-type name='B'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto *classA = AbstractMetaClass::findClass(classes, u"A");
- auto *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
const auto implicitConvs = classA->implicitConversions();
QCOMPARE(implicitConvs.size(), 1);
const auto &externalConvOps = classA->externalConversionOperators();
@@ -135,7 +135,7 @@ void TestImplicitConversions::testWithExternalConversionOperator()
if (func->isConversionOperator())
convOp = func;
}
- QVERIFY(!convOp.isNull());
+ QVERIFY(convOp);
QCOMPARE(implicitConvs.constFirst(), convOp);
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testinserttemplate.cpp b/sources/shiboken6/ApiExtractor/tests/testinserttemplate.cpp
index ffab76923..23cf0f9ea 100644
--- a/sources/shiboken6/ApiExtractor/tests/testinserttemplate.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testinserttemplate.cpp
@@ -25,10 +25,10 @@ void TestInsertTemplate::testInsertTemplateOnClassInjectCode()
</value-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->typeEntry()->codeSnips().size(), 1);
QString code = classA->typeEntry()->codeSnips().constFirst().code();
@@ -48,12 +48,12 @@ void TestInsertTemplate::testInsertTemplateOnModuleInjectCode()
</inject-code>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QVERIFY(classes.isEmpty());
TypeSystemTypeEntryCPtr module = TypeDatabase::instance()->defaultTypeSystemType();
- QVERIFY(!module.isNull());
+ QVERIFY(module);
QCOMPARE(module->name(), u"Foo");
QCOMPARE(module->codeSnips().size(), 1);
QString code = module->codeSnips().constFirst().code().trimmed();
diff --git a/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp b/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp
index 168f1a67b..9cf2e0cc7 100644
--- a/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp
@@ -33,8 +33,8 @@ R"(<typesystem package="Foo">
</typesystem>
)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
- AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), u"A");
+ QVERIFY(builder);
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
DocModificationList docMods = classA->typeEntry()->docModifications();
QCOMPARE(docMods.size(), 2);
@@ -47,7 +47,7 @@ R"(<typesystem package="Foo">
// cannot handle Qt resources.
QTemporaryDir tempDir(QDir::tempPath() + u"/shiboken_testmodifydocXXXXXX"_s);
QVERIFY2(tempDir.isValid(), qPrintable(tempDir.errorString()));
- const QString docFileName = u"a.xml"_s;
+ constexpr auto docFileName = "a.xml"_L1;
QVERIFY(QFile::copy(u":/"_s + docFileName, tempDir.filePath(docFileName)));
QtDocParser docParser;
@@ -94,11 +94,11 @@ void TestModifyDocumentation::testInjectAddedFunctionDocumentation()
</typesystem>
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
- AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), u"A");
+ QVERIFY(builder);
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
- const auto f = classA->findFunction(u"foo");
- QVERIFY(!f.isNull());
+ const auto f = classA->findFunction("foo");
+ QVERIFY(f);
QVERIFY(f->isUserAdded());
auto docMods = f->addedFunctionDocModifications();
QCOMPARE(docMods.size(), 1);
diff --git a/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp b/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp
index 2b2525a8c..a7d40f70a 100644
--- a/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp
@@ -46,11 +46,11 @@ void TestModifyFunction::testRenameArgument()
const QByteArray xmlCode = QByteArray(xmlCode1) + pattern + QByteArray(xmlCode2);
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode.constData(), false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
- const auto func = classA->findFunction(u"method");
- QVERIFY(!func.isNull());
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto func = classA->findFunction("method");
+ QVERIFY(func);
QCOMPARE(func->argumentName(1), u"otherArg");
}
@@ -74,11 +74,11 @@ void TestModifyFunction::testOwnershipTransfer()
</object-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
- const auto func = classB->findFunction(u"method");
- QVERIFY(!func.isNull());
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
+ const auto func = classB->findFunction("method");
+ QVERIFY(func);
QCOMPARE(func->argumentTargetOwnership(func->ownerClass(), 0),
TypeSystem::CppOwnership);
@@ -124,47 +124,47 @@ void TestModifyFunction::invalidateAfterUse()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
false, u"0.1"_s));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
- auto func = classB->findFunction(u"call");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
+ auto func = classB->findFunction("call");
QCOMPARE(func->modifications().size(), 1);
QCOMPARE(func->modifications().at(0).argument_mods().size(), 1);
QVERIFY(func->modifications().at(0).argument_mods().at(0).resetAfterUse());
- const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, u"C");
+ const auto classC = AbstractMetaClass::findClass(classes, "C");
QVERIFY(classC);
- func = classC->findFunction(u"call");
+ func = classC->findFunction("call");
QCOMPARE(func->modifications().size(), 1);
QCOMPARE(func->modifications().at(0).argument_mods().size(), 1);
QVERIFY(func->modifications().at(0).argument_mods().at(0).resetAfterUse());
- func = classC->findFunction(u"call2");
+ func = classC->findFunction("call2");
QCOMPARE(func->modifications().size(), 1);
QCOMPARE(func->modifications().at(0).argument_mods().size(), 1);
QVERIFY(func->modifications().at(0).argument_mods().at(0).resetAfterUse());
- const AbstractMetaClass *classD = AbstractMetaClass::findClass(classes, u"D");
+ AbstractMetaClassCPtr classD = AbstractMetaClass::findClass(classes, "D");
QVERIFY(classD);
- func = classD->findFunction(u"call");
+ func = classD->findFunction("call");
QCOMPARE(func->modifications().size(), 1);
QCOMPARE(func->modifications().at(0).argument_mods().size(), 1);
QVERIFY(func->modifications().at(0).argument_mods().at(0).resetAfterUse());
- func = classD->findFunction(u"call2");
+ func = classD->findFunction("call2");
QCOMPARE(func->modifications().size(), 1);
QCOMPARE(func->modifications().at(0).argument_mods().size(), 1);
QVERIFY(func->modifications().at(0).argument_mods().at(0).resetAfterUse());
- const AbstractMetaClass *classE = AbstractMetaClass::findClass(classes, u"E");
+ const auto classE = AbstractMetaClass::findClass(classes, "E");
QVERIFY(classE);
- func = classE->findFunction(u"call");
+ func = classE->findFunction("call");
QVERIFY(func);
QCOMPARE(func->modifications().size(), 1);
QCOMPARE(func->modifications().at(0).argument_mods().size(), 1);
QVERIFY(func->modifications().at(0).argument_mods().at(0).resetAfterUse());
- func = classE->findFunction(u"call2");
+ func = classE->findFunction("call2");
QVERIFY(func);
QCOMPARE(func->modifications().size(), 1);
QCOMPARE(func->modifications().at(0).argument_mods().size(), 1);
@@ -197,15 +197,15 @@ void TestModifyFunction::testWithApiVersion()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
false, u"0.1"_s));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto *classB = AbstractMetaClass::findClass(classes, u"B");
- auto func = classB->findFunction(u"method");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
+ auto func = classB->findFunction("method");
auto returnOwnership = func->argumentTargetOwnership(func->ownerClass(), 0);
QCOMPARE(returnOwnership, TypeSystem::CppOwnership);
- func = classB->findFunction(u"methodB");
+ func = classB->findFunction("methodB");
returnOwnership = func->argumentTargetOwnership(func->ownerClass(), 0);
QVERIFY(returnOwnership != TypeSystem::CppOwnership);
}
@@ -236,34 +236,34 @@ struct A {
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
false, u"0.1"_s));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
// Nothing specified, true
- const auto f1 = classA->findFunction(u"f1");
- QVERIFY(!f1.isNull());
+ const auto f1 = classA->findFunction("f1");
+ QVERIFY(f1);
QVERIFY(!f1->allowThread());
// 'auto' specified, should be false for nontrivial function
- const auto f2 = classA->findFunction(u"f2");
- QVERIFY(!f2.isNull());
+ const auto f2 = classA->findFunction("f2");
+ QVERIFY(f2);
QVERIFY(f2->allowThread());
// 'no' specified, should be false
- const auto f3 = classA->findFunction(u"f3");
- QVERIFY(!f3.isNull());
+ const auto f3 = classA->findFunction("f3");
+ QVERIFY(f3);
QVERIFY(!f3->allowThread());
// Nothing specified, should be false for simple getter
- const auto getter1 = classA->findFunction(u"getter1");
- QVERIFY(!getter1.isNull());
+ const auto getter1 = classA->findFunction("getter1");
+ QVERIFY(getter1);
QVERIFY(!getter1->allowThread());
// Forced to true simple getter
- const auto getter2 = classA->findFunction(u"getter2");
- QVERIFY(!getter2.isNull());
+ const auto getter2 = classA->findFunction("getter2");
+ QVERIFY(getter2);
QVERIFY(getter2->allowThread()); // Forced to true simple getter
}
@@ -286,7 +286,7 @@ void TestModifyFunction::testGlobalFunctionModification()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
QCOMPARE(builder->globalFunctions().size(), 1);
auto *td = TypeDatabase::instance();
@@ -434,44 +434,44 @@ void TestModifyFunction::testScopedModifications()
QFETCH(bool, expectedAllowThread);
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode.constData(), xmlCode.constData(), false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), u"A");
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
- auto f = classA->findFunction(QStringLiteral("unspecified"));
- QVERIFY(!f.isNull());
+ auto f = classA->findFunction("unspecified");
+ QVERIFY(f);
QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::Unknown);
QCOMPARE(f->generateExceptionHandling(), expectedGenerateUnspecified);
QCOMPARE(f->allowThread(), expectedAllowThread);
- f = classA->findFunction(QStringLiteral("nonThrowing"));
- QVERIFY(!f.isNull());
+ f = classA->findFunction("nonThrowing");
+ QVERIFY(f);
QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::NoExcept);
QCOMPARE(f->generateExceptionHandling(), expectedGenerateNonThrowing);
- f = classA->findFunction(QStringLiteral("throwing"));
- QVERIFY(!f.isNull());
+ f = classA->findFunction("throwing");
+ QVERIFY(f);
QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::Throws);
QCOMPARE(f->generateExceptionHandling(), expectedGenerateThrowing);
}
void TestModifyFunction::testSnakeCaseRenaming_data()
{
- QTest::addColumn<QString>("name");
- QTest::addColumn<QString>("expected");
+ QTest::addColumn<QLatin1StringView>("name");
+ QTest::addColumn<QLatin1StringView>("expected");
QTest::newRow("s1")
- << QStringLiteral("snakeCaseFunc") << QStringLiteral("snake_case_func");
+ << "snakeCaseFunc"_L1 << "snake_case_func"_L1;
QTest::newRow("s2")
- << QStringLiteral("SnakeCaseFunc") << QStringLiteral("snake_case_func");
+ << "SnakeCaseFunc"_L1 << "snake_case_func"_L1;
QTest::newRow("consecutive-uppercase")
- << QStringLiteral("snakeCAseFunc") << QStringLiteral("snakeCAseFunc");
+ << "snakeCAseFunc"_L1 << "snakeCAseFunc"_L1;
}
void TestModifyFunction::testSnakeCaseRenaming()
{
- QFETCH(QString, name);
- QFETCH(QString, expected);
+ QFETCH(QLatin1StringView, name);
+ QFETCH(QLatin1StringView, expected);
const QString actual = AbstractMetaBuilder::getSnakeCaseName(name);
QCOMPARE(actual, expected);
diff --git a/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp b/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp
index a3f955602..1cf4c8e0f 100644
--- a/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp
@@ -31,11 +31,11 @@ void TestMultipleInheritance::testVirtualClass()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 4);
- const AbstractMetaClass *classD = AbstractMetaClass::findClass(classes, u"D");
+ const auto classD = AbstractMetaClass::findClass(classes, "D");
bool functionFound = false;
for (const auto &f : classD->functions()) {
if (f->name() == u"theBug") {
diff --git a/sources/shiboken6/ApiExtractor/tests/testnamespace.cpp b/sources/shiboken6/ApiExtractor/tests/testnamespace.cpp
index 248812048..3773e614a 100644
--- a/sources/shiboken6/ApiExtractor/tests/testnamespace.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testnamespace.cpp
@@ -31,14 +31,14 @@ void NamespaceTest::testNamespaceMembers()
</namespace-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- AbstractMetaClass *ns = AbstractMetaClass::findClass(classes, u"Namespace");
+ const auto ns = AbstractMetaClass::findClass(classes, "Namespace");
QVERIFY(ns);
auto metaEnum = ns->findEnum(u"Option"_s);
QVERIFY(metaEnum.has_value());
- const auto func = ns->findFunction(u"foo");
- QVERIFY(!func.isNull());
+ const auto func = ns->findFunction("foo");
+ QVERIFY(func);
}
void NamespaceTest::testNamespaceInnerClassMembers()
@@ -61,16 +61,16 @@ void NamespaceTest::testNamespaceInnerClassMembers()
</namespace-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *ons = AbstractMetaClass::findClass(classes, u"OuterNamespace");
+ const auto ons = AbstractMetaClass::findClass(classes, "OuterNamespace");
QVERIFY(ons);
- const AbstractMetaClass *ins = AbstractMetaClass::findClass(classes, u"OuterNamespace::InnerNamespace");
+ const auto ins = AbstractMetaClass::findClass(classes, "OuterNamespace::InnerNamespace");
QVERIFY(ins);
- const AbstractMetaClass *sc = AbstractMetaClass::findClass(classes, u"OuterNamespace::InnerNamespace::SomeClass");
+ const auto sc = AbstractMetaClass::findClass(classes, "OuterNamespace::InnerNamespace::SomeClass");
QVERIFY(sc);
- const auto meth = sc->findFunction(u"method");
- QVERIFY(!meth.isNull());
+ const auto meth = sc->findFunction("method");
+ QVERIFY(meth);
}
QTEST_APPLESS_MAIN(NamespaceTest)
diff --git a/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp b/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp
index f6daab0b8..10ca1a0f6 100644
--- a/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp
@@ -43,13 +43,13 @@ void TestNestedTypes::testNestedTypesModifications()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto *ons = AbstractMetaClass::findClass(classes, u"OuterNamespace");
+ const auto ons = AbstractMetaClass::findClass(classes, "OuterNamespace");
QVERIFY(ons);
- auto *ins = AbstractMetaClass::findClass(classes, u"OuterNamespace::InnerNamespace");
+ const auto ins = AbstractMetaClass::findClass(classes, "OuterNamespace::InnerNamespace");
QVERIFY(ins);
QCOMPARE(ins->functions().size(), 1);
QCOMPARE(ins->typeEntry()->codeSnips().size(), 1);
@@ -68,8 +68,9 @@ void TestNestedTypes::testNestedTypesModifications()
snip = addedFunc->modifications().constFirst().snips().constFirst();
QCOMPARE(snip.code().trimmed(), u"custom_code2();");
- auto *sc = AbstractMetaClass::findClass(classes, u"OuterNamespace::InnerNamespace::SomeClass");
- QVERIFY(ins);
+ const auto sc =
+ AbstractMetaClass::findClass(classes, "OuterNamespace::InnerNamespace::SomeClass");
+ QVERIFY(sc);
QCOMPARE(sc->functions().size(), 2); // default constructor and removed method
const auto removedFunc = sc->functions().constLast();
QVERIFY(removedFunc->isModifiedRemoved());
@@ -92,23 +93,23 @@ void TestNestedTypes::testDuplicationOfNestedTypes()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
- auto *nspace = AbstractMetaClass::findClass(classes, u"Namespace");
+ const auto nspace = AbstractMetaClass::findClass(classes, "Namespace");
QVERIFY(nspace);
- auto *cls1 = AbstractMetaClass::findClass(classes, u"SomeClass");
+ const auto cls1 = AbstractMetaClass::findClass(classes, "SomeClass");
QVERIFY(cls1);
- auto *cls2 = AbstractMetaClass::findClass(classes, u"Namespace::SomeClass");
+ const auto cls2 = AbstractMetaClass::findClass(classes, "Namespace::SomeClass");
QVERIFY(cls2);
QCOMPARE(cls1, cls2);
QCOMPARE(cls1->name(), u"SomeClass");
QCOMPARE(cls1->qualifiedCppName(), u"Namespace::SomeClass");
auto t1 = TypeDatabase::instance()->findType(u"Namespace::SomeClass"_s);
- QVERIFY(!t1.isNull());
+ QVERIFY(t1);
auto t2 = TypeDatabase::instance()->findType(u"SomeClass"_s);
- QVERIFY(t2.isNull());
+ QVERIFY(!t2);
}
QTEST_APPLESS_MAIN(TestNestedTypes)
diff --git a/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp b/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp
index 8dc9b641b..9eef7ec47 100644
--- a/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp
@@ -24,7 +24,7 @@ void TestNumericalTypedef::testNumericalTypedef()
<function signature='funcReal(real)'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
QCOMPARE(builder->globalFunctions().size(), 2);
auto funcDouble = builder->globalFunctions().constFirst();
@@ -63,7 +63,7 @@ void TestNumericalTypedef::testUnsignedNumericalTypedef()
<function signature='funcUShort(custom_ushort)'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
QCOMPARE(builder->globalFunctions().size(), 2);
auto funcUnsignedShort = builder->globalFunctions().constFirst();
diff --git a/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.cpp b/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.cpp
index ba2b25829..99cced09d 100644
--- a/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.cpp
@@ -23,15 +23,15 @@ void TestPrimitiveTypeTag::testPrimitiveTypeDefaultConstructor()
<object-type name='B'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
auto typeEntry = TypeDatabase::instance()->findPrimitiveType(u"A"_s);
- QVERIFY(!typeEntry.isNull());
+ QVERIFY(typeEntry);
QVERIFY(typeEntry->hasDefaultConstructor());
QCOMPARE(typeEntry->defaultConstructor(), u"A()");
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp b/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp
index ef83d99fb..f2e261624 100644
--- a/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp
@@ -32,11 +32,11 @@ void TestRefCountTag::testReferenceCountTag()
</object-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
- const auto func = classB->findFunction(u"keepObject");
- QVERIFY(!func.isNull());
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
+ const auto func = classB->findFunction("keepObject");
+ QVERIFY(func);
const auto refCount =
func->modifications().constFirst().argument_mods().constFirst().referenceCounts().constFirst();
QCOMPARE(refCount.action, ReferenceCount::Add);
@@ -66,11 +66,11 @@ void TestRefCountTag::testWithApiVersion()
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
false, u"0.1"_s));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
- const auto func = classB->findFunction(u"keepObject");
- QVERIFY(!func.isNull());
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
+ const auto func = classB->findFunction("keepObject");
+ QVERIFY(func);
const auto refCount =
func->modifications().constFirst().argument_mods().constFirst().referenceCounts().constFirst();
QCOMPARE(refCount.action, ReferenceCount::Add);
diff --git a/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp b/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp
index 74a0adcea..ae85c5a86 100644
--- a/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp
@@ -23,12 +23,12 @@ void TestReferenceToPointer::testReferenceToPointerArgument()
<object-type name='B'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
- const auto func = classB->findFunction(u"dummy");
- QVERIFY(!func.isNull());
+ const auto func = classB->findFunction("dummy");
+ QVERIFY(func);
QCOMPARE(func->arguments().constFirst().type().minimalSignature(), u"A*&");
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp b/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp
index e0acb0e5b..2cc82071b 100644
--- a/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp
@@ -4,10 +4,15 @@
#include "testremovefield.h"
#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetafield.h>
+#include <abstractmetafunction.h>
+#include <abstractmetatype.h>
#include <abstractmetalang.h>
#include <typesystem.h>
+using namespace Qt::StringLiterals;
+
void TestRemoveField::testRemoveField()
{
const char cppCode[] = "\
@@ -23,15 +28,49 @@ void TestRemoveField::testRemoveField()
</value-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->fields().size(), 1);
const AbstractMetaField &fieldA = classA->fields().constFirst();
QCOMPARE(fieldA.name(), u"fieldA");
}
+// Verify that 'static constexpr' fields are seen as static/const and
+// appear fully qualified for function parameter default values.
+void TestRemoveField::testConstExprField()
+{
+ const char cppCode[] = R"(
+struct A {
+ static constexpr int constExprField = 44;
+
+ void f(int iParam=constExprField);
+};
+)";
+
+ const char xmlCode[] = R"(
+<typesystem package="Foo">
+ <value-type name='A'/>
+</typesystem>
+)";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(builder);
+ AbstractMetaClassList classes = builder->classes();
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ QVERIFY(classA);
+ const auto &fields = classA->fields();
+ QCOMPARE(fields.size(), 1);
+ QVERIFY(fields.constFirst().isStatic());
+ QVERIFY(fields.constFirst().type().isConstant());
+ const auto function = classA->findFunction("f"_L1);
+ QVERIFY(function);
+ const auto &arguments = function->arguments();
+ QCOMPARE(arguments.size(), 1);
+ QCOMPARE(arguments.constFirst().defaultValueExpression(), "A::constExprField"_L1);
+}
+
QTEST_APPLESS_MAIN(TestRemoveField)
diff --git a/sources/shiboken6/ApiExtractor/tests/testremovefield.h b/sources/shiboken6/ApiExtractor/tests/testremovefield.h
index febe672ce..05912d99e 100644
--- a/sources/shiboken6/ApiExtractor/tests/testremovefield.h
+++ b/sources/shiboken6/ApiExtractor/tests/testremovefield.h
@@ -11,6 +11,7 @@ class TestRemoveField : public QObject
Q_OBJECT
private slots:
void testRemoveField();
+ void testConstExprField();
};
#endif
diff --git a/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp b/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp
index 59528d517..87e318e95 100644
--- a/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp
@@ -30,14 +30,14 @@ void TestRemoveImplConv::testRemoveImplConv()
</value-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 3);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
- const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, u"C");
+ const auto classC = AbstractMetaClass::findClass(classes, "C");
QVERIFY(classC);
const auto implConv = classC->implicitConversions();
QCOMPARE(implConv.size(), 1);
diff --git a/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp b/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp
index a6d929c8f..17a069b5e 100644
--- a/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp
@@ -15,28 +15,29 @@ using namespace Qt::StringLiterals;
void TestRemoveOperatorMethod::testRemoveOperatorMethod()
{
- const char cppCode[] = "\
- #include <stdint.h>\n\
- \n\
- struct Char {};\n\
- struct ByteArray {};\n\
- struct String {};\n\
- \n\
- struct A {\n\
- A& operator>>(char&);\n\
- A& operator>>(char*);\n\
- A& operator>>(short&);\n\
- A& operator>>(unsigned short&);\n\
- A& operator>>(int&);\n\
- A& operator>>(unsigned int&);\n\
- A& operator>>(int64_t&);\n\
- A& operator>>(uint64_t&);\n\
- A& operator>>(float&);\n\
- A& operator>>(double&);\n\
- A& operator>>(Char&);\n\
- A& operator>>(ByteArray&);\n\
- A& operator>>(String&);\n\
- };\n";
+ const char cppCode[] = R"(#include <cstdint>
+
+struct Char {};
+struct ByteArray {};
+struct String {};
+
+struct A {
+ A& operator>>(char&);
+ A& operator>>(char*);
+ A& operator>>(short&);
+ A& operator>>(unsigned short&);
+ A& operator>>(int&);
+ A& operator>>(unsigned int&);
+ A& operator>>(int64_t&);
+ A& operator>>(uint64_t&);
+ A& operator>>(float&);
+ A& operator>>(double&);
+ A& operator>>(Char&);
+ A& operator>>(ByteArray&);
+ A& operator>>(String&);
+};
+)";
+
const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='char'/>\n\
@@ -67,9 +68,9 @@ void TestRemoveOperatorMethod::testRemoveOperatorMethod()
</object-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->functions().size(), 14);
QStringList removedSignatures;
diff --git a/sources/shiboken6/ApiExtractor/tests/testresolvetype.cpp b/sources/shiboken6/ApiExtractor/tests/testresolvetype.cpp
index a798c4339..67ebcc606 100644
--- a/sources/shiboken6/ApiExtractor/tests/testresolvetype.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testresolvetype.cpp
@@ -4,10 +4,12 @@
#include "testresolvetype.h"
#include "testutil.h"
#include <abstractmetaargument.h>
+#include <abstractmetaenum.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
#include <abstractmetatype.h>
#include <complextypeentry.h>
+#include <enumtypeentry.h>
#include <primitivetypeentry.h>
#include <typedatabase.h>
@@ -45,12 +47,12 @@ void TestResolveType::testResolveReturnTypeFromParentScope()
</namespace-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classD = AbstractMetaClass::findClass(classes, u"A::D");
+ const auto classD = AbstractMetaClass::findClass(classes, "A::D");
QVERIFY(classD);
- const auto meth = classD->findFunction(u"method");
- QVERIFY(!meth.isNull());
+ const auto meth = classD->findFunction("method");
+ QVERIFY(meth);
QVERIFY(meth);
}
@@ -60,13 +62,14 @@ void TestResolveType::testResolveReturnTypeFromParentScope()
struct DefaultValuesFixture
{
- QSharedPointer<AbstractMetaBuilder> builder;
+ std::shared_ptr<AbstractMetaBuilder> builder;
AbstractMetaType intType;
AbstractMetaType stringType;
AbstractMetaType classType;
AbstractMetaType listType;
- const AbstractMetaClass *klass{};
+ AbstractMetaType enumType;
+ AbstractMetaClassCPtr klass{};
};
Q_DECLARE_METATYPE(DefaultValuesFixture)
@@ -91,6 +94,7 @@ public:
static const int INT_FIELD_1 = 42;
static const char *CHAR_FIELD_1;
+ static const Enum DefaultValue = enumValue1;
};
} // Namespace
)";
@@ -106,7 +110,7 @@ public:
)";
fixture->builder.reset(TestUtil::parse(cppCode, xmlCode, false));
- if (fixture->builder.isNull())
+ if (!fixture->builder)
return -1;
for (const auto &klass : fixture->builder->classes()) {
@@ -121,7 +125,7 @@ public:
fixture->classType = AbstractMetaType(fixture->klass->typeEntry());
fixture->classType.decideUsagePattern();
- for (const auto &f : fixture->klass->findFunctions(u"Test"_s)) {
+ for (const auto &f : fixture->klass->findFunctions("Test")) {
if (f->functionType() == AbstractMetaFunction::ConstructorFunction
&& f->arguments().size() == 1) {
const auto type = f->arguments().constFirst().type();
@@ -134,11 +138,14 @@ public:
if (fixture->intType.isVoid() || fixture->stringType.isVoid())
return -3;
- auto listFunc = fixture->klass->findFunction(u"listFunc"_s);
- if (listFunc.isNull() || listFunc->arguments().size() != 1)
+ auto listFunc = fixture->klass->findFunction("listFunc");
+ if (!listFunc || listFunc->arguments().size() != 1)
return -3;
fixture->listType = listFunc->arguments().constFirst().type();
+ fixture->enumType = AbstractMetaType(fixture->klass->enums().constFirst().typeEntry());
+ fixture->enumType.decideUsagePattern();
+
return 0;
}
@@ -213,6 +220,11 @@ void TestResolveType::testFixDefaultArguments_data()
QTest::newRow("self from enum")
<< fixture << setupOk << fixture.classType
<< "Test(enumValue1)" << expected;
+
+ // Don't qualify fields to "Test::Enum::DefaultValue"
+ QTest::newRow("enum from static field")
+ << fixture << setupOk << fixture.enumType
+ << "DefaultValue" << u"Namespace::Test::DefaultValue"_s;
}
void TestResolveType::testFixDefaultArguments()
@@ -251,16 +263,16 @@ public:
)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *testClass = AbstractMetaClass::findClass(classes, u"Test");
+ const auto testClass = AbstractMetaClass::findClass(classes, "Test");
QVERIFY(testClass);
auto *tdb = TypeDatabase::instance();
auto int32TEntry = tdb->findType(u"int32_t"_s);
- QVERIFY2(!int32TEntry.isNull(), "int32_t not found");
+ QVERIFY2(int32TEntry, "int32_t not found");
QVERIFY(int32TEntry->isPrimitive());
- auto int32T = qSharedPointerCast<const PrimitiveTypeEntry>(int32TEntry);
+ auto int32T = std::static_pointer_cast<const PrimitiveTypeEntry>(int32TEntry);
auto basicType = basicReferencedTypeEntry(int32T);
QVERIFY2(basicType != int32T,
"Typedef for int32_t not found. Check the system include paths.");
diff --git a/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp b/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp
index 0e191668b..f4eecff2c 100644
--- a/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp
@@ -25,9 +25,9 @@ void TestReverseOperators::testReverseSum()
</typesystem>";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->functions().size(), 4);
@@ -42,10 +42,10 @@ void TestReverseOperators::testReverseSum()
}
}
- QVERIFY(!normalOp.isNull());
+ QVERIFY(normalOp);
QVERIFY(!normalOp->isReverseOperator());
QCOMPARE(normalOp->arguments().size(), 1);
- QVERIFY(!reverseOp.isNull());
+ QVERIFY(reverseOp);
QVERIFY(reverseOp->isReverseOperator());
QCOMPARE(reverseOp->arguments().size(), 1);
}
@@ -67,13 +67,13 @@ void TestReverseOperators::testReverseSumWithAmbiguity()
</typesystem>";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->functions().size(), 4);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
QCOMPARE(classB->functions().size(), 4);
@@ -87,11 +87,11 @@ void TestReverseOperators::testReverseSumWithAmbiguity()
normalOp = func;
}
}
- QVERIFY(!normalOp.isNull());
+ QVERIFY(normalOp);
QVERIFY(!normalOp->isReverseOperator());
QCOMPARE(normalOp->arguments().size(), 1);
QCOMPARE(normalOp->minimalSignature(), u"operator+(B,A)");
- QVERIFY(!reverseOp.isNull());
+ QVERIFY(reverseOp);
QVERIFY(reverseOp->isReverseOperator());
QCOMPARE(reverseOp->arguments().size(), 1);
QCOMPARE(reverseOp->minimalSignature(), u"operator+(A,B)");
@@ -111,10 +111,10 @@ void TestReverseOperators::testSpaceshipOperator()
</typesystem>)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false,
{}, {}, LanguageLevel::Cpp20));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
- const AbstractMetaClass *testClass = AbstractMetaClass::findClass(classes, u"Test");
+ const auto testClass = AbstractMetaClass::findClass(classes, "Test");
QVERIFY(testClass);
const auto &functions = testClass->functions();
// 6 operators should be synthesized
diff --git a/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp
index 65c95e378..ea37c6255 100644
--- a/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp
@@ -55,16 +55,16 @@ namespace Internet {
</typesystem>)XML").arg(file.fileName());
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, qPrintable(xmlCode1), false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto *classB = AbstractMetaClass::findClass(classes, u"Bookmarks");
+ const auto classB = AbstractMetaClass::findClass(classes, "Bookmarks");
QVERIFY(classB);
- const auto func = classB->findFunction(u"list");
- QVERIFY(!func.isNull());
+ const auto func = classB->findFunction("list");
+ QVERIFY(func);
AbstractMetaType funcType = func->type();
QVERIFY(!funcType.isVoid());
- QCOMPARE(funcType.cppSignature(), u"QList<Internet::Url >");
+ QCOMPARE(funcType.cppSignature(), u"QList<Internet::Url>");
}
void TestTemplates::testTemplateOnContainers()
@@ -93,15 +93,15 @@ namespace Namespace {
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
QVERIFY(!classB->baseClass());
QVERIFY(classB->baseClassName().isEmpty());
- const auto func = classB->findFunction(u"foo");
- QVERIFY(!func.isNull());
+ const auto func = classB->findFunction("foo");
+ QVERIFY(func);
AbstractMetaType argType = func->arguments().constFirst().type();
QCOMPARE(argType.instantiations().size(), 1);
QCOMPARE(argType.typeEntry()->qualifiedCppName(), u"QList");
@@ -130,14 +130,14 @@ void func(List<int> arg) {}
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
const auto globalFuncs = builder->globalFunctions();
QCOMPARE(globalFuncs.size(), 1);
const auto func = globalFuncs.constFirst();
QCOMPARE(func->minimalSignature(), u"func(List<int>)");
QCOMPARE(func->arguments().constFirst().type().cppSignature(),
- u"List<int >");
+ u"List<int>");
}
void TestTemplates::testTemplatePointerAsArgument()
@@ -155,14 +155,14 @@ void func(List<int>* arg) {}
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaFunctionCList globalFuncs = builder->globalFunctions();
QCOMPARE(globalFuncs.size(), 1);
const auto func = globalFuncs.constFirst();
QCOMPARE(func->minimalSignature(), u"func(List<int>*)");
QCOMPARE(func->arguments().constFirst().type().cppSignature(),
- u"List<int > *");
+ u"List<int> *");
}
void TestTemplates::testTemplateReferenceAsArgument()
@@ -180,14 +180,14 @@ void func(List<int>& arg) {}
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
const auto globalFuncs = builder->globalFunctions();
QCOMPARE(globalFuncs.size(), 1);
const auto func = globalFuncs.constFirst();
QCOMPARE(func->minimalSignature(), u"func(List<int>&)");
QCOMPARE(func->arguments().constFirst().type().cppSignature(),
- u"List<int > &");
+ u"List<int> &");
}
void TestTemplates::testTemplateParameterFixup()
@@ -209,21 +209,20 @@ struct List {
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
const AbstractMetaClassList templates = builder->templates();
QCOMPARE(templates.size(), 1);
- const AbstractMetaClass *list = templates.constFirst();
- // Verify that the parameter of "void append(List l)" gets fixed to "List<T >"
- const auto append = list->findFunction(QStringLiteral("append"));
- QVERIFY(!append.isNull());
+ AbstractMetaClassCPtr list = templates.constFirst();
+ // Verify that the parameter of "void append(List l)" gets fixed to "List<T>"
+ const auto append = list->findFunction("append");
+ QVERIFY(append);
QCOMPARE(append->arguments().size(), 1);
- QCOMPARE(append->arguments().at(0).type().cppSignature(), u"List<T >");
+ QCOMPARE(append->arguments().at(0).type().cppSignature(), u"List<T>");
// Verify that the parameter of "void erase(Iterator)" is not modified
- const auto erase = list->findFunction(QStringLiteral("erase"));
- QVERIFY(!erase.isNull());
+ const auto erase = list->findFunction("erase");
+ QVERIFY(erase);
QCOMPARE(erase->arguments().size(), 1);
- QEXPECT_FAIL("", "Clang: Some other code changes the parameter type", Abort);
QCOMPARE(erase->arguments().at(0).type().cppSignature(), u"List::Iterator");
}
@@ -250,16 +249,16 @@ struct FooBars : public ListContainer<FooBar> {};
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
AbstractMetaClassList templates = builder->templates();
QCOMPARE(classes.size(), 2);
QCOMPARE(templates.size(), 1);
- const auto *foobars = AbstractMetaClass::findClass(classes, u"FooBars");
+ const auto foobars = AbstractMetaClass::findClass(classes, "FooBars");
QCOMPARE(foobars->functions().size(), 4);
- const AbstractMetaClass *lc = templates.constFirst();
+ AbstractMetaClassCPtr lc = templates.constFirst();
QCOMPARE(lc->functions().size(), 2);
}
@@ -287,10 +286,10 @@ template<SomeEnum type> struct Future {};
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
QVERIFY(!classB->baseClass());
QVERIFY(classB->baseClassName().isEmpty());
@@ -326,10 +325,10 @@ template<SomeEnum type> struct Future {};
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto *classB = AbstractMetaClass::findClass(classes, u"Namespace::B");
+ const auto classB = AbstractMetaClass::findClass(classes, "Namespace::B");
QVERIFY(classB);
QVERIFY(!classB->baseClass());
QVERIFY(classB->baseClassName().isEmpty());
@@ -362,13 +361,13 @@ typedef BaseTemplateClass<TypeOne> TypeOneClass;
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 3);
- const auto *base = AbstractMetaClass::findClass(classes, u"BaseTemplateClass");
+ const auto base = AbstractMetaClass::findClass(classes, "BaseTemplateClass");
QVERIFY(base);
- const auto *one = AbstractMetaClass::findClass(classes, u"TypeOneClass");
+ const auto one = AbstractMetaClass::findClass(classes, "TypeOneClass");
QVERIFY(one);
QCOMPARE(one->templateBaseClass(), base);
QCOMPARE(one->functions().size(), base->functions().size());
@@ -376,7 +375,7 @@ typedef BaseTemplateClass<TypeOne> TypeOneClass;
auto oneType = one->typeEntry();
auto baseType = base->typeEntry();
QCOMPARE(oneType->baseContainerType(), baseType);
- QCOMPARE(one->baseClassNames(), QStringList(u"BaseTemplateClass<TypeOne>"_s));
+ QCOMPARE(one->baseClassNames(), QStringList(u"NSpace::BaseTemplateClass<NSpace::TypeOne>"_s));
QVERIFY(one->hasTemplateBaseClassInstantiations());
AbstractMetaTypeList instantiations = one->templateBaseClassInstantiations();
@@ -411,27 +410,27 @@ typedef Vector<int> IntVector;
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
- auto *vector = AbstractMetaClass::findClass(classes, u"IntVector");
+ const auto vector = AbstractMetaClass::findClass(classes, "IntVector");
QVERIFY(vector);
auto baseContainer = vector->typeEntry()->baseContainerType();
- QVERIFY(!baseContainer.isNull());
- QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer.data())->containerKind(),
+ QVERIFY(baseContainer);
+ QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer.get())->containerKind(),
ContainerTypeEntry::ListContainer);
QCOMPARE(vector->functions().size(), 4);
- const auto method = vector->findFunction(u"method");
- QVERIFY(!method.isNull());
- QCOMPARE(method->signature(), u"method(const Vector<int > & vector)");
+ const auto method = vector->findFunction("method");
+ QVERIFY(method);
+ QCOMPARE(method->signature(), u"method(const Vector<int> & vector)");
- const auto otherMethod = vector->findFunction(u"otherMethod");
- QVERIFY(!otherMethod.isNull());
+ const auto otherMethod = vector->findFunction("otherMethod");
+ QVERIFY(otherMethod);
QCOMPARE(otherMethod->signature(), u"otherMethod()");
QVERIFY(!otherMethod->type().isVoid());
- QCOMPARE(otherMethod->type().cppSignature(), u"Vector<int >");
+ QCOMPARE(otherMethod->type().cppSignature(), u"Vector<int>");
}
void TestTemplates::testNonTypeTemplates()
@@ -455,7 +454,7 @@ Array<int, 2> foo();
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
auto functions = builder->globalFunctions();
QCOMPARE(functions.size(), 1);
auto foo = functions.constFirst();
@@ -538,32 +537,30 @@ void TestTemplates::testTemplateTypeDefs()
const QByteArray cppBa = cpp.toLocal8Bit();
const QByteArray xmlBa = xml.toLocal8Bit();
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppBa.constData(), xmlBa.constData(), true));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *optional = AbstractMetaClass::findClass(classes, u"Optional");
+ const auto optional = AbstractMetaClass::findClass(classes, "Optional");
QVERIFY(optional);
// Find the typedef'ed class
- const AbstractMetaClass *optionalInt =
- AbstractMetaClass::findClass(classes, u"IntOptional");
+ const auto optionalInt = AbstractMetaClass::findClass(classes, "IntOptional");
QVERIFY(optionalInt);
QCOMPARE(optionalInt->templateBaseClass(), optional);
// Find the class typedef'ed in the typesystem XML
- const AbstractMetaClass *xmlOptionalInt =
- AbstractMetaClass::findClass(classes, u"XmlIntOptional");
+ const auto xmlOptionalInt = AbstractMetaClass::findClass(classes, "XmlIntOptional");
QVERIFY(xmlOptionalInt);
QCOMPARE(xmlOptionalInt->templateBaseClass(), optional);
// Check whether the value() method now has an 'int' return
- const auto valueMethod = optionalInt->findFunction(u"value");
- QVERIFY(!valueMethod.isNull());
+ const auto valueMethod = optionalInt->findFunction("value");
+ QVERIFY(valueMethod);
QCOMPARE(valueMethod->type().cppSignature(), u"int");
// ditto for typesystem XML
- const auto xmlValueMethod = xmlOptionalInt->findFunction(u"value");
- QVERIFY(!xmlValueMethod.isNull());
+ const auto xmlValueMethod = xmlOptionalInt->findFunction("value");
+ QVERIFY(xmlValueMethod);
QCOMPARE(xmlValueMethod->type().cppSignature(), u"int");
// Check whether the m_value field is of type 'int'
@@ -609,10 +606,10 @@ public:
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- auto testClass = AbstractMetaClass::findClass(classes, u"Test");
+ const auto testClass = AbstractMetaClass::findClass(classes, "Test");
QVERIFY(testClass);
auto fields = testClass->fields();
@@ -621,9 +618,10 @@ public:
QCOMPARE(fieldType.name(), u"Container1");
QCOMPARE(fieldType.instantiations().size(), 1);
- auto derived = AbstractMetaClass::findClass(classes, u"Derived");
+ const auto derived = AbstractMetaClass::findClass(classes, "Derived");
QVERIFY(derived);
auto base = derived->templateBaseClass();
+ QVERIFY(base);
QCOMPARE(base->name(), u"Container1");
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp b/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp
index 1ebe71ef6..72dae8cc5 100644
--- a/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp
@@ -30,15 +30,15 @@ void TestTypeRevision::testRevisionAttr()
"</object-type>"
"</typesystem>";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *rev0 = AbstractMetaClass::findClass(classes, u"Rev_0");
+ const auto rev0 = AbstractMetaClass::findClass(classes, "Rev_0");
QCOMPARE(rev0->typeEntry()->revision(), 0);
- const AbstractMetaClass *rev1 = AbstractMetaClass::findClass(classes, u"Rev_1");
+ const auto rev1 = AbstractMetaClass::findClass(classes, "Rev_1");
QCOMPARE(rev1->typeEntry()->revision(), 1);
- AbstractMetaClass *rev2 = AbstractMetaClass::findClass(classes, u"Rev_2");
+ const auto rev2 = AbstractMetaClass::findClass(classes, "Rev_2");
QCOMPARE(rev2->typeEntry()->revision(), 2);
auto rev3 = rev2->findEnum(u"Rev_3"_s);
@@ -82,7 +82,7 @@ class Bar20 {};
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, version));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
QCOMPARE(builder->classes().size(), expectedClassCount);
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testutil.h b/sources/shiboken6/ApiExtractor/tests/testutil.h
index e19517e85..dc4e3b2da 100644
--- a/sources/shiboken6/ApiExtractor/tests/testutil.h
+++ b/sources/shiboken6/ApiExtractor/tests/testutil.h
@@ -27,19 +27,19 @@ namespace TestUtil
auto *td = TypeDatabase::instance(true);
if (apiVersion.isEmpty())
TypeDatabase::clearApiVersions();
- else if (!TypeDatabase::setApiVersion(QStringLiteral("*"), apiVersion))
+ else if (!TypeDatabase::setApiVersion(QLatin1StringView("*"), apiVersion))
return nullptr;
td->setDropTypeEntries(dropTypeEntries);
QBuffer buffer;
// parse typesystem
buffer.setData(xmlCode);
if (!buffer.open(QIODevice::ReadOnly))
- return Q_NULLPTR;
+ return nullptr;
if (!td->parseFile(&buffer))
return nullptr;
buffer.close();
// parse C++ code
- QTemporaryFile tempSource(QDir::tempPath() + QStringLiteral("/st_XXXXXX_main.cpp"));
+ QTemporaryFile tempSource(QDir::tempPath() + QLatin1StringView("/st_XXXXXX_main.cpp"));
if (!tempSource.open()) {
qWarning().noquote().nospace() << "Creation of temporary file failed: "
<< tempSource.errorString();
diff --git a/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.cpp b/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.cpp
index 06fbe9ee3..98e30eac2 100644
--- a/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.cpp
@@ -22,16 +22,16 @@ void TestValueTypeDefaultCtorTag::testValueTypeDefaultCtorTagArgument()
<value-type name='B' />\n\
</typesystem>";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QVERIFY(classA->typeEntry()->hasDefaultConstructor());
QCOMPARE(classA->typeEntry()->defaultConstructor(), u"A(0, 0)");
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, u"B");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
QVERIFY(!classB->typeEntry()->hasDefaultConstructor());
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp b/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp
index 255a33953..a600181a5 100644
--- a/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp
@@ -17,12 +17,12 @@ void TestVoidArg::testVoidParsedFunction()
<value-type name='A'/>\n\
</typesystem>";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(u"a");
- QVERIFY(!addedFunc.isNull());
+ const auto addedFunc = classA->findFunction("a");
+ QVERIFY(addedFunc);
QCOMPARE(addedFunc->arguments().size(), 0);
}
@@ -36,12 +36,12 @@ void TestVoidArg::testVoidAddedFunction()
</value-type>\n\
</typesystem>";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(u"a");
- QVERIFY(!addedFunc.isNull());
+ const auto addedFunc = classA->findFunction("a");
+ QVERIFY(addedFunc);
QCOMPARE(addedFunc->arguments().size(), 0);
}
@@ -54,12 +54,12 @@ void TestVoidArg::testVoidPointerParsedFunction()
<value-type name='A' />\n\
</typesystem>";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, u"A");
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(u"a");
- QVERIFY(!addedFunc.isNull());
+ const auto addedFunc = classA->findFunction("a");
+ QVERIFY(addedFunc);
QCOMPARE(addedFunc->arguments().size(), 1);
}
diff --git a/sources/shiboken6/ApiExtractor/textstream.h b/sources/shiboken6/ApiExtractor/textstream.h
index 074e23858..228f36405 100644
--- a/sources/shiboken6/ApiExtractor/textstream.h
+++ b/sources/shiboken6/ApiExtractor/textstream.h
@@ -31,7 +31,7 @@ public:
virtual ~TextStream();
Language language() const { return m_language; }
- void setLanguage(const Language &language) { m_language = language; }
+ void setLanguage(Language language) { m_language = language; }
bool isIndentationEnabled() const { return m_indentationEnabled; }
void setIndentationEnabled(bool m)
@@ -77,6 +77,10 @@ public:
void putRawChar(char c) { m_str << c; }
TextStream &operator<<(QStringView v) { putString(v); return *this; }
+ TextStream &operator<<(const QString &qs) { putString(QStringView{qs}); return *this; }
+ TextStream &operator<<(QLatin1StringView lv) { putString(lv.constData()); return *this; }
+ TextStream &operator<<(QUtf8StringView uv) { putString(uv.data()); return *this; }
+ TextStream &operator<<(const QByteArray &ba) { putString(ba.constData()); return *this; }
TextStream &operator<<(QChar c) { putChar(c); return *this; }
TextStream &operator<<(const char *s) { putString(s); return *this; }
TextStream &operator<<(char c) { putChar(c); return *this; }
@@ -85,7 +89,7 @@ public:
TextStream &operator<<(qsizetype t) { putSizeType(t); return *this; }
#endif
- inline TextStream &operator<<(QTextStreamManipulator m) { m_str << m; return *this; }
+ inline TextStream &operator<<(const QTextStreamManipulator &m) { m_str << m; return *this; }
inline TextStream &operator<<(ManipulatorFunc f) { f(*this); return *this; }
void putRepetitiveChars(char c, int count);
@@ -140,6 +144,12 @@ void rstCodeOff(TextStream &s);
void rstItalic(TextStream &s);
void rstItalicOff(TextStream &s);
+inline TextStream &operator<<(TextStream &str, QAnyStringView asv)
+{
+ asv.visit([&str](auto s) { str << s; });
+ return str;
+}
+
/// Format an aligned field
template <class T>
class AlignedField
@@ -179,6 +189,28 @@ TextStream &operator<<(TextStream &str, const AlignedField<T> &fa)
return str;
}
+class Pad
+{
+public:
+ explicit Pad(char c, int count) : m_char(c), m_count(count) {}
+
+ void write(TextStream &str) const
+ {
+ for (int i = 0; i < m_count; ++i)
+ str << m_char;
+ }
+
+private:
+ const char m_char;
+ const int m_count;
+};
+
+inline TextStream &operator<<(TextStream &str, const Pad &pad)
+{
+ pad.write(str);
+ return str;
+}
+
class Indentation
{
public:
diff --git a/sources/shiboken6/ApiExtractor/typedatabase.cpp b/sources/shiboken6/ApiExtractor/typedatabase.cpp
index c185907b0..61fd22418 100644
--- a/sources/shiboken6/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken6/ApiExtractor/typedatabase.cpp
@@ -10,11 +10,14 @@
#include "constantvaluetypeentry.h"
#include "containertypeentry.h"
#include "customtypenentry.h"
+#include "debughelpers_p.h"
+#include "exception.h"
#include "flagstypeentry.h"
#include "functiontypeentry.h"
#include "namespacetypeentry.h"
#include "objecttypeentry.h"
#include "primitivetypeentry.h"
+#include "optionsparser.h"
#include "pythontypeentry.h"
#include "smartpointertypeentry.h"
#include "typedefentry.h"
@@ -32,29 +35,29 @@
#include <QtCore/QFile>
#include <QtCore/QDebug>
#include <QtCore/QDir>
-#include <QtCore/QPair>
#include <QtCore/QList>
#include <QtCore/QRegularExpression>
#include <QtCore/QVersionNumber>
#include <QtCore/QXmlStreamReader>
#include "reporthandler.h"
-// #include <tr1/tuple>
+
#include <algorithm>
+#include <utility>
using namespace Qt::StringLiterals;
-using TypeDatabaseParserContextPtr = QSharedPointer<TypeDatabaseParserContext>;
+using TypeDatabaseParserContextPtr = std::shared_ptr<TypeDatabaseParserContext>;
// package -> api-version
static QString wildcardToRegExp(QString w)
{
w.replace(u'?', u'.');
- w.replace(u'*', QStringLiteral(".*"));
+ w.replace(u'*', ".*"_L1);
return w;
}
-using ApiVersion =QPair<QRegularExpression, QVersionNumber>;
+using ApiVersion = std::pair<QRegularExpression, QVersionNumber>;
using ApiVersions = QList<ApiVersion>;
Q_GLOBAL_STATIC(ApiVersions, apiVersions)
@@ -85,7 +88,8 @@ static const PythonTypes &builtinPythonTypes()
{u"PyObject"_s, u"true"_s, TypeSystem::CPythonType::Other},
// shiboken-specific
{u"PyPathLike"_s, u"Shiboken::String::checkPath"_s, TypeSystem::CPythonType::Other},
- {u"PySequence"_s, u"Shiboken::String::checkIterable"_s, TypeSystem::CPythonType::Other},
+ {u"PySequence"_s, u"Shiboken::String::checkIterableArgument"_s,
+ TypeSystem::CPythonType::Other},
{u"PyUnicode"_s, u"PyUnicode_Check"_s, TypeSystem::CPythonType::String},
{u"PyTypeObject"_s, u"PyType_Check"_s, TypeSystem::CPythonType::Other},
{u"str"_s, u"Shiboken::String::check"_s, TypeSystem::CPythonType::String},
@@ -100,7 +104,127 @@ static const PythonTypes &builtinPythonTypes()
return result;
}
-struct TypeDatabasePrivate
+struct SuppressedWarning
+{
+ QRegularExpression pattern;
+ QString rawText;
+ bool generate; // Current type system
+ mutable bool matched = false;
+};
+
+QList<OptionDescription> TypeDatabase::options()
+{
+ return {
+ {u"api-version=<\"package mask\">,<\"version\">"_s,
+ u"Specify the supported api version used to generate the bindings"_s},
+ {u"drop-type-entries=\"<TypeEntry0>[;TypeEntry1;...]\""_s,
+ u"Semicolon separated list of type system entries (classes, namespaces,\n"
+ "global functions and enums) to be dropped from generation."_s},
+ {u"-T<path>"_s, {} },
+ {u"typesystem-paths="_s + OptionsParser::pathSyntax(),
+ u"Paths used when searching for typesystems"_s},
+ {u"force-process-system-include-paths="_s + OptionsParser::pathSyntax(),
+ u"Include paths that are considered as system headers by the C++ parser, but should still "
+ "be processed to extract types (e.g. Qt include paths in a yocto sysroot)"_s},
+ {u"keywords=keyword1[,keyword2,...]"_s,
+ u"A comma-separated list of keywords for conditional typesystem parsing"_s},
+ };
+}
+
+struct TypeDatabaseOptions
+{
+ QStringList m_dropTypeEntries;
+ QStringList m_forceProcessSystemIncludes;
+ QStringList m_typesystemKeywords;
+ QStringList m_typesystemPaths;
+ bool m_suppressWarnings = true;
+};
+
+class TypeDatabaseOptionsParser : public OptionsParser
+{
+public:
+ explicit TypeDatabaseOptionsParser(TypeDatabaseOptions *o) : m_options(o) {}
+
+ bool handleBoolOption(const QString &key, OptionSource source) override;
+ bool handleOption(const QString &key, const QString &value, OptionSource source) override;
+
+private:
+ TypeDatabaseOptions *m_options;
+};
+
+bool TypeDatabaseOptionsParser::handleBoolOption(const QString &key, OptionSource source)
+{
+ switch (source) {
+ case OptionSource::CommandLine:
+ case OptionSource::ProjectFile:
+ if (key == u"no-suppress-warnings") {
+ m_options->m_suppressWarnings = false;
+ return true;
+ }
+ break;
+ case OptionSource::CommandLineSingleDash:
+ if (key.startsWith(u'T')) { // "-T/path" ends up a bool option
+ m_options->m_typesystemPaths += key.sliced(1).split(QDir::listSeparator(),
+ Qt::SkipEmptyParts);
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+bool TypeDatabaseOptionsParser::handleOption(const QString &key, const QString &value,
+ OptionSource source)
+{
+ if (source == OptionSource::CommandLineSingleDash)
+ return false;
+ if (key == u"api-version") {
+ const auto fullVersions = QStringView{value}.split(u'|');
+ for (const auto &fullVersion : fullVersions) {
+ const auto parts = fullVersion.split(u',');
+ const QString package = parts.size() == 1
+ ? u"*"_s : parts.constFirst().toString();
+ const QString version = parts.constLast().toString();
+ if (!TypeDatabase::setApiVersion(package, version))
+ throw Exception(msgInvalidVersion(package, version));
+ }
+ return true;
+ }
+
+ if (key == u"drop-type-entries") {
+ m_options->m_dropTypeEntries = value.split(u';');
+ m_options->m_dropTypeEntries.sort();
+ return true;
+ }
+
+ if (key == u"keywords") {
+ m_options->m_typesystemKeywords = value.split(u',');
+ return true;
+ }
+
+ if (key == u"typesystem-paths") {
+ m_options->m_typesystemPaths += value.split(QDir::listSeparator(),
+ Qt::SkipEmptyParts);
+ return true;
+ }
+
+ if (key == u"force-process-system-include-paths") {
+ m_options->m_forceProcessSystemIncludes += value.split(QDir::listSeparator(),
+ Qt::SkipEmptyParts);
+ return true;
+ }
+
+ if (source == OptionSource::ProjectFile) {
+ if (key == u"typesystem-path") {
+ m_options->m_typesystemPaths += value;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+struct TypeDatabasePrivate : public TypeDatabaseOptions
{
TypeSystemTypeEntryCPtr defaultTypeSystemType() const;
TypeEntryPtr findType(const QString &name) const;
@@ -128,11 +252,12 @@ struct TypeDatabasePrivate
const CustomTypeEntryPtr &targetLang);
void addBuiltInPrimitiveTypes();
void addBuiltInContainerTypes(const TypeDatabaseParserContextPtr &context);
+ bool addOpaqueContainers(const TypeDatabaseParserContextPtr &context);
TypeEntryMultiMapConstIteratorRange findTypeRange(const QString &name) const;
template <class Predicate>
TypeEntryCList findTypesHelper(const QString &name, Predicate pred) const;
template <class Type, class Predicate>
- QList<QSharedPointer<const Type> > findTypesByTypeHelper(Predicate pred) const;
+ QList<std::shared_ptr<const Type> > findTypesByTypeHelper(Predicate pred) const;
TypeEntryPtr resolveTypeDefEntry(const TypedefEntryPtr &typedefEntry, QString *errorMessage);
template <class String>
bool isSuppressedWarningHelper(const String &s) const;
@@ -140,12 +265,11 @@ struct TypeDatabasePrivate
void formatDebug(QDebug &d) const;
void formatBuiltinTypes(QDebug &d) const;
- bool m_suppressWarnings = true;
TypeEntryMultiMap m_entries; // Contains duplicate entries (cf addInlineNamespaceLookups).
TypeEntryMap m_flagsEntries;
TypedefEntryMap m_typedefEntries;
TemplateEntryMap m_templates;
- QList<QRegularExpression> m_suppressedWarnings;
+ QList<SuppressedWarning> m_suppressedWarnings;
QList<TypeSystemTypeEntryCPtr > m_typeSystemEntries; // maintain order, default is first.
AddedFunctionList m_globalUserFunctions;
@@ -153,18 +277,22 @@ struct TypeDatabasePrivate
QStringList m_requiredTargetImports;
- QStringList m_typesystemPaths;
- QStringList m_typesystemKeywords;
QHash<QString, bool> m_parsedTypesystemFiles;
QList<TypeRejection> m_rejections;
-
- QStringList m_dropTypeEntries;
- QStringList m_systemIncludes;
};
+static const char ENV_TYPESYSTEMPATH[] = "TYPESYSTEMPATH";
+
TypeDatabase::TypeDatabase() : d(new TypeDatabasePrivate)
{
+ // Environment TYPESYSTEMPATH
+ if (qEnvironmentVariableIsSet(ENV_TYPESYSTEMPATH)) {
+ d->m_typesystemPaths
+ += qEnvironmentVariable(ENV_TYPESYSTEMPATH).split(QDir::listSeparator(),
+ Qt::SkipEmptyParts);
+ }
+
d->addBuiltInType(TypeEntryPtr(new VoidTypeEntry()));
d->addBuiltInType(TypeEntryPtr(new VarargsTypeEntry()));
for (const auto &pt : builtinPythonTypes())
@@ -179,6 +307,11 @@ TypeDatabase::~TypeDatabase()
delete d;
}
+std::shared_ptr<OptionsParser> TypeDatabase::createOptionsParser()
+{
+ return std::make_shared<TypeDatabaseOptionsParser>(d);
+}
+
TypeDatabase *TypeDatabase::instance(bool newInstance)
{
static TypeDatabase *db = nullptr;
@@ -205,12 +338,11 @@ static const IntTypeNormalizationEntries &intTypeNormalizationEntries()
static bool firstTime = true;
if (firstTime) {
firstTime = false;
- for (auto t : {"char", "short", "int", "long"}) {
- const QString intType = QLatin1StringView(t);
+ for (const auto &intType : {"char"_L1, "short"_L1, "int"_L1, "long"_L1}) {
if (!TypeDatabase::instance()->findType(u'u' + intType)) {
IntTypeNormalizationEntry entry;
- entry.replacement = QStringLiteral("unsigned ") + intType;
- entry.regex.setPattern(QStringLiteral("\\bu") + intType + QStringLiteral("\\b"));
+ entry.replacement = "unsigned "_L1 + intType;
+ entry.regex.setPattern("\\bu"_L1 + intType + "\\b"_L1);
Q_ASSERT(entry.regex.isValid());
result.append(entry);
}
@@ -296,26 +428,11 @@ void TypeDatabase::addRequiredTargetImport(const QString& moduleName)
d->m_requiredTargetImports << moduleName;
}
-void TypeDatabase::addTypesystemPath(const QString& typesystem_paths)
-{
- #if defined(Q_OS_WIN32)
- const char path_splitter = ';';
- #else
- const char path_splitter = ':';
- #endif
- d->m_typesystemPaths += typesystem_paths.split(QLatin1Char(path_splitter));
-}
-
-void TypeDatabase::setTypesystemKeywords(const QStringList &keywords)
-{
- d->m_typesystemKeywords = keywords;
-}
-
QStringList TypeDatabase::typesystemKeywords() const
{
QStringList result = d->m_typesystemKeywords;
for (const auto &d : d->m_dropTypeEntries)
- result.append(QStringLiteral("no_") + d);
+ result.append("no_"_L1 + d);
switch (clang::emulatedCompilerLanguageLevel()) {
case LanguageLevel::Cpp11:
@@ -339,17 +456,17 @@ QStringList TypeDatabase::typesystemKeywords() const
IncludeList TypeDatabase::extraIncludes(const QString& className) const
{
auto typeEntry = findComplexType(className);
- return typeEntry.isNull() ? IncludeList() : typeEntry->extraIncludes();
+ return typeEntry ? typeEntry->extraIncludes() : IncludeList();
}
-const QStringList &TypeDatabase::systemIncludes() const
+const QStringList &TypeDatabase::forceProcessSystemIncludes() const
{
- return d->m_systemIncludes;
+ return d->m_forceProcessSystemIncludes;
}
-void TypeDatabase::addSystemInclude(const QString &name)
+void TypeDatabase::addForceProcessSystemInclude(const QString &name)
{
- d->m_systemIncludes.append(name);
+ d->m_forceProcessSystemIncludes.append(name);
}
// Add a lookup for the short name excluding inline namespaces
@@ -370,20 +487,20 @@ ContainerTypeEntryPtr TypeDatabase::findContainerType(const QString &name) const
{
QString template_name = name;
- int pos = name.indexOf(u'<');
+ const auto pos = name.indexOf(u'<');
if (pos > 0)
template_name = name.left(pos);
auto type_entry = findType(template_name);
if (type_entry && type_entry->isContainer())
- return qSharedPointerCast<ContainerTypeEntry>(type_entry);
+ return std::static_pointer_cast<ContainerTypeEntry>(type_entry);
return {};
}
static bool inline useType(const TypeEntryCPtr &t)
{
return !t->isPrimitive()
- || qSharedPointerCast<const PrimitiveTypeEntry>(t)->preferredTargetLangType();
+ || std::static_pointer_cast<const PrimitiveTypeEntry>(t)->preferredTargetLangType();
}
FunctionTypeEntryPtr TypeDatabase::findFunctionType(const QString &name) const
@@ -391,7 +508,7 @@ FunctionTypeEntryPtr TypeDatabase::findFunctionType(const QString &name) const
const auto entries = d->findTypeRange(name);
for (const TypeEntryPtr &entry : entries) {
if (entry->type() == TypeEntry::FunctionType && useType(entry))
- return qSharedPointerCast<FunctionTypeEntry>(entry);
+ return std::static_pointer_cast<FunctionTypeEntry>(entry);
}
return {};
}
@@ -415,6 +532,17 @@ TypeSystemTypeEntryCPtr TypeDatabase::defaultTypeSystemType() const
return d->defaultTypeSystemType();
}
+QString TypeDatabase::loadedTypeSystemNames() const
+{
+ QString result;
+ for (const auto &entry : d->m_typeSystemEntries) {
+ if (!result.isEmpty())
+ result += u", "_s;
+ result += entry->name();
+ }
+ return result;
+}
+
TypeSystemTypeEntryCPtr TypeDatabasePrivate::defaultTypeSystemType() const
{
return m_typeSystemEntries.value(0, nullptr);
@@ -454,12 +582,12 @@ TypeEntryCList TypeDatabasePrivate::findTypesHelper(const QString &name, Predica
}
template<class Type, class Predicate>
-QList<QSharedPointer<const Type> > TypeDatabasePrivate::findTypesByTypeHelper(Predicate pred) const
+QList<std::shared_ptr<const Type> > TypeDatabasePrivate::findTypesByTypeHelper(Predicate pred) const
{
- QList<QSharedPointer<const Type> > result;
+ QList<std::shared_ptr<const Type> > result;
for (const auto &entry : m_entries) {
if (pred(entry))
- result.append(qSharedPointerCast<const Type>(entry));
+ result.append(std::static_pointer_cast<const Type>(entry));
}
return result;
}
@@ -559,6 +687,7 @@ bool TypeDatabase::isClassRejected(const QString& className, QString *reason) co
{
for (const TypeRejection& r : d->m_rejections) {
if (r.matchType == TypeRejection::ExcludeClass && r.className.match(className).hasMatch()) {
+ r.matched = true;
if (reason)
*reason = msgRejectReason(r);
return true;
@@ -577,6 +706,7 @@ static bool findRejection(const QList<TypeRejection> &rejections,
for (const TypeRejection& r : rejections) {
if (r.matchType == matchType && r.pattern.match(name).hasMatch()
&& r.className.match(className).hasMatch()) {
+ r.matched = true;
if (reason)
*reason = msgRejectReason(r, name);
return true;
@@ -594,7 +724,7 @@ TypeEntryPtr TypeDatabasePrivate::resolveTypeDefEntry(const TypedefEntryPtr &typ
QString *errorMessage)
{
QString sourceName = typedefEntry->sourceType();
- const int lessThanPos = sourceName.indexOf(u'<');
+ const auto lessThanPos = sourceName.indexOf(u'<');
if (lessThanPos != -1)
sourceName.truncate(lessThanPos);
ComplexTypeEntryPtr source;
@@ -604,8 +734,8 @@ TypeEntryPtr TypeDatabasePrivate::resolveTypeDefEntry(const TypedefEntryPtr &typ
case TypeEntry::ContainerType:
case TypeEntry::ObjectType:
case TypeEntry::SmartPointerType:
- source = qSharedPointerDynamicCast<ComplexTypeEntry>(e);
- Q_ASSERT(!source.isNull());
+ source = std::dynamic_pointer_cast<ComplexTypeEntry>(e);
+ Q_ASSERT(source);
break;
default:
break;
@@ -613,8 +743,7 @@ TypeEntryPtr TypeDatabasePrivate::resolveTypeDefEntry(const TypedefEntryPtr &typ
}
if (!source) {
if (errorMessage)
- *errorMessage = u"Unable to resolve typedef \""_s
- + typedefEntry->sourceType() + u'"';
+ *errorMessage = msgUnableToResolveTypedef(typedefEntry->sourceType(), sourceName);
return nullptr;
}
@@ -641,8 +770,8 @@ bool TypeDatabase::addType(const TypeEntryPtr &e, QString *errorMessage)
bool TypeDatabasePrivate::addType(TypeEntryPtr e, QString *errorMessage)
{
if (e->type() == TypeEntry::TypedefType) {
- e = resolveTypeDefEntry(qSharedPointerCast<TypedefEntry>(e), errorMessage);
- if (Q_UNLIKELY(e.isNull()))
+ e = resolveTypeDefEntry(std::static_pointer_cast<TypedefEntry>(e), errorMessage);
+ if (Q_UNLIKELY(!e))
return false;
}
m_entries.insert(e->qualifiedCppName(), e);
@@ -654,7 +783,7 @@ ConstantValueTypeEntryPtr
TypeDatabase::addConstantValueTypeEntry(const QString &value,
const TypeEntryCPtr &parent)
{
- ConstantValueTypeEntryPtr result(new ConstantValueTypeEntry(value, parent));
+ auto result = std::make_shared<ConstantValueTypeEntry>(value, parent);
result->setCodeGeneration(TypeEntry::GenerateNothing);
addType(result);
return result;
@@ -687,7 +816,7 @@ bool TypeDatabase::isReturnTypeRejected(const QString& className, const QString&
FlagsTypeEntryPtr TypeDatabase::findFlagsType(const QString &name) const
{
TypeEntryPtr fte = findType(name);
- if (fte.isNull()) {
+ if (!fte) {
fte = d->m_flagsEntries.value(name);
if (!fte) {
//last hope, search for flag without scope inside of flags hash
@@ -700,10 +829,10 @@ FlagsTypeEntryPtr TypeDatabase::findFlagsType(const QString &name) const
}
}
}
- return qSharedPointerCast<FlagsTypeEntry>(fte);
+ return std::static_pointer_cast<FlagsTypeEntry>(fte);
}
-void TypeDatabase::addFlagsType(FlagsTypeEntryPtr fte)
+void TypeDatabase::addFlagsType(const FlagsTypeEntryPtr &fte)
{
d->m_flagsEntries[fte->originalName()] = fte;
}
@@ -720,7 +849,7 @@ void TypeDatabase::addTemplate(const TemplateEntryPtr &t)
void TypeDatabase::addTemplate(const QString &name, const QString &code)
{
- TemplateEntryPtr te(new TemplateEntry(name));
+ auto te = std::make_shared<TemplateEntry>(name);
te->addCode(code);
addTemplate(te);
}
@@ -767,12 +896,8 @@ FunctionModificationList
return lst;
}
-void TypeDatabase::setSuppressWarnings(bool on)
-{
- d->m_suppressWarnings = on;
-}
-
-bool TypeDatabase::addSuppressedWarning(const QString &warning, QString *errorMessage)
+bool TypeDatabase::addSuppressedWarning(const QString &warning, bool generate,
+ QString *errorMessage)
{
QString pattern;
if (warning.startsWith(u'^') && warning.endsWith(u'$')) {
@@ -793,7 +918,7 @@ bool TypeDatabase::addSuppressedWarning(const QString &warning, QString *errorMe
qsizetype lastPos = 0;
for (qsizetype a = 0, aSize = asteriskPositions.size(); a < aSize; ++a) {
if (a)
- pattern.append(QStringLiteral(".*"));
+ pattern.append(".*"_L1);
const auto nextPos = asteriskPositions.at(a);
if (nextPos > lastPos)
pattern.append(QRegularExpression::escape(warning.mid(lastPos, nextPos - lastPos)));
@@ -810,7 +935,7 @@ bool TypeDatabase::addSuppressedWarning(const QString &warning, QString *errorMe
}
expression.setPatternOptions(expression.patternOptions() | QRegularExpression::MultilineOption);
- d->m_suppressedWarnings.append(expression);
+ d->m_suppressedWarnings.append({expression, warning, generate});
return true;
}
@@ -818,10 +943,14 @@ bool TypeDatabase::isSuppressedWarning(QStringView s) const
{
if (!d->m_suppressWarnings)
return false;
- return std::any_of(d->m_suppressedWarnings.cbegin(), d->m_suppressedWarnings.cend(),
- [&s] (const QRegularExpression &e) {
- return e.match(s).hasMatch();
- });
+ auto wit = std::find_if(d->m_suppressedWarnings.cbegin(), d->m_suppressedWarnings.cend(),
+ [&s] (const SuppressedWarning &e) {
+ return e.pattern.matchView(s).hasMatch();
+ });
+ const bool found = wit != d->m_suppressedWarnings.cend();
+ if (found)
+ wit->matched = true;
+ return found;
}
QString TypeDatabase::modifiedTypesystemFilepath(const QString& tsFile, const QString &currentPath) const
@@ -829,6 +958,27 @@ QString TypeDatabase::modifiedTypesystemFilepath(const QString& tsFile, const QS
return d->modifiedTypesystemFilepath(tsFile, currentPath);
}
+void TypeDatabase::logUnmatched() const
+{
+ for (auto &sw : d->m_suppressedWarnings) {
+ if (sw.generate && !sw.matched)
+ qWarning("Unmatched suppressed warning: \"%s\"", qPrintable(sw.rawText));
+ }
+
+ for (auto &tr : d->m_rejections) {
+ if (tr.generate && !tr.matched) {
+ QDebug d = qWarning();
+ d.noquote();
+ d.nospace();
+ d << "Unmatched rejection: " << tr.matchType;
+ if (!tr.className.pattern().isEmpty())
+ d << " class " << tr.className.pattern();
+ if (!tr.pattern.pattern().isEmpty())
+ d << " \"" << tr.pattern.pattern() << '"';
+ }
+ }
+}
+
QString TypeDatabasePrivate::modifiedTypesystemFilepath(const QString& tsFile,
const QString &currentPath) const
{
@@ -854,16 +1004,25 @@ void TypeDatabasePrivate::addBuiltInContainerTypes(const TypeDatabaseParserConte
{
// Unless the user has added the standard containers (potentially with
// some opaque types), add them by default.
+ const bool hasStdArray = findType(u"std::array"_s) != nullptr;
const bool hasStdPair = findType(u"std::pair"_s) != nullptr;
const bool hasStdList = findType(u"std::list"_s) != nullptr;
const bool hasStdVector = findType(u"std::vector"_s) != nullptr;
const bool hasStdMap = findType(u"std::map"_s) != nullptr;
const bool hasStdUnorderedMap = findType(u"std::unordered_map"_s) != nullptr;
+ const bool hasStdSpan = findType(u"std::span"_s) != nullptr;
if (hasStdPair && hasStdList && hasStdVector && hasStdMap && hasStdUnorderedMap)
return;
QByteArray ts = R"(<?xml version="1.0" encoding="UTF-8"?><typesystem>)";
+ if (!hasStdArray) {
+ ts += containerTypeSystemSnippet(
+ "std::array", "list", "array",
+ "shiboken_conversion_cppsequence_to_pylist",
+ "PySequence",
+ "shiboken_conversion_pyiterable_to_cpparray");
+ }
if (!hasStdPair) {
ts += containerTypeSystemSnippet(
"std::pair", "pair", "utility",
@@ -896,6 +1055,16 @@ void TypeDatabasePrivate::addBuiltInContainerTypes(const TypeDatabaseParserConte
"shiboken_conversion_stdmap_to_pydict",
"PyDict", "shiboken_conversion_pydict_to_stdmap");
}
+ if (!hasStdSpan
+ && clang::emulatedCompilerLanguageLevel() >= LanguageLevel::Cpp20) {
+ auto spanSnip = containerTypeSystemSnippet(
+ "std::span", "span", "span",
+ "shiboken_conversion_cppsequence_to_pylist");
+ auto pos = spanSnip.indexOf('>');
+ spanSnip.insert(pos, R"( view-on="std::vector")");
+ ts += spanSnip;
+ }
+
ts += "</typesystem>";
QBuffer buffer(&ts);
buffer.open(QIODevice::ReadOnly);
@@ -903,6 +1072,22 @@ void TypeDatabasePrivate::addBuiltInContainerTypes(const TypeDatabaseParserConte
Q_ASSERT(ok);
}
+bool TypeDatabasePrivate::addOpaqueContainers(const TypeDatabaseParserContextPtr &context)
+{
+ const auto &och = context->opaqueContainerHash;
+ for (auto it = och.cbegin(), end = och.cend(); it != end; ++it) {
+ const QString &name = it.key();
+ auto te = findType(name);
+ if (!te || !te->isContainer()) {
+ qCWarning(lcShiboken, "No container \"%s\" found.", qPrintable(name));
+ return false;
+ }
+ auto cte = std::static_pointer_cast<ContainerTypeEntry>(te);
+ cte->appendOpaqueContainers(it.value());
+ }
+ return true;
+}
+
bool TypeDatabase::parseFile(const QString &filename, bool generate)
{
QString filepath = modifiedTypesystemFilepath(filename, {});
@@ -966,7 +1151,7 @@ bool TypeDatabase::parseFile(QIODevice *device, bool generate)
bool TypeDatabasePrivate::parseFile(QIODevice *device, TypeDatabase *db, bool generate)
{
- const TypeDatabaseParserContextPtr context(new TypeDatabaseParserContext);
+ const auto context = std::make_shared<TypeDatabaseParserContext>();
context->db = db;
if (!parseFile(context, device, generate))
@@ -974,7 +1159,8 @@ bool TypeDatabasePrivate::parseFile(QIODevice *device, TypeDatabase *db, bool ge
addBuiltInPrimitiveTypes();
addBuiltInContainerTypes(context);
- return resolveSmartPointerInstantiations(context);
+ return addOpaqueContainers(context)
+ && resolveSmartPointerInstantiations(context);
}
bool TypeDatabase::parseFile(const TypeDatabaseParserContextPtr &context,
@@ -1067,7 +1253,7 @@ PrimitiveTypeEntryPtr TypeDatabase::findPrimitiveType(const QString& name) const
const auto entries = d->findTypeRange(name);
for (const auto &entry : entries) {
if (entry->isPrimitive()) {
- auto pe = qSharedPointerCast<PrimitiveTypeEntry>(entry);
+ auto pe = std::static_pointer_cast<PrimitiveTypeEntry>(entry);
if (pe->preferredTargetLangType())
return pe;
}
@@ -1081,7 +1267,7 @@ ComplexTypeEntryPtr TypeDatabase::findComplexType(const QString& name) const
const auto entries = d->findTypeRange(name);
for (const auto &entry : entries) {
if (entry->isComplex() && useType(entry))
- return qSharedPointerCast<ComplexTypeEntry>(entry);
+ return std::static_pointer_cast<ComplexTypeEntry>(entry);
}
return nullptr;
}
@@ -1090,8 +1276,8 @@ ObjectTypeEntryPtr TypeDatabase::findObjectType(const QString& name) const
{
const auto entries = d->findTypeRange(name);
for (const auto &entry : entries) {
- if (!entry.isNull() && entry->isObject() && useType(entry))
- return qSharedPointerCast<ObjectTypeEntry>(entry);
+ if (entry && entry->isObject() && useType(entry))
+ return std::static_pointer_cast<ObjectTypeEntry>(entry);
}
return nullptr;
}
@@ -1102,7 +1288,7 @@ NamespaceTypeEntryList TypeDatabase::findNamespaceTypes(const QString& name) con
const auto entries = d->findTypeRange(name);
for (const auto &entry : entries) {
if (entry->isNamespace())
- result.append(qSharedPointerCast<NamespaceTypeEntry>(entry));
+ result.append(std::static_pointer_cast<NamespaceTypeEntry>(entry));
}
return result;
}
@@ -1130,7 +1316,7 @@ bool TypeDatabase::shouldDropTypeEntry(const QString& fullTypeName) const
return d->m_dropTypeEntries.contains(fullTypeName);
}
-void TypeDatabase::setDropTypeEntries(QStringList dropTypeEntries)
+void TypeDatabase::setDropTypeEntries(const QStringList &dropTypeEntries)
{
d->m_dropTypeEntries = dropTypeEntries;
d->m_dropTypeEntries.sort();
@@ -1157,7 +1343,7 @@ static void _computeTypeIndexes()
const auto &allEntries = tdb->entries();
list.reserve(allEntries.size());
for (auto tit = allEntries.cbegin(), end = allEntries.cend(); tit != end; ++tit) {
- TypeEntryPtr entry = tit.value();
+ const TypeEntryPtr &entry = tit.value();
if (entry->isPrimitive()
|| entry->isContainer()
|| entry->isFunction()
@@ -1222,7 +1408,7 @@ bool TypeDatabase::setApiVersion(const QString& packageWildcardPattern, const QS
const QRegularExpression packageRegex(packagePattern);
if (!packageRegex.isValid())
return false;
- versions.append(qMakePair(packageRegex, versionNumber));
+ versions.append(std::make_pair(packageRegex, versionNumber));
return true;
}
@@ -1246,21 +1432,6 @@ bool TypeDatabase::hasDroppedTypeEntries() const
}
#ifndef QT_NO_DEBUG_STREAM
-
-template <class Container, class Separator>
-static void formatList(QDebug &d, const char *name, const Container &c, Separator sep)
-{
- if (const auto size = c.size()) {
- d << ", " << name << '[' << size << "]=(";
- for (qsizetype i = 0; i < size; ++i) {
- if (i)
- d << sep;
- d << c.at(i);
- }
- d << ')';
- }
-}
-
void TypeDatabase::formatDebug(QDebug &debug) const
{
d->formatDebug(debug);
@@ -1303,7 +1474,7 @@ void TypeDatabasePrivate::formatDebug(QDebug &d) const
d << ")\n";
}
d <<"\nglobalUserFunctions=" << m_globalUserFunctions << '\n';
- formatList(d, "globalFunctionMods", m_functionMods, '\n');
+ formatList(d, "globalFunctionMods", m_functionMods, "\n");
d << ')';
}
@@ -1368,9 +1539,9 @@ void TypeDatabase::formatBuiltinTypes(QDebug debug) const
// Determine base types and their typedef'ed types
QList<PrimitiveFormatListEntry> primitiveEntries;
- for (auto &e : std::as_const(d->m_entries)) {
+ for (const auto &e : std::as_const(d->m_entries)) {
if (e->isPrimitive()) {
- auto pe = qSharedPointerCast<const PrimitiveTypeEntry>(e);
+ auto pe = std::static_pointer_cast<const PrimitiveTypeEntry>(e);
auto basic = basicReferencedTypeEntry(pe);
if (basic != pe) {
const auto idx = indexOf(primitiveEntries, basic);
@@ -1405,7 +1576,7 @@ PrimitiveTypeEntryPtr
const QString &rootPackage,
const CustomTypeEntryPtr &targetLang)
{
- PrimitiveTypeEntryPtr result(new PrimitiveTypeEntry(name, {}, root));
+ auto result = std::make_shared<PrimitiveTypeEntry>(name, QVersionNumber{}, root);
result->setTargetLangApiType(targetLang);
result->setTargetLangPackage(rootPackage);
addBuiltInType(result);
@@ -1433,15 +1604,15 @@ void TypeDatabasePrivate::addBuiltInPrimitiveTypes()
// C++ primitive types
auto pyLongEntry = findType(u"PyLong"_s);
- Q_ASSERT(!pyLongEntry.isNull() && pyLongEntry->isCustom());
- auto pyLongCustomEntry = qSharedPointerCast<CustomTypeEntry>(pyLongEntry);
+ Q_ASSERT(pyLongEntry && pyLongEntry->isCustom());
+ auto pyLongCustomEntry = std::static_pointer_cast<CustomTypeEntry>(pyLongEntry);
auto pyBoolEntry = findType(u"PyBool"_s);
- Q_ASSERT(!pyBoolEntry.isNull() && pyBoolEntry->isCustom());
+ Q_ASSERT(pyBoolEntry && pyBoolEntry->isCustom());
auto sbkCharEntry = findType(u"SbkChar"_s);
- Q_ASSERT(!sbkCharEntry.isNull() && sbkCharEntry->isCustom());
- auto sbkCharCustomEntry = qSharedPointerCast<CustomTypeEntry>(sbkCharEntry);
+ Q_ASSERT(sbkCharEntry && sbkCharEntry->isCustom());
+ auto sbkCharCustomEntry = std::static_pointer_cast<CustomTypeEntry>(sbkCharEntry);
- auto pyBoolCustomEntry = qSharedPointerCast<CustomTypeEntry>(pyBoolEntry);
+ auto pyBoolCustomEntry = std::static_pointer_cast<CustomTypeEntry>(pyBoolEntry);
for (const auto &t : AbstractMetaType::cppIntegralTypes()) {
if (!m_entries.contains(t)) {
CustomTypeEntryPtr targetLangApi = pyLongCustomEntry;
@@ -1454,24 +1625,24 @@ void TypeDatabasePrivate::addBuiltInPrimitiveTypes()
}
auto pyFloatEntry = findType(u"PyFloat"_s);
- Q_ASSERT(!pyFloatEntry.isNull() && pyFloatEntry->isCustom());
- auto pyFloatCustomEntry = qSharedPointerCast<CustomTypeEntry>(pyFloatEntry);
+ Q_ASSERT(pyFloatEntry && pyFloatEntry->isCustom());
+ auto pyFloatCustomEntry = std::static_pointer_cast<CustomTypeEntry>(pyFloatEntry);
for (const auto &t : AbstractMetaType::cppFloatTypes()) {
if (!m_entries.contains(t))
addBuiltInPrimitiveType(t, root, rootPackage, pyFloatCustomEntry);
}
auto pyUnicodeEntry = findType(u"PyUnicode"_s);
- Q_ASSERT(!pyUnicodeEntry.isNull() && pyUnicodeEntry->isCustom());
- auto pyUnicodeCustomEntry = qSharedPointerCast<CustomTypeEntry>(pyUnicodeEntry);
+ Q_ASSERT(pyUnicodeEntry && pyUnicodeEntry->isCustom());
+ auto pyUnicodeCustomEntry = std::static_pointer_cast<CustomTypeEntry>(pyUnicodeEntry);
- const QString stdString = u"std::string"_s;
+ constexpr auto stdString = "std::string"_L1;
if (!m_entries.contains(stdString)) {
addBuiltInCppStringPrimitiveType(stdString, u"std::string_view"_s,
root, rootPackage,
pyUnicodeCustomEntry);
}
- const QString stdWString = u"std::wstring"_s;
+ constexpr auto stdWString = "std::wstring"_L1;
if (!m_entries.contains(stdWString)) {
addBuiltInCppStringPrimitiveType(stdWString, u"std::wstring_view"_s,
root, rootPackage,
diff --git a/sources/shiboken6/ApiExtractor/typedatabase.h b/sources/shiboken6/ApiExtractor/typedatabase.h
index 11ed26002..d5adca324 100644
--- a/sources/shiboken6/ApiExtractor/typedatabase.h
+++ b/sources/shiboken6/ApiExtractor/typedatabase.h
@@ -11,10 +11,13 @@
#include <QtCore/QRegularExpression>
#include <QtCore/QStringList>
#include <QtCore/QVersionNumber>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
QT_FORWARD_DECLARE_CLASS(QIODevice)
+struct OptionDescription;
+class OptionsParser;
struct TypeDatabasePrivate;
struct TypeDatabaseParserContext;
@@ -48,7 +51,9 @@ struct TypeRejection
QRegularExpression className;
QRegularExpression pattern;
- MatchType matchType;
+ MatchType matchType = ExcludeClass;
+ bool generate; // Current type system
+ mutable bool matched = false;
};
#ifndef QT_NO_DEBUG_STREAM
@@ -58,10 +63,14 @@ QDebug operator<<(QDebug d, const TypeRejection &r);
class TypeDatabase
{
TypeDatabase();
- Q_DISABLE_COPY(TypeDatabase)
public:
+ Q_DISABLE_COPY_MOVE(TypeDatabase)
+
~TypeDatabase();
+ static QList<OptionDescription> options();
+ std::shared_ptr<OptionsParser> createOptionsParser();
+
/**
* Return the type system instance.
* \param newInstance This parameter is useful just for unit testing, because singletons causes
@@ -76,15 +85,12 @@ public:
void addRequiredTargetImport(const QString &moduleName);
- void addTypesystemPath(const QString &typesystem_paths);
-
- void setTypesystemKeywords(const QStringList &keywords);
QStringList typesystemKeywords() const;
IncludeList extraIncludes(const QString &className) const;
- const QStringList &systemIncludes() const;
- void addSystemInclude(const QString &name);
+ const QStringList &forceProcessSystemIncludes() const;
+ void addForceProcessSystemInclude(const QString &name);
void addInlineNamespaceLookups(const NamespaceTypeEntryCPtr &n);
@@ -97,6 +103,7 @@ public:
FunctionTypeEntryPtr findFunctionType(const QString &name) const;
TypeSystemTypeEntryCPtr findTypeSystemType(const QString &name) const;
TypeSystemTypeEntryCPtr defaultTypeSystemType() const;
+ QString loadedTypeSystemNames() const;
QString defaultPackageName() const;
TypeEntryPtr findType(const QString &name) const;
@@ -135,7 +142,7 @@ public:
const ComplexTypeEntryCPtr &source);
FlagsTypeEntryPtr findFlagsType(const QString &name) const;
- void addFlagsType(FlagsTypeEntryPtr fte);
+ void addFlagsType(const FlagsTypeEntryPtr &fte);
TemplateEntryPtr findTemplate(const QString &name) const;
@@ -153,9 +160,7 @@ public:
FunctionModificationList
globalFunctionModifications(const QStringList &signatures) const;
- void setSuppressWarnings(bool on);
-
- bool addSuppressedWarning(const QString &warning, QString *errorMessage);
+ bool addSuppressedWarning(const QString &warning, bool generate, QString *errorMessage);
bool isSuppressedWarning(QStringView s) const;
@@ -163,12 +168,12 @@ public:
// Top level file parsing
bool parseFile(const QString &filename, bool generate = true);
- bool parseFile(const QSharedPointer<TypeDatabaseParserContext> &context,
+ bool parseFile(const std::shared_ptr<TypeDatabaseParserContext> &context,
const QString &filename, const QString &currentPath, bool generate);
// Top level QIODevice parsing for tests.
bool parseFile(QIODevice *device, bool generate = true);
- bool parseFile(const QSharedPointer<TypeDatabaseParserContext> &context,
+ bool parseFile(const std::shared_ptr<TypeDatabaseParserContext> &context,
QIODevice *device, bool generate = true);
static bool setApiVersion(const QString &package, const QString &version);
@@ -180,10 +185,12 @@ public:
bool shouldDropTypeEntry(const QString &fullTypeName) const;
- void setDropTypeEntries(QStringList dropTypeEntries);
+ void setDropTypeEntries(const QStringList &dropTypeEntries);
QString modifiedTypesystemFilepath(const QString &tsFile, const QString &currentPath = QString()) const;
+ void logUnmatched() const;
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const;
#endif
diff --git a/sources/shiboken6/ApiExtractor/typedatabase_p.h b/sources/shiboken6/ApiExtractor/typedatabase_p.h
index 04c1df145..fc56c7961 100644
--- a/sources/shiboken6/ApiExtractor/typedatabase_p.h
+++ b/sources/shiboken6/ApiExtractor/typedatabase_p.h
@@ -5,6 +5,7 @@
#define TYPEDATABASE_P_H
#include "typesystem_typedefs.h"
+#include "containertypeentry.h"
#include <QtCore/QHash>
#include <QtCore/QString>
@@ -14,9 +15,11 @@ class TypeDatabase;
struct TypeDatabaseParserContext
{
using SmartPointerInstantiations = QHash<SmartPointerTypeEntryPtr, QString>;
+ using OpaqueContainerHash = QHash<QString, OpaqueContainers>;
TypeDatabase *db;
SmartPointerInstantiations smartPointerInstantiations;
+ OpaqueContainerHash opaqueContainerHash;
};
#endif // TYPEDATABASE_P_H
diff --git a/sources/shiboken6/ApiExtractor/typeparser.cpp b/sources/shiboken6/ApiExtractor/typeparser.cpp
index 10f102b08..11d7bf641 100644
--- a/sources/shiboken6/ApiExtractor/typeparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typeparser.cpp
@@ -37,7 +37,7 @@ public:
{
}
- Token nextToken(QString *errorMessage = Q_NULLPTR);
+ Token nextToken(QString *errorMessage = nullptr);
QString identifier() const;
QString msgParseError(const QString &why) const;
@@ -147,8 +147,8 @@ Scanner::Token Scanner::nextToken(QString *errorMessage)
QString Scanner::msgParseError(const QString &why) const
{
- return QStringLiteral("TypeParser: Unable to parse \"")
- + QString(m_chars, m_length) + QStringLiteral("\": ") + why;
+ return "TypeParser: Unable to parse \""_L1
+ + QString(m_chars, m_length) + "\": "_L1 + why;
}
TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
@@ -166,7 +166,7 @@ TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
Scanner::Token tok = scanner.nextToken(errorMessage);
while (tok != Scanner::NoToken) {
if (tok == Scanner::InvalidToken)
- return TypeInfo();
+ return {};
// switch (tok) {
// case Scanner::StarToken: printf(" - *\n"); break;
@@ -199,12 +199,12 @@ TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
stack.top().setReferenceType(RValueReference);
break;
case RValueReference:
- const QString message = scanner.msgParseError(QStringLiteral("Too many '&' qualifiers"));
+ const QString message = scanner.msgParseError("Too many '&' qualifiers"_L1);
if (errorMessage)
*errorMessage = message;
else
qWarning().noquote().nospace() << message;
- return TypeInfo();
+ return {};
}
break;
case Scanner::LessThanToken:
@@ -246,12 +246,12 @@ TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
case Scanner::OpenParenToken: // function pointers not supported
case Scanner::CloseParenToken: {
- const QString message = scanner.msgParseError(QStringLiteral("Function pointers are not supported"));
+ const QString message = scanner.msgParseError("Function pointers are not supported"_L1);
if (errorMessage)
*errorMessage = message;
else
qWarning().noquote().nospace() << message;
- return TypeInfo();
+ return {};
}
case Scanner::Identifier:
diff --git a/sources/shiboken6/ApiExtractor/typesystem.cpp b/sources/shiboken6/ApiExtractor/typesystem.cpp
index a5f8ad36c..99d42b668 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystem.cpp
@@ -5,9 +5,11 @@
#include "arraytypeentry.h"
#include "codesnip.h"
#include "complextypeentry.h"
+#include "configurabletypeentry.h"
#include "constantvaluetypeentry.h"
#include "containertypeentry.h"
#include "customtypenentry.h"
+#include "debughelpers_p.h"
#include "enumtypeentry.h"
#include "enumvaluetypeentry.h"
#include "flagstypeentry.h"
@@ -50,6 +52,11 @@ static QString buildName(const QString &entryName, const TypeEntryCPtr &parent)
class TypeEntryPrivate
{
public:
+ TypeEntryPrivate(const TypeEntryPrivate &) = default; // Enable copy for cloning.
+ TypeEntryPrivate &operator=(const TypeEntryPrivate &) = delete;
+ TypeEntryPrivate(TypeEntryPrivate &&) = delete;
+ TypeEntryPrivate &operator=(TypeEntryPrivate &&) = delete;
+
explicit TypeEntryPrivate(const QString &entryName, TypeEntry::Type t, const QVersionNumber &vr,
const TypeEntryCPtr &parent);
virtual ~TypeEntryPrivate() = default;
@@ -181,7 +188,7 @@ TypeSystemTypeEntryCPtr typeSystemTypeEntry(TypeEntryCPtr e)
{
for (; e; e = e->parent()) {
if (e->type() == TypeEntry::TypeSystemType)
- return qSharedPointerCast<const TypeSystemTypeEntry>(e);
+ return std::static_pointer_cast<const TypeSystemTypeEntry>(e);
}
return {};
}
@@ -323,7 +330,7 @@ QString TypeEntryPrivate::shortName() const
bool foundInlineNamespace = false;
for (auto p = m_parent; p != nullptr && p->type() != TypeEntry::TypeSystemType; p = p->parent()) {
if (p->type() == TypeEntry::NamespaceType
- && qSharedPointerCast<const NamespaceTypeEntry>(p)->isInlineNamespace()) {
+ && std::static_pointer_cast<const NamespaceTypeEntry>(p)->isInlineNamespace()) {
foundInlineNamespace = true;
} else {
parents.append(p);
@@ -659,6 +666,9 @@ public:
CodeSnipList m_codeSnips;
TypeSystem::SnakeCase m_snakeCase = TypeSystem::SnakeCase::Disabled;
+ QString m_subModuleOf;
+ QString m_namespaceBegin;
+ QString m_namespaceEnd;
};
TypeSystemTypeEntry::TypeSystemTypeEntry(const QString &entryName, const QVersionNumber &vr,
@@ -696,6 +706,42 @@ void TypeSystemTypeEntry::addCodeSnip(const CodeSnip &codeSnip)
d->m_codeSnips.append(codeSnip);
}
+QString TypeSystemTypeEntry::subModuleOf() const
+{
+ S_D(const TypeSystemTypeEntry);
+ return d->m_subModuleOf;
+}
+
+void TypeSystemTypeEntry::setSubModule(const QString &s)
+{
+ S_D(TypeSystemTypeEntry);
+ d->m_subModuleOf = s;
+}
+
+const QString &TypeSystemTypeEntry::namespaceBegin() const
+{
+ S_D(const TypeSystemTypeEntry);
+ return d->m_namespaceBegin;
+}
+
+void TypeSystemTypeEntry::setNamespaceBegin(const QString &p)
+{
+ S_D(TypeSystemTypeEntry);
+ d->m_namespaceBegin = p;
+}
+
+const QString &TypeSystemTypeEntry::namespaceEnd() const
+{
+ S_D(const TypeSystemTypeEntry);
+ return d->m_namespaceEnd;
+}
+
+void TypeSystemTypeEntry::setNamespaceEnd(const QString &n)
+{
+ S_D(TypeSystemTypeEntry);
+ d->m_namespaceEnd = n;
+}
+
TypeSystem::SnakeCase TypeSystemTypeEntry::snakeCase() const
{
S_D(const TypeSystemTypeEntry);
@@ -892,7 +938,7 @@ PrimitiveTypeEntryCPtr basicReferencedTypeEntry(const PrimitiveTypeEntryCPtr &e)
PrimitiveTypeEntryCPtr basicReferencedTypeEntry(const TypeEntryCPtr &e)
{
Q_ASSERT(e->isPrimitive());
- return basicReferencedTypeEntry(qSharedPointerCast<const PrimitiveTypeEntry>(e));
+ return basicReferencedTypeEntry(std::static_pointer_cast<const PrimitiveTypeEntry>(e));
}
PrimitiveTypeEntryCPtr basicReferencedNonBuiltinTypeEntry(const PrimitiveTypeEntryCPtr &e)
@@ -926,7 +972,7 @@ void PrimitiveTypeEntry::setPreferredTargetLangType(bool b)
bool PrimitiveTypeEntry::hasCustomConversion() const
{
S_D(const PrimitiveTypeEntry);
- return !d->m_customConversion.isNull();
+ return bool(d->m_customConversion);
}
void PrimitiveTypeEntry::setCustomConversion(const CustomConversionPtr &customConversion)
@@ -952,23 +998,72 @@ PrimitiveTypeEntry::PrimitiveTypeEntry(PrimitiveTypeEntryPrivate *d)
{
}
-// ----------------- EnumTypeEntry
-class EnumTypeEntryPrivate : public TypeEntryPrivate
+// ----------------- ConfigurableTypeEntry
+
+class ConfigurableTypeEntryPrivate : public TypeEntryPrivate
{
public:
using TypeEntryPrivate::TypeEntryPrivate;
+ QString m_configCondition;
+};
+
+ConfigurableTypeEntry::ConfigurableTypeEntry(const QString &entryName, Type t,
+ const QVersionNumber &vr,
+ const TypeEntryCPtr &parent) :
+ TypeEntry(new ConfigurableTypeEntryPrivate(entryName, t, vr, parent))
+{
+}
+
+ConfigurableTypeEntry::ConfigurableTypeEntry(ConfigurableTypeEntryPrivate *d) :
+ TypeEntry(d)
+{
+}
+
+TypeEntry *ConfigurableTypeEntry::clone() const
+{
+ S_D(const ConfigurableTypeEntry);
+ return new ConfigurableTypeEntry(new ConfigurableTypeEntryPrivate(*d));
+}
+
+QString ConfigurableTypeEntry::configCondition() const
+{
+ S_D(const ConfigurableTypeEntry);
+ return d->m_configCondition;
+}
+
+void ConfigurableTypeEntry::setConfigCondition(const QString &c)
+{
+ S_D(ConfigurableTypeEntry);
+ d->m_configCondition = c;
+ if (!d->m_configCondition.startsWith(u'#'))
+ d->m_configCondition.prepend(u"#if ");
+}
+
+bool ConfigurableTypeEntry::hasConfigCondition() const
+{
+ S_D(const ConfigurableTypeEntry);
+ return !d->m_configCondition.isEmpty();
+}
+
+// ----------------- EnumTypeEntry
+class EnumTypeEntryPrivate : public ConfigurableTypeEntryPrivate
+{
+public:
+ using ConfigurableTypeEntryPrivate::ConfigurableTypeEntryPrivate;
+
EnumValueTypeEntryCPtr m_nullValue;
QStringList m_rejectedEnums;
FlagsTypeEntryPtr m_flags;
QString m_cppType;
+ QString m_docFile;
TypeSystem::PythonEnumType m_pythonEnumType = TypeSystem::PythonEnumType::Unspecified;
};
EnumTypeEntry::EnumTypeEntry(const QString &entryName,
const QVersionNumber &vr,
const TypeEntryCPtr &parent) :
- TypeEntry(new EnumTypeEntryPrivate(entryName, EnumType, vr, parent))
+ ConfigurableTypeEntry(new EnumTypeEntryPrivate(entryName, EnumType, vr, parent))
{
}
@@ -1055,6 +1150,18 @@ QStringList EnumTypeEntry::enumValueRejections() const
return d->m_rejectedEnums;
}
+QString EnumTypeEntry::docFile() const
+{
+ S_D(const EnumTypeEntry);
+ return d->m_docFile;
+}
+
+void EnumTypeEntry::setDocFile(const QString &df)
+{
+ S_D(EnumTypeEntry);
+ d->m_docFile = df;
+}
+
TypeEntry *EnumTypeEntry::clone() const
{
S_D(const EnumTypeEntry);
@@ -1062,7 +1169,7 @@ TypeEntry *EnumTypeEntry::clone() const
}
EnumTypeEntry::EnumTypeEntry(EnumTypeEntryPrivate *d) :
- TypeEntry(d)
+ ConfigurableTypeEntry(d)
{
}
@@ -1201,13 +1308,13 @@ ConstantValueTypeEntry::ConstantValueTypeEntry(TypeEntryPrivate *d) :
}
// ----------------- ComplexTypeEntry
-class ComplexTypeEntryPrivate : public TypeEntryPrivate
+class ComplexTypeEntryPrivate : public ConfigurableTypeEntryPrivate
{
public:
ComplexTypeEntryPrivate(const QString &entryName, TypeEntry::Type t,
const QVersionNumber &vr,
const TypeEntryCPtr &parent) :
- TypeEntryPrivate(entryName, t, vr, parent),
+ ConfigurableTypeEntryPrivate(entryName, t, vr, parent),
m_qualifiedCppName(buildName(entryName, parent)),
m_polymorphicBase(false),
m_genericClass(false),
@@ -1256,7 +1363,7 @@ public:
ComplexTypeEntry::ComplexTypeEntry(const QString &entryName, TypeEntry::Type t,
const QVersionNumber &vr,
const TypeEntryCPtr &parent) :
- TypeEntry(new ComplexTypeEntryPrivate(entryName, t, vr, parent))
+ ConfigurableTypeEntry(new ComplexTypeEntryPrivate(entryName, t, vr, parent))
{
}
@@ -1686,10 +1793,11 @@ void ComplexTypeEntry::useAsTypedef(const ComplexTypeEntryCPtr &source)
TypeEntry::useAsTypedef(source);
d->m_qualifiedCppName = source->qualifiedCppName();
d->m_targetType = source->targetType();
+ d->m_typeFlags.setFlag(ComplexTypeEntry::Typedef);
}
ComplexTypeEntry::ComplexTypeEntry(ComplexTypeEntryPrivate *d) :
- TypeEntry(d)
+ ConfigurableTypeEntry(d)
{
}
@@ -1777,9 +1885,6 @@ TypedefEntry::TypedefEntry(TypedefEntryPrivate *d) :
class ContainerTypeEntryPrivate : public ComplexTypeEntryPrivate
{
public:
- using OpaqueContainer = ContainerTypeEntry::OpaqueContainer;
- using OpaqueContainers = ContainerTypeEntry::OpaqueContainers;
-
ContainerTypeEntryPrivate(const QString &entryName,
ContainerTypeEntry::ContainerKind containerKind,
const QVersionNumber &vr,
@@ -1789,11 +1894,11 @@ public:
{
}
- OpaqueContainers::const_iterator findOpaqueContainer(const QString &instantiation) const
+ OpaqueContainers::const_iterator findOpaqueContainer(const QStringList &instantiations) const
{
return std::find_if(m_opaqueContainers.cbegin(), m_opaqueContainers.cend(),
- [&instantiation](const OpaqueContainer &r) {
- return r.instantiation == instantiation;
+ [&instantiations](const OpaqueContainer &r) {
+ return r.instantiations == instantiations;
});
}
@@ -1802,6 +1907,19 @@ public:
ContainerTypeEntry::ContainerKind m_containerKind;
};
+QString OpaqueContainer::templateParameters() const
+{
+ QString result;
+ result += u'<';
+ for (qsizetype i = 0, size = instantiations.size(); i < size; ++i) {
+ if (i)
+ result += u',';
+ result += instantiations.at(i);
+ }
+ result += u'>';
+ return result;
+}
+
ContainerTypeEntry::ContainerTypeEntry(const QString &entryName, ContainerKind containerKind,
const QVersionNumber &vr,
const TypeEntryCPtr &parent) :
@@ -1816,40 +1934,53 @@ ContainerTypeEntry::ContainerKind ContainerTypeEntry::containerKind() const
return d->m_containerKind;
}
-const ContainerTypeEntry::OpaqueContainers &ContainerTypeEntry::opaqueContainers() const
+qsizetype ContainerTypeEntry::templateParameterCount() const
+{
+ S_D(const ContainerTypeEntry);
+ qsizetype result = 1;
+ switch (d->m_containerKind) {
+ case MapContainer:
+ case MultiMapContainer:
+ case PairContainer:
+ case SpanContainer:
+ result = 2;
+ break;
+ case ListContainer:
+ case SetContainer:
+ break;
+ }
+ return result;
+}
+
+const OpaqueContainers &ContainerTypeEntry::opaqueContainers() const
{
S_D(const ContainerTypeEntry);
return d->m_opaqueContainers;
}
-void ContainerTypeEntry::addOpaqueContainer(OpaqueContainer r)
+void ContainerTypeEntry::appendOpaqueContainers(const OpaqueContainers &l)
{
S_D(ContainerTypeEntry);
- // Fix to match AbstractMetaType::signature() which is used for matching
- // "Foo*" -> "Foo *"
- const auto asteriskPos = r.instantiation.indexOf(u'*');
- if (asteriskPos > 0 && !r.instantiation.at(asteriskPos - 1).isSpace())
- r.instantiation.insert(asteriskPos, u' ');
- d->m_opaqueContainers.append(r);
+ d->m_opaqueContainers.append(l);
}
-bool ContainerTypeEntry::generateOpaqueContainer(const QString &instantiation) const
+bool ContainerTypeEntry::generateOpaqueContainer(const QStringList &instantiations) const
{
S_D(const ContainerTypeEntry);
- return d->findOpaqueContainer(instantiation) != d->m_opaqueContainers.cend();
+ return d->findOpaqueContainer(instantiations) != d->m_opaqueContainers.cend();
}
-QString ContainerTypeEntry::opaqueContainerName(const QString &instantiation) const
+QString ContainerTypeEntry::opaqueContainerName(const QStringList &instantiations) const
{
S_D(const ContainerTypeEntry);
- const auto it = d->findOpaqueContainer(instantiation);
+ const auto it = d->findOpaqueContainer(instantiations);
return it != d->m_opaqueContainers.cend() ? it->name : QString{};
}
bool ContainerTypeEntry::hasCustomConversion() const
{
S_D(const ContainerTypeEntry);
- return !d->m_customConversion.isNull();
+ return bool(d->m_customConversion);
}
void ContainerTypeEntry::setCustomConversion(const CustomConversionPtr &customConversion)
@@ -2130,7 +2261,7 @@ void NamespaceTypeEntry::setInlineNamespace(bool i)
bool NamespaceTypeEntry::isVisibleScope(const TypeEntryCPtr &e)
{
- return isVisibleScope(e.data());
+ return isVisibleScope(e.get());
}
bool NamespaceTypeEntry::isVisibleScope(const TypeEntry *e)
@@ -2171,7 +2302,7 @@ ValueTypeEntry::ValueTypeEntry(const QString &entryName, const QVersionNumber &v
bool ValueTypeEntry::hasCustomConversion() const
{
S_D(const ValueTypeEntry);
- return !d->m_customConversion.isNull();
+ return bool(d->m_customConversion);
}
void ValueTypeEntry::setCustomConversion(const CustomConversionPtr &customConversion)
@@ -2239,7 +2370,7 @@ public:
}
QStringList m_signatures;
- TypeSystem::SnakeCase m_snakeCase = TypeSystem::SnakeCase::Unspecified;
+ QString m_docFile;
};
FunctionTypeEntry::FunctionTypeEntry(const QString &entryName, const QString &signature,
@@ -2267,16 +2398,16 @@ bool FunctionTypeEntry::hasSignature(const QString &signature) const
return d->m_signatures.contains(signature);
}
-TypeSystem::SnakeCase FunctionTypeEntry::snakeCase() const
+QString FunctionTypeEntry::docFile() const
{
S_D(const FunctionTypeEntry);
- return d->m_snakeCase;
+ return d->m_docFile;
}
-void FunctionTypeEntry::setSnakeCase(TypeSystem::SnakeCase sc)
+void FunctionTypeEntry::setDocFile(const QString &df)
{
S_D(FunctionTypeEntry);
- d->m_snakeCase = sc;
+ d->m_docFile = df;
}
TypeEntry *FunctionTypeEntry::clone() const
@@ -2322,20 +2453,6 @@ ObjectTypeEntry::ObjectTypeEntry(ComplexTypeEntryPrivate *d) :
if (!var.isEmpty()) \
debug << ", " << var.size() << ' ' << name;
-template <class Container, class Separator>
-static void formatList(QDebug &d, const char *name, const Container &c, Separator sep)
-{
- if (const auto size = c.size()) {
- d << ", " << name << '[' << size << "]=(";
- for (qsizetype i = 0; i < size; ++i) {
- if (i)
- d << sep;
- d << c.at(i);
- }
- d << ')';
- }
-}
-
void TypeEntry::formatDebug(QDebug &debug) const
{
const QString cppName = qualifiedCppName();
@@ -2368,9 +2485,9 @@ void TypeEntry::formatDebug(QDebug &debug) const
void PrimitiveTypeEntry::formatDebug(QDebug &debug) const
{
TypeEntry::formatDebug(debug);
- if (auto e = referencedTypeEntry(); !e.isNull()) {
+ if (auto e = referencedTypeEntry()) {
debug << ", references";
- for (; e != nullptr; e = e->referencedTypeEntry())
+ for (; e ; e = e->referencedTypeEntry())
debug << ":\"" << e->qualifiedCppName() <<'"';
}
}
@@ -2418,8 +2535,7 @@ void FunctionTypeEntry::formatDebug(QDebug &debug) const
S_D(const FunctionTypeEntry);
TypeEntry::formatDebug(debug);
- debug << "signatures=" << d->m_signatures
- << ", snakeCase=" << int(d->m_snakeCase);
+ debug << "signatures=" << d->m_signatures;
}
void TypedefEntry::formatDebug(QDebug &debug) const
@@ -2454,18 +2570,23 @@ void NamespaceTypeEntry::formatDebug(QDebug &debug) const
debug << "[inline]";
}
+QDebug operator<<(QDebug d, const OpaqueContainer &oc)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "OpaqueContainer(\"" << oc.name << "\": " << oc.templateParameters() << ')';
+ return d;
+}
+
void ContainerTypeEntry::formatDebug(QDebug &debug) const
{
S_D(const ContainerTypeEntry);
ComplexTypeEntry::formatDebug(debug);
debug << ", type=" << d->m_containerKind << '"';
- if (!d->m_opaqueContainers.isEmpty()) {
- debug << ", opaque-containers=[";
- for (const auto &r : d->m_opaqueContainers)
- debug << r.instantiation << "->" << r.name << ',';
- debug << ']';
- }
+ if (!d->m_opaqueContainers.isEmpty())
+ debug << ", opaque-containers=[" << d->m_opaqueContainers << ']';
}
void SmartPointerTypeEntry::formatDebug(QDebug &debug) const
@@ -2501,7 +2622,7 @@ QDebug operator<<(QDebug d, const TypeEntry *te)
QDebug operator<<(QDebug d, const TypeEntryCPtr &te)
{
- d << te.data();
+ d << te.get();
return d;
}
@@ -2522,7 +2643,7 @@ QDebug operator<<(QDebug d, const TemplateEntry *te)
QDebug operator<<(QDebug d, const TemplateEntryCPtr &te)
{
- d << te.data();
+ d << te.get();
return d;
}
#endif // QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken6/ApiExtractor/typesystem_enums.h b/sources/shiboken6/ApiExtractor/typesystem_enums.h
index 81304e6c2..9ecbb08a1 100644
--- a/sources/shiboken6/ApiExtractor/typesystem_enums.h
+++ b/sources/shiboken6/ApiExtractor/typesystem_enums.h
@@ -35,6 +35,7 @@ enum CodeSnipPosition {
CodeSnipPositionBeginning,
CodeSnipPositionEnd,
CodeSnipPositionDeclaration,
+ CodeSnipPositionPyOverride,
CodeSnipPositionAny
};
diff --git a/sources/shiboken6/ApiExtractor/typesystem_typedefs.h b/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
index ca652252d..5a4e12ff2 100644
--- a/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
+++ b/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
@@ -5,10 +5,12 @@
#define TYPESYSTEM_TYPEDEFS_H
#include <QtCore/QList>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
class ArrayTypeEntry;
class ComplexTypeEntry;
+class ConfigurableTypeEntry;
class ConstantValueTypeEntry;
class ContainerTypeEntry;
class CustomTypeEntry;
@@ -26,44 +28,47 @@ class TypedefEntry;
class TypeSystemTypeEntry;
class ValueTypeEntry;
-using ArrayTypeEntryPtr = QSharedPointer<ArrayTypeEntry>;
-using ComplexTypeEntryPtr = QSharedPointer<ComplexTypeEntry>;
-using ConstantValueTypeEntryPtr = QSharedPointer<ConstantValueTypeEntry>;
-using ContainerTypeEntryPtr = QSharedPointer<ContainerTypeEntry>;
-using CustomTypeEntryPtr = QSharedPointer<CustomTypeEntry>;
-using EnumTypeEntryPtr = QSharedPointer<EnumTypeEntry>;
-using EnumValueTypeEntryPtr = QSharedPointer<EnumValueTypeEntry>;
-using FlagsTypeEntryPtr = QSharedPointer<FlagsTypeEntry>;
-using FunctionTypeEntryPtr = QSharedPointer<FunctionTypeEntry>;
-using NamespaceTypeEntryPtr = QSharedPointer<NamespaceTypeEntry>;
-using ObjectTypeEntryPtr = QSharedPointer<ObjectTypeEntry>;
-using PrimitiveTypeEntryPtr = QSharedPointer<PrimitiveTypeEntry>;
-using SmartPointerTypeEntryPtr = QSharedPointer<SmartPointerTypeEntry>;
-using TemplateEntryPtr = QSharedPointer<TemplateEntry>;
-using TypeEntryPtr = QSharedPointer<TypeEntry>;
-using TypedefEntryPtr = QSharedPointer<TypedefEntry>;
-using TypeSystemTypeEntryPtr = QSharedPointer<TypeSystemTypeEntry>;
-using ValueTypeEntryPtr = QSharedPointer<ValueTypeEntry>;
+using ArrayTypeEntryPtr = std::shared_ptr<ArrayTypeEntry>;
+using ComplexTypeEntryPtr = std::shared_ptr<ComplexTypeEntry>;
+using ConfigurableTypeEntryPtr = std::shared_ptr<ConfigurableTypeEntry>;
+using ConstantValueTypeEntryPtr = std::shared_ptr<ConstantValueTypeEntry>;
+using ContainerTypeEntryPtr = std::shared_ptr<ContainerTypeEntry>;
+using CustomTypeEntryPtr = std::shared_ptr<CustomTypeEntry>;
+using EnumTypeEntryPtr = std::shared_ptr<EnumTypeEntry>;
+using EnumValueTypeEntryPtr = std::shared_ptr<EnumValueTypeEntry>;
+using FlagsTypeEntryPtr = std::shared_ptr<FlagsTypeEntry>;
+using FunctionTypeEntryPtr = std::shared_ptr<FunctionTypeEntry>;
+using NamespaceTypeEntryPtr = std::shared_ptr<NamespaceTypeEntry>;
+using ObjectTypeEntryPtr = std::shared_ptr<ObjectTypeEntry>;
+using PrimitiveTypeEntryPtr = std::shared_ptr<PrimitiveTypeEntry>;
+using SmartPointerTypeEntryPtr = std::shared_ptr<SmartPointerTypeEntry>;
+using TemplateEntryPtr = std::shared_ptr<TemplateEntry>;
+using TypeEntryPtr = std::shared_ptr<TypeEntry>;
+using TypedefEntryPtr = std::shared_ptr<TypedefEntry>;
+using TypeSystemTypeEntryPtr = std::shared_ptr<TypeSystemTypeEntry>;
+using ValueTypeEntryPtr = std::shared_ptr<ValueTypeEntry>;
-using ArrayTypeEntryCPtr = QSharedPointer<const ArrayTypeEntry>;
-using ComplexTypeEntryCPtr = QSharedPointer<const ComplexTypeEntry>;
-using ConstantValueTypeEntryCPtr = QSharedPointer<const ConstantValueTypeEntry>;
-using ContainerTypeEntryCPtr = QSharedPointer<const ContainerTypeEntry>;
-using CustomTypeEntryCPtr = QSharedPointer<const CustomTypeEntry>;
-using EnumTypeEntryCPtr = QSharedPointer<const EnumTypeEntry>;
-using EnumValueTypeEntryCPtr = QSharedPointer<const EnumValueTypeEntry>;
-using FlagsTypeEntryCPtr = QSharedPointer<const FlagsTypeEntry>;
-using FunctionTypeEntryCPtr = QSharedPointer<const FunctionTypeEntry>;
-using NamespaceTypeEntryCPtr = QSharedPointer<const NamespaceTypeEntry>;
-using ObjectTypeEntryCPtr = QSharedPointer<const ObjectTypeEntry>;
-using PrimitiveTypeEntryCPtr = QSharedPointer<const PrimitiveTypeEntry>;
-using SmartPointerTypeEntryCPtr = QSharedPointer<const SmartPointerTypeEntry>;
-using TemplateEntryCPtr = QSharedPointer<const TemplateEntry>;
-using TypeEntryCPtr = QSharedPointer<const TypeEntry>;
-using TypedefEntryCPtr = QSharedPointer<const TypedefEntry>;
-using TypeSystemTypeEntryCPtr = QSharedPointer<const TypeSystemTypeEntry>;
-using ValueTypeEntryCPtr = QSharedPointer<const ValueTypeEntry>;
+using ArrayTypeEntryCPtr = std::shared_ptr<const ArrayTypeEntry>;
+using ComplexTypeEntryCPtr = std::shared_ptr<const ComplexTypeEntry>;
+using ConstantValueTypeEntryCPtr = std::shared_ptr<const ConstantValueTypeEntry>;
+using ConfigurableTypeEntryCPtr = std::shared_ptr<const ConfigurableTypeEntry>;
+using ContainerTypeEntryCPtr = std::shared_ptr<const ContainerTypeEntry>;
+using CustomTypeEntryCPtr = std::shared_ptr<const CustomTypeEntry>;
+using EnumTypeEntryCPtr = std::shared_ptr<const EnumTypeEntry>;
+using EnumValueTypeEntryCPtr = std::shared_ptr<const EnumValueTypeEntry>;
+using FlagsTypeEntryCPtr = std::shared_ptr<const FlagsTypeEntry>;
+using FunctionTypeEntryCPtr = std::shared_ptr<const FunctionTypeEntry>;
+using NamespaceTypeEntryCPtr = std::shared_ptr<const NamespaceTypeEntry>;
+using ObjectTypeEntryCPtr = std::shared_ptr<const ObjectTypeEntry>;
+using PrimitiveTypeEntryCPtr = std::shared_ptr<const PrimitiveTypeEntry>;
+using SmartPointerTypeEntryCPtr = std::shared_ptr<const SmartPointerTypeEntry>;
+using TemplateEntryCPtr = std::shared_ptr<const TemplateEntry>;
+using TypeEntryCPtr = std::shared_ptr<const TypeEntry>;
+using TypedefEntryCPtr = std::shared_ptr<const TypedefEntry>;
+using TypeSystemTypeEntryCPtr = std::shared_ptr<const TypeSystemTypeEntry>;
+using ValueTypeEntryCPtr = std::shared_ptr<const ValueTypeEntry>;
+using ComplexTypeEntryCList = QList<ComplexTypeEntryCPtr>;
using ContainerTypeEntryCList = QList<ContainerTypeEntryCPtr>;
using NamespaceTypeEntryList = QList<NamespaceTypeEntryPtr>;
using PrimitiveTypeEntryCList = QList<PrimitiveTypeEntryCPtr>;
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index 42edc567a..2b686e997 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
@@ -2,13 +2,13 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "typesystemparser_p.h"
+#include "anystringview_helpers.h"
#include "addedfunction.h"
#include "codesnip.h"
#include "enumtypeentry.h"
#include "containertypeentry.h"
#include "customconversion.h"
#include "customtypenentry.h"
-#include "enumtypeentry.h"
#include "flagstypeentry.h"
#include "functiontypeentry.h"
#include "namespacetypeentry.h"
@@ -46,78 +46,84 @@
using namespace Qt::StringLiterals;
-static inline QString allowThreadAttribute() { return QStringLiteral("allow-thread"); }
-static inline QString colonColon() { return QStringLiteral("::"); }
-static inline QString checkFunctionAttribute() { return QStringLiteral("check-function"); }
-static inline QString copyableAttribute() { return QStringLiteral("copyable"); }
-static inline QString accessAttribute() { return QStringLiteral("access"); }
-static inline QString actionAttribute() { return QStringLiteral("action"); }
-static inline QString quoteAfterLineAttribute() { return QStringLiteral("quote-after-line"); }
-static inline QString quoteBeforeLineAttribute() { return QStringLiteral("quote-before-line"); }
-static inline QString textAttribute() { return QStringLiteral("text"); }
-static inline QString nameAttribute() { return QStringLiteral("name"); }
-static inline QString sinceAttribute() { return QStringLiteral("since"); }
-static inline QString untilAttribute() { return QStringLiteral("until"); }
-static inline QString defaultSuperclassAttribute() { return QStringLiteral("default-superclass"); }
-static inline QString deleteInMainThreadAttribute() { return QStringLiteral("delete-in-main-thread"); }
-static inline QString deprecatedAttribute() { return QStringLiteral("deprecated"); }
-static inline QString disableWrapperAttribute() { return QStringLiteral("disable-wrapper"); }
-static inline QString exceptionHandlingAttribute() { return QStringLiteral("exception-handling"); }
-static inline QString extensibleAttribute() { return QStringLiteral("extensible"); }
-static inline QString fileNameAttribute() { return QStringLiteral("file-name"); }
-static inline QString flagsAttribute() { return QStringLiteral("flags"); }
-static inline QString forceAbstractAttribute() { return QStringLiteral("force-abstract"); }
-static inline QString forceIntegerAttribute() { return QStringLiteral("force-integer"); }
-static inline QString formatAttribute() { return QStringLiteral("format"); }
-static inline QString generateUsingAttribute() { return QStringLiteral("generate-using"); }
-static inline QString generateFunctionsAttribute() { return QStringLiteral("generate-functions"); }
-static inline QString classAttribute() { return QStringLiteral("class"); }
-static inline QString generateAttribute() { return QStringLiteral("generate"); }
-static inline QString generateGetSetDefAttribute() { return QStringLiteral("generate-getsetdef"); }
-static inline QString genericClassAttribute() { return QStringLiteral("generic-class"); }
-static inline QString indexAttribute() { return QStringLiteral("index"); }
-static inline QString invalidateAfterUseAttribute() { return QStringLiteral("invalidate-after-use"); }
-static inline QString isNullAttribute() { return QStringLiteral("isNull"); }
-static inline QString locationAttribute() { return QStringLiteral("location"); }
-static inline QString modifiedTypeAttribute() { return QStringLiteral("modified-type"); }
-static inline QString operatorBoolAttribute() { return QStringLiteral("operator-bool"); }
-static inline QString parentManagementAttribute() { return QStringLiteral("parent-management"); }
-static inline QString pyiTypeAttribute() { return QStringLiteral("pyi-type"); }
-static inline QString overloadNumberAttribute() { return QStringLiteral("overload-number"); }
-static inline QString ownershipAttribute() { return QStringLiteral("owner"); }
-static inline QString packageAttribute() { return QStringLiteral("package"); }
-static inline QString positionAttribute() { return QStringLiteral("position"); }
-static inline QString preferredConversionAttribute() { return QStringLiteral("preferred-conversion"); }
-static inline QString preferredTargetLangTypeAttribute() { return QStringLiteral("preferred-target-lang-type"); }
-static inline QString pythonEnumTypeAttribute() { return QStringLiteral("python-type"); }
-static inline QString cppEnumTypeAttribute() { return QStringLiteral("cpp-type"); }
-static inline QString qtMetaTypeAttribute() { return QStringLiteral("qt-register-metatype"); }
-static inline QString removeAttribute() { return QStringLiteral("remove"); }
-static inline QString renameAttribute() { return QStringLiteral("rename"); }
-static inline QString readAttribute() { return QStringLiteral("read"); }
-static inline QString targetLangNameAttribute() { return QStringLiteral("target-lang-name"); }
-static inline QString writeAttribute() { return QStringLiteral("write"); }
-static inline QString opaqueContainerFieldAttribute() { return QStringLiteral("opaque-container"); }
-static inline QString replaceAttribute() { return QStringLiteral("replace"); }
-static inline QString toAttribute() { return QStringLiteral("to"); }
-static inline QString signatureAttribute() { return QStringLiteral("signature"); }
-static inline QString snippetAttribute() { return QStringLiteral("snippet"); }
-static inline QString snakeCaseAttribute() { return QStringLiteral("snake-case"); }
-static inline QString staticAttribute() { return QStringLiteral("static"); }
-static inline QString classmethodAttribute() { return QStringLiteral("classmethod"); }
-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"); }
-static inline QString enumIdentifiedByValueAttribute() { return QStringLiteral("identified-by-value"); }
-
-static inline QString noAttributeValue() { return QStringLiteral("no"); }
-static inline QString yesAttributeValue() { return QStringLiteral("yes"); }
-static inline QString trueAttributeValue() { return QStringLiteral("true"); }
-static inline QString falseAttributeValue() { return QStringLiteral("false"); }
+constexpr auto allowThreadAttribute = "allow-thread"_L1;
+constexpr auto checkFunctionAttribute = "check-function"_L1;
+constexpr auto copyableAttribute = "copyable"_L1;
+constexpr auto accessAttribute = "access"_L1;
+constexpr auto actionAttribute = "action"_L1;
+constexpr auto quoteAfterLineAttribute = "quote-after-line"_L1;
+constexpr auto quoteBeforeLineAttribute = "quote-before-line"_L1;
+constexpr auto textAttribute = "text"_L1;
+constexpr auto nameAttribute = "name"_L1;
+constexpr auto sinceAttribute = "since"_L1;
+constexpr auto untilAttribute = "until"_L1;
+constexpr auto defaultSuperclassAttribute = "default-superclass"_L1;
+constexpr auto deleteInMainThreadAttribute = "delete-in-main-thread"_L1;
+constexpr auto deprecatedAttribute = "deprecated"_L1;
+constexpr auto disableWrapperAttribute = "disable-wrapper"_L1;
+constexpr auto docFileAttribute = "doc-file"_L1;
+constexpr auto exceptionHandlingAttribute = "exception-handling"_L1;
+constexpr auto extensibleAttribute = "extensible"_L1;
+constexpr auto fileNameAttribute = "file-name"_L1;
+constexpr auto fileAttribute = "file"_L1;
+constexpr auto flagsAttribute = "flags"_L1;
+constexpr auto forceAbstractAttribute = "force-abstract"_L1;
+constexpr auto forceIntegerAttribute = "force-integer"_L1;
+constexpr auto formatAttribute = "format"_L1;
+constexpr auto generateUsingAttribute = "generate-using"_L1;
+constexpr auto generateFunctionsAttribute = "generate-functions"_L1;
+constexpr auto classAttribute = "class"_L1;
+constexpr auto generateAttribute = "generate"_L1;
+constexpr auto generateGetSetDefAttribute = "generate-getsetdef"_L1;
+constexpr auto genericClassAttribute = "generic-class"_L1;
+constexpr auto indexAttribute = "index"_L1;
+constexpr auto invalidateAfterUseAttribute = "invalidate-after-use"_L1;
+constexpr auto isNullAttribute = "isNull"_L1;
+constexpr auto locationAttribute = "location"_L1;
+constexpr auto modifiedTypeAttribute = "modified-type"_L1;
+constexpr auto opaqueContainerAttribute = "opaque-containers"_L1;
+constexpr auto operatorBoolAttribute = "operator-bool"_L1;
+constexpr auto parentManagementAttribute = "parent-management"_L1;
+constexpr auto pyiTypeAttribute = "pyi-type"_L1;
+constexpr auto overloadNumberAttribute = "overload-number"_L1;
+constexpr auto ownershipAttribute = "owner"_L1;
+constexpr auto packageAttribute = "package"_L1;
+constexpr auto polymorphicBaseAttribute = "polymorphic-base"_L1;
+constexpr auto positionAttribute = "position"_L1;
+constexpr auto preferredConversionAttribute = "preferred-conversion"_L1;
+constexpr auto preferredTargetLangTypeAttribute = "preferred-target-lang-type"_L1;
+constexpr auto pythonEnumTypeAttribute = "python-type"_L1;
+constexpr auto pythonOverrideAttribute = "python-override"_L1;
+constexpr auto cppEnumTypeAttribute = "cpp-type"_L1;
+constexpr auto qtMetaObjectFunctionsAttribute = "qt-metaobject"_L1;
+constexpr auto qtMetaTypeAttribute = "qt-register-metatype"_L1;
+constexpr auto removeAttribute = "remove"_L1;
+constexpr auto renameAttribute = "rename"_L1;
+constexpr auto readAttribute = "read"_L1;
+constexpr auto targetLangNameAttribute = "target-lang-name"_L1;
+constexpr auto writeAttribute = "write"_L1;
+constexpr auto opaqueContainerFieldAttribute = "opaque-container"_L1;
+constexpr auto replaceAttribute = "replace"_L1;
+constexpr auto toAttribute = "to"_L1;
+constexpr auto signatureAttribute = "signature"_L1;
+constexpr auto snippetAttribute = "snippet"_L1;
+constexpr auto snakeCaseAttribute = "snake-case"_L1;
+constexpr auto staticAttribute = "static"_L1;
+constexpr auto classmethodAttribute = "classmethod"_L1;
+constexpr auto threadAttribute = "thread"_L1;
+constexpr auto sourceAttribute = "source"_L1;
+constexpr auto streamAttribute = "stream"_L1;
+constexpr auto privateAttribute = "private"_L1;
+constexpr auto xPathAttribute = "xpath"_L1;
+constexpr auto virtualSlotAttribute = "virtual-slot"_L1;
+constexpr auto visibleAttribute = "visible"_L1;
+constexpr auto enumIdentifiedByValueAttribute = "identified-by-value"_L1;
+constexpr auto subModuleOfAttribute = "submodule-of"_L1;
+
+constexpr auto noAttributeValue = "no"_L1;
+constexpr auto yesAttributeValue = "yes"_L1;
+constexpr auto trueAttributeValue = "true"_L1;
+constexpr auto falseAttributeValue = "false"_L1;
static bool isTypeEntry(StackElement el)
{
@@ -147,7 +153,7 @@ static bool setRejectionRegularExpression(const QString &patternIn,
if (patternIn.startsWith(u'^') && patternIn.endsWith(u'$'))
pattern = patternIn;
else if (patternIn == u"*")
- pattern = QStringLiteral("^.*$");
+ pattern = "^.*$"_L1;
else
pattern = u'^' + QRegularExpression::escape(patternIn) + u'$';
re->setPattern(pattern);
@@ -158,15 +164,20 @@ static bool setRejectionRegularExpression(const QString &patternIn,
return true;
}
+static inline bool hasFileSnippetAttributes(const QXmlStreamAttributes *attributes)
+{
+ return attributes->hasAttribute(fileAttribute);
+}
+
// Extract a snippet from a file within annotation "// @snippet label".
std::optional<QString>
extractSnippet(const QString &code, const QString &snippetLabel)
{
if (snippetLabel.isEmpty())
return code;
- const QString pattern = QStringLiteral(R"(^\s*//\s*@snippet\s+)")
+ const QString pattern = R"(^\s*//\s*@snippet\s+)"_L1
+ QRegularExpression::escape(snippetLabel)
- + QStringLiteral(R"(\s*$)");
+ + R"(\s*$)"_L1;
const QRegularExpression snippetRe(pattern);
Q_ASSERT(snippetRe.isValid());
@@ -175,7 +186,7 @@ std::optional<QString>
QString result;
const auto lines = QStringView{code}.split(u'\n');
for (const auto &line : lines) {
- if (snippetRe.match(line).hasMatch()) {
+ if (snippetRe.matchView(line).hasMatch()) {
foundLabel = true;
useLine = !useLine;
if (!useLine)
@@ -188,48 +199,31 @@ std::optional<QString>
return CodeSnipAbstract::fixSpaces(result);
}
-template <class EnumType, Qt::CaseSensitivity cs = Qt::CaseInsensitive>
+template <class EnumType>
struct EnumLookup
{
QStringView name;
EnumType value;
};
-template <class EnumType, Qt::CaseSensitivity cs>
-bool operator==(const EnumLookup<EnumType, cs> &e1, const EnumLookup<EnumType, cs> &e2)
-{
- return e1.name.compare(e2.name, cs) == 0;
-}
-
-template <class EnumType, Qt::CaseSensitivity cs>
-bool operator<(const EnumLookup<EnumType, cs> &e1, const EnumLookup<EnumType, cs> &e2)
-{
- return e1.name.compare(e2.name, cs) < 0;
-}
-
// Helper macros to define lookup functions that take a QStringView needle
// and an optional default return value.
#define ENUM_LOOKUP_BEGIN(EnumType, caseSensitivity, functionName) \
static std::optional<EnumType> functionName(QStringView needle) \
{ \
- using HaystackEntry = EnumLookup<EnumType, caseSensitivity>; \
- static const HaystackEntry haystack[] =
-
-#define ENUM_LOOKUP_LINEAR_SEARCH() \
- const auto end = haystack + sizeof(haystack) / sizeof(haystack[0]); \
- const auto it = std::find(haystack, end, HaystackEntry{needle, {} }); \
+ using HaystackEntry = EnumLookup<EnumType>; \
+ constexpr auto cs = caseSensitivity; \
+ static constexpr HaystackEntry haystack[] =
+
+#define ENUM_LOOKUP_LINEAR_SEARCH \
+ auto pred = [cs, needle](const HaystackEntry &he) { \
+ return he.name.compare(needle, cs) == 0; \
+ }; \
+ auto end = std::cend(haystack); \
+ auto it = std::find_if(std::cbegin(haystack), end, pred); \
if (it != end) \
return it->value; \
- return {}; \
-}
-
-#define ENUM_LOOKUP_BINARY_SEARCH() \
- const auto end = haystack + sizeof(haystack) / sizeof(haystack[0]); \
- const HaystackEntry needleEntry{needle, {} }; \
- const auto lb = std::lower_bound(haystack, end, needleEntry); \
- if (lb != end && *lb == needleEntry) \
- return lb->value; \
- return {}; \
+ return std::nullopt; \
}
ENUM_LOOKUP_BEGIN(TypeSystem::AllowThread, Qt::CaseInsensitive,
@@ -241,7 +235,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::AllowThread, Qt::CaseInsensitive,
{u"no", TypeSystem::AllowThread::Disallow},
{u"false", TypeSystem::AllowThread::Disallow},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::BoolCast, Qt::CaseInsensitive,
@@ -252,7 +246,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::BoolCast, Qt::CaseInsensitive,
{u"no", TypeSystem::BoolCast::Disabled},
{u"false", TypeSystem::BoolCast::Disabled},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::PythonEnumType, Qt::CaseSensitive,
pythonEnumTypeFromAttribute)
@@ -262,7 +256,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::PythonEnumType, Qt::CaseSensitive,
{u"Flag", TypeSystem::PythonEnumType::Flag},
{u"IntFlag", TypeSystem::PythonEnumType::IntFlag},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::QtMetaTypeRegistration, Qt::CaseSensitive,
qtMetaTypeFromAttribute)
@@ -273,7 +267,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::QtMetaTypeRegistration, Qt::CaseSensitive,
{u"no", TypeSystem::QtMetaTypeRegistration::Disabled},
{u"false", TypeSystem::QtMetaTypeRegistration::Disabled},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::Language, Qt::CaseInsensitive,
languageFromAttribute)
@@ -283,7 +277,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::Language, Qt::CaseInsensitive,
{u"shell", TypeSystem::ShellCode}, // coloca no header, mas antes da declaracao da classe
{u"target", TypeSystem::TargetLangCode} // em algum lugar do cpp
};
-ENUM_LOOKUP_BINARY_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::Ownership, Qt::CaseInsensitive,
ownershipFromFromAttribute)
@@ -292,7 +286,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::Ownership, Qt::CaseInsensitive,
{u"c++", TypeSystem::CppOwnership},
{u"default", TypeSystem::DefaultOwnership}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(AddedFunction::Access, Qt::CaseInsensitive,
addedFunctionAccessFromAttribute)
@@ -300,7 +294,7 @@ ENUM_LOOKUP_BEGIN(AddedFunction::Access, Qt::CaseInsensitive,
{u"public", AddedFunction::Public},
{u"protected", AddedFunction::Protected},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(FunctionModification::ModifierFlag, Qt::CaseSensitive,
modifierFromAttribute)
@@ -308,12 +302,11 @@ ENUM_LOOKUP_BEGIN(FunctionModification::ModifierFlag, Qt::CaseSensitive,
{u"private", FunctionModification::Private},
{u"public", FunctionModification::Public},
{u"protected", FunctionModification::Protected},
- {u"friendly", FunctionModification::Friendly},
{u"rename", FunctionModification::Rename},
{u"final", FunctionModification::Final},
{u"non-final", FunctionModification::NonFinal}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(ReferenceCount::Action, Qt::CaseInsensitive,
referenceCountFromAttribute)
@@ -324,7 +317,7 @@ ENUM_LOOKUP_BEGIN(ReferenceCount::Action, Qt::CaseInsensitive,
{u"set", ReferenceCount::Set},
{u"ignore", ReferenceCount::Ignore}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(ArgumentOwner::Action, Qt::CaseInsensitive,
argumentOwnerActionFromAttribute)
@@ -332,16 +325,17 @@ ENUM_LOOKUP_BEGIN(ArgumentOwner::Action, Qt::CaseInsensitive,
{u"add", ArgumentOwner::Add},
{u"remove", ArgumentOwner::Remove}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::CodeSnipPosition, Qt::CaseInsensitive,
codeSnipPositionFromAttribute)
{
{u"beginning", TypeSystem::CodeSnipPositionBeginning},
{u"end", TypeSystem::CodeSnipPositionEnd},
- {u"declaration", TypeSystem::CodeSnipPositionDeclaration}
+ {u"declaration", TypeSystem::CodeSnipPositionDeclaration},
+ {u"override", TypeSystem::CodeSnipPositionPyOverride}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(Include::IncludeType, Qt::CaseInsensitive,
locationFromAttribute)
@@ -350,7 +344,7 @@ ENUM_LOOKUP_BEGIN(Include::IncludeType, Qt::CaseInsensitive,
{u"local", Include::LocalPath},
{u"target", Include::TargetLangImport}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::DocModificationMode, Qt::CaseInsensitive,
docModificationFromAttribute)
@@ -359,7 +353,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::DocModificationMode, Qt::CaseInsensitive,
{u"prepend", TypeSystem::DocModificationPrepend},
{u"replace", TypeSystem::DocModificationReplace}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(ContainerTypeEntry::ContainerKind, Qt::CaseSensitive,
containerTypeFromAttribute)
@@ -375,9 +369,10 @@ ENUM_LOOKUP_BEGIN(ContainerTypeEntry::ContainerKind, Qt::CaseSensitive,
{u"multi-map", ContainerTypeEntry::MultiMapContainer},
{u"hash", ContainerTypeEntry::MapContainer},
{u"multi-hash", ContainerTypeEntry::MultiMapContainer},
- {u"pair", ContainerTypeEntry::PairContainer}
+ {u"pair", ContainerTypeEntry::PairContainer},
+ {u"span", ContainerTypeEntry::SpanContainer}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeRejection::MatchType, Qt::CaseSensitive,
typeRejectionFromAttribute)
@@ -389,7 +384,7 @@ ENUM_LOOKUP_BEGIN(TypeRejection::MatchType, Qt::CaseSensitive,
{u"argument-type", TypeRejection::ArgumentType},
{u"return-type", TypeRejection::ReturnType}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::ExceptionHandling, Qt::CaseSensitive,
exceptionHandlingFromAttribute)
@@ -401,7 +396,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::ExceptionHandling, Qt::CaseSensitive,
{u"yes", TypeSystem::ExceptionHandling::On},
{u"true", TypeSystem::ExceptionHandling::On},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::SmartPointerType, Qt::CaseSensitive,
smartPointerTypeFromAttribute)
@@ -411,7 +406,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::SmartPointerType, Qt::CaseSensitive,
{u"value-handle", TypeSystem::SmartPointerType::ValueHandle},
{u"shared", TypeSystem::SmartPointerType::Shared}
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
template <class EnumType>
static std::optional<EnumType>
@@ -440,6 +435,7 @@ static const StackElementHash &stackElementHash()
{u"add-function", StackElement::AddFunction},
{u"add-pymethoddef", StackElement::AddPyMethodDef},
{u"array", StackElement::Array},
+ {u"configuration", StackElement::Configuration},
{u"container-type", StackElement::ContainerTypeEntry},
{u"conversion-rule", StackElement::ConversionRule},
{u"custom-constructor", StackElement::Unimplemented},
@@ -465,6 +461,7 @@ static const StackElementHash &stackElementHash()
{u"native-to-target", StackElement::NativeToTarget},
{u"no-null-pointer", StackElement::NoNullPointers},
{u"object-type", StackElement::ObjectTypeEntry},
+ {u"opaque-container", StackElement::OpaqueContainer},
{u"parent", StackElement::ParentOwner},
{u"primitive-type", StackElement::PrimitiveTypeEntry},
{u"property", StackElement::Property},
@@ -520,7 +517,7 @@ ENUM_LOOKUP_BEGIN(TypeSystem::SnakeCase, Qt::CaseSensitive,
{u"true", TypeSystem::SnakeCase::Enabled},
{u"both", TypeSystem::SnakeCase::Both},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::Visibility, Qt::CaseSensitive,
visibilityFromAttribute)
@@ -531,10 +528,10 @@ ENUM_LOOKUP_BEGIN(TypeSystem::Visibility, Qt::CaseSensitive,
{u"yes", TypeSystem::Visibility::Visible},
{u"true", TypeSystem::Visibility::Visible},
};
-ENUM_LOOKUP_LINEAR_SEARCH()
+ENUM_LOOKUP_LINEAR_SEARCH
static int indexOfAttribute(const QXmlStreamAttributes &atts,
- QStringView name)
+ QAnyStringView name)
{
for (qsizetype i = 0, size = atts.size(); i < size; ++i) {
if (atts.at(i).qualifiedName() == name)
@@ -602,12 +599,12 @@ QString TypeSystemEntityResolver::readFile(const QString &entityName, QString *e
path = TypeDatabase::instance()->modifiedTypesystemFilepath(fileName, m_currentPath);
if (!QFileInfo::exists(path)) {
*errorMessage = u"Unable to resolve: "_s + entityName;
- return QString();
+ return {};
}
QFile file(path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
*errorMessage = msgCannotOpenForReading(file);
- return QString();
+ return {};
}
QString result = QString::fromUtf8(file.readAll()).trimmed();
// Remove license header comments on which QXmlStreamReader chokes
@@ -647,7 +644,7 @@ enum class ParserState
Template
};
-TypeSystemParser::TypeSystemParser(const QSharedPointer<TypeDatabaseParserContext> &context,
+TypeSystemParser::TypeSystemParser(const std::shared_ptr<TypeDatabaseParserContext> &context,
bool generate) :
m_context(context),
m_generate(generate ? TypeEntry::GenerateCode : TypeEntry::GenerateForSubclass)
@@ -690,7 +687,7 @@ static QString msgReaderError(const ConditionalStreamReader &reader, const QStri
}
static QString msgUnimplementedElementWarning(const ConditionalStreamReader &reader,
- QStringView name)
+ QAnyStringView name)
{
QString message;
QTextStream(&message) << "The element \"" << name
@@ -715,7 +712,7 @@ static inline QString msgUnimplementedAttributeWarning(const ConditionalStreamRe
static QString
msgUnimplementedAttributeValueWarning(const ConditionalStreamReader &reader,
- QStringView name, QStringView value)
+ QAnyStringView name, QAnyStringView value)
{
QString message;
QTextStream(&message) << "The value \"" << value
@@ -732,16 +729,17 @@ static inline
attribute.value());
}
-static bool addRejection(TypeDatabase *database, QXmlStreamAttributes *attributes,
+static bool addRejection(TypeDatabase *database, bool generate, QXmlStreamAttributes *attributes,
QString *errorMessage)
{
- const auto classIndex = indexOfAttribute(*attributes, classAttribute());
+ const auto classIndex = indexOfAttribute(*attributes, classAttribute);
if (classIndex == -1) {
- *errorMessage = msgMissingAttribute(classAttribute());
+ *errorMessage = msgMissingAttribute(classAttribute);
return false;
}
TypeRejection rejection;
+ rejection.generate = generate;
const QString className = attributes->takeAt(classIndex).value().toString();
if (!setRejectionRegularExpression(className, &rejection.className, errorMessage))
return false;
@@ -880,7 +878,7 @@ bool TypeSystemParser::endElement(StackElement element)
toNative.setSourceType(m_context->db->findType(toNative.sourceTypeName()));
}
}
- purgeEmptyCodeSnips(&qSharedPointerCast<TypeSystemTypeEntry>(top->entry)->codeSnips());
+ purgeEmptyCodeSnips(&std::static_pointer_cast<TypeSystemTypeEntry>(top->entry)->codeSnips());
break;
case StackElement::FunctionTypeEntry:
TypeDatabase::instance()->addGlobalUserFunctionModifications(top->functionMods);
@@ -892,7 +890,7 @@ bool TypeSystemParser::endElement(StackElement element)
case StackElement::NamespaceTypeEntry: {
Q_ASSERT(top->entry);
Q_ASSERT(top->entry->isComplex());
- auto centry = qSharedPointerCast<ComplexTypeEntry>(top->entry);
+ auto centry = std::static_pointer_cast<ComplexTypeEntry>(top->entry);
purgeEmptyCodeSnips(&centry->codeSnips());
centry->setAddedFunctions(top->addedFunctions);
centry->setFunctionModifications(top->functionMods);
@@ -902,13 +900,13 @@ bool TypeSystemParser::endElement(StackElement element)
break;
case StackElement::TypedefTypeEntry: {
- auto centry = qSharedPointerCast<TypedefEntry>(top->entry)->target();
+ auto centry = std::static_pointer_cast<TypedefEntry>(top->entry)->target();
centry->setAddedFunctions(centry->addedFunctions() + top->addedFunctions);
centry->setFunctionModifications(centry->functionModifications() + top->functionMods);
centry->setFieldModifications(centry->fieldModifications() + top->fieldMods);
centry->setDocModification(centry->docModifications() + top->docModifications);
if (top->entry->isComplex()) {
- auto cte = qSharedPointerCast<const ComplexTypeEntry>(top->entry);
+ auto cte = std::static_pointer_cast<const ComplexTypeEntry>(top->entry);
centry->setCodeSnips(centry->codeSnips() + cte->codeSnips());
}
}
@@ -931,7 +929,7 @@ bool TypeSystemParser::endElement(StackElement element)
case ParserState::PrimitiveTypeNativeToTargetConversion:
case ParserState::PrimitiveTypeTargetToNativeConversion: {
auto customConversion = CustomConversion::getCustomConversion(top->entry);
- if (customConversion.isNull()) {
+ if (!customConversion) {
m_error = msgMissingCustomConversion(top->entry);
return false;
}
@@ -1068,12 +1066,12 @@ CodeSnipAbstract *TypeSystemParser::injectCodeTarget(qsizetype offset) const
}
case ParserState::TypeEntryCodeInjection:
Q_ASSERT(top->entry->isComplex());
- return &qSharedPointerCast<ComplexTypeEntry>(top->entry)->codeSnips().last();
+ return &std::static_pointer_cast<ComplexTypeEntry>(top->entry)->codeSnips().last();
case ParserState::TypeSystemCodeInjection:
Q_ASSERT(top->entry->isTypeSystem());
- return &qSharedPointerCast<TypeSystemTypeEntry>(top->entry)->codeSnips().last();
+ return &std::static_pointer_cast<TypeSystemTypeEntry>(top->entry)->codeSnips().last();
case ParserState::Template:
- return m_templateEntry.data();
+ return m_templateEntry.get();
default:
break;
}
@@ -1122,7 +1120,7 @@ bool TypeSystemParser::characters(const String &ch)
bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts)
{
- const QString fileName = atts.value(nameAttribute()).toString();
+ const QString fileName = atts.value(nameAttribute).toString();
if (fileName.isEmpty()) {
m_error = u"Required attribute 'name' missing for include-file tag."_s;
return false;
@@ -1137,11 +1135,11 @@ bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts)
}
}
- const auto quoteFrom = atts.value(quoteAfterLineAttribute());
+ const auto quoteFrom = atts.value(quoteAfterLineAttribute);
bool foundFromOk = quoteFrom.isEmpty();
bool from = quoteFrom.isEmpty();
- const auto quoteTo = atts.value(quoteBeforeLineAttribute());
+ const auto quoteTo = atts.value(quoteBeforeLineAttribute);
bool foundToOk = quoteTo.isEmpty();
bool to = true;
@@ -1161,10 +1159,10 @@ bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts)
}
}
if (!foundFromOk || !foundToOk) {
- QString fromError = QStringLiteral("Could not find quote-after-line='%1' in file '%2'.")
- .arg(quoteFrom.toString(), fileName);
- QString toError = QStringLiteral("Could not find quote-before-line='%1' in file '%2'.")
- .arg(quoteTo.toString(), fileName);
+ QString fromError = QString::fromLatin1("Could not find quote-after-line='%1' in file '%2'.")
+ .arg(quoteFrom.toString(), fileName);
+ QString toError = QString::fromLatin1("Could not find quote-before-line='%1' in file '%2'.")
+ .arg(quoteTo.toString(), fileName);
if (!foundToOk)
m_error = toError;
@@ -1178,29 +1176,27 @@ bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts)
return true;
}
-static bool convertBoolean(QStringView value, const QString &attributeName, bool defaultValue)
+static bool convertBoolean(QStringView value, QAnyStringView attributeName, bool defaultValue)
{
- if (value.compare(trueAttributeValue(), Qt::CaseInsensitive) == 0
- || value.compare(yesAttributeValue(), Qt::CaseInsensitive) == 0) {
+ if (value.compare(trueAttributeValue, Qt::CaseInsensitive) == 0
+ || value.compare(yesAttributeValue, Qt::CaseInsensitive) == 0) {
return true;
}
- if (value.compare(falseAttributeValue(), Qt::CaseInsensitive) == 0
- || value.compare(noAttributeValue(), Qt::CaseInsensitive) == 0) {
+ if (value.compare(falseAttributeValue, Qt::CaseInsensitive) == 0
+ || value.compare(noAttributeValue, Qt::CaseInsensitive) == 0) {
return false;
}
- const QString warn = QStringLiteral("Boolean value '%1' not supported in attribute '%2'. Use 'yes' or 'no'. Defaulting to '%3'.")
- .arg(value)
- .arg(attributeName,
- defaultValue ? yesAttributeValue() : noAttributeValue());
-
- qCWarning(lcShiboken).noquote().nospace() << warn;
+ qCWarning(lcShiboken).noquote().nospace() << "Boolean value '" << value
+ << "' not supported in attribute '" << attributeName
+ << "'. Use 'yes' or 'no'. Defaulting to '"
+ << (defaultValue ? yesAttributeValue : noAttributeValue) << "'.";
return defaultValue;
}
static bool convertRemovalAttribute(QStringView value)
{
return value == u"all" // Legacy
- || convertBoolean(value, removeAttribute(), false);
+ || convertBoolean(value, removeAttribute, false);
}
// Check whether an entry should be dropped, allowing for dropping the module
@@ -1226,7 +1222,7 @@ static bool shouldDropTypeEntry(const TypeDatabase *db,
static QString checkSignatureError(const QString& signature, const QString& tag)
{
QString funcName = signature.left(signature.indexOf(u'(')).trimmed();
- static const QRegularExpression whiteSpace(QStringLiteral("\\s"));
+ static const QRegularExpression whiteSpace("\\s"_L1);
Q_ASSERT(whiteSpace.isValid());
if (!funcName.startsWith(u"operator ") && funcName.contains(whiteSpace)) {
return QString::fromLatin1("Error in <%1> tag signature attribute '%2'.\n"
@@ -1247,7 +1243,7 @@ bool TypeSystemParser::checkRootElement()
{
for (auto i = m_contextStack.size() - 1; i >= 0; --i) {
auto e = m_contextStack.at(i)->entry;
- if (!e.isNull() && e->isTypeSystem())
+ if (e && e->isTypeSystem())
return true;
}
m_error = msgNoRootTypeSystemEntry();
@@ -1285,7 +1281,7 @@ bool TypeSystemParser::applyCommonAttributes(const ConditionalStreamReader &read
} else if (name == u"view-on") {
const QString name = attributes->takeAt(i).value().toString();
TypeEntryPtr views = findViewedType(name);
- if (views.isNull()) {
+ if (!views) {
m_error = msgCannotFindView(name, type->name());
return false;
}
@@ -1302,10 +1298,10 @@ CustomTypeEntryPtr TypeSystemParser::parseCustomTypeEntry(const ConditionalStrea
{
if (!checkRootElement())
return nullptr;
- CustomTypeEntryPtr result(new CustomTypeEntry(name, since, m_contextStack.top()->entry));
+ auto result = std::make_shared<CustomTypeEntry>(name, since, m_contextStack.top()->entry);
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == checkFunctionAttribute())
+ if (name == checkFunctionAttribute)
result->setCheckFunction(attributes->takeAt(i).value().toString());
}
return result;
@@ -1320,30 +1316,30 @@ FlagsTypeEntryPtr
{
if (!checkRootElement())
return nullptr;
- FlagsTypeEntryPtr ftype(new FlagsTypeEntry(u"QFlags<"_s + enumEntry->name() + u'>',
- since,
- typeSystemTypeEntry(currentParentTypeEntry())));
+ auto ftype = std::make_shared<FlagsTypeEntry>(u"QFlags<"_s + enumEntry->name() + u'>',
+ since,
+ typeSystemTypeEntry(currentParentTypeEntry()));
ftype->setOriginator(enumEntry);
ftype->setTargetLangPackage(enumEntry->targetLangPackage());
// Try toenumEntry get the guess the qualified flag name
- if (!flagName.contains(colonColon())) {
+ if (!flagName.contains(u"::"_s)) {
auto eq = enumEntry->qualifier();
if (!eq.isEmpty())
- flagName.prepend(eq + colonColon());
+ flagName.prepend(eq + u"::"_s);
}
ftype->setOriginalName(flagName);
if (!applyCommonAttributes(reader, ftype, attributes))
return nullptr;
- QStringList lst = flagName.split(colonColon());
+ QStringList lst = flagName.split(u"::"_s);
const QString name = lst.takeLast();
const QString targetLangFlagName = lst.join(u'.');
const QString &targetLangQualifier = enumEntry->targetLangQualifier();
if (targetLangFlagName != targetLangQualifier) {
- qCWarning(lcShiboken).noquote().nospace()
- << QStringLiteral("enum %1 and flags %2 (%3) differ in qualifiers")
- .arg(targetLangQualifier, lst.value(0), targetLangFlagName);
+ qCWarning(lcShiboken, "enum %s and flags %s (%s) differ in qualifiers",
+ qPrintable(targetLangQualifier), qPrintable(lst.value(0)),
+ qPrintable(targetLangFlagName));
}
ftype->setFlagsName(name);
@@ -1423,8 +1419,9 @@ SmartPointerTypeEntryPtr
return nullptr;
}
- SmartPointerTypeEntryPtr type(new SmartPointerTypeEntry(name, getter, smartPointerType,
- refCountMethodName, since, currentParentTypeEntry()));
+ auto type = std::make_shared<SmartPointerTypeEntry>(name, getter, smartPointerType,
+ refCountMethodName, since,
+ currentParentTypeEntry());
if (!applyCommonAttributes(reader, type, attributes))
return nullptr;
applyComplexTypeAttributes(reader, type, attributes);
@@ -1442,22 +1439,22 @@ PrimitiveTypeEntryPtr
{
if (!checkRootElement())
return nullptr;
- PrimitiveTypeEntryPtr type (new PrimitiveTypeEntry(name, since, currentParentTypeEntry()));
+ auto type = std::make_shared<PrimitiveTypeEntry>(name, since, currentParentTypeEntry());
QString targetLangApiName;
if (!applyCommonAttributes(reader, type, attributes))
return nullptr;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == targetLangNameAttribute()) {
+ if (name == targetLangNameAttribute) {
type->setTargetLangName(attributes->takeAt(i).value().toString());
} else if (name == u"target-lang-api-name") {
targetLangApiName = attributes->takeAt(i).value().toString();
- } else if (name == preferredConversionAttribute()) {
+ } else if (name == preferredConversionAttribute) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- } else if (name == preferredTargetLangTypeAttribute()) {
+ } else if (name == preferredTargetLangTypeAttribute) {
const bool v = convertBoolean(attributes->takeAt(i).value(),
- preferredTargetLangTypeAttribute(), true);
+ preferredTargetLangTypeAttribute, true);
type->setPreferredTargetLangType(v);
} else if (name == u"default-constructor") {
type->setDefaultConstructor(attributes->takeAt(i).value().toString());
@@ -1466,27 +1463,40 @@ PrimitiveTypeEntryPtr
if (!targetLangApiName.isEmpty()) {
auto e = m_context->db->findType(targetLangApiName);
- if (e.isNull() || !e->isCustom()) {
+ if (!e || !e->isCustom()) {
m_error = msgInvalidTargetLanguageApiName(targetLangApiName);
return nullptr;
}
- type->setTargetLangApiType(qSharedPointerCast<CustomTypeEntry>(e));
+ type->setTargetLangApiType(std::static_pointer_cast<CustomTypeEntry>(e));
}
type->setTargetLangPackage(m_defaultPackage);
return type;
}
// "int:QList_int;QString:QList_QString"
-static bool parseOpaqueContainers(QStringView s, ContainerTypeEntryPtr cte)
+bool TypeSystemParser::parseOpaqueContainers(QStringView s, OpaqueContainers *result)
{
const auto entries = s.split(u';');
for (const auto &entry : entries) {
const auto values = entry.split(u':');
- if (values.size() != 2)
- return false;
- QString instantiation = values.at(0).trimmed().toString();
- QString name = values.at(1).trimmed().toString();
- cte->addOpaqueContainer({instantiation, name});
+ if (values.size() != 2) {
+ m_error = u"Error parsing the opaque container attribute: \""_s
+ + s.toString() + u"\"."_s;
+ return false;
+ }
+ OpaqueContainer oc;
+ oc.name = values.at(1).trimmed().toString();
+ const auto instantiations = values.at(0).split(u',', Qt::SkipEmptyParts);
+ for (const auto &instantiationV : instantiations) {
+ QString instantiation = instantiationV.trimmed().toString();
+ // Fix to match AbstractMetaType::signature() which is used for matching
+ // "Foo*" -> "Foo *"
+ const auto asteriskPos = instantiation.indexOf(u'*');
+ if (asteriskPos > 0 && !instantiation.at(asteriskPos - 1).isSpace())
+ instantiation.insert(asteriskPos, u' ');
+ oc.instantiations.append(instantiation);
+ }
+ result->append(oc);
}
return true;
}
@@ -1510,27 +1520,48 @@ ContainerTypeEntryPtr
return nullptr;
}
attributes->removeAt(typeIndex);
- ContainerTypeEntryPtr type(new ContainerTypeEntry(name, containerTypeOpt.value(),
- since, currentParentTypeEntry()));
+ auto type = std::make_shared<ContainerTypeEntry>(name, containerTypeOpt.value(),
+ since, currentParentTypeEntry());
if (!applyCommonAttributes(reader, type, attributes))
return nullptr;
applyComplexTypeAttributes(reader, type, attributes);
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == u"opaque-containers") {
+ if (name == opaqueContainerAttribute) {
const auto attribute = attributes->takeAt(i);
- if (!parseOpaqueContainers(attribute.value(), type)) {
- m_error = u"Error parsing the opaque container attribute: \""_s
- + attribute.value().toString() + u"\"."_s;
+ OpaqueContainers oc;
+ if (!parseOpaqueContainers(attribute.value(), &oc))
return nullptr;
- }
+ type->appendOpaqueContainers(oc);
}
}
return type;
}
+bool TypeSystemParser::parseOpaqueContainerElement(QXmlStreamAttributes *attributes)
+{
+ QString containerName;
+ OpaqueContainers oc;
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == nameAttribute) {
+ containerName = attributes->takeAt(i).value().toString();
+ } else if (name == opaqueContainerAttribute) {
+ const auto attribute = attributes->takeAt(i);
+ if (!parseOpaqueContainers(attribute.value(), &oc))
+ return false;
+ }
+ }
+ if (containerName.isEmpty()) {
+ m_error = msgMissingAttribute(nameAttribute);
+ return false;
+ }
+ m_context->opaqueContainerHash[containerName].append(oc);
+ return true;
+}
+
EnumTypeEntryPtr
TypeSystemParser::parseEnumTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
@@ -1538,7 +1569,7 @@ EnumTypeEntryPtr
{
if (!checkRootElement())
return nullptr;
- EnumTypeEntryPtr entry(new EnumTypeEntry(name, since, currentParentTypeEntry()));
+ auto entry = std::make_shared<EnumTypeEntry>(name, since, currentParentTypeEntry());
applyCommonAttributes(reader, entry, attributes);
entry->setTargetLangPackage(m_defaultPackage);
@@ -1551,10 +1582,12 @@ EnumTypeEntryPtr
} else if (name == u"lower-bound") {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- } else if (name == forceIntegerAttribute()) {
+ } else if (name == docFileAttribute) {
+ entry->setDocFile(attributes->takeAt(i).value().toString());
+ } else if (name == forceIntegerAttribute) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- } else if (name == pythonEnumTypeAttribute()) {
+ } else if (name == pythonEnumTypeAttribute) {
const auto attribute = attributes->takeAt(i);
const auto typeOpt = pythonEnumTypeFromAttribute(attribute.value());
if (typeOpt.has_value()) {
@@ -1563,12 +1596,12 @@ EnumTypeEntryPtr
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == cppEnumTypeAttribute()) {
+ } else if (name == cppEnumTypeAttribute) {
entry->setCppType(attributes->takeAt(i).value().toString());
- } else if (name == extensibleAttribute()) {
+ } else if (name == extensibleAttribute) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- } else if (name == flagsAttribute()) {
+ } else if (name == flagsAttribute) {
flagNames = attributes->takeAt(i).value().toString();
}
}
@@ -1590,7 +1623,7 @@ NamespaceTypeEntryPtr
{
if (!checkRootElement())
return nullptr;
- NamespaceTypeEntryPtr result(new NamespaceTypeEntry(name, since, currentParentTypeEntry()));
+ auto result = std::make_shared<NamespaceTypeEntry>(name, since, currentParentTypeEntry());
auto visibility = TypeSystem::Visibility::Unspecified;
applyCommonAttributes(reader, result, attributes);
for (auto i = attributes->size() - 1; i >= 0; --i) {
@@ -1616,7 +1649,7 @@ NamespaceTypeEntryPtr
}
result->setExtends(*extendsIt);
attributes->removeAt(i);
- } else if (attributeName == visibleAttribute()) {
+ } else if (attributeName == visibleAttribute) {
const auto attribute = attributes->takeAt(i);
const auto visibilityOpt = visibilityFromAttribute(attribute.value());
if (!visibilityOpt.has_value()) {
@@ -1624,11 +1657,12 @@ NamespaceTypeEntryPtr
return nullptr;
}
visibility = visibilityOpt.value();
- } else if (attributeName == generateAttribute()) {
- if (!convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true))
+ } else if (attributeName == generateAttribute) {
+ if (!convertBoolean(attributes->takeAt(i).value(), generateAttribute, true))
visibility = TypeSystem::Visibility::Invisible;
- } else if (attributeName == generateUsingAttribute()) {
- result->setGenerateUsing(convertBoolean(attributes->takeAt(i).value(), generateUsingAttribute(), true));
+ } else if (attributeName == generateUsingAttribute) {
+ result->setGenerateUsing(convertBoolean(attributes->takeAt(i).value(),
+ generateUsingAttribute, true));
}
}
@@ -1652,7 +1686,7 @@ ValueTypeEntryPtr
{
if (!checkRootElement())
return nullptr;
- ValueTypeEntryPtr typeEntry(new ValueTypeEntry(name, since, currentParentTypeEntry()));
+ auto typeEntry = std::make_shared<ValueTypeEntry>(name, since, currentParentTypeEntry());
if (!applyCommonAttributes(reader, typeEntry, attributes))
return nullptr;
applyComplexTypeAttributes(reader, typeEntry, attributes);
@@ -1671,45 +1705,51 @@ FunctionTypeEntryPtr
if (!checkRootElement())
return nullptr;
- QString signature;
- TypeSystem::SnakeCase snakeCase = TypeSystem::SnakeCase::Disabled;
+ FunctionModification mod;
+ const auto oldAttributesSize = attributes->size();
+ if (!parseModifyFunctionAttributes(attributes, &mod))
+ return nullptr;
+ const bool hasModification = attributes->size() < oldAttributesSize;
+ QString originalSignature;
+ QString docFile;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == signatureAttribute()) {
- signature = TypeDatabase::normalizedSignature(attributes->takeAt(i).value().toString());
- } else if (name == snakeCaseAttribute()) {
- const auto attribute = attributes->takeAt(i);
- const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
- if (!snakeCaseOpt.has_value()) {
- m_error = msgInvalidAttributeValue(attribute);
- return nullptr;
- }
- snakeCase = snakeCaseOpt.value();
- }
+ if (name == signatureAttribute)
+ originalSignature = attributes->takeAt(i).value().toString().simplified();
+ else if (name == docFileAttribute)
+ docFile = attributes->takeAt(i).value().toString();
}
+ const QString signature = TypeDatabase::normalizedSignature(originalSignature);
if (signature.isEmpty()) {
- m_error = msgMissingAttribute(signatureAttribute());
+ m_error = msgMissingAttribute(signatureAttribute);
return nullptr;
}
+ if (hasModification) {
+ mod.setOriginalSignature(originalSignature);
+ mod.setSignature(signature);
+ m_contextStack.top()->functionMods << mod;
+ }
+
TypeEntryPtr existingType = m_context->db->findType(name);
- if (existingType.isNull()) {
- FunctionTypeEntryPtr result(new FunctionTypeEntry(name, signature, since, currentParentTypeEntry()));
- result->setSnakeCase(snakeCase);
+ if (!existingType) {
+ auto result = std::make_shared<FunctionTypeEntry>(name, signature, since,
+ currentParentTypeEntry());
+ result->setTargetLangPackage(m_defaultPackage);
+ result->setDocFile(docFile);
applyCommonAttributes(reader, result, attributes);
return result;
}
if (existingType->type() != TypeEntry::FunctionType) {
- m_error = QStringLiteral("%1 expected to be a function, but isn't! Maybe it was already declared as a class or something else.")
- .arg(name);
+ m_error = name + " expected to be a function, but isn't! Maybe it was already declared as a class or something else."_L1;
return nullptr;
}
- auto result = qSharedPointerCast<FunctionTypeEntry>(existingType);
+ auto result = std::static_pointer_cast<FunctionTypeEntry>(existingType);
result->addSignature(signature);
return result;
}
@@ -1727,13 +1767,14 @@ TypedefEntryPtr
m_error = u"typedef entries must be nested in namespaces or type system."_s;
return nullptr;
}
- const auto sourceIndex = indexOfAttribute(*attributes, sourceAttribute());
+ const auto sourceIndex = indexOfAttribute(*attributes, sourceAttribute);
if (sourceIndex == -1) {
- m_error = msgMissingAttribute(sourceAttribute());
+ m_error = msgMissingAttribute(sourceAttribute);
return nullptr;
}
const QString sourceType = attributes->takeAt(sourceIndex).value().toString();
- TypedefEntryPtr result(new TypedefEntry(name, sourceType, since, currentParentTypeEntry()));
+ auto result = std::make_shared<TypedefEntry>(name, sourceType, since,
+ currentParentTypeEntry());
if (!applyCommonAttributes(reader, result, attributes))
return nullptr;
applyComplexTypeAttributes(reader, result, attributes);
@@ -1752,34 +1793,38 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
QString package = m_defaultPackage;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == streamAttribute()) {
- ctype->setStream(convertBoolean(attributes->takeAt(i).value(), streamAttribute(), false));
- } else if (name == privateAttribute()) {
+ 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()) {
+ privateAttribute, false));
+ } else if (name == generateAttribute) {
+ generate = convertBoolean(attributes->takeAt(i).value(), generateAttribute, true);
+ } else if (name ==packageAttribute) {
package = attributes->takeAt(i).value().toString();
- } else if (name == defaultSuperclassAttribute()) {
+ } else if (name == defaultSuperclassAttribute) {
ctype->setDefaultSuperclass(attributes->takeAt(i).value().toString());
- } else if (name == genericClassAttribute()) {
+ } else if (name == genericClassAttribute) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- const bool v = convertBoolean(attributes->takeAt(i).value(), genericClassAttribute(), false);
+ const bool v = convertBoolean(attributes->takeAt(i).value(),
+ genericClassAttribute, false);
ctype->setGenericClass(v);
- } else if (name == targetLangNameAttribute()) {
+ } else if (name == targetLangNameAttribute) {
ctype->setTargetLangName(attributes->takeAt(i).value().toString());
- } else if (name == u"polymorphic-base") {
- ctype->setPolymorphicIdValue(attributes->takeAt(i).value().toString());
+ } else if (name == polymorphicBaseAttribute) {
+ const bool v = convertBoolean(attributes->takeAt(i).value(),
+ polymorphicBaseAttribute, false);
+ ctype->setIsPolymorphicBase(v);
} else if (name == u"polymorphic-name-function") {
ctype->setPolymorphicNameFunction(attributes->takeAt(i).value().toString());
} else if (name == u"polymorphic-id-expression") {
ctype->setPolymorphicIdValue(attributes->takeAt(i).value().toString());
- } else if (name == copyableAttribute()) {
- const bool v = convertBoolean(attributes->takeAt(i).value(), copyableAttribute(), false);
+ } else if (name == copyableAttribute) {
+ const bool v = convertBoolean(attributes->takeAt(i).value(),
+ copyableAttribute, false);
ctype->setCopyable(v ? ComplexTypeEntry::CopyableSet : ComplexTypeEntry::NonCopyableSet);
- } else if (name == exceptionHandlingAttribute()) {
+ } else if (name == exceptionHandlingAttribute) {
const auto attribute = attributes->takeAt(i);
const auto exceptionOpt = exceptionHandlingFromAttribute(attribute.value());
if (exceptionOpt.has_value()) {
@@ -1788,7 +1833,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == allowThreadAttribute()) {
+ } else if (name == allowThreadAttribute) {
const auto attribute = attributes->takeAt(i);
const auto allowThreadOpt = allowThreadFromAttribute(attribute.value());
if (allowThreadOpt.has_value()) {
@@ -1802,19 +1847,25 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
} else if (name == u"hash-function") {
ctype->setHashFunction(attributes->takeAt(i).value().toString());
- } else if (name == forceAbstractAttribute()) {
- if (convertBoolean(attributes->takeAt(i).value(), forceAbstractAttribute(), false))
+ } else if (name == forceAbstractAttribute) {
+ if (convertBoolean(attributes->takeAt(i).value(), forceAbstractAttribute, false))
ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::ForceAbstract);
- } else if (name == deprecatedAttribute()) {
- if (convertBoolean(attributes->takeAt(i).value(), deprecatedAttribute(), false))
+ } else if (name == deprecatedAttribute) {
+ if (convertBoolean(attributes->takeAt(i).value(), deprecatedAttribute, false))
ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::Deprecated);
- } else if (name == disableWrapperAttribute()) {
- if (convertBoolean(attributes->takeAt(i).value(), disableWrapperAttribute(), false))
+ } else if (name == disableWrapperAttribute) {
+ if (convertBoolean(attributes->takeAt(i).value(), disableWrapperAttribute, false))
ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::DisableWrapper);
- } else if (name == deleteInMainThreadAttribute()) {
- if (convertBoolean(attributes->takeAt(i).value(), deleteInMainThreadAttribute(), false))
+ } else if (name == deleteInMainThreadAttribute) {
+ if (convertBoolean(attributes->takeAt(i).value(), deleteInMainThreadAttribute, false))
ctype->setDeleteInMainThread(true);
- } else if (name == generateFunctionsAttribute()) {
+ } else if (name == qtMetaObjectFunctionsAttribute) {
+ if (!convertBoolean(attributes->takeAt(i).value(),
+ qtMetaObjectFunctionsAttribute, true)) {
+ ctype->setTypeFlags(ctype->typeFlags()
+ | ComplexTypeEntry::DisableQtMetaObjectFunctions);
+ }
+ } else if (name == generateFunctionsAttribute) {
const auto names = attributes->takeAt(i).value();
const auto nameList = names.split(u';', Qt::SkipEmptyParts);
QSet<QString> nameSet;
@@ -1823,7 +1874,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
ctype->setGenerateFunctions(nameSet);
} else if (name == u"target-type") {
ctype->setTargetType(attributes->takeAt(i).value().toString());
- } else if (name == snakeCaseAttribute()) {
+ } else if (name == snakeCaseAttribute) {
const auto attribute = attributes->takeAt(i);
const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
if (snakeCaseOpt.has_value()) {
@@ -1832,7 +1883,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == isNullAttribute()) {
+ } else if (name == isNullAttribute) {
const auto attribute = attributes->takeAt(i);
const auto boolCastOpt = boolCastFromAttribute(attribute.value());
if (boolCastOpt.has_value()) {
@@ -1841,7 +1892,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == operatorBoolAttribute()) {
+ } else if (name == operatorBoolAttribute) {
const auto attribute = attributes->takeAt(i);
const auto boolCastOpt = boolCastFromAttribute(attribute.value());
if (boolCastOpt.has_value()) {
@@ -1850,7 +1901,7 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == qtMetaTypeAttribute()) {
+ } else if (name == qtMetaTypeAttribute) {
const auto attribute = attributes->takeAt(i);
const auto qtMetaTypeOpt = qtMetaTypeFromAttribute(attribute.value());
if (qtMetaTypeOpt.has_value()) {
@@ -1859,9 +1910,9 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == parentManagementAttribute()) {
+ } else if (name == parentManagementAttribute) {
const auto attribute = attributes->takeAt(i);
- if (convertBoolean(attribute.value(), parentManagementAttribute(), false))
+ if (convertBoolean(attribute.value(), parentManagementAttribute, false))
ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::ParentManagement);
ComplexTypeEntry::setParentManagementEnabled(true);
}
@@ -1882,6 +1933,32 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
ctype->setCodeGeneration(TypeEntry::GenerationDisabled);
}
+bool TypeSystemParser::parseConfiguration(StackElement topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (!isComplexTypeEntry(topElement)
+ && topElement != StackElement::EnumTypeEntry) {
+ m_error = u"<configuration> must be nested into a complex or enum type entry."_s;
+ return false;
+ }
+ QString condition;
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == u"condition") {
+ condition = attributes->takeAt(i).value().toString();
+ }
+ }
+ if (condition.isEmpty()) {
+ m_error = u"<configuration> requires a \"condition\" attribute."_s;
+ return false;
+ }
+ const auto topEntry = m_contextStack.top()->entry;
+ const auto configurableEntry = std::dynamic_pointer_cast<ConfigurableTypeEntry>(topEntry);
+ Q_ASSERT(configurableEntry);
+ configurableEntry->setConfigCondition(condition);
+ return true;
+}
+
bool TypeSystemParser::parseRenameFunction(const ConditionalStreamReader &,
QString *name, QXmlStreamAttributes *attributes)
{
@@ -1889,16 +1966,16 @@ bool TypeSystemParser::parseRenameFunction(const ConditionalStreamReader &,
QString rename;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == signatureAttribute()) {
+ if (name == signatureAttribute) {
// Do not remove as it is needed for the type entry later on
- signature = attributes->at(i).value().toString();
- } else if (name == renameAttribute()) {
+ signature = attributes->at(i).value().toString().simplified();
+ } else if (name == renameAttribute) {
rename = attributes->takeAt(i).value().toString();
}
}
if (signature.isEmpty()) {
- m_error = msgMissingAttribute(signatureAttribute());
+ m_error = msgMissingAttribute(signatureAttribute);
return false;
}
@@ -1954,7 +2031,7 @@ bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &,
return false;
}
mode = modeOpt.value();
- } else if (name == formatAttribute()) {
+ } else if (name == formatAttribute) {
const auto attribute = attributes->takeAt(i);
const auto langOpt = languageFromAttribute(attribute.value());
if (!langOpt.has_value()) {
@@ -1968,6 +2045,12 @@ bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &,
QString signature = isTypeEntry(topElement) ? QString() : m_currentSignature;
DocModification mod(mode, signature);
mod.setFormat(lang);
+ if (hasFileSnippetAttributes(attributes)) {
+ const auto snippetOptional = readFileSnippet(attributes);
+ if (!snippetOptional.has_value())
+ return false;
+ mod.setCode(snippetOptional.value().content);
+ }
auto &top = m_contextStack.top();
if (isAddFunction)
top->addedFunctions.last()->addDocModification(mod);
@@ -1989,9 +2072,9 @@ bool TypeSystemParser::parseModifyDocumentation(const ConditionalStreamReader &,
return false;
}
- const auto xpathIndex = indexOfAttribute(*attributes, xPathAttribute());
+ const auto xpathIndex = indexOfAttribute(*attributes, xPathAttribute);
if (xpathIndex == -1) {
- m_error = msgMissingAttribute(xPathAttribute());
+ m_error = msgMissingAttribute(xPathAttribute);
return false;
}
@@ -2008,14 +2091,17 @@ TypeSystemTypeEntryPtr TypeSystemParser::parseRootElement(const ConditionalStrea
QXmlStreamAttributes *attributes)
{
TypeSystem::SnakeCase snakeCase = TypeSystem::SnakeCase::Unspecified;
+ QString subModuleOf;
+ QString namespaceBegin;
+ QString namespaceEnd;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == packageAttribute()) {
+ if (name == packageAttribute) {
m_defaultPackage = attributes->takeAt(i).value().toString();
- } else if (name == defaultSuperclassAttribute()) {
+ } else if (name == defaultSuperclassAttribute) {
m_defaultSuperclass = attributes->takeAt(i).value().toString();
- } else if (name == exceptionHandlingAttribute()) {
+ } else if (name == exceptionHandlingAttribute) {
const auto attribute = attributes->takeAt(i);
const auto exceptionOpt = exceptionHandlingFromAttribute(attribute.value());
if (exceptionOpt.has_value()) {
@@ -2024,7 +2110,7 @@ TypeSystemTypeEntryPtr TypeSystemParser::parseRootElement(const ConditionalStrea
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == allowThreadAttribute()) {
+ } else if (name == allowThreadAttribute) {
const auto attribute = attributes->takeAt(i);
const auto allowThreadOpt = allowThreadFromAttribute(attribute.value());
if (allowThreadOpt.has_value()) {
@@ -2033,7 +2119,7 @@ TypeSystemTypeEntryPtr TypeSystemParser::parseRootElement(const ConditionalStrea
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == snakeCaseAttribute()) {
+ } else if (name == snakeCaseAttribute) {
const auto attribute = attributes->takeAt(i);
const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
if (snakeCaseOpt.has_value()) {
@@ -2042,25 +2128,36 @@ TypeSystemTypeEntryPtr TypeSystemParser::parseRootElement(const ConditionalStrea
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
+ } else if (name == subModuleOfAttribute) {
+ subModuleOf = attributes->takeAt(i).value().toString();
+ } else if (name == "namespace-begin"_L1) {
+ namespaceBegin = attributes->takeAt(i).value().toString();
+ } else if (name == "namespace-end"_L1) {
+ namespaceEnd = attributes->takeAt(i).value().toString();
}
}
if (m_defaultPackage.isEmpty()) { // Extending default, see addBuiltInContainerTypes()
- auto moduleEntry = qSharedPointerConstCast<TypeSystemTypeEntry>(m_context->db->defaultTypeSystemType());
- Q_ASSERT(!moduleEntry.isNull());
+ auto moduleEntry = std::const_pointer_cast<TypeSystemTypeEntry>(m_context->db->defaultTypeSystemType());
+ Q_ASSERT(moduleEntry);
m_defaultPackage = moduleEntry->name();
return moduleEntry;
}
auto moduleEntry =
- qSharedPointerConstCast<TypeSystemTypeEntry>(m_context->db->findTypeSystemType(m_defaultPackage));
- const bool add = moduleEntry.isNull();
+ std::const_pointer_cast<TypeSystemTypeEntry>(m_context->db->findTypeSystemType(m_defaultPackage));
+ const bool add = !moduleEntry;
if (add) {
moduleEntry.reset(new TypeSystemTypeEntry(m_defaultPackage, since,
currentParentTypeEntry()));
+ moduleEntry->setSubModule(subModuleOf);
}
moduleEntry->setCodeGeneration(m_generate);
moduleEntry->setSnakeCase(snakeCase);
+ if (!namespaceBegin.isEmpty())
+ moduleEntry->setNamespaceBegin(namespaceBegin);
+ if (!namespaceEnd.isEmpty())
+ moduleEntry->setNamespaceEnd(namespaceEnd);
if ((m_generate == TypeEntry::GenerateForSubclass ||
m_generate == TypeEntry::GenerateNothing) && !m_defaultPackage.isEmpty())
@@ -2078,10 +2175,10 @@ bool TypeSystemParser::loadTypesystem(const ConditionalStreamReader &,
bool generateChild = true;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == nameAttribute())
+ if (name == nameAttribute)
typeSystemName = attributes->takeAt(i).value().toString();
- else if (name == generateAttribute())
- generateChild = convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true);
+ else if (name == generateAttribute)
+ generateChild = convertBoolean(attributes->takeAt(i).value(), generateAttribute, true);
}
if (typeSystemName.isEmpty()) {
m_error = u"No typesystem name specified"_s;
@@ -2098,13 +2195,13 @@ bool TypeSystemParser::loadTypesystem(const ConditionalStreamReader &,
bool TypeSystemParser::parseRejectEnumValue(const ConditionalStreamReader &,
QXmlStreamAttributes *attributes)
{
- if (m_currentEnum.isNull()) {
+ if (!m_currentEnum) {
m_error = u"<reject-enum-value> node must be used inside a <enum-type> node"_s;
return false;
}
- const auto nameIndex = indexOfAttribute(*attributes, nameAttribute());
+ const auto nameIndex = indexOfAttribute(*attributes, nameAttribute);
if (nameIndex == -1) {
- m_error = msgMissingAttribute(nameAttribute());
+ m_error = msgMissingAttribute(nameAttribute);
return false;
}
m_currentEnum->addEnumValueRejection(attributes->takeAt(nameIndex).value().toString());
@@ -2119,7 +2216,7 @@ bool TypeSystemParser::parseReplaceArgumentType(const ConditionalStreamReader &,
m_error = u"Type replacement can only be specified for argument modifications"_s;
return false;
}
- const auto modifiedTypeIndex = indexOfAttribute(*attributes, modifiedTypeAttribute());
+ const auto modifiedTypeIndex = indexOfAttribute(*attributes, modifiedTypeAttribute);
if (modifiedTypeIndex == -1) {
m_error = u"Type replacement requires 'modified-type' attribute"_s;
return false;
@@ -2147,7 +2244,7 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
TypeSystem::Language lang = TypeSystem::NativeCode;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == classAttribute()) {
+ if (name == classAttribute) {
const auto languageAttribute = attributes->takeAt(i);
const auto langOpt = languageFromAttribute(languageAttribute.value());
if (!langOpt.has_value()) {
@@ -2157,7 +2254,7 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
lang = langOpt.value();
} else if (name == u"file") {
sourceFile = attributes->takeAt(i).value().toString();
- } else if (name == snippetAttribute()) {
+ } else if (name == snippetAttribute) {
snippetLabel = attributes->takeAt(i).value().toString();
}
}
@@ -2172,7 +2269,7 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
ValueTypeEntryPtr valueTypeEntry;
if (top->entry->isValue()) {
- valueTypeEntry = qSharedPointerCast<ValueTypeEntry>(top->entry);
+ valueTypeEntry = std::static_pointer_cast<ValueTypeEntry>(top->entry);
if (valueTypeEntry->hasTargetConversionRule() || valueTypeEntry->hasCustomConversion()) {
m_error = u"Types can have only one conversion rule"_s;
return false;
@@ -2204,13 +2301,13 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
return true;
}
- CustomConversionPtr customConversion(new CustomConversion(top->entry));
+ auto customConversion = std::make_shared<CustomConversion>(top->entry);
if (top->entry->isPrimitive())
- qSharedPointerCast<PrimitiveTypeEntry>(top->entry)->setCustomConversion(customConversion);
+ std::static_pointer_cast<PrimitiveTypeEntry>(top->entry)->setCustomConversion(customConversion);
else if (top->entry->isContainer())
- qSharedPointerCast<ContainerTypeEntry>(top->entry)->setCustomConversion(customConversion);
+ std::static_pointer_cast<ContainerTypeEntry>(top->entry)->setCustomConversion(customConversion);
else if (top->entry->isValue())
- qSharedPointerCast<ValueTypeEntry>(top->entry)->setCustomConversion(customConversion);
+ std::static_pointer_cast<ValueTypeEntry>(top->entry)->setCustomConversion(customConversion);
customConversionsForReview.append(customConversion);
return true;
}
@@ -2224,7 +2321,7 @@ bool TypeSystemParser::parseNativeToTarget(const ConditionalStreamReader &,
return false;
}
CodeSnip snip;
- if (!readFileSnippet(attributes, &snip))
+ if (!readCodeSnippet(attributes, &snip))
return false;
m_contextStack.top()->conversionCodeSnips.append(snip);
return true;
@@ -2241,7 +2338,7 @@ bool TypeSystemParser::parseAddConversion(const ConditionalStreamReader &,
QString sourceTypeName;
QString typeCheck;
CodeSnip snip;
- if (!readFileSnippet(attributes, &snip))
+ if (!readCodeSnippet(attributes, &snip))
return false;
const auto &top = m_contextStack.top();
@@ -2263,7 +2360,7 @@ bool TypeSystemParser::parseAddConversion(const ConditionalStreamReader &,
return false;
}
auto customConversion = CustomConversion::getCustomConversion(top->entry);
- if (customConversion.isNull()) {
+ if (!customConversion) {
m_error = msgMissingCustomConversion(top->entry);
return false;
}
@@ -2276,7 +2373,7 @@ static bool parseIndex(const QString &index, int *result, QString *errorMessage)
bool ok = false;
*result = index.toInt(&ok);
if (!ok)
- *errorMessage = QStringLiteral("Cannot convert '%1' to integer").arg(index);
+ *errorMessage = QString::fromLatin1("Cannot convert '%1' to integer").arg(index);
return ok;
}
@@ -2311,20 +2408,20 @@ bool TypeSystemParser::parseModifyArgument(const ConditionalStreamReader &,
bool resetAfterUse = false;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == indexAttribute()) {
+ if (name == indexAttribute) {
index = attributes->takeAt(i).value().toString();
- } else if (name == invalidateAfterUseAttribute()) {
+ } else if (name == invalidateAfterUseAttribute) {
resetAfterUse = convertBoolean(attributes->takeAt(i).value(),
- invalidateAfterUseAttribute(), false);
- } else if (name == renameAttribute()) {
+ invalidateAfterUseAttribute, false);
+ } else if (name == renameAttribute) {
renameTo = attributes->takeAt(i).value().toString();
- } else if (name == pyiTypeAttribute()) {
+ } else if (name == pyiTypeAttribute) {
pyiType = attributes->takeAt(i).value().toString();
}
}
if (index.isEmpty()) {
- m_error = msgMissingAttribute(indexAttribute());
+ m_error = msgMissingAttribute(indexAttribute);
return false;
}
@@ -2374,7 +2471,7 @@ bool TypeSystemParser::parseDefineOwnership(const ConditionalStreamReader &,
std::optional<TypeSystem::Ownership> ownershipOpt;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == classAttribute()) {
+ if (name == classAttribute) {
const auto classAttribute = attributes->takeAt(i);
const auto langOpt = languageFromAttribute(classAttribute.value());
if (!langOpt.has_value() || langOpt.value() == TypeSystem::ShellCode) {
@@ -2382,7 +2479,7 @@ bool TypeSystemParser::parseDefineOwnership(const ConditionalStreamReader &,
return false;
}
lang = langOpt.value();
- } else if (name == ownershipAttribute()) {
+ } else if (name == ownershipAttribute) {
const auto attribute = attributes->takeAt(i);
ownershipOpt = ownershipFromFromAttribute(attribute.value());
if (!ownershipOpt.has_value()) {
@@ -2393,7 +2490,7 @@ bool TypeSystemParser::parseDefineOwnership(const ConditionalStreamReader &,
}
if (!ownershipOpt.has_value()) {
- m_error = QStringLiteral("unspecified ownership");
+ m_error = "unspecified ownership"_L1;
return false;
}
auto &lastArgMod = m_contextStack.top()->functionMods.last().argument_mods().last();
@@ -2420,9 +2517,9 @@ bool TypeSystemParser::parseRename(const ConditionalStreamReader &,
return false;
}
- const auto toIndex = indexOfAttribute(*attributes, toAttribute());
+ const auto toIndex = indexOfAttribute(*attributes, toAttribute);
if (toIndex == -1) {
- m_error = msgMissingAttribute(toAttribute());
+ m_error = msgMissingAttribute(toAttribute);
return false;
}
const QString renamed_to = attributes->takeAt(toIndex).value().toString();
@@ -2436,20 +2533,20 @@ bool TypeSystemParser::parseModifyField(const ConditionalStreamReader &,
FieldModification fm;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == nameAttribute()) {
+ if (name == nameAttribute) {
fm.setName(attributes->takeAt(i).value().toString());
- } else if (name == removeAttribute()) {
+ } else if (name == removeAttribute) {
fm.setRemoved(convertRemovalAttribute(attributes->takeAt(i).value()));
- } else if (name == opaqueContainerFieldAttribute()) {
+ } else if (name == opaqueContainerFieldAttribute) {
fm.setOpaqueContainer(convertBoolean(attributes->takeAt(i).value(),
- opaqueContainerFieldAttribute(), false));
- } else if (name == readAttribute()) {
- fm.setReadable(convertBoolean(attributes->takeAt(i).value(), readAttribute(), true));
- } else if (name == writeAttribute()) {
- fm.setWritable(convertBoolean(attributes->takeAt(i).value(), writeAttribute(), true));
- } else if (name == renameAttribute()) {
+ opaqueContainerFieldAttribute, false));
+ } else if (name == readAttribute) {
+ fm.setReadable(convertBoolean(attributes->takeAt(i).value(), readAttribute, true));
+ } else if (name == writeAttribute) {
+ fm.setWritable(convertBoolean(attributes->takeAt(i).value(), writeAttribute, true));
+ } else if (name == renameAttribute) {
fm.setRenamedToName(attributes->takeAt(i).value().toString());
- } else if (name == snakeCaseAttribute()) {
+ } else if (name == snakeCaseAttribute) {
const auto attribute = attributes->takeAt(i);
const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
if (snakeCaseOpt.has_value()) {
@@ -2461,7 +2558,7 @@ bool TypeSystemParser::parseModifyField(const ConditionalStreamReader &,
}
}
if (fm.name().isEmpty()) {
- m_error = msgMissingAttribute(nameAttribute());
+ m_error = msgMissingAttribute(nameAttribute);
return false;
}
m_contextStack.top()->fieldMods << fm;
@@ -2493,29 +2590,37 @@ bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &,
", was=%1").arg(tagFromElement(topElement));
return false;
}
+
+ FunctionModification mod;
+ if (!(t == StackElement::AddFunction
+ ? parseBasicModifyFunctionAttributes(attributes, &mod)
+ : parseModifyFunctionAttributes(attributes, &mod))) {
+ return false;
+ }
+
QString originalSignature;
QString returnType;
bool staticFunction = false;
bool classMethod = false;
+ bool pythonOverride = false;
QString access;
- int overloadNumber = TypeSystem::OverloadNumberUnset;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == u"signature") {
- originalSignature = attributes->takeAt(i).value().toString();
+ if (name == signatureAttribute) {
+ originalSignature = attributes->takeAt(i).value().toString().simplified();
} else if (name == u"return-type") {
returnType = attributes->takeAt(i).value().toString();
- } else if (name == staticAttribute()) {
+ } else if (name == staticAttribute) {
staticFunction = convertBoolean(attributes->takeAt(i).value(),
- staticAttribute(), false);
- } else if (name == classmethodAttribute()) {
+ staticAttribute, false);
+ } else if (name == classmethodAttribute) {
classMethod = convertBoolean(attributes->takeAt(i).value(),
- classmethodAttribute(), false);
- } else if (name == accessAttribute()) {
+ classmethodAttribute, false);
+ } else if (name == accessAttribute) {
access = attributes->takeAt(i).value().toString();
- } else if (name == overloadNumberAttribute()) {
- if (!parseOverloadNumber(attributes->takeAt(i), &overloadNumber, &m_error))
- return false;
+ } else if (name == pythonOverrideAttribute) {
+ pythonOverride = convertBoolean(attributes->takeAt(i).value(),
+ pythonOverrideAttribute, false);
}
}
@@ -2532,13 +2637,15 @@ bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &,
}
AddedFunctionPtr func = AddedFunction::createAddedFunction(signature, returnType, &errorString);
- if (func.isNull()) {
+ if (!func) {
m_error = errorString;
return false;
}
func->setStatic(staticFunction);
func->setClassMethod(classMethod);
+ func->setPythonOverride(pythonOverride);
+ func->setTargetLangPackage(m_defaultPackage);
// Create signature for matching modifications
signature = TypeDatabase::normalizedSignature(originalSignature);
@@ -2560,8 +2667,6 @@ bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &,
m_contextStack.top()->addedFunctionModificationIndex =
m_contextStack.top()->functionMods.size();
- FunctionModification mod;
- mod.setOverloadNumber(overloadNumber);
if (!mod.setSignature(m_currentSignature, &m_error))
return false;
mod.setOriginalSignature(originalSignature);
@@ -2582,7 +2687,7 @@ bool TypeSystemParser::parseAddPyMethodDef(const ConditionalStreamReader &,
TypeSystemPyMethodDefEntry def;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == nameAttribute()) {
+ if (name == nameAttribute) {
def.name = attributes->takeAt(i).value().toString();
} else if (name == u"doc") {
def.doc = attributes->takeAt(i).value().toString();
@@ -2605,7 +2710,7 @@ bool TypeSystemParser::parseAddPyMethodDef(const ConditionalStreamReader &,
m_error = u"add-pymethoddef requires at least a name and a function attribute"_s;
return false;
}
- qSharedPointerCast<ComplexTypeEntry>(m_contextStack.top()->entry)->addPyMethodDef(def);
+ std::static_pointer_cast<ComplexTypeEntry>(m_contextStack.top()->entry)->addPyMethodDef(def);
return true;
}
@@ -2621,7 +2726,7 @@ bool TypeSystemParser::parseProperty(const ConditionalStreamReader &, StackEleme
TypeSystemProperty property;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == nameAttribute()) {
+ if (name == nameAttribute) {
property.name = attributes->takeAt(i).value().toString();
} else if (name == u"get") {
property.read = attributes->takeAt(i).value().toString();
@@ -2629,17 +2734,78 @@ bool TypeSystemParser::parseProperty(const ConditionalStreamReader &, StackEleme
property.type = attributes->takeAt(i).value().toString();
} else if (name == u"set") {
property.write = attributes->takeAt(i).value().toString();
- } else if (name == generateGetSetDefAttribute()) {
+ } else if (name == generateGetSetDefAttribute) {
property.generateGetSetDef =
convertBoolean(attributes->takeAt(i).value(),
- generateGetSetDefAttribute(), false);
+ generateGetSetDefAttribute, false);
}
}
if (!property.isValid()) {
m_error = u"<property> element is missing required attibutes (name/type/get)."_s;
return false;
}
- qSharedPointerCast<ComplexTypeEntry>(m_contextStack.top()->entry)->addProperty(property);
+ std::static_pointer_cast<ComplexTypeEntry>(m_contextStack.top()->entry)->addProperty(property);
+ return true;
+}
+
+// Parse basic attributes applicable to <add-function>/<declare-function>/<function>
+// and <modify-function> (all that is not done by injected code).
+bool TypeSystemParser::parseBasicModifyFunctionAttributes(QXmlStreamAttributes *attributes,
+ FunctionModification *mod)
+{
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == overloadNumberAttribute) {
+ int overloadNumber = TypeSystem::OverloadNumberUnset;
+ if (!parseOverloadNumber(attributes->takeAt(i), &overloadNumber, &m_error))
+ return false;
+ mod->setOverloadNumber(overloadNumber);
+ }
+ }
+ return true;
+}
+
+// Parse attributes applicable to <declare-function>/<function>
+// and <modify-function>.
+bool TypeSystemParser::parseModifyFunctionAttributes(QXmlStreamAttributes *attributes,
+ FunctionModification *mod)
+{
+ if (!parseBasicModifyFunctionAttributes(attributes, mod))
+ return false;
+
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == allowThreadAttribute) {
+ const QXmlStreamAttribute attribute = attributes->takeAt(i);
+ const auto allowThreadOpt = allowThreadFromAttribute(attribute.value());
+ if (!allowThreadOpt.has_value()) {
+ m_error = msgInvalidAttributeValue(attribute);
+ return false;
+ }
+ mod->setAllowThread(allowThreadOpt.value());
+ } else if (name == exceptionHandlingAttribute) {
+ const auto attribute = attributes->takeAt(i);
+ const auto exceptionOpt = exceptionHandlingFromAttribute(attribute.value());
+ if (!exceptionOpt.has_value()) {
+ m_error = msgInvalidAttributeValue(attribute);
+ return false;
+ }
+ mod->setExceptionHandling(exceptionOpt.value());
+ } else if (name == snakeCaseAttribute) {
+ const auto attribute = attributes->takeAt(i);
+ const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
+ if (!snakeCaseOpt.has_value()) {
+ m_error = msgInvalidAttributeValue(attribute);
+ return false;
+ }
+ mod->setSnakeCase(snakeCaseOpt.value());
+ } else if (name == deprecatedAttribute) {
+ const bool deprecated = convertBoolean(attributes->takeAt(i).value(),
+ deprecatedAttribute, false);
+ mod->setModifierFlag(deprecated ? FunctionModification::Deprecated
+ : FunctionModification::Undeprecated);
+ }
+ }
return true;
}
@@ -2657,61 +2823,24 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
}
QString originalSignature;
+ FunctionModification mod;
+ if (!parseModifyFunctionAttributes(attributes, &mod))
+ return false;
+
QString access;
bool removed = false;
QString rename;
- bool deprecated = false;
- bool isThread = false;
- int overloadNumber = TypeSystem::OverloadNumberUnset;
- TypeSystem::ExceptionHandling exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
- TypeSystem::AllowThread allowThread = TypeSystem::AllowThread::Unspecified;
- TypeSystem::SnakeCase snakeCase = TypeSystem::SnakeCase::Unspecified;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == u"signature") {
- originalSignature = attributes->takeAt(i).value().toString();
- } else if (name == accessAttribute()) {
+ if (name == signatureAttribute) {
+ originalSignature = attributes->takeAt(i).value().toString().simplified();
+ } else if (name == accessAttribute) {
access = attributes->takeAt(i).value().toString();
- } else if (name == renameAttribute()) {
+ } else if (name == renameAttribute) {
rename = attributes->takeAt(i).value().toString();
- } else if (name == removeAttribute()) {
+ } else if (name == removeAttribute) {
removed = convertRemovalAttribute(attributes->takeAt(i).value());
- } else if (name == deprecatedAttribute()) {
- deprecated = convertBoolean(attributes->takeAt(i).value(),
- deprecatedAttribute(), false);
- } else if (name == threadAttribute()) {
- isThread = convertBoolean(attributes->takeAt(i).value(),
- threadAttribute(), false);
- } else if (name == allowThreadAttribute()) {
- const QXmlStreamAttribute attribute = attributes->takeAt(i);
- const auto allowThreadOpt = allowThreadFromAttribute(attribute.value());
- if (!allowThreadOpt.has_value()) {
- m_error = msgInvalidAttributeValue(attribute);
- return false;
- }
- allowThread = allowThreadOpt.value();
- } else if (name == exceptionHandlingAttribute()) {
- const auto attribute = attributes->takeAt(i);
- const auto exceptionOpt = exceptionHandlingFromAttribute(attribute.value());
- if (exceptionOpt.has_value()) {
- exceptionHandling = exceptionOpt.value();
- } else {
- qCWarning(lcShiboken, "%s",
- qPrintable(msgInvalidAttributeValue(attribute)));
- }
- } else if (name == overloadNumberAttribute()) {
- if (!parseOverloadNumber(attributes->takeAt(i), &overloadNumber, &m_error))
- return false;
- } else if (name == snakeCaseAttribute()) {
- const auto attribute = attributes->takeAt(i);
- const auto snakeCaseOpt = snakeCaseFromAttribute(attribute.value());
- if (snakeCaseOpt.has_value()) {
- snakeCase = snakeCaseOpt.value();
- } else {
- qCWarning(lcShiboken, "%s",
- qPrintable(msgInvalidAttributeValue(attribute)));
- }
- } else if (name == virtualSlotAttribute()) {
+ } else if (name == virtualSlotAttribute || name == threadAttribute) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
}
@@ -2720,7 +2849,7 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
// Child of global <function>
const auto &top = m_contextStack.top();
if (originalSignature.isEmpty() && top->entry->isFunction()) {
- auto f = qSharedPointerCast<const FunctionTypeEntry>(top->entry);
+ auto f = std::static_pointer_cast<const FunctionTypeEntry>(top->entry);
originalSignature = f->signatures().value(0);
}
@@ -2736,13 +2865,9 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
return false;
}
- FunctionModification mod;
if (!mod.setSignature(signature, &m_error))
return false;
mod.setOriginalSignature(originalSignature);
- mod.setExceptionHandling(exceptionHandling);
- mod.setOverloadNumber(overloadNumber);
- mod.setSnakeCase(snakeCase);
m_currentSignature = signature;
if (!access.isEmpty()) {
@@ -2755,14 +2880,11 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
if (m == FunctionModification::NonFinal) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeValueWarning(reader,
- accessAttribute(), access)));
+ accessAttribute, access)));
}
mod.setModifierFlag(m);
}
- if (deprecated)
- mod.setModifierFlag(FunctionModification::Deprecated);
-
mod.setRemoved(removed);
if (!rename.isEmpty()) {
@@ -2770,10 +2892,6 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
mod.setModifierFlag(FunctionModification::Rename);
}
- mod.setIsThread(isThread);
- if (allowThread != TypeSystem::AllowThread::Unspecified)
- mod.setAllowThread(allowThread);
-
top->functionMods << mod;
return true;
}
@@ -2809,7 +2927,7 @@ bool TypeSystemParser::parseReferenceCount(const ConditionalStreamReader &reader
ReferenceCount rc;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == actionAttribute()) {
+ if (name == actionAttribute) {
const QXmlStreamAttribute attribute = attributes->takeAt(i);
const auto actionOpt = referenceCountFromAttribute(attribute.value());
if (!actionOpt.has_value()) {
@@ -2846,11 +2964,11 @@ bool TypeSystemParser::parseParentOwner(const ConditionalStreamReader &,
ArgumentOwner ao;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == indexAttribute()) {
+ if (name == indexAttribute) {
const QString index = attributes->takeAt(i).value().toString();
if (!parseArgumentIndex(index, &ao.index, &m_error))
return false;
- } else if (name == actionAttribute()) {
+ } else if (name == actionAttribute) {
const auto action = attributes->takeAt(i);
const auto actionOpt = argumentOwnerActionFromAttribute(action.value());
if (!actionOpt.has_value()) {
@@ -2864,46 +2982,62 @@ bool TypeSystemParser::parseParentOwner(const ConditionalStreamReader &,
return true;
}
-bool TypeSystemParser::readFileSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip)
+std::optional<TypeSystemParser::Snippet>
+ TypeSystemParser::readFileSnippet(QXmlStreamAttributes *attributes)
{
- QString fileName;
- QString snippetLabel;
+ Snippet result;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == u"file") {
- fileName = attributes->takeAt(i).value().toString();
- } else if (name == snippetAttribute()) {
- snippetLabel = attributes->takeAt(i).value().toString();
+ if (name == fileAttribute) {
+ result.fileName = attributes->takeAt(i).value().toString();
+ } else if (name == snippetAttribute) {
+ result.snippetLabel = attributes->takeAt(i).value().toString();
}
}
- if (fileName.isEmpty())
- return true;
- const QString resolved = m_context->db->modifiedTypesystemFilepath(fileName, m_currentPath);
+ if (result.fileName.isEmpty()) {
+ m_error = "Snippet missing file name"_L1;
+ return std::nullopt;
+ }
+ const QString resolved = m_context->db->modifiedTypesystemFilepath(result.fileName,
+ m_currentPath);
if (!QFile::exists(resolved)) {
m_error = u"File for inject code not exist: "_s
- + QDir::toNativeSeparators(fileName);
- return false;
+ + QDir::toNativeSeparators(result.fileName);
+ return std::nullopt;
}
QFile codeFile(resolved);
if (!codeFile.open(QIODevice::Text | QIODevice::ReadOnly)) {
m_error = msgCannotOpenForReading(codeFile);
- return false;
+ return std::nullopt;
}
- const auto codeOptional = extractSnippet(QString::fromUtf8(codeFile.readAll()), snippetLabel);
+ const auto contentOptional = extractSnippet(QString::fromUtf8(codeFile.readAll()),
+ result.snippetLabel);
codeFile.close();
- if (!codeOptional.has_value()) {
- m_error = msgCannotFindSnippet(resolved, snippetLabel);
- return false;
+ if (!contentOptional.has_value()) {
+ m_error = msgCannotFindSnippet(resolved, result.snippetLabel);
+ return std::nullopt;
}
+ result.content = contentOptional.value();
+ return result;
+}
+
+bool TypeSystemParser::readCodeSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip)
+{
+ if (!hasFileSnippetAttributes(attributes))
+ return true; // Expecting inline content.
+ const auto snippetOptional = readFileSnippet(attributes);
+ if (!snippetOptional.has_value())
+ return false;
+ const auto snippet = snippetOptional.value();
- QString source = fileName;
- if (!snippetLabel.isEmpty())
- source += u" ("_s + snippetLabel + u')';
+ QString source = snippet.fileName;
+ if (!snippet.snippetLabel.isEmpty())
+ source += " ("_L1 + snippet.snippetLabel + u')';
QString content;
QTextStream str(&content);
str << "// ========================================================================\n"
"// START of custom code block [file: "
- << source << "]\n" << codeOptional.value()
+ << source << "]\n" << snippet.content
<< "// END of custom code block [file: " << source
<< "]\n// ========================================================================\n";
snip->addCode(content);
@@ -2925,11 +3059,11 @@ bool TypeSystemParser::parseInjectCode(const ConditionalStreamReader &,
TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionBeginning;
TypeSystem::Language lang = TypeSystem::TargetLangCode;
CodeSnip snip;
- if (!readFileSnippet(attributes, &snip))
+ if (!readCodeSnippet(attributes, &snip))
return false;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == classAttribute()) {
+ if (name == classAttribute) {
const auto attribute = attributes->takeAt(i);
const auto langOpt = languageFromAttribute(attribute.value());
if (!langOpt.has_value()) {
@@ -2937,7 +3071,7 @@ bool TypeSystemParser::parseInjectCode(const ConditionalStreamReader &,
return false;
}
lang = langOpt.value();
- } else if (name == positionAttribute()) {
+ } else if (name == positionAttribute) {
const auto attribute = attributes->takeAt(i);
const auto positionOpt = codeSnipPositionFromAttribute(attribute.value());
if (!positionOpt.has_value()) {
@@ -2961,10 +3095,10 @@ bool TypeSystemParser::parseInjectCode(const ConditionalStreamReader &,
}
break;
case StackElement::Root:
- qSharedPointerCast<TypeSystemTypeEntry>(m_contextStack.top()->entry)->addCodeSnip(snip);
+ std::static_pointer_cast<TypeSystemTypeEntry>(m_contextStack.top()->entry)->addCodeSnip(snip);
break;
default:
- qSharedPointerCast<ComplexTypeEntry>(m_contextStack.top()->entry)->addCodeSnip(snip);
+ std::static_pointer_cast<ComplexTypeEntry>(m_contextStack.top()->entry)->addCodeSnip(snip);
break;
}
return true;
@@ -2978,9 +3112,9 @@ bool TypeSystemParser::parseInclude(const ConditionalStreamReader &,
Include::IncludeType location = Include::IncludePath;
for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == fileNameAttribute()) {
+ if (name == fileNameAttribute) {
fileName = attributes->takeAt(i).value().toString();
- } else if (name == locationAttribute()) {
+ } else if (name == locationAttribute) {
const auto attribute = attributes->takeAt(i);
const auto locationOpt = locationFromAttribute(attribute.value());
if (!locationOpt.has_value()) {
@@ -3010,12 +3144,12 @@ bool TypeSystemParser::parseInclude(const ConditionalStreamReader &,
bool TypeSystemParser::parseSystemInclude(const ConditionalStreamReader &,
QXmlStreamAttributes *attributes)
{
- const auto index = indexOfAttribute(*attributes, fileNameAttribute());
+ const auto index = indexOfAttribute(*attributes, fileNameAttribute);
if (index == -1) {
- m_error = msgMissingAttribute(fileNameAttribute());
+ m_error = msgMissingAttribute(fileNameAttribute);
return false;
}
- TypeDatabase::instance()->addSystemInclude(attributes->takeAt(index).value().toString());
+ TypeDatabase::instance()->addForceProcessSystemInclude(attributes->takeAt(index).value().toString());
return true;
}
@@ -3033,9 +3167,9 @@ TemplateInstance *
"conversion-rule, native-to-target or add-conversion tags."_s;
return nullptr;
}
- const auto nameIndex = indexOfAttribute(*attributes, nameAttribute());
+ const auto nameIndex = indexOfAttribute(*attributes, nameAttribute);
if (nameIndex == -1) {
- m_error = msgMissingAttribute(nameAttribute());
+ m_error = msgMissingAttribute(nameAttribute);
return nullptr;
}
return new TemplateInstance(attributes->takeAt(nameIndex).value().toString());
@@ -3054,7 +3188,7 @@ bool TypeSystemParser::parseReplace(const ConditionalStreamReader &,
const auto name = attributes->at(i).qualifiedName();
if (name == u"from")
from = attributes->takeAt(i).value().toString();
- else if (name == toAttribute())
+ else if (name == toAttribute)
to = attributes->takeAt(i).value().toString();
}
m_templateInstance->addReplaceRule(from, to);
@@ -3072,7 +3206,7 @@ bool TypeSystemParser::checkDuplicatedTypeEntry(const ConditionalStreamReader &r
if (t == StackElement::PrimitiveTypeEntry || t == StackElement::FunctionTypeEntry)
return true;
const auto duplicated = m_context->db->findType(name);
- if (duplicated.isNull() || duplicated->isNamespace())
+ if (!duplicated || duplicated->isNamespace())
return true;
if (duplicated->isBuiltIn()) {
qCWarning(lcShiboken, "%s",
@@ -3110,12 +3244,12 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
VersionRange versionRange;
for (auto i = attributes.size() - 1; i >= 0; --i) {
const auto name = attributes.at(i).qualifiedName();
- if (name == sinceAttribute()) {
+ if (name == sinceAttribute) {
if (!parseVersion(attributes.takeAt(i).value().toString(),
m_defaultPackage, &versionRange.since, &m_error)) {
return false;
}
- } else if (name == untilAttribute()) {
+ } else if (name == untilAttribute) {
if (!parseVersion(attributes.takeAt(i).value().toString(),
m_defaultPackage, &versionRange.until, &m_error)) {
return false;
@@ -3149,7 +3283,7 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
}
if (isTypeEntry(element) || element == StackElement::Root)
- m_contextStack.push(StackElementContextPtr(new StackElementContext()));
+ m_contextStack.push(std::make_shared<StackElementContext>());
if (m_contextStack.isEmpty()) {
m_error = msgNoRootTypeSystemEntry();
@@ -3162,11 +3296,11 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
if (isTypeEntry(element)) {
QString name;
if (element != StackElement::FunctionTypeEntry) {
- const auto nameIndex = indexOfAttribute(attributes, nameAttribute());
+ const auto nameIndex = indexOfAttribute(attributes, nameAttribute);
if (nameIndex != -1) {
name = attributes.takeAt(nameIndex).value().toString();
} else if (element != StackElement::EnumTypeEntry) { // anonymous enum?
- m_error = msgMissingAttribute(nameAttribute());
+ m_error = msgMissingAttribute(nameAttribute);
return false;
}
}
@@ -3179,7 +3313,7 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
if (m_context->db->hasDroppedTypeEntries()) {
const QString identifier = element == StackElement::FunctionTypeEntry
- ? attributes.value(signatureAttribute()).toString() : name;
+ ? attributes.value(signatureAttribute).toString().simplified() : name;
if (shouldDropTypeEntry(m_context->db, m_contextStack, identifier)) {
m_currentDroppedEntryDepth = 1;
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
@@ -3204,14 +3338,14 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
if (element != StackElement::PrimitiveTypeEntry
&& element != StackElement::FunctionTypeEntry) {
TypeEntryPtr tmp = m_context->db->findType(name);
- if (!tmp.isNull() && !tmp->isNamespace())
+ if (tmp && !tmp->isNamespace())
qCWarning(lcShiboken).noquote().nospace()
<< "Duplicate type entry: '" << name << '\'';
}
if (element == StackElement::EnumTypeEntry) {
const auto enumIdentifiedByIndex =
- indexOfAttribute(attributes, enumIdentifiedByValueAttribute());
+ indexOfAttribute(attributes, enumIdentifiedByValueAttribute);
const QString identifiedByValue = enumIdentifiedByIndex != -1
? attributes.takeAt(enumIdentifiedByIndex).value().toString() : QString();
if (name.isEmpty()) {
@@ -3270,7 +3404,7 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
case StackElement::InterfaceTypeEntry: {
if (!checkRootElement())
return false;
- ComplexTypeEntryPtr ce(new ObjectTypeEntry(name, versionRange.since, currentParentTypeEntry()));
+ auto ce = std::make_shared<ObjectTypeEntry>(name, versionRange.since, currentParentTypeEntry());
top->entry = ce;
applyCommonAttributes(reader, top->entry, &attributes);
applyComplexTypeAttributes(reader, ce, &attributes);
@@ -3318,7 +3452,8 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
|| element == StackElement::ConversionRule
|| element == StackElement::AddFunction
|| element == StackElement::DeclareFunction
- || element == StackElement::Template;
+ || element == StackElement::Template
+ || element == StackElement::OpaqueContainer;
if (!topLevel && m_stack.at(m_stack.size() - 2) == StackElement::Root) {
m_error = u"Tag requires parent: '"_s + tagName.toString() + u'\'';
@@ -3357,12 +3492,12 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
const auto topParent = m_stack.value(m_stack.size() - 3, StackElement::None);
if (isTypeEntry(topParent)) {
- const auto replaceIndex = indexOfAttribute(attributes, replaceAttribute());
+ const auto replaceIndex = indexOfAttribute(attributes, replaceAttribute);
const bool replace = replaceIndex == -1
|| convertBoolean(attributes.takeAt(replaceIndex).value(),
- replaceAttribute(), true);
+ replaceAttribute, true);
auto customConversion = CustomConversion::getCustomConversion(top->entry);
- if (customConversion.isNull()) {
+ if (!customConversion) {
m_error = msgMissingCustomConversion(top->entry);
return false;
}
@@ -3387,14 +3522,17 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
return false;
break;
case StackElement::SuppressedWarning: {
- const auto textIndex = indexOfAttribute(attributes, textAttribute());
+ const auto textIndex = indexOfAttribute(attributes, textAttribute);
if (textIndex == -1) {
qCWarning(lcShiboken) << "Suppressed warning with no text specified";
} else {
const QString suppressedWarning =
attributes.takeAt(textIndex).value().toString();
- if (!m_context->db->addSuppressedWarning(suppressedWarning, &m_error))
+ if (!m_context->db->addSuppressedWarning(suppressedWarning,
+ m_generate == TypeEntry::GenerateCode,
+ &m_error)) {
return false;
+ }
}
}
break;
@@ -3463,17 +3601,19 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
return false;
break;
case StackElement::Rejection:
- if (!addRejection(m_context->db, &attributes, &m_error))
+ if (!addRejection(m_context->db, m_generate == TypeEntry::GenerateCode,
+ &attributes, &m_error)) {
return false;
+ }
break;
case StackElement::SystemInclude:
if (!parseSystemInclude(reader, &attributes))
return false;
break;
case StackElement::Template: {
- const auto nameIndex = indexOfAttribute(attributes, nameAttribute());
+ const auto nameIndex = indexOfAttribute(attributes, nameAttribute);
if (nameIndex == -1) {
- m_error = msgMissingAttribute(nameAttribute());
+ m_error = msgMissingAttribute(nameAttribute);
return false;
}
m_templateEntry.reset(new TemplateEntry(attributes.takeAt(nameIndex).value().toString()));
@@ -3481,13 +3621,19 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, Stack
break;
case StackElement::InsertTemplate:
m_templateInstance.reset(parseInsertTemplate(reader, topElement, &attributes));
- if (m_templateInstance.isNull())
+ if (!m_templateInstance)
return false;
break;
case StackElement::Replace:
if (!parseReplace(reader, topElement, &attributes))
return false;
break;
+ case StackElement::OpaqueContainer:
+ if (!parseOpaqueContainerElement(&attributes))
+ case StackElement::Configuration:
+ if (!parseConfiguration(topElement, &attributes))
+ return false;
+ break;
default:
break; // nada
}
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser_p.h b/sources/shiboken6/ApiExtractor/typesystemparser_p.h
index 7d47c31e4..4d9d4fd92 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser_p.h
+++ b/sources/shiboken6/ApiExtractor/typesystemparser_p.h
@@ -4,6 +4,7 @@
#define TYPESYSTEMPARSER_H
#include "typesystem.h"
+#include "containertypeentry.h"
#include "typedatabase.h"
#include "typedatabase_p.h"
#include "typesystem_typedefs.h"
@@ -12,7 +13,9 @@
#include <QtCore/QStack>
#include <QtCore/QHash>
#include <QtCore/QScopedPointer>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
+#include <optional>
QT_FORWARD_DECLARE_CLASS(QVersionNumber)
QT_FORWARD_DECLARE_CLASS(QXmlStreamAttributes)
@@ -101,6 +104,8 @@ enum class StackElement {
ArgumentModifiers,
ImportFile,
+ OpaqueContainer,
+ Configuration,
Unimplemented
};
@@ -128,12 +133,12 @@ struct StackElementContext
class TypeSystemParser
{
public:
- Q_DISABLE_COPY(TypeSystemParser)
+ Q_DISABLE_COPY_MOVE(TypeSystemParser)
- using StackElementContextPtr = QSharedPointer<StackElementContext>;
+ using StackElementContextPtr = std::shared_ptr<StackElementContext>;
using ContextStack = QStack<StackElementContextPtr>;
- explicit TypeSystemParser(const QSharedPointer<TypeDatabaseParserContext> &context,
+ explicit TypeSystemParser(const std::shared_ptr<TypeDatabaseParserContext> &context,
bool generate);
~TypeSystemParser();
@@ -142,6 +147,13 @@ public:
QString errorString() const { return m_error; }
private:
+ struct Snippet
+ {
+ QString content;
+ QString fileName;
+ QString snippetLabel;
+ };
+
bool parseXml(ConditionalStreamReader &reader);
bool setupSmartPointerInstantiations();
bool startElement(const ConditionalStreamReader &reader, StackElement element);
@@ -166,9 +178,11 @@ private:
CustomTypeEntryPtr
parseCustomTypeEntry(const ConditionalStreamReader &, const QString &name,
const QVersionNumber &since, QXmlStreamAttributes *);
+ bool parseOpaqueContainers(QStringView s, OpaqueContainers *result);
ContainerTypeEntryPtr
parseContainerTypeEntry(const ConditionalStreamReader &, const QString &name,
const QVersionNumber &since, QXmlStreamAttributes *);
+ bool parseOpaqueContainerElement(QXmlStreamAttributes *attributes);
EnumTypeEntryPtr
parseEnumTypeEntry(const ConditionalStreamReader &, const QString &name,
const QVersionNumber &since, QXmlStreamAttributes *);
@@ -194,6 +208,8 @@ private:
const QVersionNumber &since, QXmlStreamAttributes *);
void applyComplexTypeAttributes(const ConditionalStreamReader &, const ComplexTypeEntryPtr &ctype,
QXmlStreamAttributes *) const;
+ bool parseConfiguration(StackElement topElement,
+ QXmlStreamAttributes *attributes);
bool parseRenameFunction(const ConditionalStreamReader &, QString *name,
QXmlStreamAttributes *);
bool parseInjectDocumentation(const ConditionalStreamReader &, StackElement topElement,
@@ -228,6 +244,10 @@ private:
StackElement topElement, QXmlStreamAttributes *attributes);
bool parseProperty(const ConditionalStreamReader &, StackElement topElement,
QXmlStreamAttributes *);
+ bool parseBasicModifyFunctionAttributes(QXmlStreamAttributes *,
+ FunctionModification *mod);
+ bool parseModifyFunctionAttributes(QXmlStreamAttributes *,
+ FunctionModification *mod);
bool parseModifyFunction(const ConditionalStreamReader &, StackElement topElement,
QXmlStreamAttributes *);
bool parseReplaceDefaultExpression(const ConditionalStreamReader &,
@@ -236,7 +256,8 @@ private:
QXmlStreamAttributes *);
bool parseParentOwner(const ConditionalStreamReader &, StackElement topElement,
QXmlStreamAttributes *);
- bool readFileSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip);
+ std::optional<Snippet> readFileSnippet(QXmlStreamAttributes *attributes);
+ bool readCodeSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip);
bool parseInjectCode(const ConditionalStreamReader &, StackElement topElement, QXmlStreamAttributes *);
bool parseInclude(const ConditionalStreamReader &, StackElement topElement,
const TypeEntryPtr &entry, QXmlStreamAttributes *);
@@ -251,7 +272,7 @@ private:
ParserState parserState(qsizetype offset = 0) const;
CodeSnipAbstract *injectCodeTarget(qsizetype offset = 0) const;
- QSharedPointer<TypeDatabaseParserContext> m_context;
+ std::shared_ptr<TypeDatabaseParserContext> m_context;
QStack<StackElement> m_stack;
int m_currentDroppedEntryDepth = 0;
int m_ignoreDepth = 0;
diff --git a/sources/shiboken6/ApiExtractor/typesystemtypeentry.h b/sources/shiboken6/ApiExtractor/typesystemtypeentry.h
index bd69058d2..9b9670696 100644
--- a/sources/shiboken6/ApiExtractor/typesystemtypeentry.h
+++ b/sources/shiboken6/ApiExtractor/typesystemtypeentry.h
@@ -5,6 +5,7 @@
#define TYPESYSTEMTYPEENTRY_H
#include "typesystem.h"
+#include "modifications_typedefs.h"
#include "typesystem_enums.h"
#include "typesystem_typedefs.h"
@@ -23,6 +24,15 @@ public:
CodeSnipList &codeSnips();
void addCodeSnip(const CodeSnip &codeSnip);
+ QString subModuleOf() const;
+ void setSubModule(const QString &);
+
+ const QString &namespaceBegin() const;
+ void setNamespaceBegin(const QString &n);
+
+ const QString &namespaceEnd() const;
+ void setNamespaceEnd(const QString &n);
+
protected:
explicit TypeSystemTypeEntry(TypeEntryPrivate *d);
};
diff --git a/sources/shiboken6/ApiExtractor/usingmember.h b/sources/shiboken6/ApiExtractor/usingmember.h
index ed362688d..346eab13c 100644
--- a/sources/shiboken6/ApiExtractor/usingmember.h
+++ b/sources/shiboken6/ApiExtractor/usingmember.h
@@ -12,7 +12,7 @@ QT_FORWARD_DECLARE_CLASS(QDebug)
struct UsingMember // Introducing a base class member via 'using' directive
{
QString memberName;
- const AbstractMetaClass *baseClass;
+ AbstractMetaClassCPtr baseClass;
Access access;
};
diff --git a/sources/shiboken6/ApiExtractor/xmlutils.cpp b/sources/shiboken6/ApiExtractor/xmlutils.cpp
index b0c9c2084..ccacd4ce7 100644
--- a/sources/shiboken6/ApiExtractor/xmlutils.cpp
+++ b/sources/shiboken6/ApiExtractor/xmlutils.cpp
@@ -21,13 +21,13 @@ QString XQuery::evaluate(QString xPathExpression, QString *errorMessage)
return doEvaluate(xPathExpression, errorMessage);
}
-QSharedPointer<XQuery> XQuery::create(const QString &focus, QString *errorMessage)
+std::shared_ptr<XQuery> XQuery::create(const QString &focus, QString *errorMessage)
{
#if defined(HAVE_LIBXSLT)
return libXml_createXQuery(focus, errorMessage);
#else
*errorMessage = QLatin1StringView(__FUNCTION__) + u" is not implemented."_s;
- return QSharedPointer<XQuery>();
+ return std::shared_ptr<XQuery>();
#endif
}
diff --git a/sources/shiboken6/ApiExtractor/xmlutils.h b/sources/shiboken6/ApiExtractor/xmlutils.h
index 2d6adbe9e..ac23c9c9c 100644
--- a/sources/shiboken6/ApiExtractor/xmlutils.h
+++ b/sources/shiboken6/ApiExtractor/xmlutils.h
@@ -3,19 +3,20 @@
#ifndef XMLUTILS_H
#define XMLUTILS_H
-#include <QtCore/QSharedPointer>
#include <QtCore/QString>
+#include <memory>
+
class XQuery
{
public:
- Q_DISABLE_COPY(XQuery);
+ Q_DISABLE_COPY_MOVE(XQuery)
virtual ~XQuery();
QString evaluate(QString xPathExpression, QString *errorMessage);
- static QSharedPointer<XQuery> create(const QString &focus, QString *errorMessage);
+ static std::shared_ptr<XQuery> create(const QString &focus, QString *errorMessage);
protected:
XQuery();
diff --git a/sources/shiboken6/ApiExtractor/xmlutils_libxslt.cpp b/sources/shiboken6/ApiExtractor/xmlutils_libxslt.cpp
index fad8889fa..5a9a26913 100644
--- a/sources/shiboken6/ApiExtractor/xmlutils_libxslt.cpp
+++ b/sources/shiboken6/ApiExtractor/xmlutils_libxslt.cpp
@@ -40,8 +40,6 @@ static void ensureInitialized()
}
}
-namespace {
-
// RAI Helpers for cleaning up libxml2/libxslt data
struct XmlDocDeleter // for std::unique_ptr<xmlDoc>
@@ -64,8 +62,6 @@ struct XmlXPathContextDeleter
void operator()(xmlXPathContextPtr xPathContext) { xmlXPathFreeContext(xPathContext); }
};
-} // namespace
-
using XmlDocUniquePtr = std::unique_ptr<xmlDoc, XmlDocDeleter>;
using XmlPathObjectUniquePtr = std::unique_ptr<xmlXPathObject, XmlXPathObjectDeleter>;
using XmlStyleSheetUniquePtr = std::unique_ptr<xsltStylesheet, XmlStyleSheetDeleter>;
@@ -141,9 +137,10 @@ QString LibXmlXQuery::doEvaluate(const QString &xPathExpression, QString *errorM
return result;
}
-QSharedPointer<XQuery> libXml_createXQuery(const QString &focus, QString *errorMessage)
+std::shared_ptr<XQuery> libXml_createXQuery(const QString &focus, QString *errorMessage)
{
- XmlDocUniquePtr doc(xmlParseFile(QFile::encodeName(focus).constData()));
+ XmlDocUniquePtr doc(xmlReadFile(QFile::encodeName(focus).constData(),
+ "utf-8", XML_PARSE_NOENT));
if (!doc) {
*errorMessage = u"libxml2: Cannot set focus to "_s + QDir::toNativeSeparators(focus);
return {};
@@ -153,25 +150,27 @@ QSharedPointer<XQuery> libXml_createXQuery(const QString &focus, QString *errorM
*errorMessage = u"libxml2: xmlXPathNewContext() failed"_s;
return {};
}
- return QSharedPointer<XQuery>(new LibXmlXQuery(doc, xpathContext));
+ return std::shared_ptr<XQuery>(new LibXmlXQuery(doc, xpathContext));
}
// XSLT transformation
-static const char xsltPrefix[] = R"(<?xml version="1.0" encoding="UTF-8" ?>
+static constexpr auto xsltPrefix = R"(<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
-)";
+)"_L1;
QString libXslt_transform(const QString &xml, QString xsl, QString *errorMessage)
{
ensureInitialized();
// Read XML data
if (!xsl.startsWith(u"<?xml")) {
- xsl.prepend(QLatin1StringView(xsltPrefix));
+ xsl.prepend(xsltPrefix);
xsl.append(u"</xsl:transform>"_s);
}
const QByteArray xmlData = xml.toUtf8();
- XmlDocUniquePtr xmlDoc(xmlParseMemory(xmlData.constData(), xmlData.size()));
+
+ XmlDocUniquePtr xmlDoc(xmlReadMemory(xmlData.constData(), int(xmlData.size()),
+ "", "utf-8", XML_PARSE_NOENT));
if (!xmlDoc) {
*errorMessage = u"xmlParseMemory() failed for XML."_s;
return xml;
diff --git a/sources/shiboken6/ApiExtractor/xmlutils_libxslt.h b/sources/shiboken6/ApiExtractor/xmlutils_libxslt.h
index 3430dce71..0dd8eafcb 100644
--- a/sources/shiboken6/ApiExtractor/xmlutils_libxslt.h
+++ b/sources/shiboken6/ApiExtractor/xmlutils_libxslt.h
@@ -4,11 +4,12 @@
#define XMLUTILS_LIBXSLT_H
#include <QtCore/QString>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
class XQuery;
-QSharedPointer<XQuery> libXml_createXQuery(const QString &focus, QString *errorMessage);
+std::shared_ptr<XQuery> libXml_createXQuery(const QString &focus, QString *errorMessage);
QString libXslt_transform(const QString &xml, QString xsl, QString *errorMessage);
diff --git a/sources/shiboken6/ApiExtractor/xmlutils_qt.h b/sources/shiboken6/ApiExtractor/xmlutils_qt.h
index f0c51915f..274827044 100644
--- a/sources/shiboken6/ApiExtractor/xmlutils_qt.h
+++ b/sources/shiboken6/ApiExtractor/xmlutils_qt.h
@@ -4,11 +4,12 @@
#define XMLUTILS_QT_H
#include <QtCore/QString>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
class XQuery;
-QSharedPointer<XQuery> qt_createXQuery(const QString &focus, QString *errorMessage);
+std::shared_ptr<XQuery> qt_createXQuery(const QString &focus, QString *errorMessage);
QString qt_xsl_transform(const QString &xml, QString xsl, QString *errorMessage);
diff --git a/sources/shiboken6/CMakeLists.txt b/sources/shiboken6/CMakeLists.txt
index 2f7b23835..9e1bb09b3 100644
--- a/sources/shiboken6/CMakeLists.txt
+++ b/sources/shiboken6/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
Include(icecc.cmake)
cmake_minimum_required(VERSION 3.18)
@@ -7,9 +10,12 @@ set(CMAKE_BUILD_TYPE Release CACHE STRING "Build Type")
include(".cmake.conf")
project(shiboken6)
-
include(cmake/ShibokenSetup.cmake)
+get_rpath_base_token(base)
+
+set(CMAKE_INSTALL_RPATH ${base}/)
+
if(SHIBOKEN_BUILD_TOOLS)
add_subdirectory(ApiExtractor) # Uses libclang
add_subdirectory(generator) # Uses ApiExtractor And QtCore
diff --git a/sources/shiboken6/cmake/FindDocTools.cmake b/sources/shiboken6/cmake/FindDocTools.cmake
index abf5e5005..621a4ac15 100644
--- a/sources/shiboken6/cmake/FindDocTools.cmake
+++ b/sources/shiboken6/cmake/FindDocTools.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
find_program(SPHINX_BUILD sphinx-build DOC "Path to sphinx-build binary.")
# graphviz dot appears to be used by sphinx and not by CMake directly. This is just found to check
diff --git a/sources/shiboken6/cmake/ShibokenHelpers.cmake b/sources/shiboken6/cmake/ShibokenHelpers.cmake
index 991026913..cff6df95e 100644
--- a/sources/shiboken6/cmake/ShibokenHelpers.cmake
+++ b/sources/shiboken6/cmake/ShibokenHelpers.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(CMakeParseArguments)
macro(set_limited_api)
@@ -12,7 +15,7 @@ endmacro()
macro(set_debug_build)
set(SHIBOKEN_BUILD_TYPE "Debug")
- if(NOT PYTHON_DEBUG_LIBRARIES)
+ if(NOT Python_LIBRARIES)
message(WARNING "Python debug shared library not found; \
assuming python was built with shared library support disabled.")
endif()
@@ -113,7 +116,7 @@ macro(shiboken_internal_set_python_site_packages)
endif()
else()
execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c "if True:
+ COMMAND ${Python_EXECUTABLE} -c "if True:
import sysconfig
from os.path import sep
@@ -206,7 +209,7 @@ macro(get_python_extension_suffix)
else()
# See PYSIDE-1841 / https://bugs.python.org/issue39825 for distutils vs sysconfig
execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c "if True:
+ COMMAND ${Python_EXECUTABLE} -c "if True:
import sys
if sys.version_info >= (3, 8, 2):
import sysconfig
@@ -238,18 +241,22 @@ macro(shiboken_check_if_limited_api)
# TODO: Figure out how to use limited API libs when cross-building to Windows, if that's ever
# needed. Perhaps use host python to walk the libs of the target python installation.
- if(NOT SHIBOKEN_IS_CROSS_BUILD)
+ if(NOT SHIBOKEN_IS_CROSS_BUILD AND WIN32)
# On Windows, PYTHON_LIBRARIES can be a list. Example:
# optimized;C:/Python36/libs/python36.lib;debug;C:/Python36/libs/python36_d.lib
# On other platforms, this result is not used at all.
execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c "if True:
- import os
- for lib in '${PYTHON_LIBRARIES}'.split(';'):
- if '/' in lib and os.path.isfile(lib):
- prefix, py = lib.rsplit('/', 1)
+ COMMAND ${Python_EXECUTABLE} -c "if True:
+ from pathlib import Path
+ libs = r'${Python_LIBRARIES}'
+ libs = libs.split(';')
+ for lib in libs:
+ if ('\\\\' in lib or '/' in lib) and Path(lib).is_file():
+ lib = Path(lib)
+ prefix = lib.parent
+ py = lib.name
if py.startswith('python3'):
- print(prefix + '/python3.lib')
+ print(prefix / 'python3.lib')
break
"
OUTPUT_VARIABLE PYTHON_LIMITED_LIBRARIES
@@ -268,6 +275,10 @@ endmacro()
macro(shiboken_find_required_python)
+ set(_shiboken_find_python_version_args "")
+ if(${ARGC} GREATER 0)
+ list(APPEND _shiboken_find_python_version_args "${ARGV0}")
+ endif()
# This function can also be called by consumers of ShibokenConfig.cmake package like pyside,
# that's why we also check for PYSIDE_IS_CROSS_BUILD (which is set by pyside project)
# and QFP_FIND_NEW_PYTHON_PACKAGE for an explicit opt in.
@@ -275,11 +286,6 @@ macro(shiboken_find_required_python)
# We have to use FindPython package instead of FindPythonInterp to get required target Python
# information.
if(SHIBOKEN_IS_CROSS_BUILD OR PYSIDE_IS_CROSS_BUILD OR QFP_FIND_NEW_PYTHON_PACKAGE)
- set(_shiboken_find_python_version_args "")
- if(${ARGC} GREATER 0)
- list(APPEND _shiboken_find_python_version_args "${ARGV0}")
- endif()
-
# We want FindPython to look in the sysroot for the python-config executable,
# but toolchain files might set CMAKE_FIND_ROOT_PATH_MODE_PROGRAM to NEVER because
# programs are mostly found for running and you usually can't run a target executable on
@@ -309,39 +315,33 @@ macro(shiboken_find_required_python)
set(CMAKE_FIND_ROOT_PATH
"${_shiboken_backup_CMAKE_FIND_ROOT_PATH}")
- # Mirror the variables that FindPythonInterp sets, instead of conditionally checking
- # and modifying all the places where the variables are used.
- set(PYTHON_EXECUTABLE "${Python_EXECUTABLE}")
- set(PYTHON_VERSION "${Python_VERSION}")
- set(PYTHON_LIBRARIES "${Python_LIBRARIES}")
- set(PYTHON_INCLUDE_DIRS "${Python_INCLUDE_DIRS}")
- set(PYTHONINTERP_FOUND "${Python_Interpreter_FOUND}")
- set(PYTHONINTERP_FOUND "${Python_Interpreter_FOUND}")
- set(PYTHONLIBS_FOUND "${Python_Development_FOUND}")
- set(PYTHON_VERSION_MAJOR "${Python_VERSION_MAJOR}")
- set(PYTHON_VERSION_MINOR "${Python_VERSION_MINOR}")
- set(PYTHON_VERSION_PATCH "${Python_VERSION_PATCH}")
- else()
- if(${ARGC} GREATER 0)
- find_package(PythonInterp ${ARGV0} REQUIRED)
- find_package(PythonLibs ${ARGV0} REQUIRED)
- else()
- # If no version is specified, just use any interpreter that can be found (from PATH).
- # This is useful for super-project builds, so that the default system interpeter
- # gets picked up (e.g. /usr/bin/python and not /usr/bin/python2.7).
- find_package(PythonInterp REQUIRED)
- find_package(PythonLibs REQUIRED)
+ # For Android platform sometimes the FindPython module returns Python_SOABI as empty in
+ # certain scenarios eg: armv7a target, macOS host etc. This is because
+ # it is unable to set Python_CONFIG i.e. `python3-config` script
+ # This workaround sets the Python_SOABI manually for this Android platform.
+ # This needs to be updated manually if the Python version for Android cross compilation
+ # changes.
+ # TODO: Find a better way to set Python_SOABI for Android platform
+ if(CMAKE_SYSTEM_NAME STREQUAL "Android" AND NOT Python_SOABI)
+ set(Python_SOABI "cpython-311")
endif()
+ else()
+ find_package(
+ Python
+ ${_shiboken_find_python_version_args}
+ REQUIRED
+ COMPONENTS Interpreter Development
+ )
endif()
shiboken_validate_python_version()
- set(SHIBOKEN_PYTHON_INTERPRETER "${PYTHON_EXECUTABLE}")
- set_property(GLOBAL PROPERTY SHIBOKEN_PYTHON_INTERPRETER "${PYTHON_EXECUTABLE}")
+ set(SHIBOKEN_PYTHON_INTERPRETER "${Python_EXECUTABLE}")
+ set_property(GLOBAL PROPERTY SHIBOKEN_PYTHON_INTERPRETER "${Python_EXECUTABLE}")
endmacro()
macro(shiboken_validate_python_version)
- if(PYTHON_VERSION_MAJOR EQUAL "3" AND PYTHON_VERSION_MINOR LESS "7")
+ if(Python_VERSION_MAJOR EQUAL "3" AND Python_VERSION_MINOR LESS "7")
message(FATAL_ERROR
"Shiboken requires Python 3.7+.")
endif()
@@ -362,14 +362,14 @@ macro(shiboken_compute_python_includes)
if (SHIBOKEN_COMPUTE_INCLUDES_IS_CALLED_FROM_EXPORT)
#TODO target_include_directories works on imported targets only starting with v3.11.0.
set_property(TARGET Shiboken6::libshiboken
- APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIRS})
+ APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Python_INCLUDE_DIRS})
else()
target_include_directories(libshiboken
- PUBLIC $<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>)
+ PUBLIC $<BUILD_INTERFACE:${Python_INCLUDE_DIRS}>)
endif()
- set(SHIBOKEN_PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}")
+ set(SHIBOKEN_PYTHON_INCLUDE_DIRS "${Python_INCLUDE_DIRS}")
set_property(GLOBAL PROPERTY shiboken_python_include_dirs "${SHIBOKEN_PYTHON_INCLUDE_DIRS}")
@@ -429,16 +429,8 @@ macro(shiboken_compute_python_libraries)
set(SHIBOKEN_PYTHON_LIBRARIES "")
endif()
- if(CMAKE_BUILD_TYPE STREQUAL "Debug")
- if(WIN32 AND NOT SHIBOKEN_PYTHON_LIBRARIES)
- set(SHIBOKEN_PYTHON_LIBRARIES ${PYTHON_DEBUG_LIBRARIES})
- endif()
- endif()
-
- if(CMAKE_BUILD_TYPE STREQUAL "Release")
- if(WIN32 AND NOT SHIBOKEN_PYTHON_LIBRARIES)
- set(SHIBOKEN_PYTHON_LIBRARIES ${PYTHON_LIBRARIES})
- endif()
+ if(WIN32 AND NOT SHIBOKEN_PYTHON_LIBRARIES)
+ set(SHIBOKEN_PYTHON_LIBRARIES ${Python_LIBRARIES})
endif()
# If the resulting variable
@@ -471,20 +463,20 @@ macro(shiboken_compute_python_libraries)
endmacro()
function(shiboken_check_if_built_and_target_python_are_compatible)
- if(NOT SHIBOKEN_PYTHON_VERSION_MAJOR STREQUAL PYTHON_VERSION_MAJOR)
+ if(NOT SHIBOKEN_PYTHON_VERSION_MAJOR STREQUAL Python_VERSION_MAJOR)
message(FATAL_ERROR "The detected Python major version is not \
compatible with the Python major version which was used when Shiboken was built.
Built with: '${SHIBOKEN_PYTHON_VERSION_MAJOR}.${SHIBOKEN_PYTHON_VERSION_MINOR}' \
-Detected: '${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}'")
+Detected: '${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}'")
else()
if(NOT SHIBOKEN_PYTHON_LIMITED_API
- AND NOT SHIBOKEN_PYTHON_VERSION_MINOR STREQUAL PYTHON_VERSION_MINOR)
+ AND NOT SHIBOKEN_PYTHON_VERSION_MINOR STREQUAL Python_VERSION_MINOR)
message(FATAL_ERROR
"The detected Python minor version is not compatible with the Python minor \
version which was used when Shiboken was built. Consider building shiboken with \
FORCE_LIMITED_API set to '1', so that only the Python major version matters.
Built with: '${SHIBOKEN_PYTHON_VERSION_MAJOR}.${SHIBOKEN_PYTHON_VERSION_MINOR}' \
-Detected: '${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}'")
+Detected: '${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}'")
endif()
endif()
endfunction()
@@ -595,6 +587,17 @@ endfunction()
macro(compute_config_py_values
full_version_var_name
)
+ set(QT_MACOS_DEPLOYMENT_TARGET "")
+ if (Qt${QT_MAJOR_VERSION}Core_FOUND)
+ get_target_property(darwin_target Qt6::Core QT_DARWIN_MIN_DEPLOYMENT_TARGET)
+ if(darwin_target)
+ set(QT_MACOS_DEPLOYMENT_TARGET
+ "__qt_macos_min_deployment_target__ = '${darwin_target}'")
+ endif()
+ elseif(APPLE)
+ message(FATAL_ERROR "Qt6::Core should be found before calling this macro")
+ endif()
+
string(TIMESTAMP PACKAGE_BUILD_DATE "%Y-%m-%dT%H:%M:%S+00:00" UTC)
if (PACKAGE_BUILD_DATE)
set(PACKAGE_BUILD_DATE "__build_date__ = '${PACKAGE_BUILD_DATE}'")
@@ -676,16 +679,10 @@ endmacro()
# tool_name should be a unique tool name, preferably without spaces.
# Returns the wrapper path in path_out_var.
#
-# Currently adds the Qt bin dir and the libclang.dll bin dir to PATH.
-# On platforms other than Windows, returs an empty string.
+# Currently adds the Qt lib dir and libclang to PATH / LD_LIBRARY_PATH / DYLD_LIBRARY_PATH.
# Meant to be used as the first argument to add_custom_command's COMMAND option.
+# TODO: Remove tool_name as the tool_name for this function is always shiboken.
function(shiboken_get_tool_shell_wrapper tool_name path_out_var)
- # No need for a wrapper on non Windows hosts.
- if(NOT CMAKE_HOST_WIN32)
- set(${path_out_var} "" PARENT_SCOPE)
- return()
- endif()
-
# Generate the wrapper only once during the execution of CMake.
get_property(is_called GLOBAL PROPERTY "_shiboken_tool_wrapper_${tool_name}_created")
@@ -698,28 +695,59 @@ function(shiboken_get_tool_shell_wrapper tool_name path_out_var)
set(path_dirs "")
set(path_dirs_native "")
+ if(CMAKE_HOST_WIN32)
+ set(wrapper_script_extension ".bat")
+ else()
+ set(wrapper_script_extension ".sh")
+ endif()
+
+ # Try to get original host shiboken paths from exported target properties.
+ shiboken_get_host_tool_wrapper_properties(orig_qt_library_dir_absolute orig_libclang_lib_dir)
+
+ # Get path to the Qt bin/lib dir depending on the platform and developer input.
+ # Prefer values given on the command line, then the original host path if it exists, otherwise
+ # try to use the Qt install prefix and libclang env vars.
+ #
+ # Note that in a cross-compiling case, using the Qt install prefix is very likely
+ # wrong, because you want to use the location of the host Qt, not the target Qt. Same for
+ # libclang. Unfortunately we currently don't provide a host Qt and host libclang option via
+ # setup.py, so the manual cmake vars will have to suffice.
+ if(SHIBOKEN_WRAPPER_HOST_QT_LIB_PATH AND EXISTS "${SHIBOKEN_WRAPPER_HOST_QT_LIB_PATH}")
+ set(qt_library_dir_absolute "${SHIBOKEN_WRAPPER_HOST_QT_LIB_PATH}")
+ elseif(orig_qt_library_dir_absolute AND EXISTS "${orig_qt_library_dir_absolute}")
+ set(qt_library_dir_absolute "${orig_qt_library_dir_absolute}")
+ elseif(CMAKE_HOST_WIN32)
+ # in Windows the Qt dll are store `bin` in directory
+ set(qt_library_dir ${QT6_INSTALL_BINS})
+ else()
+ # in Unix the .so are stored in `lib` directory
+ set(qt_library_dir ${QT6_INSTALL_LIBS})
+ endif()
+
# Assert that Qt is already found.
- if(NOT QT6_INSTALL_PREFIX OR NOT QT6_INSTALL_BINS)
+ if((QT6_INSTALL_PREFIX AND qt_library_dir) OR orig_qt_library_dir_absolute)
+ else()
message(FATAL_ERROR "Qt should have been found already by now.")
endif()
- # Get path to the Qt bin dir.
- set(qt_bin_dir "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_BINS}")
- list(APPEND path_dirs "${qt_bin_dir}")
+ if(NOT qt_library_dir_absolute)
+ set(qt_library_dir_absolute "${QT6_INSTALL_PREFIX}/${qt_library_dir}")
+ endif()
+ list(APPEND path_dirs "${qt_library_dir_absolute}")
- # Get path to libclang.dll.
- set(libclang_bin_dir "")
- if(DEFINED ENV{LLVM_INSTALL_DIR})
- set(libclang_bin_dir "$ENV{LLVM_INSTALL_DIR}/bin")
- elseif(DEFINED ENV{CLANG_INSTALL_DIR})
- set(libclang_bin_dir "$ENV{CLANG_INSTALL_DIR}/bin")
+ # Get libclang lib dir path.
+ # Prefer values given on the command line, then the original host path if it exists.
+ if(SHIBOKEN_WRAPPER_HOST_CLANG_LIB_PATH AND EXISTS "${SHIBOKEN_WRAPPER_HOST_CLANG_LIB_PATH}")
+ set(libclang_lib_dir "${SHIBOKEN_WRAPPER_HOST_CLANG_LIB_PATH}")
+ elseif(orig_libclang_lib_dir AND EXISTS "${orig_libclang_lib_dir}")
+ set(libclang_lib_dir "${orig_libclang_lib_dir}")
else()
- message(WARNING
- "Couldn't find libclang.dll. "
- "You will likely need to add it manually to PATH to ensure the build succeeds.")
+ # find libclang
+ find_libclang()
endif()
- if(libclang_bin_dir)
- list(APPEND path_dirs "${libclang_bin_dir}")
+
+ if(libclang_lib_dir)
+ list(APPEND path_dirs "${libclang_lib_dir}")
endif()
# Convert the paths from unix-style to native Windows style.
@@ -732,15 +760,130 @@ function(shiboken_get_tool_shell_wrapper tool_name path_out_var)
set(wrapper_dir "${CMAKE_BINARY_DIR}/.qfp/bin")
file(MAKE_DIRECTORY "${wrapper_dir}")
- set(wrapper_path "${wrapper_dir}/${tool_name}_wrapper.bat")
+ set(wrapper_path "${wrapper_dir}/${tool_name}_wrapper${wrapper_script_extension}")
- file(WRITE "${wrapper_path}" "@echo off
+ if(CMAKE_HOST_WIN32)
+ file(WRITE "${wrapper_path}" "@echo off
set PATH=${path_dirs_native};%PATH%
%*")
+ elseif(CMAKE_HOST_APPLE)
+ string(REPLACE ";" ":" path_dirs_native "${path_dirs_native}")
+ file(WRITE "${wrapper_path}" "#!/bin/bash
+export DYLD_LIBRARY_PATH=${path_dirs_native}:$DYLD_LIBRARY_PATH
+export DYLD_FRAMEWORK_PATH=${path_dirs_native}:$DYLD_FRAMEWORK_PATH
+$@")
+ else()
+ string(REPLACE ";" ":" path_dirs_native "${path_dirs_native}")
+ file(WRITE "${wrapper_path}" "#!/bin/bash
+export LD_LIBRARY_PATH=${path_dirs_native}:$LD_LIBRARY_PATH
+$@")
+ endif()
# Remember the creation of the file for a specific tool.
set_property(GLOBAL PROPERTY "_shiboken_tool_wrapper_${tool_name}_path" "${wrapper_path}")
set_property(GLOBAL PROPERTY "_shiboken_tool_wrapper_${tool_name}_created" TRUE)
+ # Save original host paths for future cross-builds.
+ shiboken_save_host_tool_wrapper_properties("${qt_library_dir_absolute}" "${libclang_lib_dir}")
+
+ # give execute permission to run the file
+ if(CMAKE_HOST_UNIX)
+ execute_process(COMMAND chmod +x ${wrapper_path})
+ endif()
+
set(${path_out_var} "${wrapper_path}" PARENT_SCOPE)
endfunction()
+
+# Retrieve the original host shiboken runtime dependency paths from the installed (namespaced)
+# shiboken generator target.
+function(shiboken_get_host_tool_wrapper_properties out_qt_library_dir out_libclang_lib_dir)
+ if(TARGET Shiboken6::shiboken6)
+ get_target_property(qt_library_dir Shiboken6::shiboken6 _shiboken_original_qt_lib_dir)
+ if(NOT qt_library_dir)
+ set(qt_library_dir "")
+ endif()
+ get_target_property(libclang_lib_dir Shiboken6::shiboken6
+ _shiboken_original_libclang_lib_dir)
+ if(NOT libclang_lib_dir)
+ set(libclang_lib_dir "")
+ endif()
+ endif()
+
+ set(${out_qt_library_dir} "${qt_library_dir}" PARENT_SCOPE)
+ set(${out_libclang_lib_dir} "${libclang_lib_dir}" PARENT_SCOPE)
+endfunction()
+
+# Save original host shiboken runtime dependency paths as target properties, so they can be used
+# when generating the wrapper file for cross-builds.
+# Should only be done when shiboken is being built (aka it's a non-imported target).
+function(shiboken_save_host_tool_wrapper_properties qt_library_dir libclang_lib_dir)
+ if(TARGET shiboken6)
+ get_target_property(is_imported shiboken6 IMPORTED)
+ if(is_imported)
+ return()
+ endif()
+
+ set_target_properties(shiboken6 PROPERTIES
+ _shiboken_original_qt_lib_dir "${qt_library_dir}")
+ set_property(TARGET shiboken6 APPEND PROPERTY
+ EXPORT_PROPERTIES _shiboken_original_qt_lib_dir)
+ if(libclang_lib_dir)
+ set_target_properties(shiboken6 PROPERTIES
+ _shiboken_original_libclang_lib_dir "${libclang_lib_dir}")
+ set_property(TARGET shiboken6 APPEND PROPERTY
+ EXPORT_PROPERTIES _shiboken_original_libclang_lib_dir)
+ endif()
+ endif()
+endfunction()
+
+# Returns the platform-specific relative rpath base token, if it's supported.
+# If it's not supported, returns the string NO_KNOWN_RPATH_REL_BASE.
+function(get_rpath_base_token out_var)
+ if(APPLE)
+ set(rpath_rel_base "@loader_path")
+ elseif(UNIX)
+ set(rpath_rel_base "$ORIGIN")
+ else()
+ #has no effect on Windows
+ set(rpath_rel_base "NO_KNOWN_RPATH_REL_BASE")
+ endif()
+ set(${out_var} "${rpath_rel_base}" PARENT_SCOPE)
+endfunction()
+
+# Get path to libclang.dll/libclang.so depending on the platform
+macro(find_libclang)
+ if(CMAKE_HOST_WIN32)
+ set(libclang_directory_suffix "bin")
+ set(libclang_suffix ".dll")
+ else()
+ set(libclang_directory_suffix "lib")
+ if(CMAKE_HOST_APPLE)
+ set(libclang_suffix ".dylib")
+ else()
+ set(libclang_suffix ".so")
+ endif()
+ endif()
+
+ set(libclang_lib_dir "")
+ if(DEFINED ENV{LLVM_INSTALL_DIR})
+ set(libclang_lib_dir "$ENV{LLVM_INSTALL_DIR}/${libclang_directory_suffix}")
+ elseif(DEFINED ENV{CLANG_INSTALL_DIR})
+ set(libclang_lib_dir "$ENV{CLANG_INSTALL_DIR}/${libclang_directory_suffix}")
+ else()
+ message(WARNING
+ "Couldn't find libclang${libclang_suffix} "
+ "You will likely need to add it manually to PATH to ensure the build succeeds.")
+ endif()
+endmacro()
+
+# Allow setting a shiboken debug level from the the build system or from the environment
+# to all shiboken invocations.
+function(shiboken_get_debug_level out_var)
+ set(debug_level "")
+ if(SHIBOKEN_DEBUG_LEVEL)
+ set(debug_level "--debug-level=${SHIBOKEN_DEBUG_LEVEL}")
+ elseif(DEFINED $ENV{SHIBOKEN_DEBUG_LEVEL})
+ set(debug_level "--debug-level=$ENV{SHIBOKEN_DEBUG_LEVEL}")
+ endif()
+ set(${out_var} "${debug_level}" PARENT_SCOPE)
+endfunction()
diff --git a/sources/shiboken6/cmake/ShibokenSetup.cmake b/sources/shiboken6/cmake/ShibokenSetup.cmake
index 6f37ecc67..32823d9fa 100644
--- a/sources/shiboken6/cmake/ShibokenSetup.cmake
+++ b/sources/shiboken6/cmake/ShibokenSetup.cmake
@@ -1,10 +1,12 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include(CheckIncludeFileCXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}")
include(ShibokenHelpers)
-option(USE_PYTHON_VERSION "Use specific python version to build shiboken6." "")
option(DISABLE_DOCSTRINGS "Disable documentation extraction." FALSE)
shiboken_internal_disable_pkg_config_if_needed()
@@ -41,13 +43,12 @@ set(shiboken6_library_so_version "${shiboken_MAJOR_VERSION}.${shiboken_MINOR_VER
compute_config_py_values(shiboken6_VERSION)
## For debugging the PYTHON* variables
-message(STATUS "PYTHONLIBS_FOUND: " ${PYTHONLIBS_FOUND})
-message(STATUS "PYTHON_LIBRARIES: " ${PYTHON_LIBRARIES})
-message(STATUS "PYTHON_INCLUDE_DIRS: " ${PYTHON_INCLUDE_DIRS})
-message(STATUS "PYTHON_DEBUG_LIBRARIES: " ${PYTHON_DEBUG_LIBRARIES})
-message(STATUS "PYTHONINTERP_FOUND: " ${PYTHONINTERP_FOUND})
-message(STATUS "PYTHON_EXECUTABLE: " ${PYTHON_EXECUTABLE})
-message(STATUS "PYTHON_VERSION: " ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH})
+message(STATUS "Python_Development_FOUND: " ${Python_Development_FOUND})
+message(STATUS "Python_LIBRARIES: " ${Python_LIBRARIES})
+message(STATUS "Python_INCLUDE_DIRS: " ${Python_INCLUDE_DIRS})
+message(STATUS "Python_Interpreter_FOUND: " ${Python_Interpreter_FOUND})
+message(STATUS "Python_EXECUTABLE: " ${Python_EXECUTABLE})
+message(STATUS "Python_VERSION: " ${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}.${Python_VERSION_PATCH})
if(NOT PYTHON_EXTENSION_SUFFIX)
get_python_extension_suffix()
@@ -118,7 +119,7 @@ endif()
# Detect if the python libs were compiled in debug mode
# On Linux distros there is no standard way to check that.
execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c "if True:
+ COMMAND ${Python_EXECUTABLE} -c "if True:
import sys
import sysconfig
config_py_debug = sysconfig.get_config_var('Py_DEBUG')
@@ -136,7 +137,7 @@ if(SHIBOKEN_IS_CROSS_BUILD)
set(PYTHON_WITH_COUNT_ALLOCS 0)
else()
execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c "if True:
+ COMMAND ${Python_EXECUTABLE} -c "if True:
count_allocs = False
import sys
try:
diff --git a/sources/shiboken6/cmake_uninstall.cmake b/sources/shiboken6/cmake_uninstall.cmake
index df95fb9d8..4031b4e1a 100644
--- a/sources/shiboken6/cmake_uninstall.cmake
+++ b/sources/shiboken6/cmake_uninstall.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
diff --git a/sources/shiboken6/config.tests/target_python_info/CMakeLists.txt b/sources/shiboken6/config.tests/target_python_info/CMakeLists.txt
index 5ff4c253d..b3f994017 100644
--- a/sources/shiboken6/config.tests/target_python_info/CMakeLists.txt
+++ b/sources/shiboken6/config.tests/target_python_info/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
project(proj LANGUAGES CXX)
diff --git a/sources/shiboken6/config.tests/target_qt_info/CMakeLists.txt b/sources/shiboken6/config.tests/target_qt_info/CMakeLists.txt
index be4d111dc..7cc6b6ffc 100644
--- a/sources/shiboken6/config.tests/target_qt_info/CMakeLists.txt
+++ b/sources/shiboken6/config.tests/target_qt_info/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
project(proj LANGUAGES CXX)
diff --git a/sources/shiboken6/config.tests/target_qt_mkspec/CMakeLists.txt b/sources/shiboken6/config.tests/target_qt_mkspec/CMakeLists.txt
index 526570a9c..9f6513316 100644
--- a/sources/shiboken6/config.tests/target_qt_mkspec/CMakeLists.txt
+++ b/sources/shiboken6/config.tests/target_qt_mkspec/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
project(dummy LANGUAGES CXX)
diff --git a/sources/shiboken6/data/CMakeLists.txt b/sources/shiboken6/data/CMakeLists.txt
index 88d9487da..679eefe6a 100644
--- a/sources/shiboken6/data/CMakeLists.txt
+++ b/sources/shiboken6/data/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set(LIBRARY_OUTPUT_SUFFIX ${CMAKE_DEBUG_POSTFIX})
else()
diff --git a/sources/shiboken6/data/Shiboken6Config-spec.cmake.in b/sources/shiboken6/data/Shiboken6Config-spec.cmake.in
index a07563a53..233404bc6 100644
--- a/sources/shiboken6/data/Shiboken6Config-spec.cmake.in
+++ b/sources/shiboken6/data/Shiboken6Config-spec.cmake.in
@@ -5,9 +5,9 @@
# This is the version of Python against which Shiboken was built. Not necessarily the version
# against which a downstream project is built (e.g. PySide6).
-set(SHIBOKEN_PYTHON_VERSION_MAJOR "@PYTHON_VERSION_MAJOR@")
-set(SHIBOKEN_PYTHON_VERSION_MINOR "@PYTHON_VERSION_MINOR@")
-set(SHIBOKEN_PYTHON_VERSION_PATCH "@PYTHON_VERSION_PATCH@")
+set(SHIBOKEN_PYTHON_VERSION_MAJOR "@Python_VERSION_MAJOR@")
+set(SHIBOKEN_PYTHON_VERSION_MINOR "@Python_VERSION_MINOR@")
+set(SHIBOKEN_PYTHON_VERSION_PATCH "@Python_VERSION_PATCH@")
set(SHIBOKEN_PYTHON_LIMITED_API "@PYTHON_LIMITED_API@")
# Import targets and call variable set up functions only when using an installed shiboken config
@@ -17,7 +17,7 @@ if (NOT TARGET Shiboken6::libshiboken)
include("${CMAKE_CURRENT_LIST_DIR}/ShibokenHelpers.cmake")
# Compute the python include and libraries path if needed (aka not part of super project build).
- shiboken_find_required_python(@PYTHON_VERSION_MAJOR@)
+ shiboken_find_required_python(@Python_VERSION_MAJOR@)
shiboken_check_if_built_and_target_python_are_compatible()
shiboken_check_if_limited_api()
shiboken_compute_python_includes(IS_CALLED_FROM_EXPORT)
diff --git a/sources/shiboken6/data/Shiboken6ToolsConfig.cmake.in b/sources/shiboken6/data/Shiboken6ToolsConfig.cmake.in
index 84ccf622f..438b5c651 100644
--- a/sources/shiboken6/data/Shiboken6ToolsConfig.cmake.in
+++ b/sources/shiboken6/data/Shiboken6ToolsConfig.cmake.in
@@ -1,6 +1,6 @@
@PACKAGE_INIT@
-cmake_minimum_required(VERSION 3.16)
+cmake_minimum_required(VERSION 3.18)
if(NOT TARGET Shiboken6::shiboken6)
include("${CMAKE_CURRENT_LIST_DIR}/Shiboken6ToolsTargets.cmake")
diff --git a/sources/shiboken6/data/shiboken6.pc.in b/sources/shiboken6/data/shiboken6.pc.in
index 3ba422627..a82d23168 100644
--- a/sources/shiboken6/data/shiboken6.pc.in
+++ b/sources/shiboken6/data/shiboken6.pc.in
@@ -2,11 +2,11 @@ prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_DIR@
includedir=@CMAKE_INSTALL_PREFIX@/include/shiboken6
-python_interpreter=@PYTHON_EXECUTABLE@
-python_include_dir=@PYTHON_INCLUDE_DIRS@
+python_interpreter=@Python_EXECUTABLE@
+python_include_dir=@Python_INCLUDE_DIRS@
Name: shiboken6
Description: Support library for Python bindings created with the Shiboken6 generator.
Version: @shiboken6_VERSION@
Libs: @SHIBOKEN_PYTHON_LIBRARIES@ -L${libdir} -lshiboken6@shiboken6_SUFFIX@@PYTHON_SHARED_LIBRARY_SUFFIX@@LIBRARY_OUTPUT_SUFFIX@
-Cflags: -I@PYTHON_INCLUDE_DIRS@ -I${includedir}/@shiboken6_SUFFIX@@SBK_PKG_CONFIG_PY_DEBUG_DEFINITION@
+Cflags: -I@Python_INCLUDE_DIRS@ -I${includedir}/@shiboken6_SUFFIX@@SBK_PKG_CONFIG_PY_DEBUG_DEFINITION@
diff --git a/sources/shiboken6/doc/CMakeLists.txt b/sources/shiboken6/doc/CMakeLists.txt
index 65b3d4eef..eaef4ff29 100644
--- a/sources/shiboken6/doc/CMakeLists.txt
+++ b/sources/shiboken6/doc/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
if(FULLDOCSBUILD EQUAL 0)
@@ -34,7 +37,7 @@ if(SPHINX_BUILD)
if(SHIBOKEN_IS_CROSS_BUILD)
set(python_executable "${QFP_PYTHON_HOST_PATH}")
else()
- set(python_executable "${PYTHON_EXECUTABLE}")
+ set(python_executable "${Python_EXECUTABLE}")
endif()
if(NOT python_executable OR NOT EXISTS "${python_executable}")
message(FATAL_ERROR "No python executable found to build documentation.")
diff --git a/sources/shiboken6/doc/_static/css/qt_font.css b/sources/shiboken6/doc/_static/css/qt_font.css
index bc282785e..ce39943ef 100644
--- a/sources/shiboken6/doc/_static/css/qt_font.css
+++ b/sources/shiboken6/doc/_static/css/qt_font.css
@@ -4,6 +4,12 @@
font-weight: 400;
src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot");
/* IE9 Compat Modes */
- src: local("Titillium Web"), local("TitilliumWeb-Regular"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot?#iefix") format("embedded-opentype"), url("//d33sqmj vzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext- regular.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/ assets/fonts/titillium-web-v4-latin_latin-ext-regular.svg#TitilliumWeb") format("svg");
+ src: local("Titillium Web"),
+ local("TitilliumWeb-Regular"),
+ url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot?#iefix") format("embedded-opentype"),
+ url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff2") format("woff2"),
+ url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff") format("woff"),
+ url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.ttf") format("truetype"),
+ url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.svg#TitilliumWeb") format("svg");
/* Legacy iOS */
}
diff --git a/sources/shiboken6/doc/_static/css/qt_style.css b/sources/shiboken6/doc/_static/css/qt_style.css
index ea40e5107..08c4646c6 100644
--- a/sources/shiboken6/doc/_static/css/qt_style.css
+++ b/sources/shiboken6/doc/_static/css/qt_style.css
@@ -1,37 +1,100 @@
-.btn-qt:hover,
-.btn-qt:active,
-.btn-qt:focus,
-.btn-qt.active {
- background: #41cd52;
- color: #fff !important;
- border-color: #fff;
+.text-center {
+ text-align: center !important;
}
-.btn-link {
- color: #41cd52 !important;
+.text-center img {
+ padding-top: 10px;
+ height: 70px !important;
}
-.btn-link:hover {
- color: #222840 !important;
- text-decoration: underline;
+.cover-img img {
+ object-fit: cover;
+ height: 50%;
}
-/* Using !important is not recommended, but out CSS is being added
- * to the pages before the bootstrap ones, so we cannot override them
- * without using it */
-.btn-qt {
- color: #41cd52 !important;
- border-color: #41cd52 !important;
- font-weight: bold !important;
+/* Tables */
+.section .docutils.container td {
+ float:left;
}
-.card-img-top-main {
- padding-top: 10px;
- height: 70px !important;
+
+table.docutils {
+ margin-right: auto;
+ margin-bottom: 10px;
+ border: none;
+ width: initial;
+ font-size: 0.8em;
+}
+
+table.docutils.colwidths-given td {
+ float: none;
+}
+
+table.docutils th,
+table.docutils td {
+ padding-left:0;
+ border: none;
+}
+
+table.docutils td ul {
+ margin:0
+}
+
+table.docutils td ul > li {
+ margin: 0 0 0.5em;
+}
+
+.hide {
+ display: none;
+}
+
+.fixed .container {
+ max-width:1280px;
+ margin:0 auto;
+ padding:0 3.9%; /* 0? */
+ position:relative;
+ overflow:visible
+}
+
+/* We cannot put a :download:`....` command inside
+ * a sphinx-design button, so we add some properties from the button
+ * to the download class to mimic it */
+code.download {
+ text-align: center;
+ color: var(--color-brand-primary);
+ display: block;
+ border-color: transparent;
+ background-color: transparent;
+ border: 1px solid var(--color-brand-primary) !important;
+ border-radius: 0.25rem;
+ font-size: 1rem;
+ font-weight: 400;
+ vertical-align: middle;
+ padding: .375rem .75rem;
+ user-select: none;
+ line-height: 1.5;
+ transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
+}
+
+code.download:hover {
+ color: white;
+ background-color: var(--color-brand-primary);
+ border-color: var(--color-brand-primary);
+ text-decoration: none;
+ padding: .375rem .75rem;
+}
+
+dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple):first-child > dt {
+ font-size: +2.25rem;
+ font-weight: 700;
+ color: #ff00dd;
+}
+
+.theme-toggle svg{
+ width: +1.25rem;
+ height: +2.25rem;
}
-.card-img-top {
- object-fit: contain;
- height: 120px;
- padding-top: 20px;
- transform: scale(1.3, 1.3);
+.sd-card-title code span {
+ font-size: +1rem;
+ color: var(--color-brand-primary);
}
diff --git a/sources/shiboken6/doc/_static/shiboken.png b/sources/shiboken6/doc/_static/shiboken.png
new file mode 100644
index 000000000..587d33329
--- /dev/null
+++ b/sources/shiboken6/doc/_static/shiboken.png
Binary files differ
diff --git a/sources/shiboken6/doc/_static/shiboken.svg b/sources/shiboken6/doc/_static/shiboken.svg
new file mode 100644
index 000000000..a13f3e9fb
--- /dev/null
+++ b/sources/shiboken6/doc/_static/shiboken.svg
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ width="1080"
+ zoomAndPan="magnify"
+ viewBox="0 0 810 809.999993"
+ height="1080"
+ preserveAspectRatio="xMidYMid meet"
+ version="1.0"
+ id="svg47"
+ sodipodi:docname="shiboken.svg"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview49"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ showgrid="false"
+ inkscape:zoom="0.80648148"
+ inkscape:cx="505.28129"
+ inkscape:cy="540"
+ inkscape:window-width="2552"
+ inkscape:window-height="1432"
+ inkscape:window-x="1924"
+ inkscape:window-y="4"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg47" />
+ <defs
+ id="defs17">
+ <clipPath
+ id="25c649227a">
+ <path
+ d="M 187.234375 180.804688 L 622.011719 180.804688 L 622.011719 615.582031 L 187.234375 615.582031 Z M 187.234375 180.804688 "
+ clip-rule="nonzero"
+ id="path2" />
+ </clipPath>
+ <clipPath
+ id="a7a24c818d">
+ <path
+ d="M 475.953125 479.28125 L 728.5625 479.28125 L 728.5625 731.886719 L 475.953125 731.886719 Z M 475.953125 479.28125 "
+ clip-rule="nonzero"
+ id="path5" />
+ </clipPath>
+ <clipPath
+ id="9e94c67ce5">
+ <path
+ d="M 80.601562 479.28125 L 332.789062 479.28125 L 332.789062 731.886719 L 80.601562 731.886719 Z M 80.601562 479.28125 "
+ clip-rule="nonzero"
+ id="path8" />
+ </clipPath>
+ <clipPath
+ id="f807adb387">
+ <path
+ d="M 475.953125 81.417969 L 728.5625 81.417969 L 728.5625 333.609375 L 475.953125 333.609375 Z M 475.953125 81.417969 "
+ clip-rule="nonzero"
+ id="path11" />
+ </clipPath>
+ <clipPath
+ id="a7b91dab09">
+ <path
+ d="M 80.601562 81.417969 L 332.789062 81.417969 L 332.789062 333.609375 L 80.601562 333.609375 Z M 80.601562 81.417969 "
+ clip-rule="nonzero"
+ id="path14" />
+ </clipPath>
+ </defs>
+ <path
+ fill="#41cb51"
+ d="M 404.621094 459.0625 C 371.058594 459.0625 343.753906 431.75 343.753906 398.195312 C 343.753906 364.628906 371.058594 337.324219 404.621094 337.324219 C 438.179688 337.324219 465.492188 364.628906 465.492188 398.195312 C 465.492188 431.75 438.179688 459.0625 404.621094 459.0625 Z M 404.621094 459.0625 "
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path25" />
+ <g
+ clip-path="url(#25c649227a)"
+ id="g29">
+ <path
+ fill="#41cb51"
+ d="M 614.714844 363.132812 L 568.308594 355.550781 C 564.375 340.4375 558.351562 325.984375 550.351562 312.4375 L 577.464844 273.804688 C 579.890625 270.34375 579.480469 265.648438 576.5 262.65625 L 539.613281 225.769531 C 536.59375 222.742188 531.828125 222.371094 528.386719 224.855469 L 490.152344 252.335938 C 476.578125 244.351562 462.109375 238.34375 447.003906 234.4375 L 438.867188 187.996094 C 438.136719 183.839844 434.519531 180.804688 430.292969 180.804688 L 378.117188 180.804688 C 373.859375 180.804688 370.222656 183.890625 369.535156 188.101562 L 361.953125 234.535156 C 347.023438 238.421875 332.691406 244.371094 319.222656 252.273438 L 280.808594 224.820312 C 277.335938 222.351562 272.617188 222.742188 269.597656 225.742188 L 232.703125 262.628906 C 229.71875 265.613281 229.304688 270.308594 231.730469 273.761719 L 258.851562 312.5 C 250.886719 325.996094 244.902344 340.386719 240.980469 355.402344 L 194.511719 363.140625 C 190.3125 363.835938 187.234375 367.464844 187.234375 371.714844 L 187.234375 423.890625 C 187.234375 428.105469 190.261719 431.714844 194.40625 432.445312 L 240.894531 440.6875 C 244.78125 455.6875 250.746094 470.0625 258.675781 483.582031 L 231.214844 521.964844 C 228.746094 525.425781 229.136719 530.164062 232.136719 533.175781 L 269.023438 570.0625 C 272 573.035156 276.695312 573.453125 280.15625 571.035156 L 318.875 543.9375 C 332.320312 551.878906 346.703125 557.871094 361.78125 561.808594 L 369.535156 608.3125 C 370.242188 612.503906 373.867188 615.582031 378.117188 615.582031 L 430.292969 615.582031 C 434.5 615.582031 438.109375 612.554688 438.847656 608.40625 L 447.101562 561.914062 C 462.292969 557.984375 476.804688 551.949219 490.394531 543.921875 L 529.074219 571.035156 C 532.535156 573.460938 537.230469 573.050781 540.210938 570.070312 L 577.082031 533.183594 C 580.097656 530.164062 580.480469 525.410156 577.984375 521.957031 L 550.480469 483.730469 C 558.464844 470.175781 564.453125 455.714844 568.359375 440.609375 L 614.8125 432.460938 C 618.976562 431.722656 622.011719 428.105469 622.011719 423.890625 L 622.011719 371.714844 C 622.011719 367.453125 618.921875 363.820312 614.714844 363.132812 Z M 404.621094 502.539062 C 347.085938 502.539062 300.277344 455.722656 300.277344 398.183594 C 300.277344 340.65625 347.085938 293.847656 404.621094 293.847656 C 462.160156 293.847656 508.96875 340.65625 508.96875 398.183594 C 508.96875 455.722656 462.160156 502.539062 404.621094 502.539062 Z M 404.621094 502.539062 "
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path27" />
+ </g>
+ <g
+ clip-path="url(#a7a24c818d)"
+ id="g33">
+ <path
+ fill="#ffd43b"
+ d="M 653.035156 479.28125 C 653.035156 576.996094 573.667969 656.363281 475.953125 656.363281 L 475.953125 731.886719 C 615.484375 731.886719 728.5625 618.8125 728.5625 479.28125 Z M 653.035156 479.28125 "
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path31" />
+ </g>
+ <g
+ clip-path="url(#9e94c67ce5)"
+ id="g37">
+ <path
+ fill="#306998"
+ d="M 156.125 479.28125 C 156.125 576.996094 235.492188 656.363281 333.207031 656.363281 L 333.207031 731.886719 C 193.675781 731.886719 80.601562 618.8125 80.601562 479.28125 Z M 156.125 479.28125 "
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path35" />
+ </g>
+ <g
+ clip-path="url(#f807adb387)"
+ id="g41">
+ <path
+ fill="#306998"
+ d="M 653.035156 334.023438 C 653.035156 236.308594 573.667969 156.945312 475.953125 156.945312 L 475.953125 81.417969 C 615.484375 81.417969 728.5625 194.492188 728.5625 334.023438 Z M 653.035156 334.023438 "
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path39" />
+ </g>
+ <g
+ clip-path="url(#a7b91dab09)"
+ id="g45">
+ <path
+ fill="#ffd43b"
+ d="M 156.125 334.023438 C 156.125 236.308594 235.492188 156.945312 333.207031 156.945312 L 333.207031 81.417969 C 193.675781 81.417969 80.601562 194.492188 80.601562 334.023438 Z M 156.125 334.023438 "
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path43" />
+ </g>
+</svg>
diff --git a/sources/shiboken6/doc/_themes/pysidedocs_qthelp/static/pyside.css b/sources/shiboken6/doc/_themes/pysidedocs_qthelp/static/pyside.css
index aee5e4420..94134cacf 100644
--- a/sources/shiboken6/doc/_themes/pysidedocs_qthelp/static/pyside.css
+++ b/sources/shiboken6/doc/_themes/pysidedocs_qthelp/static/pyside.css
@@ -466,7 +466,7 @@ tt.descname {
position:relative
}
#menuextras li a:hover span {
- color: #41cd52;
+ color: #2cde85;
}
/* new header */
#mm-wrap, #mm-wrap #mm-helper,
@@ -557,14 +557,14 @@ tt.descname {
display:inline;
float:left;
width:31px;
- color:#41cd52
+ color:#2cde85
}
#navbar .navbar-oneQt:before {
content:attr(data-icon);
position:absolute;
top:14px;
left:0;
- color:#41cd52;
+ color:#2cde85;
font-family:'Qt Icons';
line-height:1;
font-size:40px;
@@ -1939,5 +1939,5 @@ table.special td {
.special td:hover {
padding-top: 2px;
padding-bottom: 2px;
- border-bottom: 4px solid #41cd52;
+ border-bottom: 4px solid #2cde85;
}
diff --git a/sources/shiboken6/doc/conf.py.in b/sources/shiboken6/doc/conf.py.in
index ca0b4963b..b10f33b2a 100644
--- a/sources/shiboken6/doc/conf.py.in
+++ b/sources/shiboken6/doc/conf.py.in
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
-# PyQtB documentation build configuration file, created by
+# Shiboken documentation build configuration file, created by
# sphinx-quickstart on Wed Apr 22 15:04:20 2009.
#
# This file is execfile()d with the current directory set to its containing dir.
@@ -11,34 +11,59 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
-import sys, os
+import sys
+import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.append(os.path.abspath('.'))
+# documentation root, use Path(path).resolve() to make it absolute, like shown here.
+sys.path.append('@CMAKE_CURRENT_SOURCE_DIR@')
# -- General configuration -----------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.ifconfig',
- 'sphinx.ext.coverage', 'sphinx_panels', 'sphinx_copybutton']
+ 'sphinx.ext.coverage', 'sphinx.ext.intersphinx', 'sphinx.ext.todo',
+ 'sphinx.ext.graphviz',
+ 'sphinx.ext.viewcode',
+ 'sphinx_design', 'sphinx_copybutton',
+ 'myst_parser']
+
+myst_enable_extensions = [
+ "amsmath",
+ "colon_fence",
+ "deflist",
+ "dollarmath",
+ "fieldlist",
+ "html_admonition",
+ "html_image",
+ "replacements",
+ "smartquotes",
+ "strikethrough",
+ "substitution",
+ "tasklist",
+]
+myst_heading_anchors = 6
output_format='@DOC_OUTPUT_FORMAT@'
def setup(app):
app.add_config_value('output_format','qthelp','env')
-rst_epilog = """
-.. |project| replace:: Shiboken
+rst_epilog = """
+.. |project| replace:: Qt for Python
+.. |pymodname| replace:: Shiboken6
"""
# Add any paths that contain templates here, relative to this directory.
templates_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_templates']
# The suffix of source filenames.
-source_suffix = '.rst'
+source_suffix = {
+ '.rst': 'restructuredtext',
+ '.md': 'markdown',
+}
# The encoding of source files.
source_encoding = 'utf-8'
@@ -48,16 +73,15 @@ master_doc = 'index'
# General information about the project.
project = u'Shiboken'
-copyright = u'2021 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 (https://www.gnu.org/licenses/fdl.html) as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.'
-
+copyright = u'2024 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 (https://www.gnu.org/licenses/fdl.html) as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
-version = '@shiboken_VERSION@'
+version = '@BINDING_API_VERSION@'
# The full version, including alpha/beta/rc tags.
-release = '@shiboken_VERSION@'
+release = '@BINDING_API_VERSION_FULL@'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -74,7 +98,8 @@ release = '@shiboken_VERSION@'
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
-exclude_trees = ['_build']
+exclude_patterns = ['_build',
+ '**README.md']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
@@ -109,16 +134,16 @@ html_theme = 'furo'
# documentation.
html_theme_options = {
"dark_css_variables": {
- "color-brand-primary": "#66689d",
- "color-brand-content": "#66689d",
- "color-admonition-title--important": "#41cd52",
+ "color-brand-primary": "#2cde85",
+ "color-brand-content": "#2cde85",
+ "color-admonition-title--important": "#2cde85",
"color-admonition-title-background--important": "#474b53",
"font-stack": "'Titillium Web', sans-serif",
},
"light_css_variables": {
- "color-brand-primary": "#66689d",
- "color-brand-content": "#41cd52",
- "color-admonition-title--important": "#41cd52",
+ "color-brand-primary": "#27138b",
+ "color-brand-content": "#27138b",
+ "color-admonition-title--important": "#27138b",
"font-stack": "'Titillium Web', sans-serif",
},
}
@@ -128,14 +153,14 @@ html_theme_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_themes']
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
-#html_title = None
+html_title = "Shiboken"
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
-html_logo = "@CMAKE_CURRENT_SOURCE_DIR@/_static/qtforpython.png"
+html_logo = "@CMAKE_CURRENT_SOURCE_DIR@/_static/shiboken.png"
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
@@ -184,8 +209,3 @@ html_show_sourcelink = False
# -- Options for qthelp output --------------------------------------------------
qthelp_theme = 'pysidedocs_qthelp'
-
-# Sphinx Panels color for inactive tab
-panels_css_variables = {
- "tabs-color-label-inactive": "rgba(116, 116, 116, 1.0)",
-}
diff --git a/sources/shiboken6/doc/considerations.rst b/sources/shiboken6/doc/considerations.rst
index 1a406c7c9..ad913e7a6 100644
--- a/sources/shiboken6/doc/considerations.rst
+++ b/sources/shiboken6/doc/considerations.rst
@@ -6,6 +6,18 @@ Words of Advice
When writing or using Python bindings there is some things you must keep in mind.
+.. _rvalue_references:
+
+Rvalue References
+=================
+
+Normally, no bindings are generated for functions taking rvalue references.
+Experimental support has been added in 6.6. The functions need to be explicitly
+specified using the :ref:`add-function`, :ref:`declare-function` or
+:ref:`function` elements. For :ref:`value-type` objects, this does not have any
+implications since the arguments are copied in the generated code and the copy
+is moved from. For :ref:`object-type` objects however, it means that the object
+instance is moved from and should no longer be referenced.
.. _duck-punching-and-virtual-methods:
@@ -18,19 +30,19 @@ be tricky. That was an optimistic statement.
Let's see duck punching in action for educational purposes.
- .. code-block:: python
+.. code-block:: python
- import types
- import Binding
+ import types
+ import Binding
- obj = Binding.CppClass()
+ obj = Binding.CppClass()
- # CppClass has a virtual method called 'virtualMethod',
- # but we don't like it anymore.
- def myVirtualMethod(self_obj, arg):
- pass
+ # CppClass has a virtual method called 'virtualMethod',
+ # but we don't like it anymore.
+ def myVirtualMethod(self_obj, arg):
+ pass
- obj.virtualMethod = types.MethodType(myVirtualMethod, obj, Binding.CppClass)
+ obj.virtualMethod = types.MethodType(myVirtualMethod, obj, Binding.CppClass)
If some C++ code happens to call `CppClass::virtualMethod(...)` on the C++ object
@@ -46,17 +58,17 @@ Python-land by the usage of class constructors, like in the example above.
Brief interruption to show what I was saying:
- .. code-block:: python
+.. code-block:: python
- import types
- import Binding
+ import types
+ import Binding
- obj = Binding.createCppClass()
- def myVirtualMethod(self_obj, arg):
- pass
+ obj = Binding.createCppClass()
+ def myVirtualMethod(self_obj, arg):
+ pass
- # Punching a dead duck...
- obj.virtualMethod = types.MethodType(myVirtualMethod, obj, Binding.CppClass)
+ # Punching a dead duck...
+ obj.virtualMethod = types.MethodType(myVirtualMethod, obj, Binding.CppClass)
The `Binding.createCppClass()` factory method is just an example, C++ created objects
@@ -82,30 +94,30 @@ Below you can check the examples:
Example with old style class:
- .. code-block:: python
+.. code-block:: python
- from PySide6 import QtCore
+ from PySide6 import QtCore
- class MyOldStyleObject:
- pass
+ class MyOldStyleObject:
+ pass
- class MyObject(QtCore, MyOldStyleObject):
- pass
+ class MyObject(QtCore, MyOldStyleObject):
+ pass
this example will raise a 'TypeError' due to the limitation on PySide, to fix
this you will need use the new style class:
- .. code-block:: python
+.. code-block:: python
- from PySide6 import QtCore
+ from PySide6 import QtCore
- class MyOldStyleObject(object):
- pass
+ class MyOldStyleObject(object):
+ pass
- class MyObject(QtCore, MyOldStyleObject):
- pass
+ class MyObject(QtCore, MyOldStyleObject):
+ pass
All classes used for multiple inheritance with other PySide types need to have
diff --git a/sources/shiboken6/doc/examples/index.rst b/sources/shiboken6/doc/examples/index.rst
index 92a64195e..e3575bc06 100644
--- a/sources/shiboken6/doc/examples/index.rst
+++ b/sources/shiboken6/doc/examples/index.rst
@@ -4,6 +4,20 @@ Examples
C++ examples
------------
-.. toctree::
+.. grid:: 1 4 4 4
+ :gutter: 2
- samplebinding.rst
+ .. grid-item-card:: Sample Binding
+ :class-item: cover-img
+ :link: ../../examples/example_samplebinding_samplebinding.html
+ :img-top: ../images/icecream.png
+
+ .. grid-item-card:: Scriptable Application
+ :class-item: cover-img
+ :link: ../../examples/example_scriptableapplication_scriptableapplication.html
+ :img-top: ../../../_images/example_no_image.png
+
+ .. grid-item-card:: Widget Binding
+ :class-item: cover-img
+ :link: ../../examples/example_widgetbinding_widgetbinding.html
+ :img-top: ../../../_images/example_no_image.png
diff --git a/sources/shiboken6/doc/examples/samplebinding.rst b/sources/shiboken6/doc/examples/samplebinding.rst
deleted file mode 100644
index 17a5bd38f..000000000
--- a/sources/shiboken6/doc/examples/samplebinding.rst
+++ /dev/null
@@ -1,246 +0,0 @@
-SampleBinding Example
-***********************
-
-This example showcases how you can use Shiboken to generate CPython-based
-binding code for a C++ library. The C++ library is called :code:`Universe`,
-with two classes: :code:`Icecream` and :code:`Truck`. Ice-creams are
-characterized by their flavor, and :code:`Truck` serves as a vehicle of
-:code:`Icecream` distribution for kids in a neighborhood.
-
-First, let's look at the definition of the two classes:
-
-.. code-block:: cpp
- :caption: icecream.h
-
- class Icecream
- {
- public:
- Icecream(const std::string &flavor);
- virtual Icecream *clone();
- virtual ~Icecream();
- virtual const std::string getFlavor();
-
- private:
- std::string m_flavor;
- };
-
-.. code-block:: cpp
- :caption: truck.h
-
- class Truck {
- public:
- Truck(bool leaveOnDestruction = false);
- Truck(const Truck &other);
- Truck& operator=(const Truck &other);
- ~Truck();
-
- void addIcecreamFlavor(Icecream *icecream);
- void printAvailableFlavors() const;
-
- bool deliver() const;
- void arrive() const;
- void leave() const;
-
- void setLeaveOnDestruction(bool value);
- void setArrivalMessage(const std::string &message);
-
- private:
- void clearFlavors();
-
- bool m_leaveOnDestruction = false;
- std::string m_arrivalMessage = "A new icecream truck has arrived!\n";
- std::vector m_flavors;
- };
-
-Here's a summary of what's included in the :code:`Universe` library:
-
-* The :code:`Icecream` polymorphic type, which is intended to be overridden.
-* The :code:`Icecream::getFlavor()` method returns the flavor depending on the
- actual derived type.
-* The :code:`Truck` value type that contains pointers, hence the copy
- constructor.
-* :code:`Truck` stores the :code:`Icecream` objects in a vector, which can be
- modified via :code:`Truck::addIcecreamFlavor()`.
-* The :code:`Truck’s` arrival message can be customized using its
- :code:`setArrivalMessage()` method.
-* The :code:`Truck::deliver()` method tells us if the ice-cream delivery was
- successful.
-
-Shiboken typesystem
-====================
-
-Now that the library definitions are in place, the Shiboken generator needs a
-header file that includes the types we are interested in:
-
-.. code-block:: cpp
- :caption: bindings.h
-
- #ifndef BINDINGS_H
- #define BINDINGS_H
- #include "icecream.h"
- #include "truck.h"
- #endif // BINDINGS_H
-
-In addition, Shiboken also requires an XML-based typesystem file that defines the
-relationship between C++ and Python types:
-
-.. code-block:: xml
- :caption: bindings.xml
-
- <?xml version="1.0"?>
- <typesystem package="Universe">
- <primitive-type name="bool"/>
- <primitive-type name="std::string"/>
- <object-type name="Icecream">
- <modify-function signature="clone()">
- <modify-argument index="0">
- <define-ownership owner="c++"/>
- </modify-argument>
- </modify-function>
- </object-type>
- <value-type name="Truck">
- <modify-function signature="addIcecreamFlavor(Icecream*)">
- <modify-argument index="1">
- <define-ownership owner="c++"/>
- </modify-argument>
- </modify-function>
- </value-type>
- </typesystem>
-
-One important thing to notice here is that we declare :code:`"bool"` and
-:code:`"std::string"` as primitive types. These types are used by some of the
-C++ methods as parameters or return types, so Shiboken must know about them.
-Then, Shiboken can generate relevant conversion code between C++ and Python, although
-most C++ primitive types are handled by Shiboken without additional code.
-
-Next, we declare the two aforementioned classes. One of them as an
-“object-type” and the other as a “value-type”. The main difference is that
-object-types are passed around in generated code as pointers, whereas
-value-types are copied (value semantics).
-
-By specifying the names of these classes in the typesystem file, Shiboken
-automatically tries to generate bindings for all methods of those
-classes. You need not mention all the methods manually in the XML file, unless
-you want to modify them.
-
-Object ownership rules
-=======================
-
-Shiboken doesn't know if Python or C++ are responsible for freeing the C++ objects that were
-allocated in the Python code, and assuming this might lead to errors.
-There can be cases where Python should release the C++ memory when the reference count of the
-Python object becomes zero, but it should never delete the underlying C++ object just from
-assuming that it will not be deleted by underlying C++ library, or if it's maybe parented to
-another object (like QWidgets).
-
-In our case, the :code:`clone()` method is only called inside the C++ library,
-and we assume that the C++ code takes care of releasing the cloned object.
-
-As for :code:`addIcecreamFlavor()`, we know that a :code:`Truck` owns the
-:code:`Icecream` object, and will remove it once the :code:`Truck` is
-destroyed. That's why the ownership is set to “c++” in the typesystem file,
-so that the C++ objects are not deleted when the corresponding Python names
-go out of scope.
-
-Build
-=====
-
-To build the :code:`Universe` custom library and then generate bindings for it,
-use the :file:`CMakeLists.txt` file provided with the example. Later, you can reuse
-the file for your own libraries with minor changes.
-
-Now, run the :command:`"cmake ."` command from the prompt to configure the
-project and build with the toolchain of your choice; we recommend the
-‘(N)Makefiles’ generator.
-
-As a result, you end up with two shared libraries:
-:file:`libuniverse.(so/dylib/dll)` and :file:`Universe.(so/pyd)`. The former is
-the custom C++ library, and the latter is the Python module to import in your
-Python script.
-
-For more details about these platforms, see the :file:`README.md` file.
-
-Use the Python module
-=====================
-
-The following script uses the :code:`Universe` module, derives a few types from
-:code:`Icecream`, implements virtual methods, instantiates objects, and much more:
-
-.. code-block:: python
- :caption: main.py
-
- from Universe import Icecream, Truck
-
- class VanillaChocolateIcecream(Icecream):
- def __init__(self, flavor=""):
- super(VanillaChocolateIcecream, self).__init__(flavor)
-
- def clone(self):
- return VanillaChocolateIcecream(self.getFlavor())
-
- def getFlavor(self):
- return "vanilla sprinked with chocolate"
-
- class VanillaChocolateCherryIcecream(VanillaChocolateIcecream):
- def __init__(self, flavor=""):
- super(VanillaChocolateIcecream, self).__init__(flavor)
-
- def clone(self):
- return VanillaChocolateCherryIcecream(self.getFlavor())
-
- def getFlavor(self):
- base_flavor = super(VanillaChocolateCherryIcecream, self).getFlavor()
- return base_flavor + " and a cherry"
-
- if __name__ == '__main__':
- leave_on_destruction = True
- truck = Truck(leave_on_destruction)
-
- flavors = ["vanilla", "chocolate", "strawberry"]
- for f in flavors:
- icecream = Icecream(f)
- truck.addIcecreamFlavor(icecream)
-
- truck.addIcecreamFlavor(VanillaChocolateIcecream())
- truck.addIcecreamFlavor(VanillaChocolateCherryIcecream())
-
- truck.arrive()
- truck.printAvailableFlavors()
- result = truck.deliver()
-
- if result:
- print("All the kids got some icecream!")
- else:
- print("Aww, someone didn't get the flavor they wanted...")
-
- if not result:
- special_truck = Truck(truck)
- del truck
-
- print("")
- special_truck.setArrivalMessage("A new SPECIAL icecream truck has arrived!\n")
- special_truck.arrive()
- special_truck.addIcecreamFlavor(Icecream("SPECIAL *magical* icecream"))
- special_truck.printAvailableFlavors()
- special_truck.deliver()
- print("Now everyone got the flavor they wanted!")
- special_truck.leave()
-
-After importing the classes from the :code:`Universe` module, it derives two
-types from :code:`Icecream` for different “flavors”. It then creates a
-:code:`truck` to deliver some regular flavored Icecreams and two special ones.
-
-If the delivery fails, a new :code:`truck` is created with the old flavors
-copied over, and a new *magical* flavor that will surely satisfy all customers.
-
-Try running it to see if the ice creams are delivered.
-
-.. note::
- You can find the sources for this example under
- :file:`<PYTHON_ENV_ROOT>/site-packages/lib/PySide6/examples/samplebinding`.
-
-Refer to the following topics for detailed information about using Shiboken:
- * :doc:`Type System Variables <../typesystem_variables>`
- * :doc:`User Defined Type Conversion <../typesystem_converters>`
- * :doc:`Object ownership <../typesystem_ownership>`
- * :doc:`Considerations and Frequently Asked Questions <../considerations>`
diff --git a/sources/shiboken6/doc/gettingstarted.rst b/sources/shiboken6/doc/gettingstarted.rst
index e59886587..cad49086d 100644
--- a/sources/shiboken6/doc/gettingstarted.rst
+++ b/sources/shiboken6/doc/gettingstarted.rst
@@ -11,11 +11,11 @@ need to continue if you already have a built PySide.
General Requirements
^^^^^^^^^^^^^^^^^^^^
- * **Python**: 3.7+
- * **Qt:** 6.0+
- * **libclang:** The libclang library, recommended: version 10 for 6.0+.
- Prebuilt versions of it can be `downloaded here`_.
- * **CMake:** 3.1+ is needed.
+* **Python**: 3.7+
+* **Qt:** 6.0+
+* **libclang:** The libclang library, recommended: version 10 for 6.0+.
+ Prebuilt versions of it can be `downloaded here`_.
+* **CMake:** 3.1+ is needed.
.. _downloaded here: https://download.qt.io/development_releases/prebuilt/libclang/
@@ -40,7 +40,7 @@ The same can be used for the module, changing the value of ``internal-build-type
``shiboken6-module``.
.. warning:: If you are planning to use PySide too, for examples like
- 'scriptableapplication' you need to have build it as well. The main issue is
+ 'scriptableapplication' you need to have build it as well. The main issue is
that your PySide and Shiboken needs to be build using the same dependencies
from Qt and libclang.
diff --git a/sources/shiboken6/doc/images/boostgen.png b/sources/shiboken6/doc/images/boostgen.png
deleted file mode 100644
index ae9d9fc3d..000000000
--- a/sources/shiboken6/doc/images/boostgen.png
+++ /dev/null
Binary files differ
diff --git a/sources/shiboken6/doc/images/converter.png b/sources/shiboken6/doc/images/converter.png
index cd52e2769..3935fdc60 100644
--- a/sources/shiboken6/doc/images/converter.png
+++ b/sources/shiboken6/doc/images/converter.png
Binary files differ
diff --git a/sources/shiboken6/doc/images/converter.svg b/sources/shiboken6/doc/images/converter.svg
index 4305eb720..2df5c88e5 100644
--- a/sources/shiboken6/doc/images/converter.svg
+++ b/sources/shiboken6/doc/images/converter.svg
@@ -1,349 +1,2227 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ width="908.50861"
+ zoomAndPan="magnify"
+ viewBox="0 0 681.38145 434.11857"
+ height="578.82477"
+ preserveAspectRatio="xMidYMid"
+ version="1.0"
+ id="svg5080"
+ sodipodi:docname="converter.svg"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="206.375mm"
- height="100.54167mm"
- viewBox="0 0 206.375 100.54167"
- version="1.1"
- id="svg8"
- inkscape:version="0.92.2 2405546, 2018-03-11"
- sodipodi:docname="converter.svg">
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview5082"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ showgrid="false"
+ inkscape:zoom="0.80648148"
+ inkscape:cx="413.52468"
+ inkscape:cy="205.2124"
+ inkscape:window-width="2552"
+ inkscape:window-height="1432"
+ inkscape:window-x="1924"
+ inkscape:window-y="4"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg5080" />
<defs
- id="defs2">
- <marker
- inkscape:isstock="true"
- style="overflow:visible"
- id="marker1623"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow1Lend">
+ id="defs4108">
+ <g
+ id="g4028" />
+ <clipPath
+ id="24985ca8b2">
+ <path
+ d="m 325.10547,297.75 h 159.75 V 405 h -159.75 z m 0,0"
+ clip-rule="nonzero"
+ id="path4030" />
+ </clipPath>
+ <clipPath
+ id="3cea3902db">
+ <path
+ d="m 382.58984,359.24609 h 18 v 11.25 h -18 z m 0,0"
+ clip-rule="nonzero"
+ id="path4033" />
+ </clipPath>
+ <clipPath
+ id="dfab995897">
+ <path
+ d="m 325.10547,473.32031 h 159.75 v 107.25 h -159.75 z m 0,0"
+ clip-rule="nonzero"
+ id="path4036" />
+ </clipPath>
+ <clipPath
+ id="2d1327caba">
+ <path
+ d="m 411.91016,534.82031 h 18 v 11.25 h -18 z m 0,0"
+ clip-rule="nonzero"
+ id="path4039" />
+ </clipPath>
+ <clipPath
+ id="f03e985e13">
+ <path
+ d="m 113,313.11719 h 113.76172 v 76.5 H 113 Z m 0,0"
+ clip-rule="nonzero"
+ id="path4042" />
+ </clipPath>
+ <clipPath
+ id="c71ef1b2fa">
+ <path
+ d="m 112.76172,313.11719 h 114 v 76.5 h -114 z m 0,0"
+ clip-rule="nonzero"
+ id="path4045" />
+ </clipPath>
+ <clipPath
+ id="3bddcdf684">
+ <path
+ d="m 593.35156,488.69141 h 114 v 76.5 h -114 z m 0,0"
+ clip-rule="nonzero"
+ id="path4048" />
+ </clipPath>
+ <clipPath
+ id="cd19a8dfa8">
+ <path
+ d="m 588,313.11719 h 113.98828 v 76.5 H 588 Z m 0,0"
+ clip-rule="nonzero"
+ id="path4051" />
+ </clipPath>
+ <clipPath
+ id="61b05d6a70">
+ <path
+ d="m 125,427 h 89.71094 v 60 H 125 Z m 0,0"
+ clip-rule="nonzero"
+ id="path4054" />
+ </clipPath>
+ <clipPath
+ id="ea42d02648">
+ <path
+ d="m 124.77344,426.82031 h 89.9375 v 60.35547 h -89.9375 z m 0,0"
+ clip-rule="nonzero"
+ id="path4057" />
+ </clipPath>
+ <clipPath
+ id="84bd6662f0">
+ <path
+ d="m 125,497 h 89.71094 v 60 H 125 Z m 0,0"
+ clip-rule="nonzero"
+ id="path4060" />
+ </clipPath>
+ <clipPath
+ id="728d290ff8">
+ <path
+ d="m 124.77344,496.94922 h 89.9375 v 60.35547 h -89.9375 z m 0,0"
+ clip-rule="nonzero"
+ id="path4063" />
+ </clipPath>
+ <clipPath
+ id="00b091b271">
<path
- transform="matrix(-0.8,0,0,-0.8,-10,0)"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
- d="M 0,0 5,-5 -12.5,0 5,5 Z"
- id="path1621"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- inkscape:stockid="Arrow1Lend"
- orient="auto"
- refY="0"
- refX="0"
- id="marker1569"
- style="overflow:visible"
- inkscape:isstock="true"
- inkscape:collect="always">
+ d="m 125,567 h 89.71094 v 60 H 125 Z m 0,0"
+ clip-rule="nonzero"
+ id="path4066" />
+ </clipPath>
+ <clipPath
+ id="be13ebcaaa">
<path
- id="path1567"
- d="M 0,0 5,-5 -12.5,0 5,5 Z"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
- transform="matrix(-0.8,0,0,-0.8,-10,0)"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- inkscape:isstock="true"
- style="overflow:visible"
- id="marker1521"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow1Lend"
- inkscape:collect="always">
+ d="m 124.77344,566.78125 h 89.9375 v 60.35156 h -89.9375 z m 0,0"
+ clip-rule="nonzero"
+ id="path4069" />
+ </clipPath>
+ <clipPath
+ id="12ef88673f">
<path
- transform="matrix(-0.8,0,0,-0.8,-10,0)"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
- d="M 0,0 5,-5 -12.5,0 5,5 Z"
- id="path1519"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- inkscape:stockid="Arrow1Lend"
- orient="auto"
- refY="0"
- refX="0"
- id="marker1479"
- style="overflow:visible"
- inkscape:isstock="true"
- inkscape:collect="always">
+ d="m 242.54687,336.47266 h 66 v 30 h -66 z m 0,0"
+ clip-rule="nonzero"
+ id="path4072" />
+ </clipPath>
+ <clipPath
+ id="4425bd08fe">
<path
- id="path1477"
- d="M 0,0 5,-5 -12.5,0 5,5 Z"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
- transform="matrix(-0.8,0,0,-0.8,-10,0)"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- inkscape:isstock="true"
- style="overflow:visible"
- id="marker1443"
- refX="0"
- refY="0"
- orient="auto"
- inkscape:stockid="Arrow1Lend"
- inkscape:collect="always">
+ d="m 503.92969,336.47266 h 66 v 30 h -66 z m 0,0"
+ clip-rule="nonzero"
+ id="path4075" />
+ </clipPath>
+ <clipPath
+ id="29f410bb45">
<path
- transform="matrix(-0.8,0,0,-0.8,-10,0)"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
- d="M 0,0 5,-5 -12.5,0 5,5 Z"
- id="path1441"
- inkscape:connector-curvature="0" />
- </marker>
- <marker
- inkscape:stockid="Arrow1Lend"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Lend"
- style="overflow:visible"
- inkscape:isstock="true"
- inkscape:collect="always">
+ d="m 503.92969,512.04297 h 66 v 30 h -66 z m 0,0"
+ clip-rule="nonzero"
+ id="path4078" />
+ </clipPath>
+ <clipPath
+ id="8612924f50">
<path
- id="path1154"
- d="M 0,0 5,-5 -12.5,0 5,5 Z"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
- transform="matrix(-0.8,0,0,-0.8,-10,0)"
- inkscape:connector-curvature="0" />
- </marker>
+ d="m 236.54297,511.73437 h 66 v 30 h -66 z m 0,0"
+ clip-rule="nonzero"
+ id="path4081" />
+ </clipPath>
+ <clipPath
+ id="9616827f5c">
+ <path
+ d="m 238,451 h 62 v 38 h -62 z m 0,0"
+ clip-rule="nonzero"
+ id="path4084" />
+ </clipPath>
+ <clipPath
+ id="6d6215aef9">
+ <path
+ d="m 246.00781,440.04297 59.81641,27.89453 -12.67969,27.1875 -59.81641,-27.89063 z m 0,0"
+ clip-rule="nonzero"
+ id="path4087" />
+ </clipPath>
+ <clipPath
+ id="506e24dd3d">
+ <path
+ d="m 246.00781,440.04297 59.81641,27.89453 -12.67969,27.1875 -59.81641,-27.89063 z m 0,0"
+ clip-rule="nonzero"
+ id="path4090" />
+ </clipPath>
+ <clipPath
+ id="85c10bb5f0">
+ <path
+ d="m 246.00781,440.04297 59.81641,27.89453 -12.67969,27.1875 -59.81641,-27.89063 z m 0,0"
+ clip-rule="nonzero"
+ id="path4093" />
+ </clipPath>
+ <clipPath
+ id="96382ab88a">
+ <path
+ d="m 238,565 h 62 v 38 h -62 z m 0,0"
+ clip-rule="nonzero"
+ id="path4096" />
+ </clipPath>
+ <clipPath
+ id="8ee2f579d3">
+ <path
+ d="m 233.26953,586.86719 59.81641,-27.89063 12.67578,27.1875 -59.81641,27.89453 z m 0,0"
+ clip-rule="nonzero"
+ id="path4099" />
+ </clipPath>
+ <clipPath
+ id="c24345751d">
+ <path
+ d="m 246.00781,614.18359 59.81641,-27.89062 -12.67969,-27.19141 -59.81641,27.89453 z m 0,0"
+ clip-rule="nonzero"
+ id="path4102" />
+ </clipPath>
+ <clipPath
+ id="6c1dc82097">
+ <path
+ d="m 246.00781,614.18359 59.81641,-27.89062 -12.67969,-27.19141 -59.81641,27.89453 z m 0,0"
+ clip-rule="nonzero"
+ id="path4105" />
+ </clipPath>
</defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="0.35"
- inkscape:cx="382.16184"
- inkscape:cy="-28.417621"
- inkscape:document-units="mm"
- inkscape:current-layer="layer1"
- showgrid="true"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0"
- inkscape:window-width="1002"
- inkscape:window-height="1042"
- inkscape:window-x="10"
- inkscape:window-y="28"
- inkscape:window-maximized="0">
- <inkscape:grid
- type="xygrid"
- id="grid971"
- originx="-58.208333"
- originy="-68.791657" />
- </sodipodi:namedview>
- <metadata
- id="metadata5">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(-58.208333,-127.66667)">
+ <rect
+ x="-1.4210855e-14"
+ width="681.38147"
+ fill="#ffffff"
+ y="-2.8421709e-14"
+ height="434.11859"
+ fill-opacity="1"
+ id="rect4110"
+ style="stroke-width:0.559543" />
+ <path
+ fill="#41cb51"
+ d="M 256.85164,139.32657 V 62.127352 c 0,-0.9336 0.0898,-1.85938 0.27344,-2.77344 0.17968,-0.91406 0.44922,-1.80078 0.80468,-2.66406 0.35547,-0.86328 0.79297,-1.67969 1.3086,-2.45703 0.51562,-0.77344 1.10547,-1.49219 1.76172,-2.15235 0.65625,-0.66015 1.37109,-1.25 2.14453,-1.76562 0.77344,-0.51953 1.58984,-0.95703 2.44922,-1.3125 0.85937,-0.35938 1.74218,-0.62891 2.65625,-0.8086 0.91015,-0.18359 1.83203,-0.27343 2.76172,-0.27343 h 129.44531 c 0.92969,0 1.85156,0.0898 2.76172,0.27343 0.91406,0.17969 1.79687,0.44922 2.65625,0.8086 0.85937,0.35547 1.67578,0.79297 2.44922,1.3125 0.77343,0.51562 1.48828,1.10547 2.14453,1.76562 0.66015,0.66016 1.24609,1.37891 1.76172,2.15235 0.51562,0.77734 0.95312,1.59375 1.30859,2.45703 0.35547,0.86328 0.625,1.75 0.80469,2.66406 0.18359,0.91406 0.27343,1.83984 0.27343,2.77344 v 77.199218 c 0,0.93359 -0.0898,1.85937 -0.27343,2.77343 -0.17969,0.91407 -0.44922,1.80469 -0.80469,2.66407 -0.35547,0.86328 -0.79297,1.68359 -1.30859,2.45703 -0.51563,0.77734 -1.10157,1.49218 -1.76172,2.15234 -0.65625,0.66016 -1.3711,1.25 -2.14453,1.76953 -0.77344,0.51563 -1.58985,0.95313 -2.44922,1.3125 -0.85938,0.35547 -1.74219,0.625 -2.65625,0.8086 -0.91016,0.17968 -1.83203,0.27343 -2.76172,0.27343 H 271.0118 c -0.92969,0 -1.85157,-0.0937 -2.76172,-0.27343 -0.91407,-0.1836 -1.79688,-0.45313 -2.65625,-0.8086 -0.85938,-0.35937 -1.67578,-0.79687 -2.44922,-1.3125 -0.77344,-0.51953 -1.48828,-1.10937 -2.14453,-1.76953 -0.65625,-0.66016 -1.2461,-1.375 -1.76172,-2.15234 -0.51563,-0.77344 -0.95313,-1.59375 -1.3086,-2.45703 -0.35546,-0.85938 -0.625,-1.75 -0.80468,-2.66407 -0.1836,-0.91406 -0.27344,-1.83984 -0.27344,-2.77343 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4116" />
+ <g
+ clip-path="url(#24985ca8b2)"
+ id="g4120"
+ transform="translate(-69.242111,-250.64609)">
+ <path
+ fill="#41cb51"
+ d="m 484.67187,312.77344 v 77.19922 c 0,0.98437 -0.0937,1.96093 -0.28515,2.92968 -0.19531,0.96875 -0.47656,1.90625 -0.85547,2.82032 -0.375,0.91015 -0.83594,1.77734 -1.38281,2.59765 -0.54688,0.82031 -1.16797,1.57813 -1.86328,2.27735 -0.69532,0.69531 -1.44922,1.32031 -2.26954,1.86718 -0.8164,0.55078 -1.67968,1.01172 -2.58984,1.39063 -0.90625,0.375 -1.84375,0.66015 -2.80859,0.85547 -0.96485,0.1914 -1.9375,0.28906 -2.92188,0.28906 h -129.4375 c -0.98437,0 -1.95703,-0.0977 -2.92187,-0.28906 -0.96485,-0.19532 -1.90235,-0.48047 -2.8086,-0.85547 -0.91015,-0.37891 -1.77343,-0.83985 -2.58984,-1.39063 -0.82031,-0.54687 -1.57422,-1.17187 -2.26953,-1.86718 -0.69531,-0.69922 -1.31641,-1.45704 -1.86328,-2.27735 -0.54688,-0.82031 -1.00782,-1.6875 -1.38282,-2.59765 -0.3789,-0.91407 -0.66015,-1.85157 -0.85546,-2.82032 -0.19141,-0.96875 -0.28516,-1.94531 -0.28516,-2.92968 v -77.19922 c 0,-0.98828 0.0937,-1.96485 0.28516,-2.9336 0.19531,-0.96484 0.47656,-1.90625 0.85546,-2.8164 0.375,-0.91407 0.83594,-1.77735 1.38282,-2.59766 0.54687,-0.82422 1.16797,-1.58203 1.86328,-2.27734 0.69531,-0.69922 1.44922,-1.32422 2.26953,-1.8711 0.81641,-0.54687 1.67969,-1.01172 2.58984,-1.38672 0.90625,-0.3789 1.84375,-0.66406 2.8086,-0.85546 0.96484,-0.19532 1.9375,-0.28907 2.92187,-0.28907 h 129.44141 c 0.98437,0 1.95703,0.0977 2.92187,0.28907 0.96485,0.1914 1.90235,0.47656 2.8086,0.85546 0.91015,0.37891 1.76953,0.83985 2.58984,1.38672 0.81641,0.55078 1.57422,1.17188 2.26953,1.8711 0.69531,0.69531 1.3125,1.45703 1.85938,2.27734 0.54687,0.82031 1.00781,1.68359 1.38281,2.59766 0.37891,0.91015 0.66406,1.85156 0.85547,2.8164 0.1914,0.96875 0.28515,1.94532 0.28515,2.9336 z m -157.76171,77.19922 c 0,0.8789 0.082,1.75 0.2539,2.61328 0.17188,0.85937 0.42578,1.69922 0.76172,2.51172 0.33594,0.8125 0.74609,1.58203 1.23047,2.3164 0.48828,0.73047 1.04297,1.40625 1.66016,2.02735 0.62109,0.62109 1.29687,1.17968 2.02343,1.66796 0.73047,0.48829 1.5,0.89844 2.3086,1.23438 0.80859,0.33984 1.64453,0.59375 2.5039,0.76562 0.85938,0.17188 1.72657,0.25391 2.60547,0.25391 h 129.44141 c 0.875,0 1.74609,-0.082 2.60547,-0.25391 0.85937,-0.17187 1.69531,-0.42578 2.5039,-0.76562 0.8086,-0.33594 1.57813,-0.74609 2.3086,-1.23438 0.72656,-0.48828 1.40234,-1.04687 2.01953,-1.66796 0.62109,-0.6211 1.17578,-1.29688 1.66015,-2.02735 0.48829,-0.73437 0.89844,-1.5039 1.23438,-2.3164 0.33594,-0.8125 0.58984,-1.65235 0.76172,-2.51172 0.16797,-0.86328 0.2539,-1.73438 0.2539,-2.61328 v -77.19922 c 0,-0.87891 -0.0859,-1.75 -0.2539,-2.61328 -0.17188,-0.86329 -0.42578,-1.69922 -0.76172,-2.51172 -0.33594,-0.8125 -0.74609,-1.58594 -1.23438,-2.31641 -0.48437,-0.73047 -1.03906,-1.41016 -1.66015,-2.03125 -0.61719,-0.62109 -1.29297,-1.17578 -2.01953,-1.66406 -0.73047,-0.48828 -1.5,-0.90235 -2.3086,-1.23828 -0.80859,-0.33594 -1.64453,-0.58985 -2.5039,-0.76172 -0.85938,-0.17188 -1.73047,-0.25781 -2.60547,-0.25781 H 340.25781 c -0.8789,0 -1.74609,0.0859 -2.60547,0.25781 -0.85937,0.17187 -1.69531,0.42578 -2.5039,0.76172 -0.8086,0.33593 -1.57813,0.75 -2.3086,1.23828 -0.72656,0.48828 -1.40234,1.04297 -2.02343,1.66406 -0.61719,0.62109 -1.17188,1.30078 -1.66016,2.03125 -0.48438,0.73047 -0.89453,1.50391 -1.23047,2.31641 -0.33594,0.8125 -0.58984,1.64843 -0.76172,2.51172 -0.17187,0.86328 -0.2539,1.73437 -0.2539,2.61328 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4118" />
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4128"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(334.04375,371.84414)"
+ id="g4126">
+ <g
+ id="g4124">
+ <path
+ d="M 11.0625,-0.234375 C 9.550781,0.0664062 8.191406,0.21875 6.984375,0.21875 5.785156,0.21875 4.816406,0.0546875 4.078125,-0.265625 3.335938,-0.597656 2.765625,-1.113281 2.359375,-1.8125 1.960938,-2.507812 1.6875,-3.304688 1.53125,-4.203125 c -0.15625,-0.90625 -0.234375,-2.03125 -0.234375,-3.375 0,-1.351563 0.078125,-2.488281 0.234375,-3.40625 0.15625,-0.914063 0.429688,-1.722656 0.828125,-2.421875 0.40625,-0.707031 0.972656,-1.222656 1.703125,-1.546875 0.738281,-0.320313 1.691406,-0.484375 2.859375,-0.484375 1.175781,0 2.554687,0.164062 4.140625,0.484375 L 11,-13.53125 c -1.480469,-0.257812 -2.796875,-0.390625 -3.953125,-0.390625 -1.617187,0 -2.683594,0.480469 -3.203125,1.4375 -0.523438,0.960937 -0.78125,2.601563 -0.78125,4.921875 0,1.15625 0.046875,2.089844 0.140625,2.796875 0.09375,0.699219 0.28125,1.328125 0.5625,1.890625 0.28125,0.5625 0.6875,0.96875 1.21875,1.21875 0.53125,0.242188 1.3125,0.359375 2.34375,0.359375 1.039063,0 2.265625,-0.128906 3.671875,-0.390625 z m 0,0"
+ id="path4122" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4136"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(346.00962,371.84414)"
+ id="g4134">
+ <g
+ id="g4132">
+ <path
+ d="M 1.203125,-4.78125 V -6.265625 H 5.375 V -10.5625 h 1.53125 v 4.296875 h 4.203125 V -4.78125 H 6.90625 V -0.4375 H 5.375 v -4.34375 z m 0,0"
+ id="path4130" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4144"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(358.32742,371.84414)"
+ id="g4142">
+ <g
+ id="g4140">
+ <path
+ d="M 1.203125,-4.78125 V -6.265625 H 5.375 V -10.5625 h 1.53125 v 4.296875 h 4.203125 V -4.78125 H 6.90625 V -0.4375 H 5.375 v -4.34375 z m 0,0"
+ id="path4138" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4150"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(370.6414,371.84414)"
+ id="g4148">
+ <g
+ id="g4146" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4156"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(375.48053,371.84414)"
+ id="g4154">
+ <g
+ id="g4152" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4162"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(380.31967,371.84414)"
+ id="g4160">
+ <g
+ id="g4158" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4168"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(385.1588,371.84414)"
+ id="g4166">
+ <g
+ id="g4164" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4174"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(389.99794,371.84414)"
+ id="g4172">
+ <g
+ id="g4170" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4180"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(394.83707,371.84414)"
+ id="g4178">
+ <g
+ id="g4176" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4186"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(399.6762,371.84414)"
+ id="g4184">
+ <g
+ id="g4182" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4192"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(404.51534,371.84414)"
+ id="g4190">
+ <g
+ id="g4188" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4200"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(409.34843,371.84414)"
+ id="g4198">
+ <g
+ id="g4196">
+ <path
+ d="M 7.4375,-5.125 H 3.5625 V 0 H 1.875 v -15.21875 h 5.5625 c 1.65625,0 2.878906,0.40625 3.671875,1.21875 0.789063,0.804688 1.1875,2.03125 1.1875,3.6875 0,3.460938 -1.621094,5.1875 -4.859375,5.1875 z m -3.875,-1.5 h 3.84375 c 2.101562,0 3.15625,-1.226562 3.15625,-3.6875 0,-1.175781 -0.25,-2.039062 -0.75,-2.59375 -0.5,-0.550781 -1.304688,-0.828125 -2.40625,-0.828125 H 3.5625 Z m 0,0"
+ id="path4194" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4208"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(422.39211,371.84414)"
+ id="g4206">
+ <g
+ id="g4204">
+ <path
+ d="m 0.546875,-11 h 1.65625 l 2.75,9.5625 h 0.71875 L 8.453125,-11 H 10.09375 L 5.515625,4.890625 H 3.875 L 5.296875,0 h -1.625 z m 0,0"
+ id="path4202" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4216"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(433.01622,371.84414)"
+ id="g4214">
+ <g
+ id="g4212">
+ <path
+ d="m 7.28125,-9.5625 h -3.5 v 5.25 c 0,1.261719 0.085938,2.089844 0.265625,2.484375 0.1875,0.398437 0.628906,0.59375 1.328125,0.59375 l 1.953125,-0.125 L 7.4375,0 c -0.980469,0.15625 -1.730469,0.234375 -2.25,0.234375 -1.148438,0 -1.9375,-0.2734375 -2.375,-0.828125 -0.4375,-0.5625 -0.65625,-1.625 -0.65625,-3.1875 V -9.5625 H 0.59375 V -11 h 1.5625 v -3.359375 h 1.625 V -11 h 3.5 z m 0,0"
+ id="path4210" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4224"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(440.73684,371.84414)"
+ id="g4222">
+ <g
+ id="g4220">
+ <path
+ d="m 3.234375,0 h -1.65625 v -15.796875 h 1.65625 v 5.40625 c 1.175781,-0.550781 2.304687,-0.828125 3.390625,-0.828125 1.46875,0 2.453125,0.398438 2.953125,1.1875 0.507813,0.792969 0.765625,2.199219 0.765625,4.21875 V 0 H 8.6875 v -5.765625 c 0,-1.519531 -0.152344,-2.5625 -0.453125,-3.125 C 7.929688,-9.460938 7.300781,-9.75 6.34375,-9.75 c -0.929688,0 -1.824219,0.171875 -2.6875,0.515625 L 3.234375,-9.09375 Z m 0,0"
+ id="path4218" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4232"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(452.54873,371.84414)"
+ id="g4230">
+ <g
+ id="g4228">
+ <path
+ d="m 1.09375,-5.515625 c 0,-2.007813 0.359375,-3.460937 1.078125,-4.359375 0.71875,-0.894531 1.929687,-1.34375 3.640625,-1.34375 1.707031,0 2.914062,0.449219 3.625,1.34375 0.71875,0.898438 1.078125,2.351562 1.078125,4.359375 0,2 -0.339844,3.460937 -1.015625,4.375 -0.679688,0.90625 -1.914062,1.359375 -3.703125,1.359375 -1.78125,0 -3.011719,-0.453125 -3.6875,-1.359375 -0.679687,-0.914063 -1.015625,-2.375 -1.015625,-4.375 z m 1.703125,-0.03125 c 0,1.605469 0.191406,2.730469 0.578125,3.375 0.382812,0.648437 1.195312,0.96875 2.4375,0.96875 1.238281,0 2.050781,-0.316406 2.4375,-0.953125 0.382812,-0.644531 0.578125,-1.773438 0.578125,-3.390625 0,-1.613281 -0.214844,-2.722656 -0.640625,-3.328125 -0.429688,-0.613281 -1.21875,-0.921875 -2.375,-0.921875 -1.148438,0 -1.9375,0.308594 -2.375,0.921875 -0.429688,0.605469 -0.640625,1.714844 -0.640625,3.328125 z m 0,0"
+ id="path4226" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4240"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(464.16266,371.84414)"
+ id="g4238">
+ <g
+ id="g4236">
+ <path
+ d="M 3.234375,0 H 1.578125 V -11 H 3.21875 v 0.765625 c 1.1875,-0.65625 2.320312,-0.984375 3.40625,-0.984375 1.46875,0 2.453125,0.398438 2.953125,1.1875 0.507813,0.792969 0.765625,2.199219 0.765625,4.21875 V 0 h -1.625 v -5.765625 c 0,-1.519531 -0.152344,-2.5625 -0.453125,-3.125 C 7.960938,-9.460938 7.320312,-9.75 6.34375,-9.75 c -0.480469,0 -0.980469,0.074219 -1.5,0.21875 -0.523438,0.136719 -0.917969,0.273438 -1.1875,0.40625 l -0.421875,0.1875 z m 0,0"
+ id="path4234" />
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#3cea3902db)"
+ id="g4244"
+ transform="translate(-69.242111,-250.64609)">
+ <path
+ fill="#ffffff"
+ d="m 400.46484,364.71094 -7.35156,-5.36328 c -0.11328,-0.082 -0.25,-0.0899 -0.375,-0.0274 -0.0586,0.0312 -0.1875,0.125 -0.1875,0.32031 v 2.9375 c 0,0.17969 -0.14453,0.32813 -0.32031,0.32813 h -9.28516 c -0.17578,0 -0.32031,0.14844 -0.32031,0.33203 v 3.29688 c 0,0.18359 0.14453,0.33203 0.32031,0.33203 h 9.28516 c 0.17578,0 0.32031,0.14843 0.32031,0.32812 v 2.9375 c 0,0.19531 0.12891,0.28906 0.1875,0.32031 0.125,0.0664 0.26172,0.0547 0.375,-0.0273 l 7.35156,-5.36328 c 0.0781,-0.0586 0.0859,-0.14063 0.0859,-0.17578 0,-0.0352 -0.008,-0.11719 -0.0859,-0.17578"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4242" />
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4252"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(358.72771,337.8254)"
+ id="g4250">
+ <g
+ id="g4248">
+ <path
+ d="m 6.796875,0.234375 c -2.199219,0 -3.695313,-0.601563 -4.484375,-1.8125 -0.78125,-1.21875 -1.171875,-3.21875 -1.171875,-6 0,-2.789063 0.394531,-4.773437 1.1875,-5.953125 0.789063,-1.1875 2.28125,-1.78125 4.46875,-1.78125 1.300781,0 2.738281,0.183594 4.3125,0.546875 l -0.09375,1.984375 c -1.3125,-0.238281 -2.632813,-0.359375 -3.953125,-0.359375 -1.324219,0 -2.21875,0.398437 -2.6875,1.1875 -0.46875,0.78125 -0.703125,2.257813 -0.703125,4.421875 0,2.15625 0.222656,3.632812 0.671875,4.421875 0.457031,0.78125 1.347656,1.171875 2.671875,1.171875 1.320313,0 2.65625,-0.109375 4,-0.328125 l 0.07813,2.03125 c -1.511719,0.3125 -2.945312,0.46875 -4.296875,0.46875 z m 0,0"
+ id="path4246" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4260"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(370.69358,337.8254)"
+ id="g4258">
+ <g
+ id="g4256">
+ <path
+ d="m 2.046875,-9.796875 c 0.757813,-0.957031 2.019531,-1.4375 3.78125,-1.4375 1.757813,0 3.015625,0.480469 3.765625,1.4375 0.757812,0.949219 1.140625,2.375 1.140625,4.28125 0,1.90625 -0.371094,3.34375 -1.109375,4.3125 -0.730469,0.960937 -1.996094,1.4375 -3.796875,1.4375 -1.804687,0 -3.074219,-0.476563 -3.8125,-1.4375 -0.730469,-0.96875 -1.09375,-2.40625 -1.09375,-4.3125 0,-1.90625 0.375,-3.332031 1.125,-4.28125 z M 3.84375,-2.65625 c 0.34375,0.585938 1.003906,0.875 1.984375,0.875 0.976563,0 1.632813,-0.289062 1.96875,-0.875 C 8.140625,-3.25 8.3125,-4.210938 8.3125,-5.546875 c 0,-1.332031 -0.183594,-2.273437 -0.546875,-2.828125 -0.355469,-0.5625 -1,-0.84375 -1.9375,-0.84375 -0.9375,0 -1.589844,0.28125 -1.953125,0.84375 -0.355469,0.554688 -0.53125,1.496094 -0.53125,2.828125 0,1.335937 0.164062,2.296875 0.5,2.890625 z m 0,0"
+ id="path4254" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4268"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(382.3515,337.8254)"
+ id="g4266">
+ <g
+ id="g4264">
+ <path
+ d="M 3.84375,0 H 1.453125 v -11 h 2.375 v 0.6875 c 1.070313,-0.613281 2.082031,-0.921875 3.03125,-0.921875 1.46875,0 2.46875,0.417969 3,1.25 0.539063,0.824219 0.8125,2.1875 0.8125,4.09375 V 0 h -2.375 v -5.828125 c 0,-1.1875 -0.132813,-2.03125 -0.390625,-2.53125 -0.25,-0.5 -0.773438,-0.75 -1.5625,-0.75 -0.75,0 -1.46875,0.148437 -2.15625,0.4375 L 3.84375,-8.53125 Z m 0,0"
+ id="path4262" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4276"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(394.36136,337.8254)"
+ id="g4274">
+ <g
+ id="g4272">
+ <path
+ d="m 0.421875,-11 h 2.5 L 5.03125,-2.046875 H 5.734375 L 7.9375,-11 h 2.453125 L 7.53125,0 H 3.25 Z m 0,0"
+ id="path4270" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4284"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(405.16143,337.8254)"
+ id="g4282">
+ <g
+ id="g4280">
+ <path
+ d="m 9.28125,-1.984375 0.625,-0.0625 0.03125,1.78125 c -1.667969,0.3320312 -3.148438,0.5 -4.4375,0.5 -1.625,0 -2.796875,-0.441406 -3.515625,-1.328125 -0.710937,-0.894531 -1.0625,-2.328125 -1.0625,-4.296875 0,-3.894531 1.59375,-5.84375 4.78125,-5.84375 3.070313,0 4.609375,1.679687 4.609375,5.03125 l -0.15625,1.71875 h -6.8125 c 0.00781,0.90625 0.207031,1.574219 0.59375,2 0.382812,0.429687 1.097656,0.640625 2.140625,0.640625 1.039063,0 2.109375,-0.046875 3.203125,-0.140625 z M 7.96875,-6.34375 c 0,-1.082031 -0.171875,-1.835938 -0.515625,-2.265625 -0.34375,-0.4375 -0.929687,-0.65625 -1.75,-0.65625 -0.824219,0 -1.421875,0.230469 -1.796875,0.6875 -0.375,0.460937 -0.570312,1.203125 -0.578125,2.234375 z m 0,0"
+ id="path4278" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4292"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(416.33545,337.8254)"
+ id="g4290">
+ <g
+ id="g4288">
+ <path
+ d="m 1.453125,0 v -11 h 2.375 v 1.3125 c 1.25,-0.800781 2.492187,-1.316406 3.734375,-1.546875 v 2.390625 c -1.261719,0.25 -2.339844,0.574219 -3.234375,0.96875 L 3.84375,-7.671875 V 0 Z m 0,0"
+ id="path4286" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4300"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(424.27603,337.8254)"
+ id="g4298">
+ <g
+ id="g4296">
+ <path
+ d="M 7.375,-8.953125 H 4.328125 v 4.84375 c 0,0.898437 0.066406,1.492187 0.203125,1.78125 0.132812,0.292969 0.472656,0.4375 1.015625,0.4375 l 1.796875,-0.0625 0.109375,1.90625 c -0.980469,0.1875 -1.726563,0.28125 -2.234375,0.28125 -1.25,0 -2.109375,-0.28125 -2.578125,-0.84375 -0.460937,-0.570313 -0.6875,-1.648437 -0.6875,-3.234375 V -8.953125 H 0.546875 V -11 h 1.40625 v -3.1875 h 2.375 V -11 H 7.375 Z m 0,0"
+ id="path4294" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4308"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(432.15063,337.8254)"
+ id="g4306">
+ <g
+ id="g4304">
+ <path
+ d="m 9.28125,-1.984375 0.625,-0.0625 0.03125,1.78125 c -1.667969,0.3320312 -3.148438,0.5 -4.4375,0.5 -1.625,0 -2.796875,-0.441406 -3.515625,-1.328125 -0.710937,-0.894531 -1.0625,-2.328125 -1.0625,-4.296875 0,-3.894531 1.59375,-5.84375 4.78125,-5.84375 3.070313,0 4.609375,1.679687 4.609375,5.03125 l -0.15625,1.71875 h -6.8125 c 0.00781,0.90625 0.207031,1.574219 0.59375,2 0.382812,0.429687 1.097656,0.640625 2.140625,0.640625 1.039063,0 2.109375,-0.046875 3.203125,-0.140625 z M 7.96875,-6.34375 c 0,-1.082031 -0.171875,-1.835938 -0.515625,-2.265625 -0.34375,-0.4375 -0.929687,-0.65625 -1.75,-0.65625 -0.824219,0 -1.421875,0.230469 -1.796875,0.6875 -0.375,0.460937 -0.570312,1.203125 -0.578125,2.234375 z m 0,0"
+ id="path4302" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4316"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(443.32464,337.8254)"
+ id="g4314">
+ <g
+ id="g4312">
+ <path
+ d="m 1.453125,0 v -11 h 2.375 v 1.3125 c 1.25,-0.800781 2.492187,-1.316406 3.734375,-1.546875 v 2.390625 c -1.261719,0.25 -2.339844,0.574219 -3.234375,0.96875 L 3.84375,-7.671875 V 0 Z m 0,0"
+ id="path4310" />
+ </g>
+ </g>
+ </g>
+ <path
+ fill="#41cb51"
+ d="m 256.85164,314.90078 v -77.19921 c 0,-0.9336 0.0898,-1.85938 0.27344,-2.77344 0.17968,-0.91406 0.44922,-1.80469 0.80468,-2.66406 0.35547,-0.86329 0.79297,-1.6836 1.3086,-2.45704 0.51562,-0.77734 1.10547,-1.49218 1.76172,-2.15234 0.65625,-0.66016 1.37109,-1.25 2.14453,-1.76953 0.77344,-0.51563 1.58984,-0.95313 2.44922,-1.3125 0.85937,-0.35547 1.74218,-0.625 2.65625,-0.80859 0.91015,-0.17969 1.83203,-0.27344 2.76172,-0.27344 h 129.44531 c 0.92969,0 1.85156,0.0937 2.76172,0.27344 0.91406,0.18359 1.79687,0.45312 2.65625,0.80859 0.85937,0.35937 1.67578,0.79687 2.44922,1.3125 0.77343,0.51953 1.48828,1.10937 2.14453,1.76953 0.66015,0.66016 1.24609,1.375 1.76172,2.15234 0.51562,0.77344 0.95312,1.59375 1.30859,2.45704 0.35547,0.85937 0.625,1.75 0.80469,2.66406 0.18359,0.91406 0.27343,1.83984 0.27343,2.77344 v 77.19921 c 0,0.9336 -0.0898,1.85938 -0.27343,2.77344 -0.17969,0.91406 -0.44922,1.80078 -0.80469,2.66406 -0.35547,0.86329 -0.79297,1.67969 -1.30859,2.45704 -0.51563,0.77343 -1.10157,1.49218 -1.76172,2.15234 -0.65625,0.66016 -1.3711,1.25 -2.14453,1.76562 -0.77344,0.51954 -1.58985,0.95704 -2.44922,1.3125 -0.85938,0.35938 -1.74219,0.62891 -2.65625,0.8086 -0.91016,0.18359 -1.83203,0.27344 -2.76172,0.27344 H 271.0118 c -0.92969,0 -1.85157,-0.0899 -2.76172,-0.27344 -0.91407,-0.17969 -1.79688,-0.44922 -2.65625,-0.8086 -0.85938,-0.35546 -1.67578,-0.79296 -2.44922,-1.3125 -0.77344,-0.51562 -1.48828,-1.10546 -2.14453,-1.76562 -0.65625,-0.66016 -1.2461,-1.37891 -1.76172,-2.15234 -0.51563,-0.77735 -0.95313,-1.59375 -1.3086,-2.45704 -0.35546,-0.86328 -0.625,-1.75 -0.80468,-2.66406 -0.1836,-0.91406 -0.27344,-1.83984 -0.27344,-2.77344 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4318" />
+ <g
+ clip-path="url(#dfab995897)"
+ id="g4322"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:#17a81a;fill-opacity:1;stroke:none;stroke-width:0.82824755;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 127,132.95834 0.0687,26.45833 h 63.43127 l 5.29167,-5.29167 v -26.45833 h -63.5 z"
- id="path3715-5-6-7-9-8-7"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccc" />
+ fill="#41cb51"
+ d="m 484.67187,488.34766 v 77.19531 c 0,0.98828 -0.0937,1.96484 -0.28515,2.93359 -0.19531,0.96875 -0.47656,1.90625 -0.85547,2.82031 -0.375,0.91016 -0.83594,1.77735 -1.38281,2.59766 -0.54688,0.82031 -1.16797,1.57813 -1.86328,2.27734 -0.69532,0.69532 -1.44922,1.32032 -2.26954,1.86719 -0.8164,0.54688 -1.67968,1.01172 -2.58984,1.39063 -0.90625,0.375 -1.84375,0.66015 -2.80859,0.85156 -0.96485,0.19531 -1.9375,0.28906 -2.92188,0.28906 h -129.4375 c -0.98437,0 -1.95703,-0.0937 -2.92187,-0.28906 -0.96485,-0.19141 -1.90235,-0.47656 -2.8086,-0.85156 -0.91015,-0.37891 -1.77343,-0.84375 -2.58984,-1.39063 -0.82031,-0.54687 -1.57422,-1.17187 -2.26953,-1.86719 -0.69531,-0.69921 -1.31641,-1.45703 -1.86328,-2.27734 -0.54688,-0.82031 -1.00782,-1.6875 -1.38282,-2.59766 -0.3789,-0.91406 -0.66015,-1.85156 -0.85546,-2.82031 -0.19141,-0.96875 -0.28516,-1.94531 -0.28516,-2.93359 v -77.19531 c 0,-0.98829 0.0937,-1.96485 0.28516,-2.9336 0.19531,-0.96875 0.47656,-1.90625 0.85546,-2.82031 0.375,-0.91016 0.83594,-1.77734 1.38282,-2.59766 0.54687,-0.82031 1.16797,-1.57812 1.86328,-2.27734 0.69531,-0.69531 1.44922,-1.32031 2.26953,-1.86719 0.81641,-0.54687 1.67969,-1.01172 2.58984,-1.39062 0.90625,-0.375 1.84375,-0.66016 2.8086,-0.85547 0.96484,-0.19141 1.9375,-0.28516 2.92187,-0.28516 h 129.44141 c 0.98437,0 1.95703,0.0937 2.92187,0.28906 0.96485,0.19141 1.90235,0.47657 2.8086,0.85547 0.91015,0.375 1.76953,0.83985 2.58984,1.38672 0.81641,0.55078 1.57422,1.17188 2.26953,1.8711 0.69531,0.69531 1.3125,1.45703 1.85938,2.27734 0.54687,0.82031 1.00781,1.68359 1.38281,2.59766 0.37891,0.91015 0.66406,1.84765 0.85547,2.8164 0.1914,0.96875 0.28515,1.94531 0.28515,2.9336 z m -157.76171,77.19531 c 0,0.88281 0.082,1.7539 0.2539,2.61328 0.17188,0.86328 0.42578,1.70312 0.76172,2.51562 0.33594,0.8125 0.74609,1.58204 1.23047,2.3125 0.48828,0.73438 1.04297,1.41016 1.66016,2.03125 0.62109,0.6211 1.29687,1.17579 2.02343,1.66407 0.73047,0.48828 1.5,0.90234 2.3086,1.23828 0.80859,0.33594 1.64453,0.58984 2.5039,0.76172 0.85938,0.17187 1.72657,0.25781 2.60547,0.25781 h 129.44141 c 0.875,0 1.74609,-0.0859 2.60547,-0.25781 0.85937,-0.17188 1.69531,-0.42578 2.5039,-0.76172 0.8086,-0.33594 1.57813,-0.75 2.3086,-1.23828 0.72656,-0.48828 1.40234,-1.04297 2.01953,-1.66407 0.62109,-0.62109 1.17578,-1.29687 1.66015,-2.03125 0.48829,-0.73046 0.89844,-1.5 1.23438,-2.3125 0.33594,-0.8125 0.58984,-1.65234 0.76172,-2.51562 0.16797,-0.85938 0.2539,-1.73047 0.2539,-2.61328 v -77.19531 c 0,-0.88282 -0.0859,-1.75391 -0.2539,-2.61329 -0.17188,-0.86328 -0.42578,-1.70312 -0.76172,-2.51562 -0.33594,-0.8125 -0.74609,-1.58203 -1.23438,-2.3125 -0.48437,-0.73438 -1.03906,-1.41016 -1.66015,-2.03125 -0.61719,-0.62109 -1.29297,-1.17578 -2.01953,-1.66406 -0.73047,-0.48828 -1.5,-0.90235 -2.3086,-1.23828 -0.80859,-0.33594 -1.64453,-0.58985 -2.5039,-0.76172 -0.85938,-0.17188 -1.73047,-0.25782 -2.60547,-0.25782 H 340.25781 c -0.8789,0 -1.74609,0.0859 -2.60547,0.25782 -0.85937,0.17187 -1.69531,0.42578 -2.5039,0.76172 -0.8086,0.33593 -1.57813,0.75 -2.3086,1.23828 -0.72656,0.48828 -1.40234,1.04297 -2.02343,1.66406 -0.61719,0.62109 -1.17188,1.29687 -1.66016,2.03125 -0.48438,0.73047 -0.89453,1.5 -1.23047,2.3125 -0.33594,0.8125 -0.58984,1.65234 -0.76172,2.51562 -0.17187,0.85938 -0.2539,1.73047 -0.2539,2.61329 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4320" />
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4330"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(336.46249,547.41743)"
+ id="g4328">
+ <g
+ id="g4326">
+ <path
+ d="M 7.4375,-5.125 H 3.5625 V 0 H 1.875 v -15.21875 h 5.5625 c 1.65625,0 2.878906,0.40625 3.671875,1.21875 0.789063,0.804688 1.1875,2.03125 1.1875,3.6875 0,3.460938 -1.621094,5.1875 -4.859375,5.1875 z m -3.875,-1.5 h 3.84375 c 2.101562,0 3.15625,-1.226562 3.15625,-3.6875 0,-1.175781 -0.25,-2.039062 -0.75,-2.59375 -0.5,-0.550781 -1.304688,-0.828125 -2.40625,-0.828125 H 3.5625 Z m 0,0"
+ id="path4324" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4338"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(349.50617,547.41743)"
+ id="g4336">
+ <g
+ id="g4334">
+ <path
+ d="m 0.546875,-11 h 1.65625 l 2.75,9.5625 h 0.71875 L 8.453125,-11 H 10.09375 L 5.515625,4.890625 H 3.875 L 5.296875,0 h -1.625 z m 0,0"
+ id="path4332" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4346"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(360.13028,547.41743)"
+ id="g4344">
+ <g
+ id="g4342">
+ <path
+ d="m 7.28125,-9.5625 h -3.5 v 5.25 c 0,1.261719 0.085938,2.089844 0.265625,2.484375 0.1875,0.398437 0.628906,0.59375 1.328125,0.59375 l 1.953125,-0.125 L 7.4375,0 c -0.980469,0.15625 -1.730469,0.234375 -2.25,0.234375 -1.148438,0 -1.9375,-0.2734375 -2.375,-0.828125 -0.4375,-0.5625 -0.65625,-1.625 -0.65625,-3.1875 V -9.5625 H 0.59375 V -11 h 1.5625 v -3.359375 h 1.625 V -11 h 3.5 z m 0,0"
+ id="path4340" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4354"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(367.8509,547.41743)"
+ id="g4352">
+ <g
+ id="g4350">
+ <path
+ d="m 3.234375,0 h -1.65625 v -15.796875 h 1.65625 v 5.40625 c 1.175781,-0.550781 2.304687,-0.828125 3.390625,-0.828125 1.46875,0 2.453125,0.398438 2.953125,1.1875 0.507813,0.792969 0.765625,2.199219 0.765625,4.21875 V 0 H 8.6875 v -5.765625 c 0,-1.519531 -0.152344,-2.5625 -0.453125,-3.125 C 7.929688,-9.460938 7.300781,-9.75 6.34375,-9.75 c -0.929688,0 -1.824219,0.171875 -2.6875,0.515625 L 3.234375,-9.09375 Z m 0,0"
+ id="path4348" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4362"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(379.6628,547.41743)"
+ id="g4360">
+ <g
+ id="g4358">
+ <path
+ d="m 1.09375,-5.515625 c 0,-2.007813 0.359375,-3.460937 1.078125,-4.359375 0.71875,-0.894531 1.929687,-1.34375 3.640625,-1.34375 1.707031,0 2.914062,0.449219 3.625,1.34375 0.71875,0.898438 1.078125,2.351562 1.078125,4.359375 0,2 -0.339844,3.460937 -1.015625,4.375 -0.679688,0.90625 -1.914062,1.359375 -3.703125,1.359375 -1.78125,0 -3.011719,-0.453125 -3.6875,-1.359375 -0.679687,-0.914063 -1.015625,-2.375 -1.015625,-4.375 z m 1.703125,-0.03125 c 0,1.605469 0.191406,2.730469 0.578125,3.375 0.382812,0.648437 1.195312,0.96875 2.4375,0.96875 1.238281,0 2.050781,-0.316406 2.4375,-0.953125 0.382812,-0.644531 0.578125,-1.773438 0.578125,-3.390625 0,-1.613281 -0.214844,-2.722656 -0.640625,-3.328125 -0.429688,-0.613281 -1.21875,-0.921875 -2.375,-0.921875 -1.148438,0 -1.9375,0.308594 -2.375,0.921875 -0.429688,0.605469 -0.640625,1.714844 -0.640625,3.328125 z m 0,0"
+ id="path4356" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4370"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(391.27673,547.41743)"
+ id="g4368">
+ <g
+ id="g4366">
+ <path
+ d="M 3.234375,0 H 1.578125 V -11 H 3.21875 v 0.765625 c 1.1875,-0.65625 2.320312,-0.984375 3.40625,-0.984375 1.46875,0 2.453125,0.398438 2.953125,1.1875 0.507813,0.792969 0.765625,2.199219 0.765625,4.21875 V 0 h -1.625 v -5.765625 c 0,-1.519531 -0.152344,-2.5625 -0.453125,-3.125 C 7.960938,-9.460938 7.320312,-9.75 6.34375,-9.75 c -0.480469,0 -0.980469,0.074219 -1.5,0.21875 -0.523438,0.136719 -0.917969,0.273438 -1.1875,0.40625 l -0.421875,0.1875 z m 0,0"
+ id="path4364" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4376"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(403.08359,547.41743)"
+ id="g4374">
+ <g
+ id="g4372" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4382"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(407.92272,547.41743)"
+ id="g4380">
+ <g
+ id="g4378" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4388"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(412.76185,547.41743)"
+ id="g4386">
+ <g
+ id="g4384" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4394"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(417.60099,547.41743)"
+ id="g4392">
+ <g
+ id="g4390" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4400"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(422.44012,547.41743)"
+ id="g4398">
+ <g
+ id="g4396" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4406"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(427.27926,547.41743)"
+ id="g4404">
+ <g
+ id="g4402" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4412"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(432.11839,547.41743)"
+ id="g4410">
+ <g
+ id="g4408" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4420"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(436.95077,547.41743)"
+ id="g4418">
+ <g
+ id="g4416">
+ <path
+ d="M 11.0625,-0.234375 C 9.550781,0.0664062 8.191406,0.21875 6.984375,0.21875 5.785156,0.21875 4.816406,0.0546875 4.078125,-0.265625 3.335938,-0.597656 2.765625,-1.113281 2.359375,-1.8125 1.960938,-2.507812 1.6875,-3.304688 1.53125,-4.203125 c -0.15625,-0.90625 -0.234375,-2.03125 -0.234375,-3.375 0,-1.351563 0.078125,-2.488281 0.234375,-3.40625 0.15625,-0.914063 0.429688,-1.722656 0.828125,-2.421875 0.40625,-0.707031 0.972656,-1.222656 1.703125,-1.546875 0.738281,-0.320313 1.691406,-0.484375 2.859375,-0.484375 1.175781,0 2.554687,0.164062 4.140625,0.484375 L 11,-13.53125 c -1.480469,-0.257812 -2.796875,-0.390625 -3.953125,-0.390625 -1.617187,0 -2.683594,0.480469 -3.203125,1.4375 -0.523438,0.960937 -0.78125,2.601563 -0.78125,4.921875 0,1.15625 0.046875,2.089844 0.140625,2.796875 0.09375,0.699219 0.28125,1.328125 0.5625,1.890625 0.28125,0.5625 0.6875,0.96875 1.21875,1.21875 0.53125,0.242188 1.3125,0.359375 2.34375,0.359375 1.039063,0 2.265625,-0.128906 3.671875,-0.390625 z m 0,0"
+ id="path4414" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4428"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(448.91665,547.41743)"
+ id="g4426">
+ <g
+ id="g4424">
+ <path
+ d="M 1.203125,-4.78125 V -6.265625 H 5.375 V -10.5625 h 1.53125 v 4.296875 h 4.203125 V -4.78125 H 6.90625 V -0.4375 H 5.375 v -4.34375 z m 0,0"
+ id="path4422" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4436"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(461.23445,547.41743)"
+ id="g4434">
+ <g
+ id="g4432">
+ <path
+ d="M 1.203125,-4.78125 V -6.265625 H 5.375 V -10.5625 h 1.53125 v 4.296875 h 4.203125 V -4.78125 H 6.90625 V -0.4375 H 5.375 v -4.34375 z m 0,0"
+ id="path4430" />
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#2d1327caba)"
+ id="g4440"
+ transform="translate(-69.242111,-250.64609)">
+ <path
+ fill="#ffffff"
+ d="m 429.78516,540.28516 -7.35157,-5.36329 c -0.10937,-0.082 -0.25,-0.0937 -0.375,-0.0273 -0.0547,0.0312 -0.1875,0.125 -0.1875,0.32031 v 2.9375 c 0,0.17969 -0.14453,0.32813 -0.32031,0.32813 h -9.28516 c -0.17578,0 -0.32031,0.14844 -0.32031,0.32812 v 3.30078 c 0,0.1836 0.14453,0.33204 0.32031,0.33204 h 9.28516 c 0.17578,0 0.32031,0.14453 0.32031,0.32812 v 2.9375 c 0,0.19531 0.13282,0.28906 0.1875,0.32031 0.125,0.0625 0.26563,0.0547 0.375,-0.0273 l 7.35157,-5.36328 c 0.0781,-0.0586 0.0898,-0.14453 0.0898,-0.17578 0,-0.0352 -0.0117,-0.11719 -0.0898,-0.17578"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4438" />
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4448"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(358.72771,513.39871)"
+ id="g4446">
+ <g
+ id="g4444">
+ <path
+ d="m 6.796875,0.234375 c -2.199219,0 -3.695313,-0.601563 -4.484375,-1.8125 -0.78125,-1.21875 -1.171875,-3.21875 -1.171875,-6 0,-2.789063 0.394531,-4.773437 1.1875,-5.953125 0.789063,-1.1875 2.28125,-1.78125 4.46875,-1.78125 1.300781,0 2.738281,0.183594 4.3125,0.546875 l -0.09375,1.984375 c -1.3125,-0.238281 -2.632813,-0.359375 -3.953125,-0.359375 -1.324219,0 -2.21875,0.398437 -2.6875,1.1875 -0.46875,0.78125 -0.703125,2.257813 -0.703125,4.421875 0,2.15625 0.222656,3.632812 0.671875,4.421875 0.457031,0.78125 1.347656,1.171875 2.671875,1.171875 1.320313,0 2.65625,-0.109375 4,-0.328125 l 0.07813,2.03125 c -1.511719,0.3125 -2.945312,0.46875 -4.296875,0.46875 z m 0,0"
+ id="path4442" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4456"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(370.69358,513.39871)"
+ id="g4454">
+ <g
+ id="g4452">
+ <path
+ d="m 2.046875,-9.796875 c 0.757813,-0.957031 2.019531,-1.4375 3.78125,-1.4375 1.757813,0 3.015625,0.480469 3.765625,1.4375 0.757812,0.949219 1.140625,2.375 1.140625,4.28125 0,1.90625 -0.371094,3.34375 -1.109375,4.3125 -0.730469,0.960937 -1.996094,1.4375 -3.796875,1.4375 -1.804687,0 -3.074219,-0.476563 -3.8125,-1.4375 -0.730469,-0.96875 -1.09375,-2.40625 -1.09375,-4.3125 0,-1.90625 0.375,-3.332031 1.125,-4.28125 z M 3.84375,-2.65625 c 0.34375,0.585938 1.003906,0.875 1.984375,0.875 0.976563,0 1.632813,-0.289062 1.96875,-0.875 C 8.140625,-3.25 8.3125,-4.210938 8.3125,-5.546875 c 0,-1.332031 -0.183594,-2.273437 -0.546875,-2.828125 -0.355469,-0.5625 -1,-0.84375 -1.9375,-0.84375 -0.9375,0 -1.589844,0.28125 -1.953125,0.84375 -0.355469,0.554688 -0.53125,1.496094 -0.53125,2.828125 0,1.335937 0.164062,2.296875 0.5,2.890625 z m 0,0"
+ id="path4450" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4464"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(382.3515,513.39871)"
+ id="g4462">
+ <g
+ id="g4460">
+ <path
+ d="M 3.84375,0 H 1.453125 v -11 h 2.375 v 0.6875 c 1.070313,-0.613281 2.082031,-0.921875 3.03125,-0.921875 1.46875,0 2.46875,0.417969 3,1.25 0.539063,0.824219 0.8125,2.1875 0.8125,4.09375 V 0 h -2.375 v -5.828125 c 0,-1.1875 -0.132813,-2.03125 -0.390625,-2.53125 -0.25,-0.5 -0.773438,-0.75 -1.5625,-0.75 -0.75,0 -1.46875,0.148437 -2.15625,0.4375 L 3.84375,-8.53125 Z m 0,0"
+ id="path4458" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4472"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(394.36136,513.39871)"
+ id="g4470">
+ <g
+ id="g4468">
+ <path
+ d="m 0.421875,-11 h 2.5 L 5.03125,-2.046875 H 5.734375 L 7.9375,-11 h 2.453125 L 7.53125,0 H 3.25 Z m 0,0"
+ id="path4466" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4480"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(405.16143,513.39871)"
+ id="g4478">
+ <g
+ id="g4476">
+ <path
+ d="m 9.28125,-1.984375 0.625,-0.0625 0.03125,1.78125 c -1.667969,0.3320312 -3.148438,0.5 -4.4375,0.5 -1.625,0 -2.796875,-0.441406 -3.515625,-1.328125 -0.710937,-0.894531 -1.0625,-2.328125 -1.0625,-4.296875 0,-3.894531 1.59375,-5.84375 4.78125,-5.84375 3.070313,0 4.609375,1.679687 4.609375,5.03125 l -0.15625,1.71875 h -6.8125 c 0.00781,0.90625 0.207031,1.574219 0.59375,2 0.382812,0.429687 1.097656,0.640625 2.140625,0.640625 1.039063,0 2.109375,-0.046875 3.203125,-0.140625 z M 7.96875,-6.34375 c 0,-1.082031 -0.171875,-1.835938 -0.515625,-2.265625 -0.34375,-0.4375 -0.929687,-0.65625 -1.75,-0.65625 -0.824219,0 -1.421875,0.230469 -1.796875,0.6875 -0.375,0.460937 -0.570312,1.203125 -0.578125,2.234375 z m 0,0"
+ id="path4474" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4488"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(416.33545,513.39871)"
+ id="g4486">
+ <g
+ id="g4484">
+ <path
+ d="m 1.453125,0 v -11 h 2.375 v 1.3125 c 1.25,-0.800781 2.492187,-1.316406 3.734375,-1.546875 v 2.390625 c -1.261719,0.25 -2.339844,0.574219 -3.234375,0.96875 L 3.84375,-7.671875 V 0 Z m 0,0"
+ id="path4482" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4496"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(424.27603,513.39871)"
+ id="g4494">
+ <g
+ id="g4492">
+ <path
+ d="M 7.375,-8.953125 H 4.328125 v 4.84375 c 0,0.898437 0.066406,1.492187 0.203125,1.78125 0.132812,0.292969 0.472656,0.4375 1.015625,0.4375 l 1.796875,-0.0625 0.109375,1.90625 c -0.980469,0.1875 -1.726563,0.28125 -2.234375,0.28125 -1.25,0 -2.109375,-0.28125 -2.578125,-0.84375 -0.460937,-0.570313 -0.6875,-1.648437 -0.6875,-3.234375 V -8.953125 H 0.546875 V -11 h 1.40625 v -3.1875 h 2.375 V -11 H 7.375 Z m 0,0"
+ id="path4490" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4504"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(432.15063,513.39871)"
+ id="g4502">
+ <g
+ id="g4500">
+ <path
+ d="m 9.28125,-1.984375 0.625,-0.0625 0.03125,1.78125 c -1.667969,0.3320312 -3.148438,0.5 -4.4375,0.5 -1.625,0 -2.796875,-0.441406 -3.515625,-1.328125 -0.710937,-0.894531 -1.0625,-2.328125 -1.0625,-4.296875 0,-3.894531 1.59375,-5.84375 4.78125,-5.84375 3.070313,0 4.609375,1.679687 4.609375,5.03125 l -0.15625,1.71875 h -6.8125 c 0.00781,0.90625 0.207031,1.574219 0.59375,2 0.382812,0.429687 1.097656,0.640625 2.140625,0.640625 1.039063,0 2.109375,-0.046875 3.203125,-0.140625 z M 7.96875,-6.34375 c 0,-1.082031 -0.171875,-1.835938 -0.515625,-2.265625 -0.34375,-0.4375 -0.929687,-0.65625 -1.75,-0.65625 -0.824219,0 -1.421875,0.230469 -1.796875,0.6875 -0.375,0.460937 -0.570312,1.203125 -0.578125,2.234375 z m 0,0"
+ id="path4498" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4512"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(443.32464,513.39871)"
+ id="g4510">
+ <g
+ id="g4508">
+ <path
+ d="m 1.453125,0 v -11 h 2.375 v 1.3125 c 1.25,-0.800781 2.492187,-1.316406 3.734375,-1.546875 v 2.390625 c -1.261719,0.25 -2.339844,0.574219 -3.234375,0.96875 L 3.84375,-7.671875 V 0 Z m 0,0"
+ id="path4506" />
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#f03e985e13)"
+ id="g4516"
+ transform="translate(-69.242111,-250.64609)">
+ <path
+ fill="#09102b"
+ d="m 113.46875,378.90234 v -55.07031 c 0,-0.66406 0.0625,-1.32422 0.19141,-1.97656 0.13281,-0.65235 0.32422,-1.28516 0.57812,-1.89844 0.25391,-0.61719 0.5625,-1.19922 0.9336,-1.75391 0.36718,-0.55468 0.78515,-1.0664 1.2539,-1.53515 0.46875,-0.46875 0.98047,-0.89063 1.53125,-1.26172 0.55469,-0.36719 1.13672,-0.67969 1.75,-0.93359 0.60938,-0.25782 1.24219,-0.44922 1.89453,-0.57813 0.64844,-0.12891 1.3086,-0.19531 1.96875,-0.19531 h 92.375 c 0.66016,0 1.32031,0.0664 1.96875,0.19531 0.65235,0.12891 1.28516,0.32031 1.89453,0.57813 0.61328,0.2539 1.19532,0.5664 1.75,0.93359 0.55078,0.37109 1.0625,0.79297 1.53125,1.26172 0.46875,0.46875 0.88672,0.98047 1.25391,1.53515 0.37109,0.55469 0.67969,1.13672 0.93359,1.75391 0.25391,0.61328 0.44532,1.24609 0.57813,1.89844 0.1289,0.65234 0.1914,1.3125 0.1914,1.97656 v 55.07031 c 0,0.66407 -0.0625,1.32422 -0.1914,1.97657 -0.13281,0.65234 -0.32422,1.28515 -0.57813,1.89843 -0.2539,0.61719 -0.5625,1.19922 -0.93359,1.75391 -0.36719,0.55469 -0.78516,1.06641 -1.25391,1.53516 -0.46875,0.46875 -0.98047,0.89062 -1.53125,1.26171 -0.55468,0.36719 -1.13672,0.67969 -1.75,0.9336 -0.60937,0.25781 -1.24218,0.44922 -1.89453,0.57812 -0.64844,0.12891 -1.30859,0.19532 -1.96875,0.19532 h -92.375 c -0.66015,0 -1.32031,-0.0664 -1.96875,-0.19532 -0.65234,-0.1289 -1.28515,-0.32031 -1.89453,-0.57812 -0.61328,-0.25391 -1.19531,-0.56641 -1.75,-0.9336 -0.55078,-0.37109 -1.0625,-0.79296 -1.53125,-1.26171 -0.46875,-0.46875 -0.88672,-0.98047 -1.2539,-1.53516 -0.3711,-0.55469 -0.67969,-1.13672 -0.9336,-1.75391 -0.2539,-0.61328 -0.44531,-1.24609 -0.57812,-1.89843 -0.12891,-0.65235 -0.19141,-1.3125 -0.19141,-1.97657 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4514" />
+ </g>
+ <g
+ clip-path="url(#c71ef1b2fa)"
+ id="g4520"
+ transform="translate(-69.242111,-250.64609)">
+ <path
+ fill="#09102b"
+ d="m 226.62891,323.83203 v 55.06641 c 0,0.70312 -0.0703,1.40234 -0.20704,2.08984 -0.13671,0.69141 -0.33984,1.36328 -0.60546,2.01172 -0.26954,0.65234 -0.59766,1.26953 -0.98829,1.85156 -0.39062,0.58594 -0.83203,1.12891 -1.32812,1.625 -0.49609,0.5 -1.03906,0.94141 -1.62109,1.33594 -0.58204,0.39062 -1.19922,0.71875 -1.84766,0.98828 -0.64844,0.26953 -1.31641,0.47266 -2.00391,0.60938 -0.6875,0.13671 -1.38281,0.20703 -2.08593,0.20703 h -92.36719 c -0.70313,0 -1.39844,-0.0703 -2.08594,-0.20703 -0.6875,-0.13672 -1.35547,-0.33985 -2.0039,-0.60938 -0.64844,-0.26953 -1.26563,-0.59766 -1.84766,-0.98828 -0.58203,-0.39453 -1.125,-0.83594 -1.62109,-1.33594 -0.4961,-0.49609 -0.9375,-1.03906 -1.32813,-1.625 -0.39062,-0.58203 -0.71875,-1.19922 -0.98828,-1.85156 -0.26563,-0.64844 -0.46875,-1.32031 -0.60547,-2.01172 -0.13672,-0.6875 -0.20703,-1.38672 -0.20703,-2.08984 v -55.06641 c 0,-0.70312 0.0703,-1.39844 0.20703,-2.08984 0.13672,-0.69141 0.33984,-1.35938 0.60547,-2.01172 0.26953,-0.64844 0.59766,-1.26563 0.98828,-1.85156 0.39063,-0.58594 0.83203,-1.125 1.32813,-1.625 0.49609,-0.4961 1.03906,-0.94141 1.62109,-1.33204 0.58203,-0.39062 1.19922,-0.72265 1.84766,-0.99218 0.64843,-0.26953 1.3164,-0.47266 2.0039,-0.60938 0.6875,-0.13672 1.38281,-0.20703 2.08594,-0.20703 h 92.37109 c 0.69922,0 1.39453,0.0703 2.08203,0.20703 0.6875,0.13672 1.35547,0.33985 2.00391,0.60938 0.64844,0.26953 1.26562,0.60156 1.84766,0.99218 0.58593,0.39063 1.125,0.83594 1.62109,1.33204 0.49609,0.5 0.9375,1.03906 1.32812,1.625 0.39063,0.58593 0.71875,1.20312 0.98829,1.85156 0.26562,0.65234 0.46875,1.32031 0.60546,2.01172 0.13672,0.6914 0.20704,1.38672 0.20704,2.08984 z m -112.58203,55.06641 c 0,0.6289 0.0625,1.25 0.18359,1.86328 0.125,0.61719 0.30469,1.21484 0.54297,1.79297 0.23828,0.57812 0.53125,1.1289 0.8789,1.65234 0.34766,0.51953 0.74219,1.00391 1.1875,1.44531 0.44141,0.44532 0.92188,0.83985 1.44141,1.19141 0.51953,0.34766 1.07031,0.64062 1.64844,0.88281 0.57812,0.23828 1.17187,0.41797 1.78515,0.54297 0.61329,0.12109 1.23438,0.18359 1.85938,0.18359 h 92.37109 c 0.625,0 1.24219,-0.0625 1.85547,-0.18359 0.61328,-0.125 1.21094,-0.30469 1.78906,-0.54297 0.57813,-0.24219 1.125,-0.53515 1.64453,-0.88281 0.52344,-0.35156 1.00391,-0.74609 1.44532,-1.19141 0.4414,-0.4414 0.83593,-0.92578 1.18359,-1.44531 0.34766,-0.52344 0.64063,-1.07422 0.88281,-1.65234 0.23828,-0.57813 0.41797,-1.17578 0.53907,-1.79297 0.125,-0.61328 0.18359,-1.23438 0.18359,-1.86328 v -55.06641 c 0,-0.625 -0.0586,-1.24609 -0.18359,-1.86328 -0.1211,-0.61328 -0.30079,-1.21094 -0.53907,-1.79297 -0.24218,-0.57812 -0.53515,-1.12891 -0.88281,-1.64844 -0.34766,-0.52343 -0.74219,-1.0039 -1.18359,-1.44922 -0.44141,-0.44531 -0.92188,-0.83984 -1.44532,-1.1875 -0.51953,-0.34765 -1.0664,-0.64453 -1.64453,-0.88281 -0.57812,-0.24219 -1.17578,-0.42187 -1.78906,-0.54297 -0.61328,-0.125 -1.23047,-0.18359 -1.85547,-0.18359 h -92.37109 c -0.625,0 -1.24609,0.0586 -1.85938,0.18359 -0.61328,0.1211 -1.20703,0.30078 -1.78515,0.54297 -0.57813,0.23828 -1.12891,0.53516 -1.64844,0.88281 -0.51953,0.34766 -1,0.74219 -1.44141,1.1875 -0.44531,0.44532 -0.83984,0.92579 -1.1875,1.44922 -0.34765,0.51953 -0.64062,1.07032 -0.8789,1.64844 -0.23828,0.58203 -0.41797,1.17969 -0.54297,1.79297 -0.12109,0.61719 -0.18359,1.23828 -0.18359,1.86328 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4518" />
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4528"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(126.50046,359.41913)"
+ id="g4526">
+ <g
+ id="g4524">
+ <path
+ d="M 11.0625,-0.234375 C 9.550781,0.0664062 8.191406,0.21875 6.984375,0.21875 5.785156,0.21875 4.816406,0.0546875 4.078125,-0.265625 3.335938,-0.597656 2.765625,-1.113281 2.359375,-1.8125 1.960938,-2.507812 1.6875,-3.304688 1.53125,-4.203125 c -0.15625,-0.90625 -0.234375,-2.03125 -0.234375,-3.375 0,-1.351563 0.078125,-2.488281 0.234375,-3.40625 0.15625,-0.914063 0.429688,-1.722656 0.828125,-2.421875 0.40625,-0.707031 0.972656,-1.222656 1.703125,-1.546875 0.738281,-0.320313 1.691406,-0.484375 2.859375,-0.484375 1.175781,0 2.554687,0.164062 4.140625,0.484375 L 11,-13.53125 c -1.480469,-0.257812 -2.796875,-0.390625 -3.953125,-0.390625 -1.617187,0 -2.683594,0.480469 -3.203125,1.4375 -0.523438,0.960937 -0.78125,2.601563 -0.78125,4.921875 0,1.15625 0.046875,2.089844 0.140625,2.796875 0.09375,0.699219 0.28125,1.328125 0.5625,1.890625 0.28125,0.5625 0.6875,0.96875 1.21875,1.21875 0.53125,0.242188 1.3125,0.359375 2.34375,0.359375 1.039063,0 2.265625,-0.128906 3.671875,-0.390625 z m 0,0"
+ id="path4522" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4536"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(138.46633,359.41913)"
+ id="g4534">
+ <g
+ id="g4532">
+ <path
+ d="M 1.203125,-4.78125 V -6.265625 H 5.375 V -10.5625 h 1.53125 v 4.296875 h 4.203125 V -4.78125 H 6.90625 V -0.4375 H 5.375 v -4.34375 z m 0,0"
+ id="path4530" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4544"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(150.78413,359.41913)"
+ id="g4542">
+ <g
+ id="g4540">
+ <path
+ d="M 1.203125,-4.78125 V -6.265625 H 5.375 V -10.5625 h 1.53125 v 4.296875 h 4.203125 V -4.78125 H 6.90625 V -0.4375 H 5.375 v -4.34375 z m 0,0"
+ id="path4538" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4550"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(163.10194,359.41913)"
+ id="g4548">
+ <g
+ id="g4546" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4558"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(167.94108,359.41913)"
+ id="g4556">
+ <g
+ id="g4554">
+ <path
+ d="m 0.28125,-13.703125 v -1.515625 h 11 v 1.515625 H 6.640625 V 0 H 4.96875 v -13.703125 z m 0,0"
+ id="path4552" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4566"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(179.51102,359.41913)"
+ id="g4564">
+ <g
+ id="g4562">
+ <path
+ d="m 0.546875,-11 h 1.65625 l 2.75,9.5625 h 0.71875 L 8.453125,-11 H 10.09375 L 5.515625,4.890625 H 3.875 L 5.296875,0 h -1.625 z m 0,0"
+ id="path4560" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4574"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(190.13512,359.41913)"
+ id="g4572">
+ <g
+ id="g4570">
+ <path
+ d="M 1.578125,4.890625 V -11 H 3.21875 v 0.796875 c 1.113281,-0.675781 2.210938,-1.015625 3.296875,-1.015625 1.394531,0 2.40625,0.445312 3.03125,1.328125 C 10.179688,-9.003906 10.5,-7.539062 10.5,-5.5 c 0,2.042969 -0.375,3.507812 -1.125,4.390625 -0.742188,0.886719 -1.964844,1.328125 -3.671875,1.328125 -0.898437,0 -1.71875,-0.078125 -2.46875,-0.234375 v 4.90625 z M 6.265625,-9.75 c -0.4375,0 -0.914063,0.074219 -1.421875,0.21875 -0.5,0.148438 -0.898438,0.292969 -1.1875,0.4375 l -0.421875,0.234375 v 7.40625 c 1.039063,0.167969 1.832031,0.25 2.375,0.25 1.1875,0 2.019531,-0.335937 2.5,-1.015625 0.476563,-0.675781 0.71875,-1.773438 0.71875,-3.296875 0,-1.53125 -0.21875,-2.617187 -0.65625,-3.265625 C 7.742188,-9.425781 7.109375,-9.75 6.265625,-9.75 Z m 0,0"
+ id="path4568" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4582"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(201.72705,359.41913)"
+ id="g4580">
+ <g
+ id="g4578">
+ <path
+ d="M 9.0625,-1.359375 9.703125,-1.4375 9.75,-0.125 C 8.070312,0.101562 6.640625,0.21875 5.453125,0.21875 c -1.585937,0 -2.710937,-0.457031 -3.375,-1.375 C 1.421875,-2.070312 1.09375,-3.5 1.09375,-5.4375 c 0,-3.851562 1.535156,-5.78125 4.609375,-5.78125 1.476563,0 2.582031,0.417969 3.3125,1.25 0.738281,0.824219 1.109375,2.121094 1.109375,3.890625 L 10.03125,-4.8125 H 2.765625 c 0,1.21875 0.21875,2.121094 0.65625,2.703125 0.445313,0.585937 1.21875,0.875 2.3125,0.875 1.09375,0 2.203125,-0.039063 3.328125,-0.125 z m -0.59375,-4.78125 c 0,-1.34375 -0.21875,-2.289063 -0.65625,-2.84375 -0.429688,-0.5625 -1.132812,-0.84375 -2.109375,-0.84375 -0.96875,0 -1.703125,0.292969 -2.203125,0.875 -0.492188,0.585937 -0.742188,1.523437 -0.75,2.8125 z m 0,0"
+ id="path4576" />
+ </g>
+ </g>
+ </g>
+ <path
+ fill="#09102b"
+ d="m 524.81258,303.82657 v -55.06641 c 0,-0.66406 0.0664,-1.32422 0.19531,-1.97656 0.12891,-0.65235 0.32031,-1.28516 0.57422,-1.90235 0.2539,-0.61328 0.5664,-1.19531 0.93359,-1.75 0.3711,-0.55468 0.78906,-1.0664 1.25781,-1.53515 0.46875,-0.47266 0.98047,-0.89063 1.53125,-1.26172 0.55079,-0.3711 1.13282,-0.67969 1.7461,-0.9375 0.61328,-0.25391 1.24609,-0.44531 1.89453,-0.57422 0.65234,-0.12891 1.30859,-0.19531 1.97266,-0.19531 h 92.37109 c 0.66406,0 1.32031,0.0664 1.97266,0.19531 0.64843,0.12891 1.28125,0.32031 1.89453,0.57422 0.61328,0.25781 1.19531,0.5664 1.74609,0.9375 0.55469,0.37109 1.0625,0.78906 1.53125,1.26172 0.46875,0.46875 0.89063,0.98047 1.25781,1.53515 0.36719,0.55469 0.67969,1.13672 0.9336,1.75 0.2539,0.61719 0.44531,1.25 0.57422,1.90235 0.1289,0.65234 0.19531,1.3125 0.19531,1.97656 v 55.06641 c 0,0.66796 -0.0664,1.32421 -0.19531,1.97656 -0.12891,0.65625 -0.32032,1.28906 -0.57422,1.90234 -0.25391,0.61328 -0.56641,1.19922 -0.9336,1.75391 -0.36718,0.55078 -0.78906,1.0625 -1.25781,1.53515 -0.46875,0.46875 -0.97656,0.89063 -1.53125,1.25782 -0.55078,0.37109 -1.13281,0.68359 -1.74609,0.9375 -0.61328,0.2539 -1.2461,0.44922 -1.89453,0.57812 -0.65235,0.12891 -1.3086,0.19531 -1.97266,0.19531 h -92.37109 c -0.66407,0 -1.32032,-0.0664 -1.97266,-0.19531 -0.64844,-0.1289 -1.28125,-0.32422 -1.89453,-0.57812 -0.61328,-0.25391 -1.19531,-0.56641 -1.7461,-0.9375 -0.55078,-0.36719 -1.0625,-0.78907 -1.53125,-1.25782 -0.46875,-0.47265 -0.88671,-0.98437 -1.25781,-1.53515 -0.36719,-0.55469 -0.67969,-1.14063 -0.93359,-1.75391 -0.25391,-0.61328 -0.44531,-1.24609 -0.57422,-1.90234 -0.12891,-0.65235 -0.19531,-1.3086 -0.19531,-1.97656 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4584" />
+ <g
+ clip-path="url(#3bddcdf684)"
+ id="g4588"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:#3a4055;fill-opacity:1;stroke:none;stroke-width:0.67261654;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 68.791667,132.95834 v 26.45833 H 105.83333 L 111.125,154.125 V 127.66667 H 74.083333 Z"
- id="path3715-5-6-7-9-8-7-6-3"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccc" />
+ fill="#09102b"
+ d="m 707.21875,499.40625 v 55.06641 c 0,0.70312 -0.0703,1.39843 -0.20703,2.08984 -0.13672,0.69141 -0.33985,1.35937 -0.60938,2.01172 -0.26562,0.64844 -0.59765,1.26562 -0.98828,1.85156 -0.38672,0.58594 -0.83203,1.12891 -1.32812,1.625 -0.4961,0.49609 -1.03516,0.94141 -1.61719,1.33203 -0.58594,0.39063 -1.19922,0.72266 -1.84766,0.99219 -0.64843,0.26953 -1.3164,0.47266 -2.00781,0.60937 -0.6875,0.13672 -1.38281,0.20704 -2.08203,0.20704 h -92.36719 c -0.70312,0 -1.39844,-0.0703 -2.08594,-0.20704 -0.6875,-0.13671 -1.35546,-0.33984 -2.0039,-0.60937 -0.64844,-0.26953 -1.26563,-0.60156 -1.84766,-0.99219 -0.58594,-0.39062 -1.125,-0.83594 -1.62109,-1.33203 -0.4961,-0.49609 -0.9375,-1.03906 -1.32813,-1.625 -0.39062,-0.58594 -0.71875,-1.20312 -0.98828,-1.85156 -0.26953,-0.65235 -0.47265,-1.32031 -0.60937,-2.01172 -0.13672,-0.69141 -0.20313,-1.38672 -0.20313,-2.08984 v -55.06641 c 0,-0.70313 0.0664,-1.39844 0.20313,-2.08984 0.13672,-0.69141 0.33984,-1.35938 0.60937,-2.01172 0.26953,-0.64844 0.59766,-1.26953 0.98828,-1.85157 0.39063,-0.58593 0.83203,-1.1289 1.32813,-1.625 0.49609,-0.5 1.03515,-0.9414 1.62109,-1.33203 0.58203,-0.39062 1.19922,-0.72265 1.84766,-0.99218 0.64844,-0.26954 1.3164,-0.47266 2.0039,-0.60938 0.6875,-0.13672 1.38282,-0.20703 2.08594,-0.20703 h 92.36719 c 0.70312,0 1.39844,0.0703 2.08594,0.20703 0.6875,0.13672 1.35547,0.33984 2.0039,0.60938 0.64844,0.26953 1.26563,0.60156 1.84766,0.99218 0.58203,0.39063 1.12109,0.83594 1.61719,1.33203 0.49609,0.4961 0.9414,1.03907 1.33203,1.625 0.38672,0.58594 0.71875,1.20313 0.98437,1.85157 0.26953,0.65234 0.47266,1.32031 0.60938,2.01172 0.13672,0.6914 0.20703,1.38671 0.20703,2.08984 z m -112.58203,55.06641 c 0,0.625 0.0625,1.24609 0.18359,1.86328 0.1211,0.61328 0.30078,1.21093 0.54297,1.79297 0.23828,0.57812 0.53125,1.1289 0.87891,1.65234 0.34765,0.51953 0.74218,1.00391 1.18359,1.44531 0.44531,0.44531 0.92578,0.83985 1.44531,1.1875 0.51953,0.35156 1.06641,0.64453 1.64453,0.88281 0.57813,0.24219 1.17579,0.42188 1.78907,0.54297 0.61328,0.125 1.23047,0.1836 1.85937,0.1836 h 92.36719 c 0.625,0 1.24609,-0.0586 1.85937,-0.1836 0.61329,-0.12109 1.20704,-0.30078 1.78516,-0.54297 0.57813,-0.23828 1.12891,-0.53125 1.64844,-0.88281 0.51953,-0.34765 1,-0.74219 1.44531,-1.1875 0.44141,-0.4414 0.83594,-0.92578 1.18359,-1.44531 0.34766,-0.52344 0.64063,-1.07422 0.87891,-1.65234 0.23828,-0.58204 0.42188,-1.17969 0.54297,-1.79297 0.12109,-0.61719 0.18359,-1.23828 0.18359,-1.86328 v -55.06641 c 0,-0.625 -0.0625,-1.24609 -0.18359,-1.86328 -0.12109,-0.61328 -0.30469,-1.21094 -0.54297,-1.79297 -0.23828,-0.57813 -0.53125,-1.12891 -0.87891,-1.65234 -0.34765,-0.51954 -0.74218,-1.00391 -1.18359,-1.44532 -0.44531,-0.44531 -0.92578,-0.83984 -1.44531,-1.1875 -0.51953,-0.35156 -1.07031,-0.64453 -1.64844,-0.88281 -0.57812,-0.24219 -1.17187,-0.42187 -1.78516,-0.54687 -0.61328,-0.1211 -1.23437,-0.1836 -1.85937,-0.1836 h -92.36719 c -0.6289,0 -1.24609,0.0625 -1.85937,0.1836 -0.61328,0.125 -1.21094,0.30468 -1.78907,0.54687 -0.57812,0.23828 -1.125,0.53125 -1.64453,0.88281 -0.51953,0.34766 -1,0.74219 -1.44531,1.1875 -0.44141,0.44141 -0.83594,0.92578 -1.18359,1.44532 -0.34766,0.52343 -0.64063,1.07421 -0.87891,1.65234 -0.24219,0.58203 -0.42187,1.17969 -0.54297,1.79297 -0.12109,0.61719 -0.18359,1.23828 -0.18359,1.86328 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4586" />
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4596"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(607.08883,534.99247)"
+ id="g4594">
+ <g
+ id="g4592">
+ <path
+ d="M 11.0625,-0.234375 C 9.550781,0.0664062 8.191406,0.21875 6.984375,0.21875 5.785156,0.21875 4.816406,0.0546875 4.078125,-0.265625 3.335938,-0.597656 2.765625,-1.113281 2.359375,-1.8125 1.960938,-2.507812 1.6875,-3.304688 1.53125,-4.203125 c -0.15625,-0.90625 -0.234375,-2.03125 -0.234375,-3.375 0,-1.351563 0.078125,-2.488281 0.234375,-3.40625 0.15625,-0.914063 0.429688,-1.722656 0.828125,-2.421875 0.40625,-0.707031 0.972656,-1.222656 1.703125,-1.546875 0.738281,-0.320313 1.691406,-0.484375 2.859375,-0.484375 1.175781,0 2.554687,0.164062 4.140625,0.484375 L 11,-13.53125 c -1.480469,-0.257812 -2.796875,-0.390625 -3.953125,-0.390625 -1.617187,0 -2.683594,0.480469 -3.203125,1.4375 -0.523438,0.960937 -0.78125,2.601563 -0.78125,4.921875 0,1.15625 0.046875,2.089844 0.140625,2.796875 0.09375,0.699219 0.28125,1.328125 0.5625,1.890625 0.28125,0.5625 0.6875,0.96875 1.21875,1.21875 0.53125,0.242188 1.3125,0.359375 2.34375,0.359375 1.039063,0 2.265625,-0.128906 3.671875,-0.390625 z m 0,0"
+ id="path4590" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4604"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(619.0547,534.99247)"
+ id="g4602">
+ <g
+ id="g4600">
+ <path
+ d="M 1.203125,-4.78125 V -6.265625 H 5.375 V -10.5625 h 1.53125 v 4.296875 h 4.203125 V -4.78125 H 6.90625 V -0.4375 H 5.375 v -4.34375 z m 0,0"
+ id="path4598" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4612"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(631.37251,534.99247)"
+ id="g4610">
+ <g
+ id="g4608">
+ <path
+ d="M 1.203125,-4.78125 V -6.265625 H 5.375 V -10.5625 h 1.53125 v 4.296875 h 4.203125 V -4.78125 H 6.90625 V -0.4375 H 5.375 v -4.34375 z m 0,0"
+ id="path4606" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4618"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(643.69031,534.99247)"
+ id="g4616">
+ <g
+ id="g4614" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4626"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(648.52945,534.99247)"
+ id="g4624">
+ <g
+ id="g4622">
+ <path
+ d="m 0.28125,-13.703125 v -1.515625 h 11 v 1.515625 H 6.640625 V 0 H 4.96875 v -13.703125 z m 0,0"
+ id="path4620" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4634"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(660.09939,534.99247)"
+ id="g4632">
+ <g
+ id="g4630">
+ <path
+ d="m 0.546875,-11 h 1.65625 l 2.75,9.5625 h 0.71875 L 8.453125,-11 H 10.09375 L 5.515625,4.890625 H 3.875 L 5.296875,0 h -1.625 z m 0,0"
+ id="path4628" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4642"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(670.72349,534.99247)"
+ id="g4640">
+ <g
+ id="g4638">
+ <path
+ d="M 1.578125,4.890625 V -11 H 3.21875 v 0.796875 c 1.113281,-0.675781 2.210938,-1.015625 3.296875,-1.015625 1.394531,0 2.40625,0.445312 3.03125,1.328125 C 10.179688,-9.003906 10.5,-7.539062 10.5,-5.5 c 0,2.042969 -0.375,3.507812 -1.125,4.390625 -0.742188,0.886719 -1.964844,1.328125 -3.671875,1.328125 -0.898437,0 -1.71875,-0.078125 -2.46875,-0.234375 v 4.90625 z M 6.265625,-9.75 c -0.4375,0 -0.914063,0.074219 -1.421875,0.21875 -0.5,0.148438 -0.898438,0.292969 -1.1875,0.4375 l -0.421875,0.234375 v 7.40625 c 1.039063,0.167969 1.832031,0.25 2.375,0.25 1.1875,0 2.019531,-0.335937 2.5,-1.015625 0.476563,-0.675781 0.71875,-1.773438 0.71875,-3.296875 0,-1.53125 -0.21875,-2.617187 -0.65625,-3.265625 C 7.742188,-9.425781 7.109375,-9.75 6.265625,-9.75 Z m 0,0"
+ id="path4636" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4650"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(682.31543,534.99247)"
+ id="g4648">
+ <g
+ id="g4646">
+ <path
+ d="M 9.0625,-1.359375 9.703125,-1.4375 9.75,-0.125 C 8.070312,0.101562 6.640625,0.21875 5.453125,0.21875 c -1.585937,0 -2.710937,-0.457031 -3.375,-1.375 C 1.421875,-2.070312 1.09375,-3.5 1.09375,-5.4375 c 0,-3.851562 1.535156,-5.78125 4.609375,-5.78125 1.476563,0 2.582031,0.417969 3.3125,1.25 0.738281,0.824219 1.109375,2.121094 1.109375,3.890625 L 10.03125,-4.8125 H 2.765625 c 0,1.21875 0.21875,2.121094 0.65625,2.703125 0.445313,0.585937 1.21875,0.875 2.3125,0.875 1.09375,0 2.203125,-0.039063 3.328125,-0.125 z m -0.59375,-4.78125 c 0,-1.34375 -0.21875,-2.289063 -0.65625,-2.84375 -0.429688,-0.5625 -1.132812,-0.84375 -2.109375,-0.84375 -0.96875,0 -1.703125,0.292969 -2.203125,0.875 -0.492188,0.585937 -0.742188,1.523437 -0.75,2.8125 z m 0,0"
+ id="path4644" />
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#cd19a8dfa8)"
+ id="g4656"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:#848895;fill-opacity:1;stroke:none;stroke-width:0.52087492;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 58.208333,173.96875 V 185.875 h 48.947917 l 3.96875,-3.96875 V 170 H 62.177083 Z"
- id="path3715-5-6-7-9-8-7-6-56"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccc" />
+ fill="#306998"
+ d="m 588.69141,378.90234 v -55.07031 c 0,-0.66406 0.0664,-1.32422 0.19531,-1.97656 0.1289,-0.65235 0.32031,-1.28516 0.57422,-1.89844 0.2539,-0.61719 0.5664,-1.19922 0.93359,-1.75391 0.37109,-0.55468 0.78906,-1.0664 1.25781,-1.53515 0.46875,-0.46875 0.98047,-0.89063 1.53125,-1.26172 0.55078,-0.36719 1.13282,-0.67969 1.7461,-0.93359 0.61328,-0.25782 1.24609,-0.44922 1.89843,-0.57813 0.64844,-0.12891 1.30469,-0.19531 1.96875,-0.19531 h 92.3711 c 0.66406,0 1.32031,0.0664 1.97265,0.19531 0.65235,0.12891 1.28125,0.32031 1.89454,0.57813 0.61328,0.2539 1.19531,0.5664 1.74609,0.93359 0.55469,0.37109 1.0625,0.79297 1.53125,1.26172 0.46875,0.46875 0.89062,0.98047 1.25781,1.53515 0.36719,0.55469 0.67969,1.13672 0.9336,1.75391 0.2539,0.61328 0.44531,1.24609 0.57421,1.89844 0.12891,0.65234 0.19532,1.3125 0.19532,1.97656 v 55.07031 c 0,0.66407 -0.0664,1.32422 -0.19532,1.97657 -0.1289,0.65234 -0.32031,1.28515 -0.57421,1.89843 -0.25391,0.61719 -0.56641,1.19922 -0.9336,1.75391 -0.36719,0.55469 -0.78906,1.06641 -1.25781,1.53516 -0.46875,0.46875 -0.97656,0.89062 -1.53125,1.26171 -0.55078,0.36719 -1.13281,0.67969 -1.74609,0.9336 -0.61329,0.25781 -1.24219,0.44922 -1.89454,0.57812 -0.65234,0.12891 -1.30859,0.19532 -1.97265,0.19532 h -92.3711 c -0.66406,0 -1.32031,-0.0664 -1.96875,-0.19532 -0.65234,-0.1289 -1.28515,-0.32031 -1.89843,-0.57812 -0.61328,-0.25391 -1.19532,-0.56641 -1.7461,-0.9336 -0.55078,-0.37109 -1.0625,-0.79296 -1.53125,-1.26171 -0.46875,-0.46875 -0.88672,-0.98047 -1.25781,-1.53516 -0.36719,-0.55469 -0.67969,-1.13672 -0.93359,-1.75391 -0.25391,-0.61328 -0.44532,-1.24609 -0.57422,-1.89843 -0.12891,-0.65235 -0.19531,-1.3125 -0.19531,-1.97657 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4652" />
<path
- style="fill:#17a81a;fill-opacity:1;stroke:none;stroke-width:0.82824755;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 127.00003,175.29167 0.0687,26.45833 H 190.5 l 5.29167,-5.29167 V 170 h -63.5 z"
- id="path3715-5-6-7-9-8-7-2"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccc" />
+ fill="#306998"
+ d="m 701.85547,323.83203 v 55.06641 c 0,0.70312 -0.0703,1.40234 -0.20703,2.08984 -0.13672,0.69141 -0.33985,1.36328 -0.60938,2.01172 -0.26562,0.65234 -0.59765,1.26953 -0.98437,1.85156 -0.39063,0.58594 -0.83594,1.12891 -1.33203,1.625 -0.4961,0.5 -1.03516,0.94141 -1.61719,1.33594 -0.58594,0.39062 -1.19922,0.71875 -1.84766,0.98828 -0.64844,0.26953 -1.3164,0.47266 -2.0039,0.60938 -0.69141,0.13671 -1.38672,0.20703 -2.08594,0.20703 h -92.36719 c -0.70312,0 -1.39844,-0.0703 -2.08594,-0.20703 -0.6875,-0.13672 -1.35547,-0.33985 -2.0039,-0.60938 -0.64844,-0.26953 -1.26563,-0.59766 -1.84766,-0.98828 -0.58594,-0.39453 -1.125,-0.83594 -1.62109,-1.33594 -0.4961,-0.49609 -0.9375,-1.03906 -1.32813,-1.625 -0.39062,-0.58203 -0.71875,-1.19922 -0.98828,-1.85156 -0.26953,-0.64844 -0.47266,-1.32031 -0.60937,-2.01172 -0.13672,-0.6875 -0.20313,-1.38672 -0.20313,-2.08984 v -55.06641 c 0,-0.70312 0.0664,-1.39844 0.20313,-2.08984 0.13671,-0.69141 0.33984,-1.35938 0.60937,-2.01172 0.26953,-0.64844 0.59766,-1.26563 0.98828,-1.85156 0.39063,-0.58594 0.83203,-1.125 1.32813,-1.625 0.49609,-0.4961 1.03515,-0.94141 1.62109,-1.33204 0.58203,-0.39062 1.19922,-0.72265 1.84766,-0.99218 0.64843,-0.26953 1.3164,-0.47266 2.0039,-0.60938 0.6875,-0.13672 1.38282,-0.20703 2.08594,-0.20703 h 92.36719 c 0.70312,0 1.39844,0.0703 2.08594,0.20703 0.6875,0.13672 1.35546,0.33985 2.0039,0.60938 0.64844,0.26953 1.26563,0.60156 1.84766,0.99218 0.58203,0.39063 1.125,0.83594 1.62109,1.33204 0.4961,0.5 0.9375,1.03906 1.32813,1.625 0.39062,0.58593 0.71875,1.20312 0.98437,1.85156 0.26953,0.65234 0.47266,1.32031 0.60938,2.01172 0.13672,0.6914 0.20703,1.38672 0.20703,2.08984 z m -112.58203,55.06641 c 0,0.6289 0.0625,1.25 0.18359,1.86328 0.12109,0.61719 0.30469,1.21484 0.54297,1.79297 0.23828,0.57812 0.53125,1.1289 0.87891,1.65234 0.34765,0.51953 0.74218,1.00391 1.18359,1.44531 0.44531,0.44532 0.92578,0.83985 1.44531,1.19141 0.51953,0.34766 1.07031,0.64062 1.64844,0.88281 0.57422,0.23828 1.17187,0.41797 1.78516,0.54297 0.61328,0.12109 1.23437,0.18359 1.85937,0.18359 h 92.36719 c 0.625,0 1.24609,-0.0625 1.85937,-0.18359 0.61328,-0.125 1.21094,-0.30469 1.78907,-0.54297 0.57421,-0.24219 1.125,-0.53515 1.64453,-0.88281 0.51953,-0.35156 1,-0.74609 1.44531,-1.19141 0.44141,-0.4414 0.83594,-0.92578 1.18359,-1.44531 0.34766,-0.52344 0.64063,-1.07422 0.87891,-1.65234 0.24219,-0.57813 0.42187,-1.17578 0.54297,-1.79297 0.12109,-0.61328 0.18359,-1.23438 0.18359,-1.86328 v -55.06641 c 0,-0.625 -0.0625,-1.24609 -0.18359,-1.86328 -0.1211,-0.61328 -0.30078,-1.21094 -0.54297,-1.79297 -0.23828,-0.57812 -0.53125,-1.12891 -0.87891,-1.64844 -0.34765,-0.52343 -0.74218,-1.0039 -1.18359,-1.44922 -0.44531,-0.44531 -0.92578,-0.83984 -1.44531,-1.1875 -0.51953,-0.34765 -1.07032,-0.64453 -1.64453,-0.88281 -0.57813,-0.24219 -1.17579,-0.42187 -1.78907,-0.54297 -0.61328,-0.125 -1.23437,-0.18359 -1.85937,-0.18359 h -92.36719 c -0.625,0 -1.24609,0.0586 -1.85937,0.18359 -0.61329,0.1211 -1.21094,0.30078 -1.78516,0.54297 -0.57813,0.23828 -1.12891,0.53516 -1.64844,0.88281 -0.51953,0.34766 -1,0.74219 -1.44531,1.1875 -0.44141,0.44532 -0.83594,0.92579 -1.18359,1.44922 -0.34766,0.51953 -0.64063,1.07032 -0.87891,1.64844 -0.23828,0.58203 -0.42188,1.17969 -0.54297,1.79297 -0.12109,0.61719 -0.18359,1.23828 -0.18359,1.86328 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4654" />
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4664"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(611.5815,344.04413)"
+ id="g4662">
+ <g
+ id="g4660">
+ <path
+ d="M 7.4375,-5.125 H 3.5625 V 0 H 1.875 v -15.21875 h 5.5625 c 1.65625,0 2.878906,0.40625 3.671875,1.21875 0.789063,0.804688 1.1875,2.03125 1.1875,3.6875 0,3.460938 -1.621094,5.1875 -4.859375,5.1875 z m -3.875,-1.5 h 3.84375 c 2.101562,0 3.15625,-1.226562 3.15625,-3.6875 0,-1.175781 -0.25,-2.039062 -0.75,-2.59375 -0.5,-0.550781 -1.304688,-0.828125 -2.40625,-0.828125 H 3.5625 Z m 0,0"
+ id="path4658" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4672"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(624.62518,344.04413)"
+ id="g4670">
+ <g
+ id="g4668">
+ <path
+ d="m 0.546875,-11 h 1.65625 l 2.75,9.5625 h 0.71875 L 8.453125,-11 H 10.09375 L 5.515625,4.890625 H 3.875 L 5.296875,0 h -1.625 z m 0,0"
+ id="path4666" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4680"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(635.24928,344.04413)"
+ id="g4678">
+ <g
+ id="g4676">
+ <path
+ d="m 7.28125,-9.5625 h -3.5 v 5.25 c 0,1.261719 0.085938,2.089844 0.265625,2.484375 0.1875,0.398437 0.628906,0.59375 1.328125,0.59375 l 1.953125,-0.125 L 7.4375,0 c -0.980469,0.15625 -1.730469,0.234375 -2.25,0.234375 -1.148438,0 -1.9375,-0.2734375 -2.375,-0.828125 -0.4375,-0.5625 -0.65625,-1.625 -0.65625,-3.1875 V -9.5625 H 0.59375 V -11 h 1.5625 v -3.359375 h 1.625 V -11 h 3.5 z m 0,0"
+ id="path4674" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4688"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(642.96991,344.04413)"
+ id="g4686">
+ <g
+ id="g4684">
+ <path
+ d="m 3.234375,0 h -1.65625 v -15.796875 h 1.65625 v 5.40625 c 1.175781,-0.550781 2.304687,-0.828125 3.390625,-0.828125 1.46875,0 2.453125,0.398438 2.953125,1.1875 0.507813,0.792969 0.765625,2.199219 0.765625,4.21875 V 0 H 8.6875 v -5.765625 c 0,-1.519531 -0.152344,-2.5625 -0.453125,-3.125 C 7.929688,-9.460938 7.300781,-9.75 6.34375,-9.75 c -0.929688,0 -1.824219,0.171875 -2.6875,0.515625 L 3.234375,-9.09375 Z m 0,0"
+ id="path4682" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4696"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(654.7818,344.04413)"
+ id="g4694">
+ <g
+ id="g4692">
+ <path
+ d="m 1.09375,-5.515625 c 0,-2.007813 0.359375,-3.460937 1.078125,-4.359375 0.71875,-0.894531 1.929687,-1.34375 3.640625,-1.34375 1.707031,0 2.914062,0.449219 3.625,1.34375 0.71875,0.898438 1.078125,2.351562 1.078125,4.359375 0,2 -0.339844,3.460937 -1.015625,4.375 -0.679688,0.90625 -1.914062,1.359375 -3.703125,1.359375 -1.78125,0 -3.011719,-0.453125 -3.6875,-1.359375 -0.679687,-0.914063 -1.015625,-2.375 -1.015625,-4.375 z m 1.703125,-0.03125 c 0,1.605469 0.191406,2.730469 0.578125,3.375 0.382812,0.648437 1.195312,0.96875 2.4375,0.96875 1.238281,0 2.050781,-0.316406 2.4375,-0.953125 0.382812,-0.644531 0.578125,-1.773438 0.578125,-3.390625 0,-1.613281 -0.214844,-2.722656 -0.640625,-3.328125 -0.429688,-0.613281 -1.21875,-0.921875 -2.375,-0.921875 -1.148438,0 -1.9375,0.308594 -2.375,0.921875 -0.429688,0.605469 -0.640625,1.714844 -0.640625,3.328125 z m 0,0"
+ id="path4690" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4704"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(666.39573,344.04413)"
+ id="g4702">
+ <g
+ id="g4700">
+ <path
+ d="M 3.234375,0 H 1.578125 V -11 H 3.21875 v 0.765625 c 1.1875,-0.65625 2.320312,-0.984375 3.40625,-0.984375 1.46875,0 2.453125,0.398438 2.953125,1.1875 0.507813,0.792969 0.765625,2.199219 0.765625,4.21875 V 0 h -1.625 v -5.765625 c 0,-1.519531 -0.152344,-2.5625 -0.453125,-3.125 C 7.960938,-9.460938 7.320312,-9.75 6.34375,-9.75 c -0.480469,0 -0.980469,0.074219 -1.5,0.21875 -0.523438,0.136719 -0.917969,0.273438 -1.1875,0.40625 l -0.421875,0.1875 z m 0,0"
+ id="path4698" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4712"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(622.45064,374.79413)"
+ id="g4710">
+ <g
+ id="g4708">
+ <path
+ d="m 0.28125,-13.703125 v -1.515625 h 11 v 1.515625 H 6.640625 V 0 H 4.96875 v -13.703125 z m 0,0"
+ id="path4706" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4720"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(634.02058,374.79413)"
+ id="g4718">
+ <g
+ id="g4716">
+ <path
+ d="m 0.546875,-11 h 1.65625 l 2.75,9.5625 h 0.71875 L 8.453125,-11 H 10.09375 L 5.515625,4.890625 H 3.875 L 5.296875,0 h -1.625 z m 0,0"
+ id="path4714" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4728"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(644.64468,374.79413)"
+ id="g4726">
+ <g
+ id="g4724">
+ <path
+ d="M 1.578125,4.890625 V -11 H 3.21875 v 0.796875 c 1.113281,-0.675781 2.210938,-1.015625 3.296875,-1.015625 1.394531,0 2.40625,0.445312 3.03125,1.328125 C 10.179688,-9.003906 10.5,-7.539062 10.5,-5.5 c 0,2.042969 -0.375,3.507812 -1.125,4.390625 -0.742188,0.886719 -1.964844,1.328125 -3.671875,1.328125 -0.898437,0 -1.71875,-0.078125 -2.46875,-0.234375 v 4.90625 z M 6.265625,-9.75 c -0.4375,0 -0.914063,0.074219 -1.421875,0.21875 -0.5,0.148438 -0.898438,0.292969 -1.1875,0.4375 l -0.421875,0.234375 v 7.40625 c 1.039063,0.167969 1.832031,0.25 2.375,0.25 1.1875,0 2.019531,-0.335937 2.5,-1.015625 0.476563,-0.675781 0.71875,-1.773438 0.71875,-3.296875 0,-1.53125 -0.21875,-2.617187 -0.65625,-3.265625 C 7.742188,-9.425781 7.109375,-9.75 6.265625,-9.75 Z m 0,0"
+ id="path4722" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4736"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(656.23661,374.79413)"
+ id="g4734">
+ <g
+ id="g4732">
+ <path
+ d="M 9.0625,-1.359375 9.703125,-1.4375 9.75,-0.125 C 8.070312,0.101562 6.640625,0.21875 5.453125,0.21875 c -1.585937,0 -2.710937,-0.457031 -3.375,-1.375 C 1.421875,-2.070312 1.09375,-3.5 1.09375,-5.4375 c 0,-3.851562 1.535156,-5.78125 4.609375,-5.78125 1.476563,0 2.582031,0.417969 3.3125,1.25 0.738281,0.824219 1.109375,2.121094 1.109375,3.890625 L 10.03125,-4.8125 H 2.765625 c 0,1.21875 0.21875,2.121094 0.65625,2.703125 0.445313,0.585937 1.21875,0.875 2.3125,0.875 1.09375,0 2.203125,-0.039063 3.328125,-0.125 z m -0.59375,-4.78125 c 0,-1.34375 -0.21875,-2.289063 -0.65625,-2.84375 -0.429688,-0.5625 -1.132812,-0.84375 -2.109375,-0.84375 -0.96875,0 -1.703125,0.292969 -2.203125,0.875 -0.492188,0.585937 -0.742188,1.523437 -0.75,2.8125 z m 0,0"
+ id="path4730" />
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#61b05d6a70)"
+ id="g4740"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:#848895;fill-opacity:1;stroke:none;stroke-width:0.52087492;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 58.208333,195.13542 v 11.90625 h 48.947917 l 3.96875,-3.96875 V 191.16667 H 62.177083 Z"
- id="path3715-5-6-7-9-8-7-6-56-7"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccc" />
+ fill="#306998"
+ d="m 125.32813,478.72266 v -43.44532 c 0,-0.52734 0.0508,-1.04687 0.15625,-1.5625 0.10156,-0.51172 0.25,-1.01172 0.45312,-1.49609 0.19922,-0.48828 0.44531,-0.94922 0.73438,-1.38281 0.29296,-0.4375 0.62109,-0.83985 0.99218,-1.21094 0.3711,-0.375 0.77344,-0.70313 1.20703,-0.99609 0.4375,-0.29297 0.89453,-0.53907 1.37891,-0.73829 0.48437,-0.20312 0.98437,-0.35156 1.49609,-0.45703 0.51172,-0.10156 1.03125,-0.15234 1.55469,-0.15234 h 72.875 c 0.52344,0 1.04297,0.0508 1.55859,0.15234 0.51172,0.10547 1.01172,0.25391 1.49219,0.45703 0.48438,0.19922 0.94531,0.44532 1.37891,0.73829 0.4375,0.29296 0.83984,0.62109 1.20703,0.99609 0.37109,0.37109 0.70312,0.77344 0.99219,1.21094 0.29297,0.43359 0.53906,0.89453 0.73828,1.38281 0.19922,0.48437 0.35156,0.98437 0.45312,1.49609 0.10157,0.51563 0.15235,1.03516 0.15235,1.5625 v 43.44532 c 0,0.52343 -0.0508,1.04296 -0.15235,1.55859 -0.10156,0.51562 -0.2539,1.01562 -0.45312,1.5 -0.19922,0.48437 -0.44531,0.94531 -0.73828,1.38281 -0.28907,0.4375 -0.6211,0.83985 -0.99219,1.21094 -0.36719,0.37109 -0.76953,0.70312 -1.20703,0.99219 -0.4336,0.29297 -0.89453,0.53906 -1.37891,0.74218 -0.48047,0.19922 -0.98047,0.35157 -1.49219,0.45313 -0.51562,0.10156 -1.03515,0.15234 -1.55859,0.15234 h -72.875 c -0.52344,0 -1.04297,-0.0508 -1.55469,-0.15234 -0.51172,-0.10156 -1.01172,-0.25391 -1.49609,-0.45313 -0.48438,-0.20312 -0.94141,-0.44921 -1.37891,-0.74218 -0.43359,-0.28907 -0.83593,-0.6211 -1.20703,-0.99219 -0.37109,-0.37109 -0.69922,-0.77344 -0.99218,-1.21094 -0.28907,-0.4375 -0.53516,-0.89844 -0.73438,-1.38281 -0.20312,-0.48438 -0.35156,-0.98438 -0.45312,-1.5 -0.10547,-0.51563 -0.15625,-1.03516 -0.15625,-1.55859 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4738" />
+ </g>
+ <g
+ clip-path="url(#ea42d02648)"
+ id="g4744"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:#848895;fill-opacity:1;stroke:none;stroke-width:0.52087492;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 58.208343,216.30209 v 11.90625 h 48.947907 l 3.96875,-3.96875 V 212.33334 H 62.177093 Z"
- id="path3715-5-6-7-9-8-7-6-56-0"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccc" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05555534px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
- x="65.68634"
- y="179.68727"
- id="text1032"><tspan
- sodipodi:role="line"
- id="tspan1030"
- x="65.68634"
- y="179.68727"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05555534px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332">PythonType1</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05555534px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
- x="65.326508"
- y="200.85394"
- id="text1032-1"><tspan
- sodipodi:role="line"
- id="tspan1030-1"
- x="65.326508"
- y="200.85394"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05555534px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332">PythonType2</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05555534px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
- x="65.319458"
- y="222.02061"
- id="text1032-4"><tspan
- sodipodi:role="line"
- id="tspan1030-6"
- x="65.319458"
- y="222.02061"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05555534px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332">PythonType3</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:Titillium;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
- x="90.120621"
- y="139.29776"
- id="text1062"><tspan
- sodipodi:role="line"
- id="tspan1060"
- x="90.120621"
- y="139.29776"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.87777805px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332">C++</tspan><tspan
- sodipodi:role="line"
- x="90.120621"
- y="152.52693"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.87777805px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
- id="tspan1064">Type</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:Titillium;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
- x="135.41069"
- y="138.95909"
- id="text1068"><tspan
- sodipodi:role="line"
- id="tspan1066"
- x="135.41069"
- y="138.95909"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332">Converter</tspan><tspan
- sodipodi:role="line"
- x="135.41069"
- y="152.18826"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
- id="tspan1070">C++ -&gt; Python</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:Titillium;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
- x="135.41072"
- y="181.29242"
- id="text1068-9"><tspan
- sodipodi:role="line"
- id="tspan1066-7"
- x="135.41072"
- y="181.29242"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332">Converter</tspan><tspan
- sodipodi:role="line"
- x="135.41072"
- y="194.52159"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.46666622px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
- id="tspan1070-5">Python -&gt; C++</tspan></text>
+ fill="#306998"
+ d="m 214.60547,435.27734 v 43.44141 c 0,0.55469 -0.0508,1.10547 -0.16016,1.65234 -0.10937,0.54297 -0.26953,1.07032 -0.48047,1.58594 -0.21093,0.51172 -0.47265,1 -0.77734,1.46094 -0.30859,0.46094 -0.66016,0.88672 -1.05078,1.28125 -0.39063,0.39453 -0.81641,0.74219 -1.27735,1.05078 -0.46093,0.30859 -0.94531,0.57031 -1.45703,0.78125 -0.51172,0.21484 -1.03906,0.375 -1.58203,0.48047 -0.54297,0.10937 -1.08984,0.16406 -1.64453,0.16406 h -72.87109 c -0.55469,0 -1.10547,-0.0547 -1.64844,-0.16406 -0.54297,-0.10547 -1.07031,-0.26563 -1.57813,-0.48047 -0.51171,-0.21094 -1,-0.47266 -1.46093,-0.78125 -0.46094,-0.30859 -0.88672,-0.65625 -1.27735,-1.05078 -0.39062,-0.39453 -0.73828,-0.82031 -1.04687,-1.28125 -0.30859,-0.46094 -0.56641,-0.94922 -0.78125,-1.46094 -0.21094,-0.51562 -0.37109,-1.04297 -0.47656,-1.58594 -0.10938,-0.54687 -0.16407,-1.09765 -0.16407,-1.65234 v -43.44141 c 0,-0.55468 0.0547,-1.10547 0.16407,-1.65234 0.10547,-0.54297 0.26562,-1.07031 0.47656,-1.58594 0.21484,-0.51172 0.47266,-1 0.78125,-1.46094 0.30859,-0.46093 0.65625,-0.88671 1.04687,-1.28125 0.39063,-0.39453 0.81641,-0.74218 1.27735,-1.05078 0.46093,-0.30859 0.94922,-0.57031 1.46093,-0.78125 0.50782,-0.21484 1.03516,-0.375 1.57813,-0.48047 0.54297,-0.10937 1.09375,-0.16406 1.64844,-0.16406 h 72.87109 c 0.55469,0 1.10156,0.0547 1.64453,0.16406 0.54297,0.10547 1.07031,0.26563 1.58203,0.48047 0.51172,0.21094 1,0.47266 1.45703,0.78125 0.46094,0.3086 0.88672,0.66016 1.27735,1.05078 0.39453,0.39454 0.74219,0.82032 1.05078,1.28125 0.30469,0.46094 0.56641,0.94922 0.77734,1.46094 0.21094,0.51563 0.3711,1.04297 0.48047,1.58985 0.10938,0.54296 0.16016,1.09375 0.16016,1.64843 z m -88.81641,43.44141 c 0,0.49609 0.0469,0.98437 0.14453,1.47266 0.0937,0.48437 0.23829,0.95703 0.42579,1.41406 0.1875,0.45703 0.42187,0.89062 0.69531,1.30078 0.27344,0.41406 0.58594,0.79297 0.93359,1.14453 0.34766,0.34766 0.73047,0.66016 1.14063,0.9375 0.41015,0.27344 0.84375,0.50391 1.29687,0.69531 0.45703,0.1875 0.92578,0.33203 1.41016,0.42969 0.48437,0.0937 0.97265,0.14453 1.46875,0.14453 h 72.87109 c 0.49609,0 0.98438,-0.0508 1.46875,-0.14453 0.48438,-0.0977 0.95313,-0.24219 1.41016,-0.42969 0.45312,-0.1914 0.88672,-0.42187 1.29687,-0.69531 0.41016,-0.27734 0.78906,-0.58984 1.14063,-0.9375 0.34765,-0.35156 0.66015,-0.73047 0.93359,-1.14453 0.27344,-0.41016 0.50781,-0.84375 0.69531,-1.30078 0.1875,-0.45703 0.33203,-0.92969 0.42578,-1.41406 0.0977,-0.48829 0.14454,-0.97657 0.14454,-1.47266 v -43.44141 c 0,-0.49609 -0.0469,-0.98437 -0.14454,-1.47265 -0.0937,-0.48438 -0.23828,-0.95703 -0.42578,-1.41407 -0.1875,-0.45703 -0.42187,-0.89062 -0.69531,-1.30078 -0.27344,-0.41406 -0.58594,-0.79297 -0.93359,-1.14453 -0.35157,-0.34765 -0.73047,-0.66015 -1.14063,-0.9375 -0.41015,-0.27344 -0.84375,-0.5039 -1.29687,-0.69531 -0.45703,-0.1875 -0.92578,-0.33203 -1.41016,-0.42969 -0.48437,-0.0937 -0.97266,-0.14453 -1.46875,-0.14453 h -72.87109 c -0.4961,0 -0.98438,0.0508 -1.46875,0.14453 -0.48438,0.0977 -0.95313,0.24219 -1.41016,0.42969 -0.45312,0.19141 -0.88672,0.42187 -1.29687,0.69531 -0.41016,0.27735 -0.79297,0.58985 -1.14063,0.9375 -0.34765,0.35156 -0.66015,0.73047 -0.93359,1.14453 -0.27344,0.41016 -0.50781,0.84375 -0.69531,1.30078 -0.1875,0.45704 -0.33204,0.92969 -0.42579,1.41407 -0.0977,0.48828 -0.14453,0.97656 -0.14453,1.47265 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4742" />
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4752"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(143.38693,451.22147)"
+ id="g4750">
+ <g
+ id="g4748">
+ <path
+ d="M 5.875,-4.046875 H 2.8125 V 0 H 1.46875 V -12.015625 H 5.875 c 1.300781,0 2.265625,0.320313 2.890625,0.953125 0.625,0.636719 0.9375,1.609375 0.9375,2.921875 0,2.730469 -1.277344,4.09375 -3.828125,4.09375 z M 2.8125,-5.21875 h 3.03125 c 1.65625,0 2.484375,-0.972656 2.484375,-2.921875 0,-0.925781 -0.199219,-1.601563 -0.59375,-2.03125 -0.386719,-0.4375 -1.015625,-0.65625 -1.890625,-0.65625 H 2.8125 Z m 0,0"
+ id="path4746" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4760"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(153.67768,451.22147)"
+ id="g4758">
+ <g
+ id="g4756">
+ <path
+ d="M 0.4375,-8.671875 H 1.734375 L 3.90625,-1.125 h 0.578125 l 2.1875,-7.546875 H 7.96875 L 4.359375,3.859375 H 3.0625 L 4.1875,0 H 2.90625 Z m 0,0"
+ id="path4754" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4768"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(162.05952,451.22147)"
+ id="g4766">
+ <g
+ id="g4764">
+ <path
+ d="M 5.75,-7.546875 H 2.984375 v 4.140625 c 0,1 0.070313,1.65625 0.21875,1.96875 0.144531,0.3125 0.488281,0.46875 1.03125,0.46875 L 5.78125,-1.078125 5.875,0 C 5.09375,0.125 4.5,0.1875 4.09375,0.1875 3.195312,0.1875 2.570312,-0.03125 2.21875,-0.46875 1.875,-0.90625 1.703125,-1.742188 1.703125,-2.984375 v -4.5625 H 0.46875 v -1.125 h 1.234375 v -2.65625 h 1.28125 v 2.65625 H 5.75 Z m 0,0"
+ id="path4762" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4776"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(168.15067,451.22147)"
+ id="g4774">
+ <g
+ id="g4772">
+ <path
+ d="M 2.546875,0 H 1.25 v -12.46875 h 1.296875 v 4.28125 c 0.925781,-0.445312 1.816406,-0.671875 2.671875,-0.671875 1.164062,0 1.945312,0.3125 2.34375,0.9375 0.394531,0.625 0.59375,1.742187 0.59375,3.34375 V 0 H 6.859375 V -4.546875 C 6.859375,-5.753906 6.738281,-6.578125 6.5,-7.015625 6.257812,-7.460938 5.757812,-7.6875 5,-7.6875 c -0.730469,0 -1.4375,0.132812 -2.125,0.390625 l -0.328125,0.125 z m 0,0"
+ id="path4770" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4784"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(177.4696,451.22147)"
+ id="g4782">
+ <g
+ id="g4780">
+ <path
+ d="m 0.875,-4.359375 c 0,-1.582031 0.28125,-2.726563 0.84375,-3.4375 0.5625,-0.707031 1.515625,-1.0625 2.859375,-1.0625 1.351563,0 2.3125,0.355469 2.875,1.0625 0.5625,0.710937 0.84375,1.855469 0.84375,3.4375 C 8.296875,-2.773438 8.03125,-1.625 7.5,-0.90625 6.96875,-0.1875 5.992188,0.171875 4.578125,0.171875 c -1.40625,0 -2.375,-0.359375 -2.90625,-1.078125 C 1.140625,-1.625 0.875,-2.773438 0.875,-4.359375 Z M 2.203125,-4.375 c 0,1.261719 0.148437,2.148438 0.453125,2.65625 0.3125,0.511719 0.957031,0.765625 1.9375,0.765625 0.976562,0 1.617188,-0.25 1.921875,-0.75 C 6.816406,-2.210938 6.96875,-3.101562 6.96875,-4.375 6.96875,-5.644531 6.796875,-6.519531 6.453125,-7 6.117188,-7.476562 5.5,-7.71875 4.59375,-7.71875 3.6875,-7.71875 3.0625,-7.476562 2.71875,-7 2.375,-6.519531 2.203125,-5.644531 2.203125,-4.375 Z m 0,0"
+ id="path4778" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4792"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(186.63236,451.22147)"
+ id="g4790">
+ <g
+ id="g4788">
+ <path
+ d="M 2.546875,0 H 1.25 v -8.671875 h 1.28125 v 0.59375 c 0.9375,-0.519531 1.832031,-0.78125 2.6875,-0.78125 1.164062,0 1.945312,0.3125 2.34375,0.9375 0.394531,0.625 0.59375,1.742187 0.59375,3.34375 V 0 H 6.875 v -4.546875 c 0,-1.207031 -0.121094,-2.03125 -0.359375,-2.46875 C 6.273438,-7.460938 5.769531,-7.6875 5,-7.6875 c -0.375,0 -0.765625,0.058594 -1.171875,0.171875 -0.40625,0.105469 -0.726563,0.210937 -0.953125,0.3125 l -0.328125,0.15625 z m 0,0"
+ id="path4786" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4800"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(145.18979,475.48154)"
+ id="g4798">
+ <g
+ id="g4796">
+ <path
+ d="m 0.21875,-10.8125 v -1.203125 h 8.6875 V -10.8125 H 5.25 V 0 H 3.921875 v -10.8125 z m 0,0"
+ id="path4794" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4808"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(154.31784,475.48154)"
+ id="g4806">
+ <g
+ id="g4804">
+ <path
+ d="M 0.4375,-8.671875 H 1.734375 L 3.90625,-1.125 h 0.578125 l 2.1875,-7.546875 H 7.96875 L 4.359375,3.859375 H 3.0625 L 4.1875,0 H 2.90625 Z m 0,0"
+ id="path4802" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4816"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(162.69968,475.48154)"
+ id="g4814">
+ <g
+ id="g4812">
+ <path
+ d="M 1.25,3.859375 V -8.671875 H 2.53125 V -8.0625 c 0.882812,-0.53125 1.753906,-0.796875 2.609375,-0.796875 1.09375,0 1.890625,0.355469 2.390625,1.0625 0.5,0.699219 0.75,1.855469 0.75,3.46875 0,1.605469 -0.292969,2.757813 -0.875,3.453125 C 6.820312,-0.175781 5.851562,0.171875 4.5,0.171875 c -0.710938,0 -1.359375,-0.0625 -1.953125,-0.1875 v 3.875 z M 4.953125,-7.6875 c -0.355469,0 -0.730469,0.058594 -1.125,0.171875 C 3.429688,-7.398438 3.113281,-7.285156 2.875,-7.171875 L 2.546875,-7 v 5.859375 c 0.820313,0.125 1.445313,0.1875 1.875,0.1875 0.9375,0 1.59375,-0.265625 1.96875,-0.796875 0.382813,-0.53125 0.578125,-1.394531 0.578125,-2.59375 0,-1.207031 -0.171875,-2.066406 -0.515625,-2.578125 -0.34375,-0.507813 -0.84375,-0.765625 -1.5,-0.765625 z m 0,0"
+ id="path4810" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4824"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(171.84508,475.48154)"
+ id="g4822">
+ <g
+ id="g4820">
+ <path
+ d="m 7.15625,-1.078125 0.5,-0.046875 0.03125,1.015625 C 6.375,0.078125 5.25,0.171875 4.3125,0.171875 3.0625,0.171875 2.175781,-0.1875 1.65625,-0.90625 1.132812,-1.632812 0.875,-2.757812 0.875,-4.28125 c 0,-3.050781 1.207031,-4.578125 3.625,-4.578125 1.164062,0 2.035156,0.328125 2.609375,0.984375 0.582031,0.65625 0.875,1.683594 0.875,3.078125 l -0.0625,1 H 2.1875 c 0,0.960937 0.171875,1.671875 0.515625,2.140625 0.351563,0.460938 0.957031,0.6875 1.8125,0.6875 0.863281,0 1.742187,-0.035156 2.640625,-0.109375 z M 6.6875,-4.84375 c 0,-1.0625 -0.171875,-1.8125 -0.515625,-2.25 C 5.828125,-7.539062 5.269531,-7.765625 4.5,-7.765625 c -0.773438,0 -1.351562,0.234375 -1.734375,0.703125 -0.386719,0.460938 -0.585937,1.199219 -0.59375,2.21875 z m 0,0"
+ id="path4818" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4830"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(180.6087,475.48154)"
+ id="g4828">
+ <g
+ id="g4826" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4838"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(184.42651,475.48154)"
+ id="g4836">
+ <g
+ id="g4834">
+ <path
+ d="M 6.75,-11.453125 V 0 H 5.421875 V -9.96875 L 2.46875,-8.015625 1.859375,-9.03125 5.5,-11.453125 Z m 0,0"
+ id="path4832" />
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#84bd6662f0)"
+ id="g4842"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:#3a4055;fill-opacity:1;stroke:none;stroke-width:0.67261654;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 211.66667,175.29167 V 201.75 h 37.04166 L 254,196.45833 V 170 h -37.04167 z"
- id="path3715-5-6-7-9-8-7-6-3-9"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccc" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:Titillium;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
- x="232.99562"
- y="181.63109"
- id="text1062-7"><tspan
- sodipodi:role="line"
- id="tspan1060-4"
- x="232.99562"
- y="181.63109"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.87777805px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332">C++</tspan><tspan
- sodipodi:role="line"
- x="232.99562"
- y="194.86026"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.87777805px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:center;writing-mode:lr-tb;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
- id="tspan1064-9">Type</tspan></text>
+ fill="#306998"
+ d="m 125.32813,548.84766 v -43.44532 c 0,-0.52343 0.0508,-1.04297 0.15625,-1.55859 0.10156,-0.51563 0.25,-1.01563 0.45312,-1.5 0.19922,-0.48438 0.44531,-0.94531 0.73438,-1.38281 0.29296,-0.4336 0.62109,-0.83985 0.99218,-1.21094 0.3711,-0.37109 0.77344,-0.70313 1.20703,-0.99219 0.4375,-0.29297 0.89453,-0.53906 1.37891,-0.73828 0.48437,-0.20312 0.98437,-0.35547 1.49609,-0.45703 0.51172,-0.10156 1.03125,-0.15234 1.55469,-0.15234 h 72.875 c 0.52344,0 1.04297,0.0508 1.55859,0.15234 0.51172,0.10156 1.01172,0.25391 1.49219,0.45703 0.48438,0.19922 0.94531,0.44531 1.37891,0.73828 0.4375,0.28906 0.83984,0.6211 1.20703,0.99219 0.37109,0.37109 0.70312,0.77734 0.99219,1.21094 0.29297,0.4375 0.53906,0.89843 0.73828,1.38281 0.19922,0.48437 0.35156,0.98437 0.45312,1.5 0.10157,0.51562 0.15235,1.03516 0.15235,1.55859 v 43.44532 c 0,0.52734 -0.0508,1.04687 -0.15235,1.5625 -0.10156,0.51171 -0.2539,1.01171 -0.45312,1.5 -0.19922,0.48437 -0.44531,0.94531 -0.73828,1.3789 -0.28907,0.4375 -0.6211,0.84375 -0.99219,1.21485 -0.36719,0.37109 -0.76953,0.69921 -1.20703,0.99218 -0.4336,0.29297 -0.89453,0.53907 -1.37891,0.73828 -0.48047,0.20313 -0.98047,0.35547 -1.49219,0.45704 -0.51562,0.10156 -1.03515,0.15234 -1.55859,0.15234 h -72.875 c -0.52344,0 -1.04297,-0.0508 -1.55469,-0.15234 -0.51172,-0.10157 -1.01172,-0.25391 -1.49609,-0.45704 -0.48438,-0.19921 -0.94141,-0.44531 -1.37891,-0.73828 -0.43359,-0.29297 -0.83593,-0.62109 -1.20703,-0.99218 -0.37109,-0.3711 -0.69922,-0.77735 -0.99218,-1.21485 -0.28907,-0.43359 -0.53516,-0.89453 -0.73438,-1.3789 -0.20312,-0.48829 -0.35156,-0.98829 -0.45312,-1.5 -0.10547,-0.51563 -0.15625,-1.03516 -0.15625,-1.5625 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4840" />
+ </g>
+ <g
+ clip-path="url(#728d290ff8)"
+ id="g4846"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:#848895;fill-opacity:1;stroke:none;stroke-width:0.52087492;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 211.66667,131.63542 v 11.90625 h 48.94791 l 3.96875,-3.96875 v -11.90625 h -48.94791 z"
- id="path3715-5-6-7-9-8-7-6-56-0-1"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccc" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05555534px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
- x="220.67876"
- y="137.35394"
- id="text1032-4-7"><tspan
- sodipodi:role="line"
- id="tspan1030-6-0"
- x="220.67876"
- y="137.35394"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.05555534px;font-family:Titillium;-inkscape-font-specification:'Titillium, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.26458332">PythonType</tspan></text>
+ fill="#306998"
+ d="m 214.60547,505.40234 v 43.44532 c 0,0.55468 -0.0508,1.10546 -0.16016,1.64843 -0.10937,0.54688 -0.26953,1.07422 -0.48047,1.58594 -0.21093,0.51563 -0.47265,1 -0.77734,1.46484 -0.30859,0.46094 -0.66016,0.88672 -1.05078,1.28125 -0.39063,0.39063 -0.81641,0.74219 -1.27735,1.05079 -0.46093,0.30859 -0.94531,0.57031 -1.45703,0.78125 -0.51172,0.21093 -1.03906,0.37109 -1.58203,0.48046 -0.54297,0.10938 -1.08984,0.16407 -1.64453,0.16407 h -72.87109 c -0.55469,0 -1.10547,-0.0547 -1.64844,-0.16407 -0.54297,-0.10937 -1.07031,-0.26953 -1.57813,-0.48046 -0.51171,-0.21094 -1,-0.47266 -1.46093,-0.78125 -0.46094,-0.3086 -0.88672,-0.66016 -1.27735,-1.05079 -0.39062,-0.39453 -0.73828,-0.82031 -1.04687,-1.28125 -0.30859,-0.46484 -0.56641,-0.94921 -0.78125,-1.46484 -0.21094,-0.51172 -0.37109,-1.03906 -0.47656,-1.58594 -0.10938,-0.54297 -0.16407,-1.09375 -0.16407,-1.64843 v -43.44532 c 0,-0.55468 0.0547,-1.10156 0.16407,-1.64843 0.10547,-0.54297 0.26562,-1.07422 0.47656,-1.58594 0.21484,-0.51172 0.47266,-1 0.78125,-1.46094 0.30859,-0.46094 0.65625,-0.89062 1.04687,-1.28125 0.39063,-0.39453 0.81641,-0.74609 1.27735,-1.05469 0.46093,-0.30859 0.94922,-0.5664 1.46093,-0.78125 0.50782,-0.21093 1.03516,-0.37109 1.57813,-0.48047 0.54297,-0.10937 1.09375,-0.16015 1.64844,-0.16015 h 72.87109 c 0.55469,0 1.10156,0.0547 1.64453,0.16015 0.54297,0.10938 1.07031,0.26954 1.58203,0.48438 0.51172,0.21094 1,0.47266 1.45703,0.78125 0.46094,0.30859 0.88672,0.65625 1.27735,1.05078 0.39453,0.39063 0.74219,0.82031 1.05078,1.28125 0.30469,0.46094 0.56641,0.94922 0.77734,1.46094 0.21094,0.51172 0.3711,1.04297 0.48047,1.58594 0.10938,0.54687 0.16016,1.09375 0.16016,1.64843 z m -88.81641,43.44532 c 0,0.49609 0.0469,0.98437 0.14453,1.46875 0.0937,0.48828 0.23829,0.95703 0.42579,1.41406 0.1875,0.45703 0.42187,0.89453 0.69531,1.30469 0.27344,0.41015 0.58594,0.79296 0.93359,1.14062 0.34766,0.35156 0.73047,0.66406 1.14063,0.9375 0.41015,0.27734 0.84375,0.50781 1.29687,0.69922 0.45703,0.1875 0.92578,0.33203 1.41016,0.42578 0.48437,0.0977 0.97265,0.14453 1.46875,0.14453 h 72.87109 c 0.49609,0 0.98438,-0.0469 1.46875,-0.14453 0.48438,-0.0937 0.95313,-0.23828 1.41016,-0.42578 0.45312,-0.19141 0.88672,-0.42188 1.29687,-0.69922 0.41016,-0.27344 0.78906,-0.58594 1.14063,-0.9375 0.34765,-0.34766 0.66015,-0.73047 0.93359,-1.14062 0.27344,-0.41016 0.50781,-0.84766 0.69531,-1.30469 0.1875,-0.45703 0.33203,-0.92578 0.42578,-1.41406 0.0977,-0.48438 0.14454,-0.97266 0.14454,-1.46875 v -43.44532 c 0,-0.49218 -0.0469,-0.98437 -0.14454,-1.46875 -0.0937,-0.48437 -0.23828,-0.95703 -0.42578,-1.41406 -0.1875,-0.45703 -0.42187,-0.89062 -0.69531,-1.30469 -0.27344,-0.41015 -0.58594,-0.78906 -0.93359,-1.14062 -0.35157,-0.35156 -0.73047,-0.66406 -1.14063,-0.9375 -0.41015,-0.27344 -0.84375,-0.50781 -1.29687,-0.69531 -0.45703,-0.19141 -0.92578,-0.33204 -1.41016,-0.42969 -0.48437,-0.0977 -0.97266,-0.14453 -1.46875,-0.14453 h -72.87109 c -0.4961,0 -0.98438,0.0469 -1.46875,0.14453 -0.48438,0.0976 -0.95313,0.23828 -1.41016,0.42969 -0.45312,0.1875 -0.88672,0.42187 -1.29687,0.69531 -0.41016,0.27344 -0.79297,0.58594 -1.14063,0.9375 -0.34765,0.35156 -0.66015,0.73047 -0.93359,1.14062 -0.27344,0.41407 -0.50781,0.84766 -0.69531,1.30469 -0.1875,0.45703 -0.33204,0.92969 -0.42579,1.41406 -0.0977,0.48438 -0.14453,0.97657 -0.14453,1.46875 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4844" />
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4854"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(143.38693,521.34911)"
+ id="g4852">
+ <g
+ id="g4850">
+ <path
+ d="M 5.875,-4.046875 H 2.8125 V 0 H 1.46875 V -12.015625 H 5.875 c 1.300781,0 2.265625,0.320313 2.890625,0.953125 0.625,0.636719 0.9375,1.609375 0.9375,2.921875 0,2.730469 -1.277344,4.09375 -3.828125,4.09375 z M 2.8125,-5.21875 h 3.03125 c 1.65625,0 2.484375,-0.972656 2.484375,-2.921875 0,-0.925781 -0.199219,-1.601563 -0.59375,-2.03125 -0.386719,-0.4375 -1.015625,-0.65625 -1.890625,-0.65625 H 2.8125 Z m 0,0"
+ id="path4848" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4862"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(153.67768,521.34911)"
+ id="g4860">
+ <g
+ id="g4858">
+ <path
+ d="M 0.4375,-8.671875 H 1.734375 L 3.90625,-1.125 h 0.578125 l 2.1875,-7.546875 H 7.96875 L 4.359375,3.859375 H 3.0625 L 4.1875,0 H 2.90625 Z m 0,0"
+ id="path4856" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4870"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(162.05952,521.34911)"
+ id="g4868">
+ <g
+ id="g4866">
+ <path
+ d="M 5.75,-7.546875 H 2.984375 v 4.140625 c 0,1 0.070313,1.65625 0.21875,1.96875 0.144531,0.3125 0.488281,0.46875 1.03125,0.46875 L 5.78125,-1.078125 5.875,0 C 5.09375,0.125 4.5,0.1875 4.09375,0.1875 3.195312,0.1875 2.570312,-0.03125 2.21875,-0.46875 1.875,-0.90625 1.703125,-1.742188 1.703125,-2.984375 v -4.5625 H 0.46875 v -1.125 h 1.234375 v -2.65625 h 1.28125 v 2.65625 H 5.75 Z m 0,0"
+ id="path4864" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4878"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(168.15067,521.34911)"
+ id="g4876">
+ <g
+ id="g4874">
+ <path
+ d="M 2.546875,0 H 1.25 v -12.46875 h 1.296875 v 4.28125 c 0.925781,-0.445312 1.816406,-0.671875 2.671875,-0.671875 1.164062,0 1.945312,0.3125 2.34375,0.9375 0.394531,0.625 0.59375,1.742187 0.59375,3.34375 V 0 H 6.859375 V -4.546875 C 6.859375,-5.753906 6.738281,-6.578125 6.5,-7.015625 6.257812,-7.460938 5.757812,-7.6875 5,-7.6875 c -0.730469,0 -1.4375,0.132812 -2.125,0.390625 l -0.328125,0.125 z m 0,0"
+ id="path4872" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4886"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(177.4696,521.34911)"
+ id="g4884">
+ <g
+ id="g4882">
+ <path
+ d="m 0.875,-4.359375 c 0,-1.582031 0.28125,-2.726563 0.84375,-3.4375 0.5625,-0.707031 1.515625,-1.0625 2.859375,-1.0625 1.351563,0 2.3125,0.355469 2.875,1.0625 0.5625,0.710937 0.84375,1.855469 0.84375,3.4375 C 8.296875,-2.773438 8.03125,-1.625 7.5,-0.90625 6.96875,-0.1875 5.992188,0.171875 4.578125,0.171875 c -1.40625,0 -2.375,-0.359375 -2.90625,-1.078125 C 1.140625,-1.625 0.875,-2.773438 0.875,-4.359375 Z M 2.203125,-4.375 c 0,1.261719 0.148437,2.148438 0.453125,2.65625 0.3125,0.511719 0.957031,0.765625 1.9375,0.765625 0.976562,0 1.617188,-0.25 1.921875,-0.75 C 6.816406,-2.210938 6.96875,-3.101562 6.96875,-4.375 6.96875,-5.644531 6.796875,-6.519531 6.453125,-7 6.117188,-7.476562 5.5,-7.71875 4.59375,-7.71875 3.6875,-7.71875 3.0625,-7.476562 2.71875,-7 2.375,-6.519531 2.203125,-5.644531 2.203125,-4.375 Z m 0,0"
+ id="path4880" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4894"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(186.63236,521.34911)"
+ id="g4892">
+ <g
+ id="g4890">
+ <path
+ d="M 2.546875,0 H 1.25 v -8.671875 h 1.28125 v 0.59375 c 0.9375,-0.519531 1.832031,-0.78125 2.6875,-0.78125 1.164062,0 1.945312,0.3125 2.34375,0.9375 0.394531,0.625 0.59375,1.742187 0.59375,3.34375 V 0 H 6.875 v -4.546875 c 0,-1.207031 -0.121094,-2.03125 -0.359375,-2.46875 C 6.273438,-7.460938 5.769531,-7.6875 5,-7.6875 c -0.375,0 -0.765625,0.058594 -1.171875,0.171875 -0.40625,0.105469 -0.726563,0.210937 -0.953125,0.3125 l -0.328125,0.15625 z m 0,0"
+ id="path4888" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4902"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(145.18979,545.60918)"
+ id="g4900">
+ <g
+ id="g4898">
+ <path
+ d="m 0.21875,-10.8125 v -1.203125 h 8.6875 V -10.8125 H 5.25 V 0 H 3.921875 v -10.8125 z m 0,0"
+ id="path4896" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4910"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(154.31784,545.60918)"
+ id="g4908">
+ <g
+ id="g4906">
+ <path
+ d="M 0.4375,-8.671875 H 1.734375 L 3.90625,-1.125 h 0.578125 l 2.1875,-7.546875 H 7.96875 L 4.359375,3.859375 H 3.0625 L 4.1875,0 H 2.90625 Z m 0,0"
+ id="path4904" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4918"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(162.69968,545.60918)"
+ id="g4916">
+ <g
+ id="g4914">
+ <path
+ d="M 1.25,3.859375 V -8.671875 H 2.53125 V -8.0625 c 0.882812,-0.53125 1.753906,-0.796875 2.609375,-0.796875 1.09375,0 1.890625,0.355469 2.390625,1.0625 0.5,0.699219 0.75,1.855469 0.75,3.46875 0,1.605469 -0.292969,2.757813 -0.875,3.453125 C 6.820312,-0.175781 5.851562,0.171875 4.5,0.171875 c -0.710938,0 -1.359375,-0.0625 -1.953125,-0.1875 v 3.875 z M 4.953125,-7.6875 c -0.355469,0 -0.730469,0.058594 -1.125,0.171875 C 3.429688,-7.398438 3.113281,-7.285156 2.875,-7.171875 L 2.546875,-7 v 5.859375 c 0.820313,0.125 1.445313,0.1875 1.875,0.1875 0.9375,0 1.59375,-0.265625 1.96875,-0.796875 0.382813,-0.53125 0.578125,-1.394531 0.578125,-2.59375 0,-1.207031 -0.171875,-2.066406 -0.515625,-2.578125 -0.34375,-0.507813 -0.84375,-0.765625 -1.5,-0.765625 z m 0,0"
+ id="path4912" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4926"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(171.84508,545.60918)"
+ id="g4924">
+ <g
+ id="g4922">
+ <path
+ d="m 7.15625,-1.078125 0.5,-0.046875 0.03125,1.015625 C 6.375,0.078125 5.25,0.171875 4.3125,0.171875 3.0625,0.171875 2.175781,-0.1875 1.65625,-0.90625 1.132812,-1.632812 0.875,-2.757812 0.875,-4.28125 c 0,-3.050781 1.207031,-4.578125 3.625,-4.578125 1.164062,0 2.035156,0.328125 2.609375,0.984375 0.582031,0.65625 0.875,1.683594 0.875,3.078125 l -0.0625,1 H 2.1875 c 0,0.960937 0.171875,1.671875 0.515625,2.140625 0.351563,0.460938 0.957031,0.6875 1.8125,0.6875 0.863281,0 1.742187,-0.035156 2.640625,-0.109375 z M 6.6875,-4.84375 c 0,-1.0625 -0.171875,-1.8125 -0.515625,-2.25 C 5.828125,-7.539062 5.269531,-7.765625 4.5,-7.765625 c -0.773438,0 -1.351562,0.234375 -1.734375,0.703125 -0.386719,0.460938 -0.585937,1.199219 -0.59375,2.21875 z m 0,0"
+ id="path4920" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4932"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(180.6087,545.60918)"
+ id="g4930">
+ <g
+ id="g4928" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4940"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(184.42651,545.60918)"
+ id="g4938">
+ <g
+ id="g4936">
+ <path
+ d="m 8.515625,0 h -7.3125 v -1.125 l 3.34375,-3.53125 c 0.582031,-0.601562 1.003906,-1.0625 1.265625,-1.375 0.269531,-0.3125 0.507812,-0.679688 0.71875,-1.109375 0.21875,-0.425781 0.328125,-0.851563 0.328125,-1.28125 0,-0.738281 -0.203125,-1.257813 -0.609375,-1.5625 -0.40625,-0.300781 -1.039062,-0.453125 -1.890625,-0.453125 -0.75,0 -1.589844,0.101562 -2.515625,0.296875 l -0.453125,0.09375 -0.109375,-1.109375 c 1.101562,-0.3125 2.238281,-0.46875 3.40625,-0.46875 1.164062,0 2.046875,0.246094 2.640625,0.734375 0.601563,0.492187 0.90625,1.265625 0.90625,2.328125 0,0.8125 -0.183594,1.523438 -0.546875,2.125 -0.355469,0.605469 -0.976562,1.328125 -1.859375,2.171875 L 2.78125,-1.15625 h 5.734375 z m 0,0"
+ id="path4934" />
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#00b091b271)"
+ id="g4944"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:none;stroke:#000000;stroke-width:0.26499999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
- d="M 111.125,143.54167 H 127"
- id="path1149"
- inkscape:connector-curvature="0" />
+ fill="#306998"
+ d="m 125.32813,618.67969 v -43.44532 c 0,-0.52343 0.0508,-1.04687 0.15625,-1.55859 0.10156,-0.51562 0.25,-1.01562 0.45312,-1.5 0.19922,-0.48437 0.44531,-0.94531 0.73438,-1.38281 0.29296,-0.4375 0.62109,-0.83985 0.99218,-1.21094 0.3711,-0.37109 0.77344,-0.70312 1.20703,-0.99609 0.4375,-0.28907 0.89453,-0.53907 1.37891,-0.73828 0.48437,-0.19922 0.98437,-0.35157 1.49609,-0.45313 0.51172,-0.10547 1.03125,-0.15625 1.55469,-0.15625 h 72.875 c 0.52344,0 1.04297,0.0508 1.55859,0.15625 0.51172,0.10156 1.01172,0.25391 1.49219,0.45313 0.48438,0.19921 0.94531,0.44921 1.37891,0.73828 0.4375,0.29297 0.83984,0.625 1.20703,0.99609 0.37109,0.37109 0.70312,0.77344 0.99219,1.21094 0.29297,0.4375 0.53906,0.89844 0.73828,1.38281 0.19922,0.48438 0.35156,0.98438 0.45312,1.5 0.10157,0.51172 0.15235,1.03516 0.15235,1.55859 v 43.44532 c 0,0.52343 -0.0508,1.04297 -0.15235,1.55859 -0.10156,0.51563 -0.2539,1.01563 -0.45312,1.5 -0.19922,0.48438 -0.44531,0.94531 -0.73828,1.38281 -0.28907,0.4375 -0.6211,0.83985 -0.99219,1.21094 -0.36719,0.37109 -0.76953,0.70313 -1.20703,0.99609 -0.4336,0.28907 -0.89453,0.53516 -1.37891,0.73829 -0.48047,0.19921 -0.98047,0.35156 -1.49219,0.45312 -0.51562,0.10547 -1.03515,0.15625 -1.55859,0.15625 h -72.875 c -0.52344,0 -1.04297,-0.0508 -1.55469,-0.15625 -0.51172,-0.10156 -1.01172,-0.25391 -1.49609,-0.45312 -0.48438,-0.20313 -0.94141,-0.44922 -1.37891,-0.73829 -0.43359,-0.29296 -0.83593,-0.625 -1.20703,-0.99609 -0.37109,-0.37109 -0.69922,-0.77344 -0.99218,-1.21094 -0.28907,-0.4375 -0.53516,-0.89843 -0.73438,-1.38281 -0.20312,-0.48437 -0.35156,-0.98437 -0.45312,-1.5 -0.10547,-0.51562 -0.15625,-1.03516 -0.15625,-1.55859 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4942" />
+ </g>
+ <g
+ clip-path="url(#be13ebcaaa)"
+ id="g4948"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker1443)"
- d="M 111.125,175.29167 H 127"
- id="path1433"
- inkscape:connector-curvature="0" />
+ fill="#306998"
+ d="m 214.60547,575.23437 v 43.44141 c 0,0.55859 -0.0508,1.10547 -0.16016,1.65234 -0.10937,0.54297 -0.26953,1.07422 -0.48047,1.58594 -0.21093,0.51172 -0.47265,1 -0.77734,1.46094 -0.30859,0.46094 -0.66016,0.89062 -1.05078,1.28125 -0.39063,0.39453 -0.81641,0.74219 -1.27735,1.05078 -0.46093,0.30859 -0.94531,0.57031 -1.45703,0.78125 -0.51172,0.21484 -1.03906,0.375 -1.58203,0.48438 -0.54297,0.10546 -1.08984,0.16015 -1.64453,0.16015 h -72.87109 c -0.55469,0 -1.10547,-0.0547 -1.64844,-0.16015 -0.54297,-0.10938 -1.07031,-0.26954 -1.57813,-0.48438 -0.51171,-0.21094 -1,-0.47266 -1.46093,-0.78125 -0.46094,-0.30859 -0.88672,-0.65625 -1.27735,-1.05078 -0.39062,-0.39063 -0.73828,-0.82031 -1.04687,-1.28125 -0.30859,-0.46094 -0.56641,-0.94922 -0.78125,-1.46094 -0.21094,-0.51172 -0.37109,-1.04297 -0.47656,-1.58594 -0.10938,-0.54687 -0.16407,-1.09375 -0.16407,-1.65234 v -43.44141 c 0,-0.55468 0.0547,-1.10546 0.16407,-1.64843 0.10547,-0.54688 0.26562,-1.07422 0.47656,-1.58594 0.21484,-0.51563 0.47266,-1.00391 0.78125,-1.46484 0.30859,-0.46094 0.65625,-0.88672 1.04687,-1.28125 0.39063,-0.39063 0.81641,-0.74219 1.27735,-1.05079 0.46093,-0.30859 0.94922,-0.57031 1.46093,-0.78125 0.50782,-0.21484 1.03516,-0.375 1.57813,-0.48046 0.54297,-0.10938 1.09375,-0.16407 1.64844,-0.16407 h 72.87109 c 0.55469,0 1.10156,0.0547 1.64453,0.16407 0.54297,0.10937 1.07031,0.26953 1.58203,0.48046 0.51172,0.21094 1,0.47266 1.45703,0.78125 0.46094,0.3086 0.88672,0.66016 1.27735,1.05079 0.39453,0.39453 0.74219,0.82031 1.05078,1.28125 0.30469,0.46484 0.56641,0.94921 0.77734,1.46484 0.21094,0.51172 0.3711,1.03906 0.48047,1.58594 0.10938,0.54297 0.16016,1.09375 0.16016,1.64843 z m -88.81641,43.44141 c 0,0.49609 0.0469,0.98828 0.14453,1.47266 0.0937,0.48437 0.23829,0.95703 0.42579,1.41406 0.1875,0.45703 0.42187,0.89062 0.69531,1.30078 0.27344,0.41406 0.58594,0.79297 0.93359,1.14453 0.34766,0.34766 0.73047,0.66016 1.14063,0.9375 0.41015,0.27344 0.84375,0.50781 1.29687,0.69531 0.45703,0.19141 0.92578,0.33204 1.41016,0.42969 0.48437,0.0977 0.97265,0.14453 1.46875,0.14453 h 72.87109 c 0.49609,0 0.98438,-0.0469 1.46875,-0.14453 0.48438,-0.0976 0.95313,-0.23828 1.41016,-0.42969 0.45312,-0.1875 0.88672,-0.42187 1.29687,-0.69531 0.41016,-0.27734 0.78906,-0.58984 1.14063,-0.9375 0.34765,-0.35156 0.66015,-0.73047 0.93359,-1.14453 0.27344,-0.41016 0.50781,-0.84375 0.69531,-1.30078 0.1875,-0.45703 0.33203,-0.92969 0.42578,-1.41406 0.0977,-0.48438 0.14454,-0.97657 0.14454,-1.47266 v -43.44141 c 0,-0.49609 -0.0469,-0.98437 -0.14454,-1.46875 -0.0937,-0.48828 -0.23828,-0.95703 -0.42578,-1.41406 -0.1875,-0.45703 -0.42187,-0.89453 -0.69531,-1.30469 -0.27344,-0.41015 -0.58594,-0.79296 -0.93359,-1.14062 -0.35157,-0.35156 -0.73047,-0.66406 -1.14063,-0.9375 -0.41015,-0.27734 -0.84375,-0.50781 -1.29687,-0.69922 -0.45703,-0.1875 -0.92578,-0.33203 -1.41016,-0.42969 -0.48437,-0.0937 -0.97266,-0.14453 -1.46875,-0.14453 h -72.87109 c -0.4961,0 -0.98438,0.0508 -1.46875,0.14453 -0.48438,0.0977 -0.95313,0.24219 -1.41016,0.42969 -0.45312,0.19141 -0.88672,0.42188 -1.29687,0.69922 -0.41016,0.27344 -0.79297,0.58594 -1.14063,0.9375 -0.34765,0.34766 -0.66015,0.73047 -0.93359,1.14062 -0.27344,0.41016 -0.50781,0.84766 -0.69531,1.30469 -0.1875,0.45703 -0.33204,0.92578 -0.42579,1.41406 -0.0977,0.48438 -0.14453,0.97266 -0.14453,1.46875 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path4946" />
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4956"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(143.38693,591.17926)"
+ id="g4954">
+ <g
+ id="g4952">
+ <path
+ d="M 5.875,-4.046875 H 2.8125 V 0 H 1.46875 V -12.015625 H 5.875 c 1.300781,0 2.265625,0.320313 2.890625,0.953125 0.625,0.636719 0.9375,1.609375 0.9375,2.921875 0,2.730469 -1.277344,4.09375 -3.828125,4.09375 z M 2.8125,-5.21875 h 3.03125 c 1.65625,0 2.484375,-0.972656 2.484375,-2.921875 0,-0.925781 -0.199219,-1.601563 -0.59375,-2.03125 -0.386719,-0.4375 -1.015625,-0.65625 -1.890625,-0.65625 H 2.8125 Z m 0,0"
+ id="path4950" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4964"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(153.67768,591.17926)"
+ id="g4962">
+ <g
+ id="g4960">
+ <path
+ d="M 0.4375,-8.671875 H 1.734375 L 3.90625,-1.125 h 0.578125 l 2.1875,-7.546875 H 7.96875 L 4.359375,3.859375 H 3.0625 L 4.1875,0 H 2.90625 Z m 0,0"
+ id="path4958" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4972"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(162.05952,591.17926)"
+ id="g4970">
+ <g
+ id="g4968">
+ <path
+ d="M 5.75,-7.546875 H 2.984375 v 4.140625 c 0,1 0.070313,1.65625 0.21875,1.96875 0.144531,0.3125 0.488281,0.46875 1.03125,0.46875 L 5.78125,-1.078125 5.875,0 C 5.09375,0.125 4.5,0.1875 4.09375,0.1875 3.195312,0.1875 2.570312,-0.03125 2.21875,-0.46875 1.875,-0.90625 1.703125,-1.742188 1.703125,-2.984375 v -4.5625 H 0.46875 v -1.125 h 1.234375 v -2.65625 h 1.28125 v 2.65625 H 5.75 Z m 0,0"
+ id="path4966" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4980"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(168.15067,591.17926)"
+ id="g4978">
+ <g
+ id="g4976">
+ <path
+ d="M 2.546875,0 H 1.25 v -12.46875 h 1.296875 v 4.28125 c 0.925781,-0.445312 1.816406,-0.671875 2.671875,-0.671875 1.164062,0 1.945312,0.3125 2.34375,0.9375 0.394531,0.625 0.59375,1.742187 0.59375,3.34375 V 0 H 6.859375 V -4.546875 C 6.859375,-5.753906 6.738281,-6.578125 6.5,-7.015625 6.257812,-7.460938 5.757812,-7.6875 5,-7.6875 c -0.730469,0 -1.4375,0.132812 -2.125,0.390625 l -0.328125,0.125 z m 0,0"
+ id="path4974" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4988"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(177.4696,591.17926)"
+ id="g4986">
+ <g
+ id="g4984">
+ <path
+ d="m 0.875,-4.359375 c 0,-1.582031 0.28125,-2.726563 0.84375,-3.4375 0.5625,-0.707031 1.515625,-1.0625 2.859375,-1.0625 1.351563,0 2.3125,0.355469 2.875,1.0625 0.5625,0.710937 0.84375,1.855469 0.84375,3.4375 C 8.296875,-2.773438 8.03125,-1.625 7.5,-0.90625 6.96875,-0.1875 5.992188,0.171875 4.578125,0.171875 c -1.40625,0 -2.375,-0.359375 -2.90625,-1.078125 C 1.140625,-1.625 0.875,-2.773438 0.875,-4.359375 Z M 2.203125,-4.375 c 0,1.261719 0.148437,2.148438 0.453125,2.65625 0.3125,0.511719 0.957031,0.765625 1.9375,0.765625 0.976562,0 1.617188,-0.25 1.921875,-0.75 C 6.816406,-2.210938 6.96875,-3.101562 6.96875,-4.375 6.96875,-5.644531 6.796875,-6.519531 6.453125,-7 6.117188,-7.476562 5.5,-7.71875 4.59375,-7.71875 3.6875,-7.71875 3.0625,-7.476562 2.71875,-7 2.375,-6.519531 2.203125,-5.644531 2.203125,-4.375 Z m 0,0"
+ id="path4982" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g4996"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(186.63236,591.17926)"
+ id="g4994">
+ <g
+ id="g4992">
+ <path
+ d="M 2.546875,0 H 1.25 v -8.671875 h 1.28125 v 0.59375 c 0.9375,-0.519531 1.832031,-0.78125 2.6875,-0.78125 1.164062,0 1.945312,0.3125 2.34375,0.9375 0.394531,0.625 0.59375,1.742187 0.59375,3.34375 V 0 H 6.875 v -4.546875 c 0,-1.207031 -0.121094,-2.03125 -0.359375,-2.46875 C 6.273438,-7.460938 5.769531,-7.6875 5,-7.6875 c -0.375,0 -0.765625,0.058594 -1.171875,0.171875 -0.40625,0.105469 -0.726563,0.210937 -0.953125,0.3125 l -0.328125,0.15625 z m 0,0"
+ id="path4990" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g5004"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(145.18979,615.43933)"
+ id="g5002">
+ <g
+ id="g5000">
+ <path
+ d="m 0.21875,-10.8125 v -1.203125 h 8.6875 V -10.8125 H 5.25 V 0 H 3.921875 v -10.8125 z m 0,0"
+ id="path4998" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g5012"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(154.31784,615.43933)"
+ id="g5010">
+ <g
+ id="g5008">
+ <path
+ d="M 0.4375,-8.671875 H 1.734375 L 3.90625,-1.125 h 0.578125 l 2.1875,-7.546875 H 7.96875 L 4.359375,3.859375 H 3.0625 L 4.1875,0 H 2.90625 Z m 0,0"
+ id="path5006" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g5020"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(162.69968,615.43933)"
+ id="g5018">
+ <g
+ id="g5016">
+ <path
+ d="M 1.25,3.859375 V -8.671875 H 2.53125 V -8.0625 c 0.882812,-0.53125 1.753906,-0.796875 2.609375,-0.796875 1.09375,0 1.890625,0.355469 2.390625,1.0625 0.5,0.699219 0.75,1.855469 0.75,3.46875 0,1.605469 -0.292969,2.757813 -0.875,3.453125 C 6.820312,-0.175781 5.851562,0.171875 4.5,0.171875 c -0.710938,0 -1.359375,-0.0625 -1.953125,-0.1875 v 3.875 z M 4.953125,-7.6875 c -0.355469,0 -0.730469,0.058594 -1.125,0.171875 C 3.429688,-7.398438 3.113281,-7.285156 2.875,-7.171875 L 2.546875,-7 v 5.859375 c 0.820313,0.125 1.445313,0.1875 1.875,0.1875 0.9375,0 1.59375,-0.265625 1.96875,-0.796875 0.382813,-0.53125 0.578125,-1.394531 0.578125,-2.59375 0,-1.207031 -0.171875,-2.066406 -0.515625,-2.578125 -0.34375,-0.507813 -0.84375,-0.765625 -1.5,-0.765625 z m 0,0"
+ id="path5014" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g5028"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(171.84508,615.43933)"
+ id="g5026">
+ <g
+ id="g5024">
+ <path
+ d="m 7.15625,-1.078125 0.5,-0.046875 0.03125,1.015625 C 6.375,0.078125 5.25,0.171875 4.3125,0.171875 3.0625,0.171875 2.175781,-0.1875 1.65625,-0.90625 1.132812,-1.632812 0.875,-2.757812 0.875,-4.28125 c 0,-3.050781 1.207031,-4.578125 3.625,-4.578125 1.164062,0 2.035156,0.328125 2.609375,0.984375 0.582031,0.65625 0.875,1.683594 0.875,3.078125 l -0.0625,1 H 2.1875 c 0,0.960937 0.171875,1.671875 0.515625,2.140625 0.351563,0.460938 0.957031,0.6875 1.8125,0.6875 0.863281,0 1.742187,-0.035156 2.640625,-0.109375 z M 6.6875,-4.84375 c 0,-1.0625 -0.171875,-1.8125 -0.515625,-2.25 C 5.828125,-7.539062 5.269531,-7.765625 4.5,-7.765625 c -0.773438,0 -1.351562,0.234375 -1.734375,0.703125 -0.386719,0.460938 -0.585937,1.199219 -0.59375,2.21875 z m 0,0"
+ id="path5022" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g5034"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(180.6087,615.43933)"
+ id="g5032">
+ <g
+ id="g5030" />
+ </g>
+ </g>
+ <g
+ fill="#fefeff"
+ fill-opacity="1"
+ id="g5042"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ transform="translate(184.42651,615.43933)"
+ id="g5040">
+ <g
+ id="g5038">
+ <path
+ d="m 1.25,-11.15625 c 1.082031,-0.320312 2.242188,-0.484375 3.484375,-0.484375 1.25,0 2.148437,0.242187 2.703125,0.71875 0.5625,0.46875 0.84375,1.226563 0.84375,2.265625 0,0.53125 -0.074219,0.917969 -0.21875,1.15625 -0.148438,0.230469 -0.261719,0.414062 -0.34375,0.546875 -0.085938,0.125 -0.199219,0.246094 -0.34375,0.359375 -0.25,0.199219 -0.453125,0.335938 -0.609375,0.40625 l -0.1875,0.125 c 0.675781,0.25 1.175781,0.5625 1.5,0.9375 0.320313,0.375 0.484375,0.992188 0.484375,1.84375 0,1.167969 -0.304688,2.039062 -0.90625,2.609375 -0.59375,0.5625 -1.53125,0.84375 -2.8125,0.84375 -1.023438,0 -2.101562,-0.1171875 -3.234375,-0.34375 l -0.53125,-0.125 0.125,-1.09375 C 2.453125,-1.128906 3.617188,-1 4.703125,-1 6.359375,-1.019531 7.1875,-1.765625 7.1875,-3.234375 c 0,-1.375 -0.789062,-2.085937 -2.359375,-2.140625 h -2.3125 v -1.15625 h 2.3125 c 0.488281,0 0.957031,-0.191406 1.40625,-0.578125 0.445313,-0.382813 0.671875,-0.894531 0.671875,-1.53125 0,-0.632813 -0.183594,-1.09375 -0.546875,-1.375 -0.355469,-0.289063 -0.953125,-0.4375 -1.796875,-0.4375 -0.929688,0 -1.839844,0.08984 -2.734375,0.265625 L 1.375,-10.109375 Z m 0,0"
+ id="path5036" />
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#12ef88673f)"
+ id="g5046"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker1479)"
- d="M 111.125,196.45834 127,185.875"
- id="path1469"
- inkscape:connector-curvature="0" />
+ fill="#000000"
+ d="m 293.44922,366.47266 15.07422,-14.98829 -15.07422,-15.01171 -3.37891,3.36328 9.27344,9.26562 h -56.76953 v 4.76563 h 56.76953 l -9.27344,9.23828 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path5044" />
+ </g>
+ <g
+ clip-path="url(#4425bd08fe)"
+ id="g5050"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker1521)"
- d="M 111.125,217.625 127,201.75"
- id="path1511"
- inkscape:connector-curvature="0" />
+ fill="#000000"
+ d="m 554.83203,366.47266 15.07422,-14.98829 -15.07422,-15.01171 -3.38281,3.36328 9.27344,9.26562 h -56.76954 v 4.76563 h 56.76954 l -9.27344,9.23828 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path5048" />
+ </g>
+ <g
+ clip-path="url(#29f410bb45)"
+ id="g5054"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker1569)"
- d="m 195.79166,185.875 h 15.875"
- id="path1559"
- inkscape:connector-curvature="0" />
+ fill="#000000"
+ d="m 554.83203,542.04297 15.07422,-14.98438 -15.07422,-15.01562 -3.38281,3.36719 9.27344,9.26562 h -56.76954 v 4.76563 h 56.76954 l -9.27344,9.23828 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path5052" />
+ </g>
+ <g
+ clip-path="url(#8612924f50)"
+ id="g5058"
+ transform="translate(-69.242111,-250.64609)">
<path
- style="fill:none;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker1623)"
- d="m 195.79166,138.25001 h 15.875"
- id="path1613"
- inkscape:connector-curvature="0" />
+ fill="#000000"
+ d="m 287.44531,541.73437 15.07422,-14.98828 -15.07422,-15.01172 -3.3789,3.36329 9.26953,9.26562 h -56.76953 v 4.76953 h 56.76953 l -9.26953,9.23438 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path5056" />
+ </g>
+ <g
+ clip-path="url(#9616827f5c)"
+ id="g5068"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ clip-path="url(#6d6215aef9)"
+ id="g5066">
+ <g
+ clip-path="url(#506e24dd3d)"
+ id="g5064">
+ <g
+ clip-path="url(#85c10bb5f0)"
+ id="g5062">
+ <path
+ fill="#000000"
+ d="m 279.46094,488.74609 19.99609,-7.21093 -7.32031,-19.98047 -4.48438,1.625 4.48828,12.3125 -51.44921,-23.98828 -2.01563,4.32031 51.44922,23.98828 -12.30469,4.45312 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path5060" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#96382ab88a)"
+ id="g5078"
+ transform="translate(-69.242111,-250.64609)">
+ <g
+ clip-path="url(#8ee2f579d3)"
+ id="g5076">
+ <g
+ clip-path="url(#c24345751d)"
+ id="g5074">
+ <g
+ clip-path="url(#6c1dc82097)"
+ id="g5072">
+ <path
+ fill="#000000"
+ d="m 279.46094,565.48437 19.99609,7.21094 -7.32031,19.97656 -4.48438,-1.62109 4.48828,-12.31641 -51.44921,23.99219 -2.01563,-4.32031 51.44922,-23.99219 -12.30469,-4.44922 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path5070" />
+ </g>
+ </g>
+ </g>
</g>
</svg>
diff --git a/sources/shiboken6/doc/images/genrunnerarch.png b/sources/shiboken6/doc/images/genrunnerarch.png
deleted file mode 100644
index db1077cd0..000000000
--- a/sources/shiboken6/doc/images/genrunnerarch.png
+++ /dev/null
Binary files differ
diff --git a/sources/shiboken6/doc/images/genrunnerarch.svg b/sources/shiboken6/doc/images/genrunnerarch.svg
deleted file mode 100644
index ea7eb73e7..000000000
--- a/sources/shiboken6/doc/images/genrunnerarch.svg
+++ /dev/null
@@ -1,654 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="980"
- height="380"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.47pre4 r22446"
- version="1.0"
- sodipodi:docname="genrunnerarch.svg"
- inkscape:output_extension="org.inkscape.output.svg.inkscape"
- inkscape:export-filename="genrunnerarch.png"
- inkscape:export-xdpi="56.549999"
- inkscape:export-ydpi="56.549999">
- <defs
- id="defs4">
- <marker
- inkscape:stockid="EmptyDiamondL"
- orient="auto"
- refY="0"
- refX="0"
- id="EmptyDiamondL"
- style="overflow:visible">
- <path
- id="path3930"
- d="M 0,-7.0710768 -7.0710894,0 0,7.0710589 7.0710462,0 0,-7.0710768 z"
- style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
- transform="scale(0.8,0.8)" />
- </marker>
- <marker
- inkscape:stockid="EmptyTriangleInL"
- orient="auto"
- refY="0"
- refX="0"
- id="EmptyTriangleInL"
- style="overflow:visible">
- <path
- id="path3975"
- d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
- style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
- transform="matrix(-0.8,0,0,-0.8,4.8,0)" />
- </marker>
- <marker
- inkscape:stockid="Arrow1Sstart"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Sstart"
- style="overflow:visible">
- <path
- id="path3835"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
- transform="matrix(0.2,0,0,0.2,1.2,0)" />
- </marker>
- <marker
- inkscape:stockid="Arrow1Mend"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Mend"
- style="overflow:visible">
- <path
- id="path3832"
- d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
- style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
- transform="matrix(-0.4,0,0,-0.4,-4,0)" />
- </marker>
- <marker
- inkscape:stockid="Tail"
- orient="auto"
- refY="0"
- refX="0"
- id="Tail"
- style="overflow:visible">
- <g
- id="g3859"
- transform="scale(-1.2,-1.2)">
- <path
- id="path3861"
- d="M -3.8048674,-3.9585227 0.54352094,0"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none" />
- <path
- id="path3863"
- d="M -1.2866832,-3.9585227 3.0617053,0"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none" />
- <path
- id="path3865"
- d="M 1.3053582,-3.9585227 5.6537466,0"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none" />
- <path
- id="path3867"
- d="M -3.8048674,4.1775838 0.54352094,0.21974226"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none" />
- <path
- id="path3869"
- d="M -1.2866832,4.1775838 3.0617053,0.21974226"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none" />
- <path
- id="path3871"
- d="M 1.3053582,4.1775838 5.6537466,0.21974226"
- style="fill:none;stroke:#000000;stroke-width:0.80000001;stroke-linecap:round;marker-start:none;marker-end:none" />
- </g>
- </marker>
- <marker
- inkscape:stockid="Arrow2Lend"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow2Lend"
- style="overflow:visible">
- <path
- id="path3636"
- style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
- d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
- transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
- </marker>
- <inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 526.18109 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="744.09448 : 526.18109 : 1"
- inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
- id="perspective10" />
- <inkscape:perspective
- id="perspective3033"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" />
- <inkscape:perspective
- id="perspective3881"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" />
- <inkscape:perspective
- id="perspective3915"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" />
- <inkscape:perspective
- id="perspective3956"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" />
- <inkscape:perspective
- id="perspective5100"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" />
- <inkscape:perspective
- id="perspective5322"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" />
- <inkscape:perspective
- id="perspective5365"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" />
- <inkscape:perspective
- id="perspective5391"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" />
- <marker
- inkscape:stockid="EmptyTriangleInL"
- orient="auto"
- refY="0"
- refX="0"
- id="EmptyTriangleInL-4"
- style="overflow:visible">
- <path
- id="path3975-9"
- d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
- style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
- transform="matrix(-0.8,0,0,-0.8,4.8,0)" />
- </marker>
- <inkscape:perspective
- id="perspective5621"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" />
- <inkscape:perspective
- id="perspective5643"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" />
- <marker
- inkscape:stockid="EmptyDiamondL"
- orient="auto"
- refY="0"
- refX="0"
- id="EmptyDiamondL-7"
- style="overflow:visible">
- <path
- id="path3930-7"
- d="M 0,-7.0710768 -7.0710894,0 0,7.0710589 7.0710462,0 0,-7.0710768 z"
- style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
- transform="scale(0.8,0.8)" />
- </marker>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- gridtolerance="10000"
- guidetolerance="10"
- objecttolerance="10"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1.0716799"
- inkscape:cx="460.27913"
- inkscape:cy="148.01364"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="1862"
- inkscape:window-height="1019"
- inkscape:window-x="20"
- inkscape:window-y="89"
- showguides="true"
- inkscape:guide-bbox="true"
- inkscape:window-maximized="0" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(472.44407,-697.53823)">
- <flowRoot
- xml:space="preserve"
- id="flowRoot3229"
- style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- transform="translate(2.0918751e-6,-6.0000008)"><flowRegion
- id="flowRegion3231"><rect
- id="rect3233"
- width="125.74072"
- height="40.5849"
- x="388.45547"
- y="279.5423" /></flowRegion><flowPara
- id="flowPara3235" /></flowRoot> <g
- id="g5867"
- transform="translate(6.7062969,-7.6922472)">
- <rect
- rx="3.4968286"
- ry="5.2462597"
- y="713.31403"
- x="-472.05276"
- height="363.61459"
- width="393.78473"
- id="rect3609"
- style="fill:#e4fae3;fill-opacity:0.65882353;stroke:#8eff89;stroke-width:0.78260708;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <text
- transform="scale(1.0000266,0.9999734)"
- id="text3601"
- y="742.43872"
- x="-275.16165"
- style="font-size:38.71272278px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- id="tspan3605"
- style="font-size:27.09890556px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
- y="742.43872"
- x="-275.16165"
- sodipodi:role="line"><tspan
- id="tspan2508"
- style="font-weight:bold">API Extractor</tspan></tspan></text>
- <g
- transform="matrix(0.9678438,0,0,0.9677923,-587.62742,-106.48682)"
- id="g3763">
- <rect
- style="fill:#bff3bc;fill-opacity:1;stroke:#0af400;stroke-width:0.79775763;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="rect3737"
- width="244.82956"
- height="101.59812"
- x="267.06232"
- y="905.13727"
- ry="3.1522403"
- rx="2.4096873" />
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="389.39117"
- y="931.86993"
- id="text3739"><tspan
- sodipodi:role="line"
- x="389.39117"
- y="931.86993"
- style="font-size:22px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold"
- id="tspan3741">ApiExtractor</tspan><tspan
- id="tspan2523"
- sodipodi:role="line"
- x="389.39117"
- y="953.38947"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">commands the parsing and</tspan><tspan
- id="tspan2517"
- sodipodi:role="line"
- x="389.39117"
- y="973.38947"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">building of the data model</tspan><tspan
- id="tspan2519"
- sodipodi:role="line"
- x="389.39117"
- y="993.38947"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">and calls the user generators</tspan></text>
- </g>
- <rect
- rx="2.1814992"
- ry="5.2485871"
- y="713.45312"
- x="219.72128"
- height="363.77597"
- width="274.11292"
- id="rect9190"
- style="fill:#b8d1f1;fill-opacity:0.51184836;stroke:#0045a4;stroke-width:0.6182732;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <text
- transform="scale(1.0000266,0.9999734)"
- id="text9192"
- y="742.66901"
- x="357.65579"
- style="font-size:38.71272278px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#002e7a;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- id="tspan9194"
- style="font-size:27.09890556px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#002e7a;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
- y="742.66901"
- x="357.65579"
- sodipodi:role="line"><tspan
- id="tspan2512"
- style="font-weight:bold;fill:#002e7a;fill-opacity:1">front-end</tspan><tspan
- id="tspan2514"
- style="font-size:22px;fill:#002e7a;fill-opacity:1" /></tspan></text>
- <rect
- rx="2.2192271"
- ry="5.2485123"
- y="713.23639"
- x="-68.659073"
- height="363.77075"
- width="278.85358"
- id="rect9190-9"
- style="fill:#cbe990;fill-opacity:0.51184836;stroke:#6ca400;stroke-width:0.62359226;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <text
- transform="scale(1.0000266,0.9999734)"
- id="text9192-3"
- y="741.71094"
- x="70.291061"
- style="font-size:38.71272278px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#050800;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- xml:space="preserve"><tspan
- id="tspan9194-7"
- style="font-size:26px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#050800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
- y="741.71094"
- x="70.291061"
- sodipodi:role="line">Generator Runner</tspan></text>
- <g
- transform="matrix(0.9678438,0,0,0.9677923,-687.04869,-241.74888)"
- id="g9234-4">
- <rect
- style="fill:#addc52;fill-opacity:1;stroke:#6ca400;stroke-width:0.73640609;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="rect9206-4"
- width="218.17299"
- height="83.517967"
- x="694.6994"
- y="1044.8701"
- ry="2.5912752"
- rx="2.4978092" />
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="803.78589"
- y="1072.3693"
- id="text9208-3"><tspan
- sodipodi:role="line"
- x="803.78589"
- y="1072.3693"
- style="font-size:22px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#050800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold"
- id="tspan9210-0">Generator</tspan><tspan
- id="tspan9222-8"
- sodipodi:role="line"
- x="803.78589"
- y="1093.8888"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#050800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">base class for front-end</tspan><tspan
- id="tspan3946"
- sodipodi:role="line"
- x="803.78589"
- y="1113.8888"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#050800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">output classes</tspan></text>
- </g>
- <g
- transform="matrix(0.9678438,0,0,0.9677923,-726.09128,-46.791689)"
- id="g10497-6">
- <rect
- style="fill:#89b3e7;fill-opacity:1;stroke:#0049a4;stroke-width:1.04736876;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="rect10444-8"
- width="256.05252"
- height="143.95157"
- x="990.81482"
- y="843.58032"
- ry="4.4663219"
- rx="2.9314826" />
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#002758;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="1118.0945"
- y="873.04047"
- id="text10446-8"><tspan
- sodipodi:role="line"
- x="1118.0945"
- y="873.04047"
- style="font-size:22px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#002758;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold"
- id="tspan10448-4">SpecificGenerator</tspan><tspan
- id="tspan4063"
- sodipodi:role="line"
- x="1118.0945"
- y="894.56"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#002758;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">generators written for any</tspan><tspan
- id="tspan5381"
- sodipodi:role="line"
- x="1118.0945"
- y="914.56"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#002758;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">desired output,</tspan><tspan
- id="tspan4065"
- sodipodi:role="line"
- x="1118.0945"
- y="934.56"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#002758;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"> e.g.: HppGenerator,</tspan><tspan
- id="tspan4071"
- sodipodi:role="line"
- x="1118.0945"
- y="954.56"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#002758;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">CppGenerator,</tspan><tspan
- id="tspan4073"
- sodipodi:role="line"
- x="1118.0945"
- y="974.56"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#002758;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">ConverterGenerator</tspan></text>
- </g>
- <path
- sodipodi:nodetypes="cc"
- transform="translate(109.91989,748.26874)"
- id="path4056"
- d="m -201.98482,41.728896 76.97065,5e-6"
- style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:6, 1;stroke-dashoffset:0" />
- <path
- sodipodi:nodetypes="cc"
- id="path4056-2"
- d="m 197.04022,787.89746 35.38656,0"
- style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker-start:url(#EmptyTriangleInL)" />
- <g
- transform="matrix(0.9678438,0,0,0.9677923,-1010.4541,91.401187)"
- id="g10497">
- <rect
- style="fill:#addc52;fill-opacity:1;stroke:#6ca400;stroke-width:0.88060772;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="rect10444"
- width="256.21927"
- height="101.69494"
- x="990.73145"
- y="843.49695"
- ry="3.1552441"
- rx="2.9333918" />
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;text-align:start;text-anchor:start;fill:#035800;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="1012.22"
- y="870.08466"
- id="text10446"><tspan
- sodipodi:role="line"
- x="1012.22"
- y="870.08466"
- style="font-size:22px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;text-anchor:start;fill:#050800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold"
- id="tspan10448">Generator App</tspan><tspan
- id="tspan10456"
- sodipodi:role="line"
- x="1012.22"
- y="891.60419"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;fill:#050800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">* loads generators</tspan><tspan
- id="tspan5353"
- sodipodi:role="line"
- x="1012.22"
- y="911.60419"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;fill:#050800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">* setup API Extractor</tspan><tspan
- id="tspan5355"
- sodipodi:role="line"
- x="1012.22"
- y="931.60419"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;text-anchor:start;fill:#050800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">* executes each generator</tspan></text>
- </g>
- <path
- sodipodi:nodetypes="cc"
- id="path4056-9"
- d="m 72.409302,850.57374 0,56.99122"
- style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:6, 1;stroke-dashoffset:0" />
- <path
- sodipodi:nodetypes="ccc"
- id="path4056-2-0"
- d="m -86.437722,825.54499 52.188784,0 0.06367,81.67009"
- style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker-start:url(#EmptyDiamondL)" />
- <path
- sodipodi:nodetypes="cc"
- id="path4056-91"
- d="m -394.83596,853.70064 0,121.42437"
- style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:6, 1;stroke-dashoffset:0" />
- <g
- transform="matrix(0.9678438,0,0,0.9677923,-707.18032,-153.53291)"
- id="g3809">
- <rect
- style="fill:#bff3bc;fill-opacity:1;stroke:#0af400;stroke-width:1.00168562;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="rect3785"
- width="332.48172"
- height="82.830231"
- x="302.83319"
- y="1068.9153"
- ry="3.1461167"
- rx="3.8065021" />
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="469.03497"
- y="1095.5493"
- id="text3787"><tspan
- id="tspan3791"
- sodipodi:role="line"
- x="469.03497"
- y="1095.5493"
- style="font-size:22px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold">AbstractMetaBuilder</tspan><tspan
- sodipodi:role="line"
- x="469.03497"
- y="1117.0688"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
- id="tspan3807">builds the data model with information</tspan><tspan
- id="tspan2545"
- sodipodi:role="line"
- x="469.03497"
- y="1137.0688"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">from headers and binding directives</tspan><tspan
- id="tspan3795"
- sodipodi:role="line"
- x="469.03497"
- y="1157.0688"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans" /></text>
- </g>
- <g
- transform="matrix(0.9678438,0,0,0.9677923,-755.89347,194.37862)"
- id="g3709">
- <rect
- style="fill:#bff3bc;fill-opacity:1;stroke:#0af400;stroke-width:0.69825613;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="rect2821"
- width="198.90968"
- height="93.892342"
- x="305.2475"
- y="807.38849"
- ry="2.6812849"
- rx="2.1703238" />
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="405.17499"
- y="831.81903"
- id="text3611"><tspan
- id="tspan3687"
- sodipodi:role="line"
- x="405.17499"
- y="831.81903"
- style="font-size:22px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold">TypeDatabase</tspan><tspan
- id="tspan5641"
- sodipodi:role="line"
- x="405.17499"
- y="853.33856"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">parses typesystem</tspan><tspan
- id="tspan3689"
- sodipodi:role="line"
- x="405.17499"
- y="873.33856"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">and stores information</tspan></text>
- </g>
- <g
- transform="matrix(0.9678438,0,0,0.9677923,-589.50555,-13.923919)"
- id="g3728">
- <rect
- style="fill:#bff3bc;fill-opacity:1;stroke:#0af400;stroke-width:0.54871088;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="rect3625"
- width="117.15066"
- height="86.355225"
- x="133.25664"
- y="809.36938"
- ry="2.6793056"
- rx="1.3412292" />
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
- x="191.58197"
- y="838.75159"
- id="text3627"><tspan
- sodipodi:role="line"
- x="191.58197"
- y="838.75159"
- style="font-size:22px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans Bold"
- id="tspan3631">Parser</tspan><tspan
- id="tspan3695"
- sodipodi:role="line"
- x="191.58197"
- y="860.27112"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">parses the</tspan><tspan
- id="tspan3697"
- sodipodi:role="line"
- x="191.58197"
- y="880.27112"
- style="font-size:16px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;fill:#035800;fill-opacity:1;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans">lib headers</tspan></text>
- </g>
- <path
- sodipodi:nodetypes="ccc"
- id="path4056-2-0-1"
- d="m 197.39006,961.71122 158.27877,0 0.19429,-51.88885"
- style="fill:none;stroke:#000000;stroke-width:1.38812411;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:8.32874408, 1.38812401;stroke-dashoffset:0;marker-start:none" />
- </g>
- </g>
-</svg>
diff --git a/sources/shiboken6/doc/images/qtforpython-underthehood.png b/sources/shiboken6/doc/images/qtforpython-underthehood.png
index 64e30b1c5..295cefcf9 100644
--- a/sources/shiboken6/doc/images/qtforpython-underthehood.png
+++ b/sources/shiboken6/doc/images/qtforpython-underthehood.png
Binary files differ
diff --git a/sources/shiboken6/doc/images/qtforpython-underthehood.svg b/sources/shiboken6/doc/images/qtforpython-underthehood.svg
new file mode 100644
index 000000000..8924d9d4b
--- /dev/null
+++ b/sources/shiboken6/doc/images/qtforpython-underthehood.svg
@@ -0,0 +1,1502 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ width="972.87427"
+ zoomAndPan="magnify"
+ viewBox="0 0 729.6557 410.72465"
+ height="547.63287"
+ preserveAspectRatio="xMidYMid"
+ version="1.0"
+ id="svg684"
+ sodipodi:docname="qtforpython-underthehood.svg"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
+ inkscape:export-filename="qtforpython-underthehood.png"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview686"
+ pagecolor="#ffffff"
+ bordercolor="#000000"
+ borderopacity="0.25"
+ inkscape:showpageshadow="2"
+ inkscape:pageopacity="0.0"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1"
+ showgrid="false"
+ inkscape:zoom="0.80648148"
+ inkscape:cx="400.50517"
+ inkscape:cy="272.16992"
+ inkscape:window-width="2552"
+ inkscape:window-height="1432"
+ inkscape:window-x="1924"
+ inkscape:window-y="4"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg684" />
+ <defs
+ id="defs94">
+ <filter
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ id="941f55d5ad">
+ <feColorMatrix
+ values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"
+ color-interpolation-filters="sRGB"
+ id="feColorMatrix2" />
+ </filter>
+ <filter
+ x="0"
+ y="0"
+ width="1"
+ height="1"
+ id="7900779894">
+ <feColorMatrix
+ values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0.2126 0.7152 0.0722 0 0"
+ color-interpolation-filters="sRGB"
+ id="feColorMatrix5" />
+ </filter>
+ <clipPath
+ id="43b70e6d50">
+ <path
+ d="m 329.69531,337.88281 h 134.25 v 134.25 h -134.25 z m 0,0"
+ clip-rule="nonzero"
+ id="path10" />
+ </clipPath>
+ <clipPath
+ id="5e0498f898">
+ <path
+ d="m 418.84375,430.04687 h 78 v 78 h -78 z m 0,0"
+ clip-rule="nonzero"
+ id="path13" />
+ </clipPath>
+ <clipPath
+ id="ee2fc7472f">
+ <path
+ d="m 296.76953,430.04687 h 77.87109 v 78 h -77.87109 z m 0,0"
+ clip-rule="nonzero"
+ id="path16" />
+ </clipPath>
+ <clipPath
+ id="e49c99af70">
+ <path
+ d="m 418.84375,307.19531 h 78 v 77.8711 h -78 z m 0,0"
+ clip-rule="nonzero"
+ id="path19" />
+ </clipPath>
+ <clipPath
+ id="9f18cca9db">
+ <path
+ d="m 296.76953,307.19531 h 77.87109 v 77.8711 h -77.87109 z m 0,0"
+ clip-rule="nonzero"
+ id="path22" />
+ </clipPath>
+ <clipPath
+ id="9c58565a54">
+ <path
+ d="m 240.875,207.47656 h 111.52734 v 82.5 H 240.875 Z m 0,0"
+ clip-rule="nonzero"
+ id="path25" />
+ </clipPath>
+ <clipPath
+ id="9d28a89d3d">
+ <path
+ d="m 46.855469,529 h 73.500001 v 30 H 46.855469 Z m 0,0"
+ clip-rule="nonzero"
+ id="path28" />
+ </clipPath>
+ <clipPath
+ id="0baef73a1e">
+ <path
+ d="m 163.94922,224.44922 h 69.75 v 72 h -69.75 z m 0,0"
+ clip-rule="nonzero"
+ id="path31" />
+ </clipPath>
+ <clipPath
+ id="1f4a27800a">
+ <path
+ d="M 62.34375,227.08203 H 153 V 293 H 62.34375 Z m 0,0"
+ clip-rule="nonzero"
+ id="path34" />
+ </clipPath>
+ <mask
+ id="e94e818b4b">
+ <g
+ filter="url(#941f55d5ad)"
+ id="g42">
+ <g
+ filter="url(#7900779894)"
+ transform="matrix(0.196004,0,0,0.194118,62.344152,227.08093)"
+ id="g40">
+ <image
+ x="0"
+ y="0"
+ width="463"
+ xlink:href="data:image/png;base64,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"
+ height="340"
+ preserveAspectRatio="xMidYMid"
+ id="image38" />
+ </g>
+ </g>
+ </mask>
+ <mask
+ id="8f2a27f6f4">
+ <g
+ filter="url(#941f55d5ad)"
+ id="g51">
+ <g
+ filter="url(#7900779894)"
+ transform="matrix(0.198482,0,0,0.198482,536.61425,471.98102)"
+ id="g49">
+ <image
+ x="0"
+ y="0"
+ width="461"
+ xlink:href="data:image/png;base64,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"
+ height="461"
+ preserveAspectRatio="xMidYMid"
+ id="image47" />
+ </g>
+ </g>
+ </mask>
+ <clipPath
+ id="9cd47c7ee3">
+ <path
+ d="m 268,534 h 119 v 74 H 268 Z m 0,0"
+ clip-rule="nonzero"
+ id="path55" />
+ </clipPath>
+ <clipPath
+ id="69785d3302">
+ <path
+ d="m 284.80469,510.52344 111.6914,32.23828 -23.91797,82.86719 -111.6914,-32.23829 z m 0,0"
+ clip-rule="nonzero"
+ id="path58" />
+ </clipPath>
+ <clipPath
+ id="9c0953b9a2">
+ <path
+ d="m 372.87891,625.72656 -111.69141,-32.23437 23.91797,-82.8711 111.6914,32.23828 z m 0,0"
+ clip-rule="nonzero"
+ id="path61" />
+ </clipPath>
+ <clipPath
+ id="8e32f12866">
+ <path
+ d="m 372.87891,625.72656 -111.69141,-32.23437 23.91797,-82.8711 111.6914,32.23828 z m 0,0"
+ clip-rule="nonzero"
+ id="path64" />
+ </clipPath>
+ <clipPath
+ id="a3af3eb6b6">
+ <path
+ d="m 698.37109,329 h 48.75 v 135.9375 h -48.75 z m 0,0"
+ clip-rule="nonzero"
+ id="path67" />
+ </clipPath>
+ <clipPath
+ id="31f8f05393">
+ <path
+ d="m 508,316 h 77 v 50 h -77 z m 0,0"
+ clip-rule="nonzero"
+ id="path70" />
+ </clipPath>
+ <clipPath
+ id="41889181af">
+ <path
+ d="M 594.73828,339.63672 520.52344,380.56641 506.03516,354.29687 580.25,313.36719 Z m 0,0"
+ clip-rule="nonzero"
+ id="path73" />
+ </clipPath>
+ <clipPath
+ id="fe9d13e8b4">
+ <path
+ d="m 520.6875,380.47656 74.21484,-40.92969 -14.48828,-26.26953 -74.21094,40.92969 z m 0,0"
+ clip-rule="nonzero"
+ id="path76" />
+ </clipPath>
+ <clipPath
+ id="6c6e35ef02">
+ <path
+ d="m 520.6875,380.47656 74.21484,-40.92969 -14.48828,-26.26953 -74.21094,40.92969 z m 0,0"
+ clip-rule="nonzero"
+ id="path79" />
+ </clipPath>
+ <clipPath
+ id="9d2f7452d2">
+ <path
+ d="m 544,250 h 60.1875 v 43.51172 H 544 Z m 0,0"
+ clip-rule="nonzero"
+ id="path82" />
+ </clipPath>
+ <clipPath
+ id="5d999a0038">
+ <path
+ d="M 543.4375,219 H 560 v 8 h -16.5625 z m 0,0"
+ clip-rule="nonzero"
+ id="path85" />
+ </clipPath>
+ <clipPath
+ id="a4f0b4e13e">
+ <path
+ d="m 548,215.51172 h 47 V 249 h -47 z m 0,0"
+ clip-rule="nonzero"
+ id="path88" />
+ </clipPath>
+ <clipPath
+ id="0ea259bc34">
+ <path
+ d="m 595,215.51172 h 6 V 249 h -6 z m 0,0"
+ clip-rule="nonzero"
+ id="path91" />
+ </clipPath>
+ </defs>
+ <rect
+ style="fill:#ffffff;stroke:none;stroke-width:0.75"
+ id="rect1721"
+ width="728.9057"
+ height="409.97464"
+ x="0.375"
+ y="0.375" />
+ <path
+ fill="#41cb51"
+ d="m 353.33158,222.2777 c -10.36328,0 -18.79687,-8.4336 -18.79687,-18.79688 0,-10.36328 8.43359,-18.79297 18.79687,-18.79297 10.35938,0 18.79297,8.42969 18.79297,18.79297 0,10.36328 -8.43359,18.79688 -18.79297,18.79688 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path102" />
+ <g
+ clip-path="url(#43b70e6d50)"
+ id="g106"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#41cb51"
+ d="m 461.69141,394.18359 -14.32813,-2.33984 c -1.21484,-4.66797 -3.07422,-9.12891 -5.54687,-13.3125 l 8.37109,-11.92969 c 0.75,-1.07031 0.625,-2.51953 -0.29688,-3.4414 L 438.5,351.76953 c -0.92969,-0.93359 -2.40234,-1.05078 -3.46484,-0.28125 l -11.80469,8.48438 c -4.19141,-2.46485 -8.66016,-4.32032 -13.32422,-5.52735 l -2.51172,-14.33984 c -0.22656,-1.28516 -1.34375,-2.22266 -2.64844,-2.22266 h -16.10937 c -1.31641,0 -2.4375,0.95313 -2.65235,2.25391 l -2.33984,14.33984 c -4.60937,1.19922 -9.03516,3.03516 -13.19531,5.47656 l -11.86328,-8.47656 c -1.07032,-0.76172 -2.52735,-0.64062 -3.46094,0.28516 l -11.39063,11.39062 c -0.92187,0.91797 -1.05078,2.36719 -0.30078,3.4336 l 8.375,11.96484 c -2.46093,4.16406 -4.30859,8.60938 -5.51953,13.24609 l -14.34765,2.39063 c -1.29688,0.21484 -2.2461,1.33203 -2.2461,2.64453 v 16.11328 c 0,1.30078 0.9336,2.41406 2.21485,2.64063 l 14.35156,2.54687 c 1.20312,4.62891 3.04297,9.06641 5.49219,13.24219 l -8.48047,11.85156 c -0.76172,1.07031 -0.64063,2.53516 0.28515,3.46094 l 11.39063,11.39062 c 0.91797,0.91797 2.36719,1.04688 3.4375,0.30079 l 11.95703,-8.36719 c 4.14844,2.45312 8.58984,4.30078 13.24609,5.51953 l 2.39453,14.35937 c 0.21875,1.29297 1.33985,2.24219 2.65235,2.24219 h 16.10937 c 1.29688,0 2.41407,-0.93359 2.64063,-2.21484 l 2.54687,-14.35547 c 4.69141,-1.21484 9.17578,-3.07813 13.3711,-5.55469 l 11.9414,8.3711 c 1.07032,0.75 2.51953,0.625 3.44141,-0.29688 l 11.38281,-11.39062 c 0.9336,-0.92969 1.05078,-2.39844 0.28125,-3.46485 l -8.49219,-11.80469 c 2.46094,-4.1875 4.3125,-8.65234 5.51954,-13.3164 l 14.34375,-2.51563 c 1.28515,-0.22656 2.22265,-1.34375 2.22265,-2.64453 v -16.11328 c 0,-1.3125 -0.95312,-2.4375 -2.2539,-2.64844 z m -64.8711,43.04688 c -17.76953,0 -32.22265,-14.45703 -32.22265,-32.22266 0,-17.76562 14.45312,-32.21875 32.22265,-32.21875 17.76563,0 32.21875,14.45313 32.21875,32.21875 0,17.76563 -14.45312,32.22266 -32.21875,32.22266 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path104" />
+ </g>
+ <g
+ clip-path="url(#5e0498f898)"
+ id="g110"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#ffd43b"
+ d="m 473.52344,430.04687 c 0,30.17188 -24.50782,54.67969 -54.67969,54.67969 v 23.32031 c 43.08594,0 78,-34.91406 78,-78 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path108" />
+ </g>
+ <g
+ clip-path="url(#ee2fc7472f)"
+ id="g114"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#306998"
+ d="m 320.08984,430.04687 c 0,30.17188 24.50391,54.67969 54.67969,54.67969 v 23.32031 c -43.08594,0 -78,-34.91406 -78,-78 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path112" />
+ </g>
+ <g
+ clip-path="url(#e49c99af70)"
+ id="g118"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#306998"
+ d="m 473.52344,385.19531 c 0,-30.17187 -24.50782,-54.67969 -54.67969,-54.67969 v -23.32031 c 43.08594,0 78,34.91406 78,78 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path116" />
+ </g>
+ <g
+ clip-path="url(#9f18cca9db)"
+ id="g122"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#ffd43b"
+ d="m 320.08984,385.19531 c 0,-30.17187 24.50391,-54.67969 54.67969,-54.67969 v -23.32031 c -43.08594,0 -78,34.91406 -78,78 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path120" />
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g130"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(618.829,252.49077)"
+ id="g128">
+ <g
+ id="g126">
+ <path
+ d="m 10.484375,0.375 c -3.398437,0 -5.699219,-0.9375 -6.90625,-2.8125 -1.210937,-1.882812 -1.8125,-4.972656 -1.8125,-9.265625 0,-4.289063 0.609375,-7.347656 1.828125,-9.171875 1.21875,-1.820312 3.515625,-2.734375 6.890625,-2.734375 2.007813,0 4.222656,0.28125 6.640625,0.84375 L 17,-19.703125 C 14.957031,-20.066406 12.921875,-20.25 10.890625,-20.25 c -2.03125,0 -3.414063,0.605469 -4.140625,1.8125 -0.71875,1.210938 -1.078125,3.484375 -1.078125,6.828125 0,3.335937 0.347656,5.605469 1.046875,6.8125 0.695312,1.210937 2.0625,1.8125 4.09375,1.8125 2.039062,0 4.101562,-0.171875 6.1875,-0.515625 l 0.09375,3.125 c -2.324219,0.5 -4.527344,0.75 -6.609375,0.75 z m 0,0"
+ id="path124" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g138"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(636.53192,252.49077)"
+ id="g136">
+ <g
+ id="g134">
+ <path
+ d="m 11.1875,-7.21875 h -4.75 V 0 h -3.75 v -23.234375 h 8.5 c 5.269531,0 7.90625,2.601563 7.90625,7.796875 0,2.667969 -0.664062,4.703125 -1.984375,6.109375 -1.324219,1.40625 -3.296875,2.109375 -5.921875,2.109375 z m -4.75,-3.265625 h 4.71875 c 2.71875,0 4.078125,-1.648437 4.078125,-4.953125 0,-1.582031 -0.328125,-2.734375 -0.984375,-3.453125 -0.65625,-0.726563 -1.6875,-1.09375 -3.09375,-1.09375 H 6.4375 Z m 0,0"
+ id="path132" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g146"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(655.82879,252.49077)"
+ id="g144">
+ <g
+ id="g142">
+ <path
+ d="M 0.671875,-16.96875 H 4.3125 l 3.59375,13.8125 H 8.8125 l 3.609375,-13.8125 h 3.65625 L 9.640625,7.296875 H 6 L 8.046875,0 H 5.125 Z m 0,0"
+ id="path140" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g154"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(671.76817,252.49077)"
+ id="g152">
+ <g
+ id="g150">
+ <path
+ d="M 11.359375,-13.8125 H 6.6875 v 7.46875 c 0,1.375 0.097656,2.292969 0.296875,2.75 0.207031,0.449219 0.726563,0.671875 1.5625,0.671875 l 2.78125,-0.09375 L 11.5,-0.0625 C 9.988281,0.226562 8.835938,0.375 8.046875,0.375 c -1.929687,0 -3.25,-0.4375 -3.96875,-1.3125 -0.710937,-0.882812 -1.0625,-2.550781 -1.0625,-5 v -7.875 H 0.84375 v -3.15625 H 3.015625 V -21.875 H 6.6875 v 4.90625 h 4.671875 z m 0,0"
+ id="path148" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g162"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(683.16307,252.49077)"
+ id="g160">
+ <g
+ id="g158">
+ <path
+ d="M 5.9375,0 H 2.234375 V -24.015625 H 5.9375 v 7.9375 c 1.675781,-0.832031 3.222656,-1.25 4.640625,-1.25 2.257813,0 3.800781,0.640625 4.625,1.921875 0.832031,1.273438 1.25,3.375 1.25,6.3125 V 0 H 12.75 v -8.984375 c 0,-1.832031 -0.195312,-3.132813 -0.578125,-3.90625 -0.386719,-0.769531 -1.199219,-1.15625 -2.4375,-1.15625 -1.085937,0 -2.167969,0.183594 -3.25,0.546875 L 5.9375,-13.296875 Z m 0,0"
+ id="path156" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g170"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(700.9338,252.49077)"
+ id="g168">
+ <g
+ id="g166">
+ <path
+ d="m 3.171875,-15.125 c 1.164063,-1.46875 3.101563,-2.203125 5.8125,-2.203125 2.71875,0 4.65625,0.734375 5.8125,2.203125 1.164063,1.46875 1.75,3.671875 1.75,6.609375 0,2.9375 -0.570313,5.15625 -1.703125,6.65625 -1.125,1.492187 -3.078125,2.234375 -5.859375,2.234375 -2.78125,0 -4.742187,-0.742188 -5.875,-2.234375 -1.125,-1.5 -1.6875,-3.71875 -1.6875,-6.65625 0,-2.9375 0.582031,-5.140625 1.75,-6.609375 z M 5.9375,-4.109375 C 6.457031,-3.203125 7.472656,-2.75 8.984375,-2.75 c 1.519531,0 2.539063,-0.453125 3.0625,-1.359375 0.519531,-0.90625 0.78125,-2.382813 0.78125,-4.4375 0,-2.0625 -0.28125,-3.519531 -0.84375,-4.375 -0.554687,-0.863281 -1.554687,-1.296875 -3,-1.296875 -1.449219,0 -2.449219,0.433594 -3,1.296875 -0.554687,0.855469 -0.828125,2.3125 -0.828125,4.375 0,2.054687 0.257812,3.53125 0.78125,4.4375 z m 0,0"
+ id="path164" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g178"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(718.16191,252.49077)"
+ id="g176">
+ <g
+ id="g174">
+ <path
+ d="M 5.9375,0 H 2.234375 V -16.96875 H 5.90625 v 1.0625 c 1.644531,-0.945312 3.203125,-1.421875 4.671875,-1.421875 2.257813,0 3.800781,0.640625 4.625,1.921875 0.832031,1.273438 1.25,3.375 1.25,6.3125 V 0 H 12.78125 v -8.984375 c 0,-1.832031 -0.199219,-3.132813 -0.59375,-3.90625 -0.398438,-0.769531 -1.203125,-1.15625 -2.421875,-1.15625 -1.148437,0 -2.257813,0.230469 -3.328125,0.6875 l -0.5,0.203125 z m 0,0"
+ id="path172" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g186"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(618.829,286.99077)"
+ id="g184">
+ <g
+ id="g182">
+ <path
+ d="m 2.6875,0 v -23.234375 h 14.640625 v 3.28125 H 6.4375 v 6.59375 h 8.859375 v 3.25 H 6.4375 v 6.78125 H 17.328125 V 0 Z m 0,0"
+ id="path180" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g194"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(636.83714,286.99077)"
+ id="g192">
+ <g
+ id="g190">
+ <path
+ d="m 0.609375,-16.96875 h 3.9375 l 3.328125,5.875 3.359375,-5.875 H 15.15625 L 10.109375,-8.609375 15.15625,0 H 11.234375 L 7.875,-5.796875 4.546875,0 h -3.9375 L 5.53125,-8.515625 Z m 0,0"
+ id="path188" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g202"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(651.82693,286.99077)"
+ id="g200">
+ <g
+ id="g198">
+ <path
+ d="M 11.359375,-13.8125 H 6.6875 v 7.46875 c 0,1.375 0.097656,2.292969 0.296875,2.75 0.207031,0.449219 0.726563,0.671875 1.5625,0.671875 l 2.78125,-0.09375 L 11.5,-0.0625 C 9.988281,0.226562 8.835938,0.375 8.046875,0.375 c -1.929687,0 -3.25,-0.4375 -3.96875,-1.3125 -0.710937,-0.882812 -1.0625,-2.550781 -1.0625,-5 v -7.875 H 0.84375 v -3.15625 H 3.015625 V -21.875 H 6.6875 v 4.90625 h 4.671875 z m 0,0"
+ id="path196" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g210"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(663.22182,286.99077)"
+ id="g208">
+ <g
+ id="g206">
+ <path
+ d="m 14.3125,-3.046875 0.953125,-0.109375 0.0625,2.75 C 12.753906,0.113281 10.472656,0.375 8.484375,0.375 5.972656,0.375 4.164062,-0.3125 3.0625,-1.6875 1.96875,-3.070312 1.421875,-5.28125 1.421875,-8.3125 c 0,-6.007812 2.453125,-9.015625 7.359375,-9.015625 4.75,0 7.125,2.589844 7.125,7.765625 l -0.234375,2.640625 H 5.15625 c 0.019531,1.40625 0.320312,2.4375 0.90625,3.09375 0.59375,0.65625 1.691406,0.984375 3.296875,0.984375 1.601563,0 3.253906,-0.066406 4.953125,-0.203125 z m -2.03125,-6.71875 c 0,-1.675781 -0.265625,-2.847656 -0.796875,-3.515625 -0.53125,-0.664062 -1.433594,-1 -2.703125,-1 -1.261719,0 -2.183594,0.355469 -2.765625,1.0625 -0.574219,0.699219 -0.871094,1.851562 -0.890625,3.453125 z m 0,0"
+ id="path204" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g218"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(679.70382,286.99077)"
+ id="g216">
+ <g
+ id="g214">
+ <path
+ d="M 5.9375,0 H 2.234375 V -16.96875 H 5.90625 v 1.0625 c 1.644531,-0.945312 3.203125,-1.421875 4.671875,-1.421875 2.257813,0 3.800781,0.640625 4.625,1.921875 0.832031,1.273438 1.25,3.375 1.25,6.3125 V 0 H 12.78125 v -8.984375 c 0,-1.832031 -0.199219,-3.132813 -0.59375,-3.90625 -0.398438,-0.769531 -1.203125,-1.15625 -2.421875,-1.15625 -1.148437,0 -2.257813,0.230469 -3.328125,0.6875 l -0.5,0.203125 z m 0,0"
+ id="path212" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g226"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(697.47455,286.99077)"
+ id="g224">
+ <g
+ id="g222">
+ <path
+ d="m 14.015625,-13.46875 c -2.679687,-0.363281 -4.617187,-0.546875 -5.8125,-0.546875 -1.199219,0 -2.03125,0.148437 -2.5,0.4375 -0.460937,0.28125 -0.6875,0.730469 -0.6875,1.34375 0,0.605469 0.253906,1.03125 0.765625,1.28125 0.507812,0.25 1.707031,0.542969 3.59375,0.875 1.894531,0.324219 3.238281,0.835937 4.03125,1.53125 0.789062,0.699219 1.1875,1.945313 1.1875,3.734375 0,1.78125 -0.574219,3.09375 -1.71875,3.9375 -1.148438,0.8359375 -2.8125,1.25 -5,1.25 -1.386719,0 -3.132812,-0.195312 -5.234375,-0.578125 L 1.59375,-0.375 1.734375,-3.453125 c 2.707031,0.355469 4.660156,0.53125 5.859375,0.53125 1.195312,0 2.050781,-0.144531 2.5625,-0.4375 0.507812,-0.289063 0.765625,-0.773437 0.765625,-1.453125 0,-0.675781 -0.246094,-1.144531 -0.734375,-1.40625 C 9.707031,-6.476562 8.546875,-6.757812 6.703125,-7.0625 4.859375,-7.375 3.503906,-7.859375 2.640625,-8.515625 c -0.855469,-0.65625 -1.28125,-1.851563 -1.28125,-3.59375 0,-1.738281 0.59375,-3.035156 1.78125,-3.890625 1.1875,-0.863281 2.707031,-1.296875 4.5625,-1.296875 1.445313,0 3.222656,0.183594 5.328125,0.546875 l 1.046875,0.203125 z m 0,0"
+ id="path220" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g234"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(712.63391,286.99077)"
+ id="g232">
+ <g
+ id="g230">
+ <path
+ d="M 2.234375,0 V -16.96875 H 5.9375 V 0 Z m 0,-19.84375 V -23.75 H 5.9375 v 3.90625 z m 0,0"
+ id="path228" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g242"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(720.06086,286.99077)"
+ id="g240">
+ <g
+ id="g238">
+ <path
+ d="m 3.171875,-15.125 c 1.164063,-1.46875 3.101563,-2.203125 5.8125,-2.203125 2.71875,0 4.65625,0.734375 5.8125,2.203125 1.164063,1.46875 1.75,3.671875 1.75,6.609375 0,2.9375 -0.570313,5.15625 -1.703125,6.65625 -1.125,1.492187 -3.078125,2.234375 -5.859375,2.234375 -2.78125,0 -4.742187,-0.742188 -5.875,-2.234375 -1.125,-1.5 -1.6875,-3.71875 -1.6875,-6.65625 0,-2.9375 0.582031,-5.140625 1.75,-6.609375 z M 5.9375,-4.109375 C 6.457031,-3.203125 7.472656,-2.75 8.984375,-2.75 c 1.519531,0 2.539063,-0.453125 3.0625,-1.359375 0.519531,-0.90625 0.78125,-2.382813 0.78125,-4.4375 0,-2.0625 -0.28125,-3.519531 -0.84375,-4.375 -0.554687,-0.863281 -1.554687,-1.296875 -3,-1.296875 -1.449219,0 -2.449219,0.433594 -3,1.296875 -0.554687,0.855469 -0.828125,2.3125 -0.828125,4.375 0,2.054687 0.257812,3.53125 0.78125,4.4375 z m 0,0"
+ id="path236" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g250"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(737.28897,286.99077)"
+ id="g248">
+ <g
+ id="g246">
+ <path
+ d="M 5.9375,0 H 2.234375 V -16.96875 H 5.90625 v 1.0625 c 1.644531,-0.945312 3.203125,-1.421875 4.671875,-1.421875 2.257813,0 3.800781,0.640625 4.625,1.921875 0.832031,1.273438 1.25,3.375 1.25,6.3125 V 0 H 12.78125 v -8.984375 c 0,-1.832031 -0.199219,-3.132813 -0.59375,-3.90625 -0.398438,-0.769531 -1.203125,-1.15625 -2.421875,-1.15625 -1.148437,0 -2.257813,0.230469 -3.328125,0.6875 l -0.5,0.203125 z m 0,0"
+ id="path244" />
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#9c58565a54)"
+ id="g254"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#09102b"
+ d="m 321.85156,262.05469 c -0.89844,-1.01172 -1.60547,-1.91016 -2.41406,-2.70703 -2.69531,-2.64454 -5.30078,-5.39844 -8.1875,-7.82422 -3.11328,-2.61719 -7.58984,-1.91016 -10.45703,1.125 -0.71485,0.75 -1.97656,0.98437 -3.11328,1.51172 -0.48828,1.21093 0.67187,1.74609 1.39062,2.42578 6.50781,6.16797 11.5625,13.44922 15.94531,21.17187 1.67969,2.95313 2.80469,6.23047 4.07813,9.40235 0.99609,2.48828 1.125,2.84375 3.84766,2.625 4.85546,-0.39063 9.08593,-2.03907 12.14453,-6.20313 5.32812,-7.23437 11.07422,-14.17187 15.0664,-22.29687 0.64453,-1.32032 1.125,-2.72657 2.01563,-4.89844 -3.98438,0.71484 -7.26172,0.6875 -9.36719,3.84765 -1.28906,1.9375 -2.60547,3.85157 -4.38281,6.4961 -0.45703,-2.78125 -0.73828,-4.70313 -1.08203,-6.60547 -2.60547,-14.33203 -8.38672,-27.26563 -19.23438,-37.11719 -9.86719,-8.97656 -21.45703,-15.17969 -35.35156,-15.35156 -11.67188,-0.13672 -21.69531,4.42969 -30.45313,11.76562 -3.5039,2.94141 -6.47265,6.53516 -9.58593,9.92188 -0.8086,0.87891 -1.25,2.07422 -1.85938,3.13672 0.23438,0.22656 0.47266,0.45312 0.70703,0.67578 1.4336,-0.88672 2.92188,-1.69922 4.27735,-2.69531 0.84375,-0.625 1.49609,-1.51563 2.20312,-2.3125 9.07813,-10.24219 20.54297,-12.97657 33.53125,-10.1875 9.91797,2.1289 18.11719,7.46484 25.00391,14.77343 7.28125,7.70313 12.21875,16.77735 15.17578,26.94141 0.13672,0.44922 0.24609,0.91406 0.32031,1.375 0.0156,0.20703 -0.0937,0.43359 -0.21875,1.00391 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path252" />
+ </g>
+ <g
+ clip-path="url(#9d28a89d3d)"
+ id="g258"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#09102b"
+ d="m 46.824219,529.01953 v 29.27344 h 73.558591 v -29.27344 z m 28.085937,22.82422 c -0.01563,0 -0.01563,0 -0.01563,0 h -3.992187 c -0.0625,0 -0.125,-0.0469 -0.167969,-0.0937 L 67.273438,546.34766 63.78125,551.75 c -0.03125,0.0469 -0.09375,0.0937 -0.152344,0.0937 h -3.964844 c -0.07812,0 -0.136718,-0.0469 -0.167968,-0.10938 -0.03125,-0.0586 -0.03125,-0.13671 0.01563,-0.19531 l 5.519531,-8.41406 -5.003906,-7.71484 c -0.02734,-0.0586 -0.02734,-0.13672 0,-0.19532 0.03125,-0.0625 0.09375,-0.10937 0.167968,-0.10937 h 3.859376 c 0.0625,0 0.121093,0.0469 0.167968,0.0937 l 3.125,4.98828 3.050782,-4.98828 c 0.04687,-0.0469 0.105468,-0.0937 0.167968,-0.0937 h 3.828125 c 0.07422,0 0.136719,0.0469 0.167969,0.10937 0.02734,0.0586 0.02734,0.13672 0,0.19532 l -5.035156,7.83593 5.507812,8.25 c 0.02734,0.043 0.05859,0.0899 0.05859,0.15235 0,0.10156 -0.07422,0.19531 -0.183594,0.19531 z m 17.644532,-0.19922 c 0,0.10547 -0.09375,0.19922 -0.199219,0.19922 h -3.0625 c -0.109375,0 -0.183594,-0.0937 -0.183594,-0.19922 v -11.32031 l -2.882813,11.36719 c -0.01562,0.0898 -0.08984,0.15234 -0.183593,0.15234 h -3.1875 c -0.08984,0 -0.167969,-0.0625 -0.183594,-0.15234 l -2.851563,-11.36719 v 11.32031 c 0,0.10547 -0.08984,0.19531 -0.195312,0.19531 h -3.082031 c -0.105469,0 -0.183594,-0.0898 -0.183594,-0.19531 v -16.33984 c 0,-0.10547 0.07813,-0.19922 0.183594,-0.19922 H 81.5 c 0.08984,0 0.167969,0.0586 0.183594,0.15234 l 2.773437,10.45313 2.761719,-10.45313 c 0.01563,-0.0937 0.08984,-0.15234 0.183594,-0.15234 h 4.953125 c 0.105469,0 0.199219,0.0937 0.199219,0.19922 z m 14.882812,0 c 0,0.10547 -0.0742,0.19922 -0.18359,0.19922 H 95.726562 c -0.105468,0 -0.183593,-0.0937 -0.183593,-0.19922 v -16.20312 c 0,-0.10547 0.07813,-0.19922 0.183593,-0.19922 h 3.308594 c 0.105469,0 0.199219,0.0937 0.199219,0.19922 v 13.26953 h 8.019535 c 0.10937,0 0.18359,0.0742 0.18359,0.17968 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path256" />
+ </g>
+ <path
+ fill="#09102b"
+ d="m 10.753456,359.80895 h 58.707032 v 6.48437 H 10.753456 Z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path260" />
+ <path
+ fill="#09102b"
+ d="m 10.761268,287.53551 v 36.91406 h 58.70703 v -36.91406 z m 51.84766,32.34766 H 17.620643 c -0.835937,0 -1.523437,-0.6836 -1.523437,-1.51954 0,-0.85546 0.6875,-1.52343 1.523437,-1.52343 h 44.988285 c 0.82031,0 1.52343,0.66797 1.52343,1.52343 0,0.83594 -0.70312,1.51954 -1.52343,1.51954 z m 0,-10.65235 H 17.620643 c -0.835937,0 -1.523437,-0.68359 -1.523437,-1.51953 0,-0.85156 0.6875,-1.52344 1.523437,-1.52344 h 44.988285 c 0.82031,0 1.52343,0.67188 1.52343,1.52344 0,0.83594 -0.70312,1.51953 -1.52343,1.51953 z m 0,-10.64844 H 17.620643 c -0.835937,0 -1.523437,-0.6875 -1.523437,-1.52343 0,-0.85157 0.6875,-1.52344 1.523437,-1.52344 h 44.988285 c 0.82031,0 1.52343,0.67187 1.52343,1.52344 0,0.83593 -0.70312,1.52343 -1.52343,1.52343 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path262" />
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g270"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(126.27432,523.15898)"
+ id="g268">
+ <g
+ id="g266">
+ <path
+ d="m 4.6875,-23.234375 4.984375,9.15625 5.046875,-9.15625 H 18.6875 L 11.8125,-11.4375 18.6875,0 H 14.484375 L 9.5,-8.75 4.40625,0 H 0.4375 l 6.921875,-11.234375 -6.921875,-12 z m 0,0"
+ id="path264" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g278"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(144.65551,523.15898)"
+ id="g276">
+ <g
+ id="g274">
+ <path
+ d="m 2.6875,0 v -23.234375 h 6.546875 l 5.1875,18.140625 5.1875,-18.140625 H 26.1875 V 0 H 22.390625 V -19.0625 H 21.875 l -5.484375,18.109375 h -3.9375 l -5.5,-18.109375 H 6.4375 V 0 Z m 0,0"
+ id="path272" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g286"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(172.73611,523.15898)"
+ id="g284">
+ <g
+ id="g282">
+ <path
+ d="M 15.703125,0 H 2.6875 v -23.234375 h 3.75 v 19.875 h 9.265625 z m 0,0"
+ id="path280" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g294"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(126.27432,557.65898)"
+ id="g292">
+ <g
+ id="g290">
+ <path
+ d="m 0.4375,-19.875 v -3.359375 H 17.40625 V -19.875 H 10.859375 V 0 H 7.0625 v -19.875 z m 0,0"
+ id="path288" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g302"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(143.36677,557.65898)"
+ id="g300">
+ <g
+ id="g298">
+ <path
+ d="M 0.671875,-16.96875 H 4.3125 l 3.59375,13.8125 H 8.8125 l 3.609375,-13.8125 h 3.65625 L 9.640625,7.296875 H 6 L 8.046875,0 H 5.125 Z m 0,0"
+ id="path296" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g310"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(159.30615,557.65898)"
+ id="g308">
+ <g
+ id="g306">
+ <path
+ d="M 2.234375,7.296875 V -16.96875 H 5.90625 v 1.0625 c 1.5625,-0.945312 3.019531,-1.421875 4.375,-1.421875 2.238281,0 3.875,0.683594 4.90625,2.046875 1.039062,1.367188 1.5625,3.664062 1.5625,6.890625 0,3.21875 -0.59375,5.484375 -1.78125,6.796875 -1.179688,1.3125 -3.117188,1.96875 -5.8125,1.96875 -0.929688,0 -2,-0.105469 -3.21875,-0.3125 v 7.234375 z m 7.40625,-21.34375 c -1.0625,0 -2.132813,0.242187 -3.203125,0.71875 l -0.5,0.234375 v 10 c 0.90625,0.1875 1.898438,0.28125 2.984375,0.28125 1.539063,0 2.601563,-0.441406 3.1875,-1.328125 0.582031,-0.882813 0.875,-2.390625 0.875,-4.515625 0,-3.59375 -1.117187,-5.390625 -3.34375,-5.390625 z m 0,0"
+ id="path304" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g318"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(176.77166,557.65898)"
+ id="g316">
+ <g
+ id="g314">
+ <path
+ d="m 14.3125,-3.046875 0.953125,-0.109375 0.0625,2.75 C 12.753906,0.113281 10.472656,0.375 8.484375,0.375 5.972656,0.375 4.164062,-0.3125 3.0625,-1.6875 1.96875,-3.070312 1.421875,-5.28125 1.421875,-8.3125 c 0,-6.007812 2.453125,-9.015625 7.359375,-9.015625 4.75,0 7.125,2.589844 7.125,7.765625 l -0.234375,2.640625 H 5.15625 c 0.019531,1.40625 0.320312,2.4375 0.90625,3.09375 0.59375,0.65625 1.691406,0.984375 3.296875,0.984375 1.601563,0 3.253906,-0.066406 4.953125,-0.203125 z m -2.03125,-6.71875 c 0,-1.675781 -0.265625,-2.847656 -0.796875,-3.515625 -0.53125,-0.664062 -1.433594,-1 -2.703125,-1 -1.261719,0 -2.183594,0.355469 -2.765625,1.0625 -0.574219,0.699219 -0.871094,1.851562 -0.890625,3.453125 z m 0,0"
+ id="path312" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g326"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(193.25366,557.65898)"
+ id="g324">
+ <g
+ id="g322">
+ <path
+ d="m 14.015625,-13.46875 c -2.679687,-0.363281 -4.617187,-0.546875 -5.8125,-0.546875 -1.199219,0 -2.03125,0.148437 -2.5,0.4375 -0.460937,0.28125 -0.6875,0.730469 -0.6875,1.34375 0,0.605469 0.253906,1.03125 0.765625,1.28125 0.507812,0.25 1.707031,0.542969 3.59375,0.875 1.894531,0.324219 3.238281,0.835937 4.03125,1.53125 0.789062,0.699219 1.1875,1.945313 1.1875,3.734375 0,1.78125 -0.574219,3.09375 -1.71875,3.9375 -1.148438,0.8359375 -2.8125,1.25 -5,1.25 -1.386719,0 -3.132812,-0.195312 -5.234375,-0.578125 L 1.59375,-0.375 1.734375,-3.453125 c 2.707031,0.355469 4.660156,0.53125 5.859375,0.53125 1.195312,0 2.050781,-0.144531 2.5625,-0.4375 0.507812,-0.289063 0.765625,-0.773437 0.765625,-1.453125 0,-0.675781 -0.246094,-1.144531 -0.734375,-1.40625 C 9.707031,-6.476562 8.546875,-6.757812 6.703125,-7.0625 4.859375,-7.375 3.503906,-7.859375 2.640625,-8.515625 c -0.855469,-0.65625 -1.28125,-1.851563 -1.28125,-3.59375 0,-1.738281 0.59375,-3.035156 1.78125,-3.890625 1.1875,-0.863281 2.707031,-1.296875 4.5625,-1.296875 1.445313,0 3.222656,0.183594 5.328125,0.546875 l 1.046875,0.203125 z m 0,0"
+ id="path320" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g334"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(208.41301,557.65898)"
+ id="g332">
+ <g
+ id="g330">
+ <path
+ d="M 0.671875,-16.96875 H 4.3125 l 3.59375,13.8125 H 8.8125 l 3.609375,-13.8125 h 3.65625 L 9.640625,7.296875 H 6 L 8.046875,0 H 5.125 Z m 0,0"
+ id="path328" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g342"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(224.35239,557.65898)"
+ id="g340">
+ <g
+ id="g338">
+ <path
+ d="m 14.015625,-13.46875 c -2.679687,-0.363281 -4.617187,-0.546875 -5.8125,-0.546875 -1.199219,0 -2.03125,0.148437 -2.5,0.4375 -0.460937,0.28125 -0.6875,0.730469 -0.6875,1.34375 0,0.605469 0.253906,1.03125 0.765625,1.28125 0.507812,0.25 1.707031,0.542969 3.59375,0.875 1.894531,0.324219 3.238281,0.835937 4.03125,1.53125 0.789062,0.699219 1.1875,1.945313 1.1875,3.734375 0,1.78125 -0.574219,3.09375 -1.71875,3.9375 -1.148438,0.8359375 -2.8125,1.25 -5,1.25 -1.386719,0 -3.132812,-0.195312 -5.234375,-0.578125 L 1.59375,-0.375 1.734375,-3.453125 c 2.707031,0.355469 4.660156,0.53125 5.859375,0.53125 1.195312,0 2.050781,-0.144531 2.5625,-0.4375 0.507812,-0.289063 0.765625,-0.773437 0.765625,-1.453125 0,-0.675781 -0.246094,-1.144531 -0.734375,-1.40625 C 9.707031,-6.476562 8.546875,-6.757812 6.703125,-7.0625 4.859375,-7.375 3.503906,-7.859375 2.640625,-8.515625 c -0.855469,-0.65625 -1.28125,-1.851563 -1.28125,-3.59375 0,-1.738281 0.59375,-3.035156 1.78125,-3.890625 1.1875,-0.863281 2.707031,-1.296875 4.5625,-1.296875 1.445313,0 3.222656,0.183594 5.328125,0.546875 l 1.046875,0.203125 z m 0,0"
+ id="path336" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g350"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(239.51175,557.65898)"
+ id="g348">
+ <g
+ id="g346">
+ <path
+ d="M 11.359375,-13.8125 H 6.6875 v 7.46875 c 0,1.375 0.097656,2.292969 0.296875,2.75 0.207031,0.449219 0.726563,0.671875 1.5625,0.671875 l 2.78125,-0.09375 L 11.5,-0.0625 C 9.988281,0.226562 8.835938,0.375 8.046875,0.375 c -1.929687,0 -3.25,-0.4375 -3.96875,-1.3125 -0.710937,-0.882812 -1.0625,-2.550781 -1.0625,-5 v -7.875 H 0.84375 v -3.15625 H 3.015625 V -21.875 H 6.6875 v 4.90625 h 4.671875 z m 0,0"
+ id="path344" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g358"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(250.90664,557.65898)"
+ id="g356">
+ <g
+ id="g354">
+ <path
+ d="m 14.3125,-3.046875 0.953125,-0.109375 0.0625,2.75 C 12.753906,0.113281 10.472656,0.375 8.484375,0.375 5.972656,0.375 4.164062,-0.3125 3.0625,-1.6875 1.96875,-3.070312 1.421875,-5.28125 1.421875,-8.3125 c 0,-6.007812 2.453125,-9.015625 7.359375,-9.015625 4.75,0 7.125,2.589844 7.125,7.765625 l -0.234375,2.640625 H 5.15625 c 0.019531,1.40625 0.320312,2.4375 0.90625,3.09375 0.59375,0.65625 1.691406,0.984375 3.296875,0.984375 1.601563,0 3.253906,-0.066406 4.953125,-0.203125 z m -2.03125,-6.71875 c 0,-1.675781 -0.265625,-2.847656 -0.796875,-3.515625 -0.53125,-0.664062 -1.433594,-1 -2.703125,-1 -1.261719,0 -2.183594,0.355469 -2.765625,1.0625 -0.574219,0.699219 -0.871094,1.851562 -0.890625,3.453125 z m 0,0"
+ id="path352" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g366"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(267.38864,557.65898)"
+ id="g364">
+ <g
+ id="g362">
+ <path
+ d="M 5.9375,0 H 2.234375 V -16.96875 H 5.90625 v 1.0625 c 1.601562,-0.945312 3.070312,-1.421875 4.40625,-1.421875 1.96875,0 3.40625,0.554687 4.3125,1.65625 2.050781,-1.101563 4.09375,-1.65625 6.125,-1.65625 2.039062,0 3.476562,0.632813 4.3125,1.890625 0.84375,1.25 1.265625,3.367188 1.265625,6.34375 V 0 H 22.65625 v -8.984375 c 0,-1.832031 -0.1875,-3.132813 -0.5625,-3.90625 -0.367188,-0.769531 -1.136719,-1.15625 -2.3125,-1.15625 -1.023438,0 -2.121094,0.230469 -3.296875,0.6875 L 15.90625,-13.125 c 0.1875,0.449219 0.28125,1.898438 0.28125,4.34375 V 0 h -3.671875 v -8.71875 c 0,-2.007812 -0.183594,-3.398438 -0.546875,-4.171875 -0.355469,-0.769531 -1.148438,-1.15625 -2.375,-1.15625 -1.125,0 -2.179688,0.230469 -3.15625,0.6875 l -0.5,0.203125 z m 0,0"
+ id="path360" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g374"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(295.06227,557.65898)"
+ id="g372">
+ <g
+ id="g370">
+ <path
+ d="m 14.015625,-13.46875 c -2.679687,-0.363281 -4.617187,-0.546875 -5.8125,-0.546875 -1.199219,0 -2.03125,0.148437 -2.5,0.4375 -0.460937,0.28125 -0.6875,0.730469 -0.6875,1.34375 0,0.605469 0.253906,1.03125 0.765625,1.28125 0.507812,0.25 1.707031,0.542969 3.59375,0.875 1.894531,0.324219 3.238281,0.835937 4.03125,1.53125 0.789062,0.699219 1.1875,1.945313 1.1875,3.734375 0,1.78125 -0.574219,3.09375 -1.71875,3.9375 -1.148438,0.8359375 -2.8125,1.25 -5,1.25 -1.386719,0 -3.132812,-0.195312 -5.234375,-0.578125 L 1.59375,-0.375 1.734375,-3.453125 c 2.707031,0.355469 4.660156,0.53125 5.859375,0.53125 1.195312,0 2.050781,-0.144531 2.5625,-0.4375 0.507812,-0.289063 0.765625,-0.773437 0.765625,-1.453125 0,-0.675781 -0.246094,-1.144531 -0.734375,-1.40625 C 9.707031,-6.476562 8.546875,-6.757812 6.703125,-7.0625 4.859375,-7.375 3.503906,-7.859375 2.640625,-8.515625 c -0.855469,-0.65625 -1.28125,-1.851563 -1.28125,-3.59375 0,-1.738281 0.59375,-3.035156 1.78125,-3.890625 1.1875,-0.863281 2.707031,-1.296875 4.5625,-1.296875 1.445313,0 3.222656,0.183594 5.328125,0.546875 l 1.046875,0.203125 z m 0,0"
+ id="path368" />
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#0baef73a1e)"
+ id="g378"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#09102b"
+ d="m 230.94531,263.10547 h -1.21875 V 254.125 c 0,-0.36719 -0.0703,-0.72266 -0.21094,-1.0625 -0.13671,-0.33594 -0.33593,-0.63672 -0.59765,-0.89844 -0.25781,-0.25781 -0.55469,-0.45703 -0.89063,-0.59765 -0.33984,-0.14063 -0.6875,-0.21094 -1.05468,-0.21094 h -2.44922 v -10.71094 c 0.004,-0.31641 -0.10547,-0.58594 -0.32032,-0.8125 L 209.78516,225.0625 c -0.23047,-0.26172 -0.51954,-0.39453 -0.86329,-0.39844 h -35.35546 c -0.14844,0 -0.29688,0.0312 -0.4375,0.0898 -0.14063,0.0586 -0.26563,0.14062 -0.3711,0.25 -0.10937,0.10546 -0.1914,0.23046 -0.25,0.375 -0.0586,0.14062 -0.0859,0.28515 -0.0859,0.4414 v 25.55078 h -2.48828 c -0.36328,0 -0.71484,0.0703 -1.05468,0.21094 -0.33594,0.14063 -0.63282,0.34375 -0.89063,0.60156 -0.25781,0.26172 -0.45703,0.5586 -0.59766,0.89844 -0.14062,0.33984 -0.21093,0.69141 -0.21093,1.05859 v 12.70313 h -0.44141 c -0.36328,0 -0.71484,0.0703 -1.05078,0.21094 -0.33984,0.14062 -0.63672,0.34375 -0.89453,0.60156 -0.25781,0.26172 -0.45703,0.55859 -0.59766,0.89844 -0.13672,0.33984 -0.20703,0.6914 -0.20703,1.05859 0,0 0,0.10156 0,0.16016 l 3.17578,23.74218 c 0.0117,0.35938 0.0898,0.70313 0.23438,1.03125 0.14843,0.32422 0.34765,0.61329 0.60547,0.86329 0.25781,0.25 0.55078,0.4414 0.88281,0.57421 0.32812,0.13282 0.67187,0.19922 1.02734,0.19922 h 57.07813 c 0.35547,0 0.69922,-0.0664 1.02734,-0.19922 0.33203,-0.13281 0.625,-0.32421 0.87891,-0.57031 0.25781,-0.25 0.46093,-0.53515 0.60547,-0.86328 0.14453,-0.32422 0.22656,-0.66797 0.24218,-1.02344 l 3.95313,-27.5039 c 0.004,-0.0547 0.004,-0.10938 0,-0.16407 0,-0.36718 -0.0742,-0.71875 -0.21485,-1.05468 -0.14062,-0.33985 -0.33984,-0.63672 -0.59765,-0.89453 -0.25781,-0.25782 -0.55469,-0.45704 -0.89063,-0.59375 -0.33593,-0.14063 -0.6875,-0.21094 -1.05078,-0.21094 z m -61.48828,3.73828 V 254.125 c 0.004,-0.12109 0.0469,-0.22656 0.13281,-0.3125 0.082,-0.0859 0.1875,-0.12891 0.3086,-0.13281 h 2.48437 v 13.16406 z m 33.60938,-3.19141 -1.95704,3.19141 h -26.39453 v -39.87109 h 33.08594 v 13.67187 c 0.0117,0.30859 0.12109,0.56641 0.33984,0.78516 0.21485,0.21484 0.47657,0.32422 0.78125,0.33203 h 13.28907 v 21.34375 h -18.12891 c -0.42578,0 -0.75391,0.17969 -0.98047,0.54687 z m 21.45703,-0.54687 v -9.42578 h 2.48437 c 0.1211,0.004 0.22656,0.0469 0.3125,0.13281 0.082,0.0859 0.12891,0.19141 0.12891,0.3125 v 8.98047 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path376" />
+ </g>
+ <path
+ fill="#09102b"
+ d="m 138.5308,35.426124 h 17.95313 c 0.15234,0 0.29687,-0.0312 0.4375,-0.0898 0.14062,-0.0586 0.26562,-0.14062 0.375,-0.25 0.10546,-0.10547 0.1875,-0.23047 0.24609,-0.37109 0.0586,-0.14453 0.0898,-0.28907 0.0898,-0.44532 0,-0.15234 -0.0312,-0.29687 -0.0898,-0.4414 -0.0586,-0.14063 -0.14063,-0.26563 -0.24609,-0.3711 -0.10938,-0.10937 -0.23438,-0.1914 -0.375,-0.25 -0.14063,-0.0586 -0.28516,-0.0898 -0.4375,-0.0898 H 138.5308 c -0.15234,0 -0.29687,0.0312 -0.4375,0.0898 -0.14062,0.0586 -0.26562,0.14063 -0.37109,0.25 -0.10938,0.10547 -0.19141,0.23047 -0.25,0.3711 -0.0586,0.14453 -0.0859,0.28906 -0.0859,0.4414 0,0.15625 0.0273,0.30079 0.0859,0.44532 0.0586,0.14062 0.14062,0.26562 0.25,0.37109 0.10547,0.10938 0.23047,0.19141 0.37109,0.25 0.14063,0.0586 0.28516,0.0898 0.4375,0.0898 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path380" />
+ <path
+ fill="#09102b"
+ d="m 144.88236,56.051124 h -6.35156 c -0.15234,0 -0.29687,0.0274 -0.4375,0.0859 -0.14062,0.0586 -0.26562,0.14063 -0.37109,0.25 -0.10938,0.10938 -0.19141,0.23438 -0.25,0.375 -0.0586,0.14063 -0.0859,0.28906 -0.0859,0.44141 0,0.15234 0.0273,0.30078 0.0859,0.4414 0.0586,0.14063 0.14062,0.26563 0.25,0.375 0.10547,0.10938 0.23047,0.19141 0.37109,0.25 0.14063,0.0586 0.28516,0.0859 0.4375,0.0859 h 6.35156 c 0.15235,0 0.30078,-0.0273 0.44141,-0.0859 0.14062,-0.0586 0.26172,-0.14062 0.37109,-0.25 0.10547,-0.10937 0.19141,-0.23437 0.25,-0.375 0.0547,-0.14062 0.0859,-0.28906 0.0859,-0.4414 0,-0.15235 -0.0312,-0.30078 -0.0859,-0.44141 -0.0586,-0.14062 -0.14453,-0.26562 -0.25,-0.375 -0.10937,-0.10937 -0.23047,-0.1914 -0.37109,-0.25 -0.14063,-0.0586 -0.28906,-0.0859 -0.44141,-0.0859 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path382" />
+ <path
+ fill="#09102b"
+ d="m 158.89799,56.051124 h -8.54688 c -0.14843,0 -0.29687,0.0274 -0.4375,0.0859 -0.14062,0.0586 -0.26562,0.14063 -0.37109,0.25 -0.10938,0.10938 -0.19141,0.23438 -0.25,0.375 -0.0586,0.14063 -0.0859,0.28906 -0.0859,0.44141 0,0.15234 0.0273,0.30078 0.0859,0.4414 0.0586,0.14063 0.14062,0.26563 0.25,0.375 0.10547,0.10938 0.23047,0.19141 0.37109,0.25 0.14063,0.0586 0.28907,0.0859 0.4375,0.0859 h 8.54688 c 0.15234,0 0.29687,-0.0273 0.4375,-0.0859 0.14062,-0.0586 0.26562,-0.14062 0.375,-0.25 0.10547,-0.10937 0.1875,-0.23437 0.24609,-0.375 0.0586,-0.14062 0.0898,-0.28906 0.0898,-0.4414 0,-0.15235 -0.0312,-0.30078 -0.0898,-0.44141 -0.0586,-0.14062 -0.14062,-0.26562 -0.24609,-0.375 -0.10938,-0.10937 -0.23438,-0.1914 -0.375,-0.25 -0.14063,-0.0586 -0.28516,-0.0859 -0.4375,-0.0859 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path384" />
+ <path
+ fill="#09102b"
+ d="m 138.5308,40.613624 h 20.30078 c 0.15235,0 0.30078,-0.0273 0.44141,-0.0859 0.14062,-0.0586 0.26562,-0.14453 0.37109,-0.25 0.10938,-0.10938 0.19141,-0.23438 0.25,-0.375 0.0586,-0.14063 0.0859,-0.28907 0.0859,-0.44141 0,-0.15625 -0.0273,-0.30078 -0.0859,-0.44141 -0.0586,-0.14453 -0.14062,-0.26953 -0.25,-0.375 -0.10547,-0.10937 -0.23047,-0.1914 -0.37109,-0.25 -0.14063,-0.0586 -0.28906,-0.0898 -0.44141,-0.0898 H 138.5308 c -0.15234,0 -0.29687,0.0312 -0.4375,0.0898 -0.14062,0.0586 -0.26562,0.14063 -0.37109,0.25 -0.10938,0.10547 -0.19141,0.23047 -0.25,0.375 -0.0586,0.14063 -0.0859,0.28516 -0.0859,0.44141 0,0.15234 0.0273,0.30078 0.0859,0.44141 0.0586,0.14062 0.14062,0.26562 0.25,0.375 0.10547,0.10547 0.23047,0.1914 0.37109,0.25 0.14063,0.0586 0.28516,0.0859 0.4375,0.0859 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path386" />
+ <path
+ fill="#09102b"
+ d="M 166.35111,50.269874 H 138.5308 c -0.15234,0 -0.29687,0.0312 -0.4375,0.0898 -0.14062,0.0586 -0.26562,0.14062 -0.37109,0.25 -0.10938,0.10547 -0.19141,0.23047 -0.25,0.375 -0.0586,0.14062 -0.0859,0.28515 -0.0859,0.4414 0,0.15235 0.0273,0.29688 0.0859,0.44141 0.0586,0.14063 0.14062,0.26563 0.25,0.37109 0.10547,0.10938 0.23047,0.19532 0.37109,0.25391 0.14063,0.0586 0.28516,0.0859 0.4375,0.0859 h 27.82031 c 0.15235,0 0.29688,-0.0273 0.4375,-0.0859 0.14063,-0.0586 0.26563,-0.14453 0.3711,-0.25391 0.10937,-0.10546 0.1914,-0.23046 0.25,-0.37109 0.0586,-0.14453 0.0859,-0.28906 0.0859,-0.44141 0,-0.15625 -0.0273,-0.30078 -0.0859,-0.4414 -0.0586,-0.14453 -0.14063,-0.26953 -0.25,-0.375 -0.10547,-0.10938 -0.23047,-0.19141 -0.3711,-0.25 -0.14062,-0.0586 -0.28515,-0.0898 -0.4375,-0.0898 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path388" />
+ <path
+ fill="#09102b"
+ d="m 172.45268,44.351914 h -33.95704 c -0.15234,0 -0.30078,0.0312 -0.4414,0.0898 -0.14063,0.0586 -0.26172,0.14062 -0.3711,0.25 -0.10937,0.10547 -0.1914,0.23047 -0.25,0.375 -0.0586,0.14062 -0.0859,0.28516 -0.0859,0.44141 0,0.15234 0.0273,0.30078 0.0859,0.4414 0.0586,0.14063 0.14063,0.26563 0.25,0.375 0.10938,0.10547 0.23047,0.19141 0.3711,0.25 0.14062,0.0586 0.28906,0.0859 0.4414,0.0859 h 33.95704 c 0.15234,0 0.29687,-0.0273 0.4375,-0.0859 0.14062,-0.0586 0.26562,-0.14453 0.375,-0.25 0.10546,-0.10937 0.1875,-0.23437 0.24609,-0.375 0.0586,-0.14062 0.0898,-0.28906 0.0898,-0.4414 0,-0.15625 -0.0312,-0.30079 -0.0898,-0.44141 -0.0586,-0.14453 -0.14063,-0.26953 -0.24609,-0.375 -0.10938,-0.10938 -0.23438,-0.19141 -0.375,-0.25 -0.14063,-0.0586 -0.28516,-0.0898 -0.4375,-0.0898 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path390" />
+ <g
+ clip-path="url(#1f4a27800a)"
+ id="g398"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ mask="url(#e94e818b4b)"
+ id="g396">
+ <g
+ transform="matrix(0.196004,0,0,0.194118,62.344152,227.08093)"
+ id="g394">
+ <image
+ x="0"
+ y="0"
+ width="463"
+ xlink:href="data:image/png;base64,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"
+ height="340"
+ preserveAspectRatio="xMidYMid"
+ id="image392" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g406"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(62.344152,330.62669)"
+ id="g404">
+ <g
+ id="g402">
+ <path
+ d="M 11.78125,0.390625 C 8.039062,0.390625 5.4375,-0.613281 3.96875,-2.625 2.5,-4.632812 1.765625,-7.8125 1.765625,-12.15625 1.765625,-16.5 2.507812,-19.722656 4,-21.828125 5.5,-23.941406 8.09375,-25 11.78125,-25 c 3.6875,0 6.269531,1.046875 7.75,3.140625 1.488281,2.09375 2.234375,5.324219 2.234375,9.6875 0,2.875 -0.308594,5.199219 -0.921875,6.96875 -0.605469,1.773437 -1.601562,3.121094 -2.984375,4.046875 l 3.015625,4.859375 -3.703125,1.71875 -3.203125,-5.25 c -0.449219,0.144531 -1.179688,0.21875 -2.1875,0.21875 z M 7.109375,-5.1875 c 0.8125,1.398438 2.367187,2.09375 4.671875,2.09375 2.300781,0 3.851562,-0.6875 4.65625,-2.0625 0.800781,-1.375 1.203125,-3.703125 1.203125,-6.984375 0,-3.28125 -0.417969,-5.660156 -1.25,-7.140625 -0.824219,-1.488281 -2.359375,-2.234375 -4.609375,-2.234375 -2.25,0 -3.796875,0.746094 -4.640625,2.234375 -0.835937,1.480469 -1.25,3.851562 -1.25,7.109375 0,3.25 0.40625,5.578125 1.21875,6.984375 z m 0,0"
+ id="path400" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g414"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(85.1083,330.62669)"
+ id="g412">
+ <g
+ id="g410">
+ <path
+ d="M 12.03125,-14.625 H 7.078125 v 7.90625 c 0,1.460938 0.101563,2.429688 0.3125,2.90625 0.21875,0.480469 0.769531,0.71875 1.65625,0.71875 L 12,-3.203125 l 0.171875,3.125 c -1.605469,0.3125 -2.824219,0.46875 -3.65625,0.46875 -2.042969,0 -3.4375,-0.4609375 -4.1875,-1.390625 -0.75,-0.9375 -1.125,-2.695312 -1.125,-5.28125 V -14.625 h -2.3125 v -3.328125 h 2.3125 v -5.21875 h 3.875 v 5.21875 h 4.953125 z m 0,0"
+ id="path408" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g420"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(97.172393,330.62669)"
+ id="g418">
+ <g
+ id="g416" />
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g428"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(104.28144,330.62669)"
+ id="g426">
+ <g
+ id="g424">
+ <path
+ d="m 17.453125,0 v -10.640625 h -10.625 V 0 H 2.84375 V -24.609375 H 6.828125 V -14.125 h 10.625 v -10.484375 h 4.03125 V 0 Z m 0,0"
+ id="path422" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g436"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(127.7637,330.62669)"
+ id="g434">
+ <g
+ id="g432">
+ <path
+ d="m 15.15625,-3.234375 1.015625,-0.109375 0.0625,2.90625 c -2.730469,0.550781 -5.148437,0.828125 -7.25,0.828125 -2.65625,0 -4.570313,-0.726563 -5.734375,-2.1875 -1.15625,-1.457031 -1.734375,-3.789063 -1.734375,-7 0,-6.375 2.59375,-9.5625 7.78125,-9.5625 5.03125,0 7.546875,2.746094 7.546875,8.234375 l -0.25,2.796875 H 5.453125 c 0.03125,1.492187 0.351563,2.585937 0.96875,3.28125 0.625,0.6875 1.785156,1.03125 3.484375,1.03125 1.707031,0 3.457031,-0.070313 5.25,-0.21875 z M 13,-10.34375 c 0,-1.769531 -0.28125,-3.007812 -0.84375,-3.71875 -0.5625,-0.707031 -1.515625,-1.0625 -2.859375,-1.0625 -1.335937,0 -2.308594,0.375 -2.921875,1.125 -0.617188,0.742188 -0.933594,1.960938 -0.953125,3.65625 z m 0,0"
+ id="path430" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g444"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(145.21372,330.62669)"
+ id="g442">
+ <g
+ id="g440">
+ <path
+ d="m 15.65625,-12.421875 v 8.1875 c 0.03125,0.523437 0.171875,0.914063 0.421875,1.171875 0.25,0.25 0.640625,0.40625 1.171875,0.46875 l -0.109375,2.984375 c -2.0625,0 -3.65625,-0.4414062 -4.78125,-1.328125 -1.917969,0.8867188 -3.84375,1.328125 -5.78125,1.328125 -3.574219,0 -5.359375,-1.898437 -5.359375,-5.703125 0,-1.820312 0.484375,-3.140625 1.453125,-3.953125 0.96875,-0.8125 2.460937,-1.300781 4.484375,-1.46875 l 4.625,-0.40625 v -1.28125 c 0,-0.957031 -0.210938,-1.628906 -0.625,-2.015625 -0.417969,-0.382812 -1.039062,-0.578125 -1.859375,-0.578125 -1.53125,0 -3.445313,0.09375 -5.734375,0.28125 l -1.15625,0.07813 -0.140625,-2.765625 c 2.601563,-0.625 5,-0.9375 7.1875,-0.9375 2.195313,0 3.78125,0.476563 4.75,1.421875 0.96875,0.949219 1.453125,2.453125 1.453125,4.515625 z M 7.609375,-7.96875 c -1.648437,0.136719 -2.46875,1.03125 -2.46875,2.6875 0,1.65625 0.726563,2.484375 2.1875,2.484375 1.195313,0 2.46875,-0.191406 3.8125,-0.578125 L 11.78125,-3.59375 V -8.375 Z m 0,0"
+ id="path438" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g452"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(162.62784,330.62669)"
+ id="g450">
+ <g
+ id="g448">
+ <path
+ d="M 17.03125,-25.4375 V 0 h -3.890625 v -0.9375 c -1.742187,0.8867188 -3.34375,1.328125 -4.8125,1.328125 -2.34375,0 -4.0625,-0.703125 -5.15625,-2.109375 -1.085937,-1.414062 -1.625,-3.785156 -1.625,-7.109375 0,-3.332031 0.601563,-5.753906 1.8125,-7.265625 1.207031,-1.507812 3.09375,-2.265625 5.65625,-2.265625 0.863281,0 2.226563,0.15625 4.09375,0.46875 V -25.4375 Z M 12.5,-3.734375 l 0.609375,-0.25 V -14.625 c -1.4375,-0.238281 -2.765625,-0.359375 -3.984375,-0.359375 -2.417969,0 -3.625,2.015625 -3.625,6.046875 0,2.199219 0.28125,3.726562 0.84375,4.578125 0.5625,0.84375 1.453125,1.265625 2.671875,1.265625 1.21875,0 2.378906,-0.210938 3.484375,-0.640625 z m 0,0"
+ id="path446" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g460"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(181.22687,330.62669)"
+ id="g458">
+ <g
+ id="g456">
+ <path
+ d="m 15.15625,-3.234375 1.015625,-0.109375 0.0625,2.90625 c -2.730469,0.550781 -5.148437,0.828125 -7.25,0.828125 -2.65625,0 -4.570313,-0.726563 -5.734375,-2.1875 -1.15625,-1.457031 -1.734375,-3.789063 -1.734375,-7 0,-6.375 2.59375,-9.5625 7.78125,-9.5625 5.03125,0 7.546875,2.746094 7.546875,8.234375 l -0.25,2.796875 H 5.453125 c 0.03125,1.492187 0.351563,2.585937 0.96875,3.28125 0.625,0.6875 1.785156,1.03125 3.484375,1.03125 1.707031,0 3.457031,-0.070313 5.25,-0.21875 z M 13,-10.34375 c 0,-1.769531 -0.28125,-3.007812 -0.84375,-3.71875 -0.5625,-0.707031 -1.515625,-1.0625 -2.859375,-1.0625 -1.335937,0 -2.308594,0.375 -2.921875,1.125 -0.617188,0.742188 -0.933594,1.960938 -0.953125,3.65625 z m 0,0"
+ id="path454" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g468"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(198.6769,330.62669)"
+ id="g466">
+ <g
+ id="g464">
+ <path
+ d="M 2.375,0 V -17.953125 H 6.25 v 2.140625 c 2.03125,-1.3125 4.066406,-2.160156 6.109375,-2.546875 v 3.921875 c -2.0625,0.40625 -3.824219,0.933594 -5.28125,1.578125 L 6.28125,-12.53125 V 0 Z m 0,0"
+ id="path462" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g476"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(210.84872,330.62669)"
+ id="g474">
+ <g
+ id="g472">
+ <path
+ d="m 14.828125,-14.265625 c -2.824219,-0.375 -4.871094,-0.5625 -6.140625,-0.5625 -1.261719,0 -2.140625,0.152344 -2.640625,0.453125 -0.492187,0.292969 -0.734375,0.761719 -0.734375,1.40625 0,0.648438 0.269531,1.105469 0.8125,1.375 0.539062,0.261719 1.8125,0.5625 3.8125,0.90625 2,0.34375 3.414062,0.890625 4.25,1.640625 0.84375,0.742187 1.265625,2.058594 1.265625,3.953125 0,1.886719 -0.609375,3.273438 -1.828125,4.15625 -1.210938,0.8867188 -2.976562,1.328125 -5.296875,1.328125 -1.460937,0 -3.304687,-0.203125 -5.53125,-0.609375 L 1.6875,-0.390625 1.828125,-3.65625 c 2.875,0.375 4.945313,0.5625 6.21875,0.5625 1.269531,0 2.171875,-0.148438 2.703125,-0.453125 0.539062,-0.3125 0.8125,-0.828125 0.8125,-1.546875 0,-0.71875 -0.261719,-1.210938 -0.78125,-1.484375 -0.511719,-0.28125 -1.742188,-0.582031 -3.6875,-0.90625 -1.949219,-0.320313 -3.382812,-0.832031 -4.296875,-1.53125 -0.90625,-0.695313 -1.359375,-1.96875 -1.359375,-3.8125 0,-1.84375 0.625,-3.21875 1.875,-4.125 1.257812,-0.90625 2.875,-1.359375 4.84375,-1.359375 1.53125,0 3.410156,0.1875 5.640625,0.5625 l 1.109375,0.21875 z m 0,0"
+ id="path470" />
+ </g>
+ </g>
+ </g>
+ <g
+ mask="url(#8f2a27f6f4)"
+ id="g482"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="matrix(0.198482,0,0,0.198482,536.61425,471.98102)"
+ id="g480">
+ <image
+ x="0"
+ y="0"
+ width="461"
+ xlink:href="data:image/png;base64,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"
+ height="461"
+ preserveAspectRatio="xMidYMid"
+ id="image478" />
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g490"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(633.94891,514.05933)"
+ id="g488">
+ <g
+ id="g486">
+ <path
+ d="M 0.8125,-23.234375 H 4.78125 L 8.109375,-3.25 H 8.8125 l 4.421875,-19.921875 h 4.40625 L 22.046875,-3.25 h 0.75 L 26.125,-23.234375 h 3.96875 L 25.515625,0 H 19.4375 l -4,-18.625 L 11.46875,0 H 5.359375 Z m 0,0"
+ id="path484" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g498"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(664.09827,514.05933)"
+ id="g496">
+ <g
+ id="g494">
+ <path
+ d="M 5.9375,0 H 2.234375 V -24.015625 H 5.9375 v 7.9375 c 1.675781,-0.832031 3.222656,-1.25 4.640625,-1.25 2.257813,0 3.800781,0.640625 4.625,1.921875 0.832031,1.273438 1.25,3.375 1.25,6.3125 V 0 H 12.75 v -8.984375 c 0,-1.832031 -0.195312,-3.132813 -0.578125,-3.90625 -0.386719,-0.769531 -1.199219,-1.15625 -2.4375,-1.15625 -1.085937,0 -2.167969,0.183594 -3.25,0.546875 L 5.9375,-13.296875 Z m 0,0"
+ id="path492" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g506"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(681.869,514.05933)"
+ id="g504">
+ <g
+ id="g502">
+ <path
+ d="m 14.3125,-3.046875 0.953125,-0.109375 0.0625,2.75 C 12.753906,0.113281 10.472656,0.375 8.484375,0.375 5.972656,0.375 4.164062,-0.3125 3.0625,-1.6875 1.96875,-3.070312 1.421875,-5.28125 1.421875,-8.3125 c 0,-6.007812 2.453125,-9.015625 7.359375,-9.015625 4.75,0 7.125,2.589844 7.125,7.765625 l -0.234375,2.640625 H 5.15625 c 0.019531,1.40625 0.320312,2.4375 0.90625,3.09375 0.59375,0.65625 1.691406,0.984375 3.296875,0.984375 1.601563,0 3.253906,-0.066406 4.953125,-0.203125 z m -2.03125,-6.71875 c 0,-1.675781 -0.265625,-2.847656 -0.796875,-3.515625 -0.53125,-0.664062 -1.433594,-1 -2.703125,-1 -1.261719,0 -2.183594,0.355469 -2.765625,1.0625 -0.574219,0.699219 -0.871094,1.851562 -0.890625,3.453125 z m 0,0"
+ id="path500" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g514"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(698.351,514.05933)"
+ id="g512">
+ <g
+ id="g510">
+ <path
+ d="m 14.3125,-3.046875 0.953125,-0.109375 0.0625,2.75 C 12.753906,0.113281 10.472656,0.375 8.484375,0.375 5.972656,0.375 4.164062,-0.3125 3.0625,-1.6875 1.96875,-3.070312 1.421875,-5.28125 1.421875,-8.3125 c 0,-6.007812 2.453125,-9.015625 7.359375,-9.015625 4.75,0 7.125,2.589844 7.125,7.765625 l -0.234375,2.640625 H 5.15625 c 0.019531,1.40625 0.320312,2.4375 0.90625,3.09375 0.59375,0.65625 1.691406,0.984375 3.296875,0.984375 1.601563,0 3.253906,-0.066406 4.953125,-0.203125 z m -2.03125,-6.71875 c 0,-1.675781 -0.265625,-2.847656 -0.796875,-3.515625 -0.53125,-0.664062 -1.433594,-1 -2.703125,-1 -1.261719,0 -2.183594,0.355469 -2.765625,1.0625 -0.574219,0.699219 -0.871094,1.851562 -0.890625,3.453125 z m 0,0"
+ id="path508" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g522"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(714.833,514.05933)"
+ id="g520">
+ <g
+ id="g518">
+ <path
+ d="M 2.4375,0 V -24.015625 H 6.140625 V 0 Z m 0,0"
+ id="path516" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g530"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(633.94891,548.55933)"
+ id="g528">
+ <g
+ id="g526">
+ <path
+ d="m 11.1875,-7.21875 h -4.75 V 0 h -3.75 v -23.234375 h 8.5 c 5.269531,0 7.90625,2.601563 7.90625,7.796875 0,2.667969 -0.664062,4.703125 -1.984375,6.109375 -1.324219,1.40625 -3.296875,2.109375 -5.921875,2.109375 z m -4.75,-3.265625 h 4.71875 c 2.71875,0 4.078125,-1.648437 4.078125,-4.953125 0,-1.582031 -0.328125,-2.734375 -0.984375,-3.453125 -0.65625,-0.726563 -1.6875,-1.09375 -3.09375,-1.09375 H 6.4375 Z m 0,0"
+ id="path524" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g538"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(653.24578,548.55933)"
+ id="g536">
+ <g
+ id="g534">
+ <path
+ d="M 14.796875,-11.734375 V -4 c 0.01953,0.5 0.144531,0.871094 0.375,1.109375 0.238281,0.230469 0.609375,0.382813 1.109375,0.453125 L 16.1875,0.375 c -1.949219,0 -3.453125,-0.4140625 -4.515625,-1.25 -1.8125,0.8359375 -3.636719,1.25 -5.46875,1.25 -3.367187,0 -5.046875,-1.796875 -5.046875,-5.390625 0,-1.71875 0.457031,-2.960937 1.375,-3.734375 0.914062,-0.769531 2.320312,-1.234375 4.21875,-1.390625 l 4.375,-0.375 v -1.21875 c 0,-0.90625 -0.199219,-1.535156 -0.59375,-1.890625 -0.398438,-0.363281 -0.980469,-0.546875 -1.75,-0.546875 -1.449219,0 -3.257812,0.08984 -5.421875,0.265625 l -1.09375,0.0625 -0.125,-2.609375 c 2.457031,-0.582031 4.722656,-0.875 6.796875,-0.875 2.070312,0 3.566406,0.449219 4.484375,1.34375 0.914063,0.886719 1.375,2.304687 1.375,4.25 z M 7.1875,-7.53125 c -1.5625,0.136719 -2.34375,0.984375 -2.34375,2.546875 0,1.5625 0.691406,2.34375 2.078125,2.34375 1.125,0 2.320313,-0.179687 3.59375,-0.546875 L 11.125,-3.390625 V -7.90625 Z m 0,0"
+ id="path532" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g546"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(669.69387,548.55933)"
+ id="g544">
+ <g
+ id="g542">
+ <path
+ d="m 8.578125,-17.328125 c 1.195313,0 2.613281,0.15625 4.25,0.46875 l 0.84375,0.171875 -0.140625,2.921875 c -1.78125,-0.1875 -3.105469,-0.28125 -3.96875,-0.28125 -1.71875,0 -2.875,0.386719 -3.46875,1.15625 -0.585938,0.773437 -0.875,2.21875 -0.875,4.34375 0,2.125 0.28125,3.59375 0.84375,4.40625 0.570312,0.8125 1.75,1.21875 3.53125,1.21875 L 13.5625,-3.1875 13.671875,-0.234375 C 11.390625,0.171875 9.671875,0.375 8.515625,0.375 5.929688,0.375 4.113281,-0.316406 3.0625,-1.703125 2.019531,-3.097656 1.5,-5.378906 1.5,-8.546875 c 0,-3.164063 0.550781,-5.421875 1.65625,-6.765625 1.101562,-1.34375 2.910156,-2.015625 5.421875,-2.015625 z m 0,0"
+ id="path540" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g554"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(683.93754,548.55933)"
+ id="g552">
+ <g
+ id="g550">
+ <path
+ d="M 5.9375,0 H 2.234375 V -24.015625 H 5.9375 v 13.875 l 2.109375,-0.203125 4,-6.625 H 16.1875 L 11.296875,-9.015625 16.453125,0 H 12.28125 L 8.140625,-7.15625 5.9375,-6.921875 Z m 0,0"
+ id="path548" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g562"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(700.11432,548.55933)"
+ id="g560">
+ <g
+ id="g558">
+ <path
+ d="M 14.796875,-11.734375 V -4 c 0.01953,0.5 0.144531,0.871094 0.375,1.109375 0.238281,0.230469 0.609375,0.382813 1.109375,0.453125 L 16.1875,0.375 c -1.949219,0 -3.453125,-0.4140625 -4.515625,-1.25 -1.8125,0.8359375 -3.636719,1.25 -5.46875,1.25 -3.367187,0 -5.046875,-1.796875 -5.046875,-5.390625 0,-1.71875 0.457031,-2.960937 1.375,-3.734375 0.914062,-0.769531 2.320312,-1.234375 4.21875,-1.390625 l 4.375,-0.375 v -1.21875 c 0,-0.90625 -0.199219,-1.535156 -0.59375,-1.890625 -0.398438,-0.363281 -0.980469,-0.546875 -1.75,-0.546875 -1.449219,0 -3.257812,0.08984 -5.421875,0.265625 l -1.09375,0.0625 -0.125,-2.609375 c 2.457031,-0.582031 4.722656,-0.875 6.796875,-0.875 2.070312,0 3.566406,0.449219 4.484375,1.34375 0.914063,0.886719 1.375,2.304687 1.375,4.25 z M 7.1875,-7.53125 c -1.5625,0.136719 -2.34375,0.984375 -2.34375,2.546875 0,1.5625 0.691406,2.34375 2.078125,2.34375 1.125,0 2.320313,-0.179687 3.59375,-0.546875 L 11.125,-3.390625 V -7.90625 Z m 0,0"
+ id="path556" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g570"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(716.56241,548.55933)"
+ id="g568">
+ <g
+ id="g566">
+ <path
+ d="m 17.0625,2.3125 c 0,3.707031 -2.683594,5.5625 -8.046875,5.5625 C 6.441406,7.875 4.53125,7.519531 3.28125,6.8125 2.039062,6.113281 1.421875,4.835938 1.421875,2.984375 1.421875,2.148438 1.625,1.429688 2.03125,0.828125 2.4375,0.234375 3.09375,-0.414062 4,-1.125 3.257812,-1.613281 2.890625,-2.4375 2.890625,-3.59375 c 0,-0.457031 0.300781,-1.191406 0.90625,-2.203125 L 4.109375,-6.3125 C 2.472656,-7.28125 1.65625,-8.972656 1.65625,-11.390625 c 0,-2.039063 0.609375,-3.535156 1.828125,-4.484375 1.226563,-0.945312 2.882813,-1.421875 4.96875,-1.421875 0.988281,0 1.96875,0.109375 2.9375,0.328125 L 11.90625,-16.859375 17.171875,-17 v 2.984375 l -2.828125,-0.15625 c 0.613281,0.792969 0.921875,1.71875 0.921875,2.78125 0,2.210937 -0.5625,3.742187 -1.6875,4.59375 -1.117187,0.84375 -2.859375,1.265625 -5.234375,1.265625 -0.585938,0 -1.078125,-0.046875 -1.484375,-0.140625 C 6.535156,-4.898438 6.375,-4.300781 6.375,-3.875 c 0,0.417969 0.207031,0.703125 0.625,0.859375 0.414062,0.15625 1.429688,0.246094 3.046875,0.265625 2.6875,0.023438 4.523437,0.386719 5.515625,1.09375 1,0.699219 1.5,2.019531 1.5,3.96875 z M 5.046875,2.640625 c 0,0.789063 0.316406,1.351563 0.953125,1.6875 0.632812,0.34375 1.722656,0.515625 3.265625,0.515625 2.726563,0 4.09375,-0.777344 4.09375,-2.328125 0,-0.886719 -0.246094,-1.449219 -0.734375,-1.6875 C 12.144531,0.585938 11.179688,0.457031 9.734375,0.4375 L 6.40625,0.234375 C 5.914062,0.640625 5.566406,1.019531 5.359375,1.375 5.148438,1.726562 5.046875,2.148438 5.046875,2.640625 Z m 0.28125,-14.03125 c 0,1.03125 0.242187,1.792969 0.734375,2.28125 0.5,0.492187 1.300781,0.734375 2.40625,0.734375 1.113281,0 1.910156,-0.242188 2.390625,-0.734375 0.488281,-0.488281 0.734375,-1.25 0.734375,-2.28125 0,-1.039063 -0.25,-1.804687 -0.75,-2.296875 -0.492188,-0.488281 -1.289062,-0.734375 -2.390625,-0.734375 -2.085937,0 -3.125,1.011719 -3.125,3.03125 z m 0,0"
+ id="path564" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g578"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(733.62094,548.55933)"
+ id="g576">
+ <g
+ id="g574">
+ <path
+ d="m 14.3125,-3.046875 0.953125,-0.109375 0.0625,2.75 C 12.753906,0.113281 10.472656,0.375 8.484375,0.375 5.972656,0.375 4.164062,-0.3125 3.0625,-1.6875 1.96875,-3.070312 1.421875,-5.28125 1.421875,-8.3125 c 0,-6.007812 2.453125,-9.015625 7.359375,-9.015625 4.75,0 7.125,2.589844 7.125,7.765625 l -0.234375,2.640625 H 5.15625 c 0.019531,1.40625 0.320312,2.4375 0.90625,3.09375 0.59375,0.65625 1.691406,0.984375 3.296875,0.984375 1.601563,0 3.253906,-0.066406 4.953125,-0.203125 z m -2.03125,-6.71875 c 0,-1.675781 -0.265625,-2.847656 -0.796875,-3.515625 -0.53125,-0.664062 -1.433594,-1 -2.703125,-1 -1.261719,0 -2.183594,0.355469 -2.765625,1.0625 -0.574219,0.699219 -0.871094,1.851562 -0.890625,3.453125 z m 0,0"
+ id="path572" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#000000"
+ fill-opacity="1"
+ id="g586"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(750.10294,548.55933)"
+ id="g584">
+ <g
+ id="g582">
+ <path
+ d="m 14.015625,-13.46875 c -2.679687,-0.363281 -4.617187,-0.546875 -5.8125,-0.546875 -1.199219,0 -2.03125,0.148437 -2.5,0.4375 -0.460937,0.28125 -0.6875,0.730469 -0.6875,1.34375 0,0.605469 0.253906,1.03125 0.765625,1.28125 0.507812,0.25 1.707031,0.542969 3.59375,0.875 1.894531,0.324219 3.238281,0.835937 4.03125,1.53125 0.789062,0.699219 1.1875,1.945313 1.1875,3.734375 0,1.78125 -0.574219,3.09375 -1.71875,3.9375 -1.148438,0.8359375 -2.8125,1.25 -5,1.25 -1.386719,0 -3.132812,-0.195312 -5.234375,-0.578125 L 1.59375,-0.375 1.734375,-3.453125 c 2.707031,0.355469 4.660156,0.53125 5.859375,0.53125 1.195312,0 2.050781,-0.144531 2.5625,-0.4375 0.507812,-0.289063 0.765625,-0.773437 0.765625,-1.453125 0,-0.675781 -0.246094,-1.144531 -0.734375,-1.40625 C 9.707031,-6.476562 8.546875,-6.757812 6.703125,-7.0625 4.859375,-7.375 3.503906,-7.859375 2.640625,-8.515625 c -0.855469,-0.65625 -1.28125,-1.851563 -1.28125,-3.59375 0,-1.738281 0.59375,-3.035156 1.78125,-3.890625 1.1875,-0.863281 2.707031,-1.296875 4.5625,-1.296875 1.445313,0 3.222656,0.183594 5.328125,0.546875 l 1.046875,0.203125 z m 0,0"
+ id="path580" />
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#9cd47c7ee3)"
+ id="g596"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ clip-path="url(#69785d3302)"
+ id="g594">
+ <g
+ clip-path="url(#9c0953b9a2)"
+ id="g592">
+ <g
+ clip-path="url(#8e32f12866)"
+ id="g590">
+ <path
+ fill="#09102b"
+ d="m 358.17187,562.08984 c -1.19531,0.76172 -2.16015,1.45703 -3.19921,2.02344 -3.46094,1.87891 -6.86329,3.89453 -10.45313,5.5 -3.87109,1.73047 -8.14062,-0.26953 -10.125,-4.14453 -0.5,-0.96484 -1.69141,-1.5625 -2.67578,-2.41797 -0.13672,-1.35937 1.17969,-1.5625 2.09375,-2.03906 8.29297,-4.31641 15.45703,-10.17188 22.07812,-16.66406 2.53516,-2.48047 4.60938,-5.44922 6.80079,-8.26563 1.71875,-2.21484 1.94921,-2.53516 4.60546,-1.53125 4.74219,1.79297 8.49219,4.66797 10.34375,9.73828 3.22657,8.80469 6.95704,17.42969 8.59375,26.74219 0.26172,1.51172 0.33594,3.0625 0.59375,5.5 -3.77343,-1.86719 -7.05859,-2.78516 -8.24609,-6.56641 -0.72656,-2.32031 -1.48828,-4.61718 -2.5,-7.78906 -1.25781,2.66406 -2.09766,4.50781 -2.99219,6.32031 -6.76172,13.64844 -16.28906,24.96875 -29.98828,31.73828 -12.46484,6.16797 -25.84765,9.05469 -39.78906,5.21875 -11.70703,-3.23437 -20.39844,-10.70703 -27.02734,-20.60156 -2.64844,-3.96875 -4.57422,-8.4375 -6.70313,-12.73828 -0.55469,-1.11328 -0.65234,-2.44141 -0.95312,-3.68359 0.30078,-0.15625 0.60156,-0.31641 0.90625,-0.47657 1.17578,1.30469 2.42578,2.55469 3.48828,3.94532 0.66406,0.87109 1.05859,1.94922 1.53515,2.95312 6.10547,12.90625 16.76953,18.96094 30.5625,19.90625 10.53516,0.72656 20.27344,-2.26562 29.27735,-7.62109 9.51172,-5.64063 17.07812,-13.32813 22.98047,-22.6836 0.26953,-0.41406 0.51171,-0.84765 0.71875,-1.28906 0.0781,-0.20312 0.0351,-0.46484 0.0742,-1.07422 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path588" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#a3af3eb6b6)"
+ id="g600"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#09102b"
+ d="m 704.36719,330.69531 c 1.40625,-2.07812 3.07422,-1.63672 4.66797,-1.07812 4.41406,1.53125 8.38281,3.79297 11.63281,7.23828 10.34375,10.98828 17.05859,23.99609 20.78125,38.50781 3.82031,14.875 2.98047,29.55469 -3.1211,43.75 -2.87109,6.67969 -6.11328,13.20703 -9.29687,20.03516 0.74219,-0.2461 1.6875,-0.47266 2.58203,-0.85938 6.08203,-2.59765 7.51172,-2.37109 12.3125,2.26953 1.07422,1.03516 1.95703,2.26563 3.19531,3.70703 -1.25,0.77735 -2.1289,1.35547 -3.04687,1.88672 -9.82422,5.69532 -19.75781,11.22266 -29.42188,17.19922 -2.34375,1.44531 -4.15234,1.31641 -6.14453,0.36719 -4.0039,-1.91797 -6.86328,-5.28906 -9.32812,-8.80078 -0.86328,-1.22656 -0.58203,-3.52344 -0.33594,-5.25781 1.86328,-12.69922 2.53906,-25.44922 1.51953,-38.23438 -0.32422,-3.98828 -1.25,-7.91797 -1.94922,-12.22656 1.26953,-0.47266 2.67969,0.3125 3.875,1.0664 5.60547,3.54297 10.27735,7.85157 11.26563,14.91797 0.46484,3.33985 0.95703,6.66797 1.39062,10.00782 0.19141,1.48437 0.23438,2.99218 0.375,4.83593 7.40625,-6.82031 14.4961,-36.78515 12.53906,-51.98437 -2.3789,-18.48047 -10.55859,-34.16406 -23.49218,-47.34766 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path598" />
+ </g>
+ <g
+ clip-path="url(#31f8f05393)"
+ id="g610"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ clip-path="url(#41889181af)"
+ id="g608">
+ <g
+ clip-path="url(#fe9d13e8b4)"
+ id="g606">
+ <g
+ clip-path="url(#6c6e35ef02)"
+ id="g604">
+ <path
+ fill="#09102b"
+ d="m 509.19922,356.76172 c -0.71094,1.38672 0.0273,2.15234 0.80469,2.83984 2.14062,1.92188 4.55078,3.38281 7.39453,4.10156 9.04687,2.27735 18.11718,1.99219 27.11328,-0.35156 9.22656,-2.40234 16.95703,-7.25781 22.86719,-14.80469 2.77734,-3.55078 5.36328,-7.2539 8.1289,-11.01953 0.0859,0.47657 0.2461,1.05469 0.30078,1.65235 0.39453,4.05468 0.94141,4.75781 4.89453,5.94922 0.88282,0.27343 1.8125,0.3789 2.96485,0.61328 0.0508,-0.90625 0.10547,-1.55469 0.11719,-2.20703 0.17968,-7.00391 0.23437,-14.01172 0.61328,-21.01172 0.0859,-1.69922 -0.52344,-2.63282 -1.62891,-3.42188 -2.23047,-1.58203 -4.91797,-2.11328 -7.55859,-2.39062 -0.92188,-0.0937 -2.08594,0.74609 -2.95703,1.39843 -6.35157,4.8125 -13.08594,9 -20.34375,12.28516 -2.26172,1.01953 -4.67579,1.70313 -7.22657,2.61719 0.1211,0.82422 0.96875,1.35156 1.73047,1.76562 3.59375,1.96094 7.32422,3.1836 11.46094,1.59766 1.95703,-0.75 3.91406,-1.48047 5.85547,-2.25 0.86719,-0.34375 1.69922,-0.77344 2.74219,-1.25 -1.50782,6.03516 -15.69532,18.84375 -24.54297,22.34766 -10.75782,4.26171 -21.71485,4.55859 -32.73047,1.53906 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path602" />
+ </g>
+ </g>
+ </g>
+ </g>
+ <g
+ clip-path="url(#9d2f7452d2)"
+ id="g614"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#09102b"
+ d="m 547.03516,293.51172 h 54.54296 c 1.38282,0 2.51563,-1.12891 2.51563,-2.50781 v -40.83594 h -59.57422 v 40.83594 c 0,1.3789 1.13281,2.50781 2.51563,2.50781 z m 16.36328,-33.44531 h 21.8125 c 1.5,0 2.72656,1.22265 2.72656,2.71484 0,1.49219 -1.22656,2.71484 -2.72656,2.71484 h -21.8125 c -1.4961,0 -2.72266,-1.22265 -2.72266,-2.71484 0,-1.49219 1.22656,-2.71484 2.72266,-2.71484 z m 0,0"
+ fill-opacity="1"
+ fill-rule="evenodd"
+ id="path612" />
+ </g>
+ <g
+ clip-path="url(#5d999a0038)"
+ id="g618"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#09102b"
+ d="m 554.07812,219.76172 h 1.70313 c 1.91797,0 3.48047,1.55859 3.48047,3.47265 0,1.91016 -1.5625,3.46875 -3.48047,3.46875 h -8.76953 c -1.91797,0 -3.48047,-1.55859 -3.48047,-3.46875 0,-1.83984 1.44922,-3.35546 3.26562,-3.46484 v 1.73828 c -0.85546,0.10938 -1.52734,0.84375 -1.52734,1.72656 0,0.87891 0.67188,1.61719 1.52734,1.72266 v 0.004 h 0.0469 c 0.0547,0.008 0.10937,0.008 0.16797,0.008 h 8.76953 c 0.95703,0 1.74219,-0.78125 1.74219,-1.73438 0,-0.95703 -0.78516,-1.73828 -1.74219,-1.73828 h -1.70313 z m 0,0"
+ fill-opacity="1"
+ fill-rule="nonzero"
+ id="path616" />
+ </g>
+ <g
+ clip-path="url(#a4f0b4e13e)"
+ id="g622"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#09102b"
+ d="M 594.1875,248.43359 H 548.53516 V 228.4375 h 7.24609 c 2.875,0 5.21875,-2.33594 5.21875,-5.20313 0,-2.86718 -2.34375,-5.20703 -5.21875,-5.20703 h -3.44141 v 5.20313 h -3.80468 v -6.04297 c 0,-0.92188 0.73437,-1.67578 1.6289,-1.67578 h 42.39453 c 0.89844,0 1.62891,0.7539 1.62891,1.67578 z m -39.69922,-5.64062 h 33.75 v 1.73047 h -33.75 z m 0,-4.61719 h 33.75 v 1.73438 h -33.75 z m 8.23047,-14.98047 h 17.28906 v 1.73438 h -17.28906 z m 4.13281,-3.77734 h 9.01953 v 1.73437 h -9.01953 z m -12.36328,14.14453 h 33.75 v 1.73437 h -33.75 z m 0,0"
+ fill-opacity="1"
+ fill-rule="evenodd"
+ id="path620" />
+ </g>
+ <g
+ clip-path="url(#0ea259bc34)"
+ id="g626"
+ transform="translate(-43.488732,-201.52699)">
+ <path
+ fill="#09102b"
+ d="m 595.92969,248.43359 h 4.14843 V 217.1875 c 0,-0.92188 -0.73437,-1.67578 -1.63281,-1.67578 h -2.95312 c 0.27734,0.49609 0.4375,1.07031 0.4375,1.67578 z m 0,0"
+ fill-opacity="1"
+ fill-rule="evenodd"
+ id="path624" />
+ </g>
+ <g
+ fill="#ffffff"
+ fill-opacity="1"
+ id="g634"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(549.69852,280.96421)"
+ id="g632">
+ <g
+ id="g630">
+ <path
+ d="m 4.421875,0.109375 c -0.75,0 -1.414063,-0.1484375 -1.984375,-0.453125 -0.5625,-0.3125 -1.007812,-0.773438 -1.328125,-1.390625 -0.3125,-0.625 -0.46875,-1.394531 -0.46875,-2.3125 0,-0.90625 0.15625,-1.671875 0.46875,-2.296875 0.320313,-0.625 0.765625,-1.085938 1.328125,-1.390625 0.570312,-0.3125 1.234375,-0.46875 1.984375,-0.46875 0.78125,0 1.441406,0.152344 1.984375,0.453125 0.539062,0.304688 0.925781,0.765625 1.15625,1.390625 l -1.15625,0.71875 H 6.265625 c -0.179687,-0.425781 -0.417969,-0.726563 -0.71875,-0.90625 -0.292969,-0.1875 -0.667969,-0.28125 -1.125,-0.28125 -0.679687,0 -1.203125,0.226563 -1.578125,0.671875 -0.375,0.4375 -0.5625,1.140625 -0.5625,2.109375 0,0.96875 0.1875,1.679687 0.5625,2.125 0.375,0.4375 0.898438,0.65625 1.578125,0.65625 1.050781,0 1.691406,-0.507813 1.921875,-1.53125 h 0.140625 l 1.1875,0.609375 C 7.441406,-1.414062 7.0625,-0.835938 6.53125,-0.453125 6,-0.078125 5.296875,0.109375 4.421875,0.109375 Z m 0,0"
+ id="path628" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#ffffff"
+ fill-opacity="1"
+ id="g642"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(557.62495,280.96421)"
+ id="g640">
+ <g
+ id="g638">
+ <path
+ d="m 4.171875,-8.09375 c 0.582031,0 1.078125,0.109375 1.484375,0.328125 0.414062,0.210937 0.726562,0.507813 0.9375,0.890625 0.207031,0.375 0.3125,0.820312 0.3125,1.328125 0,0.5 -0.105469,0.945313 -0.3125,1.328125 -0.210938,0.375 -0.523438,0.671875 -0.9375,0.890625 -0.40625,0.210937 -0.902344,0.3125 -1.484375,0.3125 H 2.65625 V 0 H 1.046875 v -8.09375 z m -0.203125,3.8125 c 0.882812,0 1.328125,-0.421875 1.328125,-1.265625 0,-0.84375 -0.445313,-1.265625 -1.328125,-1.265625 h -1.3125 v 2.53125 z m 0,0"
+ id="path636" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#ffffff"
+ fill-opacity="1"
+ id="g650"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(565.00968,280.96421)"
+ id="g648">
+ <g
+ id="g646">
+ <path
+ d="M 1.34375,2.59375 C 1.082031,2.59375 0.847656,2.570312 0.640625,2.53125 0.429688,2.488281 0.257812,2.4375 0.125,2.375 L 0.359375,1.125 0.46875,1.09375 C 0.5625,1.144531 0.675781,1.179688 0.8125,1.203125 0.945312,1.234375 1.085938,1.25 1.234375,1.25 1.472656,1.25 1.675781,1.21875 1.84375,1.15625 2.007812,1.09375 2.148438,0.984375 2.265625,0.828125 2.378906,0.679688 2.476562,0.476562 2.5625,0.21875 L 0.125,-6.09375 H 1.734375 L 3.25,-1.859375 h 0.140625 l 1.46875,-4.234375 h 1.5625 L 3.96875,0.375 C 3.769531,0.90625 3.550781,1.328125 3.3125,1.640625 3.082031,1.960938 2.804688,2.203125 2.484375,2.359375 2.171875,2.515625 1.789062,2.59375 1.34375,2.59375 Z m 0,0"
+ id="path644" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#ffffff"
+ fill-opacity="1"
+ id="g658"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(571.55424,280.96421)"
+ id="g656">
+ <g
+ id="g654">
+ <path
+ d="m 4.203125,-1.453125 0.40625,1.125 C 4.441406,-0.179688 4.234375,-0.0703125 3.984375,0 3.734375,0.0703125 3.445312,0.109375 3.125,0.109375 c -0.65625,0 -1.15625,-0.1757812 -1.5,-0.53125 -0.34375,-0.363281 -0.515625,-0.882813 -0.515625,-1.5625 v -2.90625 H 0.1875 v -1.21875 h 0.921875 v -1.1875 l 1.53125,-0.25 v 1.4375 H 4.375 v 1.21875 H 2.640625 v 2.78125 c 0,0.3125 0.0625,0.539063 0.1875,0.671875 0.125,0.136719 0.304687,0.203125 0.546875,0.203125 0.269531,0 0.507812,-0.070313 0.71875,-0.21875 z m 0,0"
+ id="path652" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#ffffff"
+ fill-opacity="1"
+ id="g666"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(576.2913,280.96421)"
+ id="g664">
+ <g
+ id="g662">
+ <path
+ d="m 0.875,0 v -8.546875 h 1.53125 v 3.25 l 0.125,0.015625 c 0.195312,-0.300781 0.441406,-0.53125 0.734375,-0.6875 0.300781,-0.164062 0.660156,-0.25 1.078125,-0.25 1.34375,0 2.015625,0.765625 2.015625,2.296875 V 0 h -1.53125 v -3.734375 c 0,-0.414063 -0.085937,-0.71875 -0.25,-0.90625 -0.167969,-0.1875 -0.421875,-0.28125 -0.765625,-0.28125 -0.4375,0 -0.78125,0.148437 -1.03125,0.4375 -0.25,0.28125 -0.375,0.726563 -0.375,1.328125 V 0 Z m 0,0"
+ id="path660" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#ffffff"
+ fill-opacity="1"
+ id="g674"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(583.43283,280.96421)"
+ id="g672">
+ <g
+ id="g670">
+ <path
+ d="M 3.546875,0.109375 C 2.953125,0.109375 2.425781,-0.0078125 1.96875,-0.25 1.519531,-0.5 1.171875,-0.859375 0.921875,-1.328125 c -0.25,-0.476563 -0.375,-1.050781 -0.375,-1.71875 0,-0.664063 0.125,-1.238281 0.375,-1.71875 0.25,-0.476563 0.597656,-0.835937 1.046875,-1.078125 0.457031,-0.25 0.984375,-0.375 1.578125,-0.375 0.59375,0 1.113281,0.125 1.5625,0.375 0.457031,0.242188 0.8125,0.601562 1.0625,1.078125 0.25,0.480469 0.375,1.054687 0.375,1.71875 0,0.667969 -0.125,1.242187 -0.375,1.71875 -0.25,0.46875 -0.605469,0.828125 -1.0625,1.078125 -0.449219,0.2421875 -0.96875,0.359375 -1.5625,0.359375 z m 0,-1.296875 c 0.945313,0 1.421875,-0.617188 1.421875,-1.859375 0,-0.644531 -0.125,-1.117187 -0.375,-1.421875 -0.242188,-0.300781 -0.589844,-0.453125 -1.046875,-0.453125 -0.949219,0 -1.421875,0.625 -1.421875,1.875 0,1.242187 0.472656,1.859375 1.421875,1.859375 z m 0,0"
+ id="path668" />
+ </g>
+ </g>
+ </g>
+ <g
+ fill="#ffffff"
+ fill-opacity="1"
+ id="g682"
+ transform="translate(-43.488732,-201.52699)">
+ <g
+ transform="translate(590.51908,280.96421)"
+ id="g680">
+ <g
+ id="g678">
+ <path
+ d="m 0.875,0 v -6.09375 h 1.46875 v 0.890625 l 0.125,0.03125 c 0.375,-0.695313 0.988281,-1.046875 1.84375,-1.046875 0.707031,0 1.222656,0.195312 1.546875,0.578125 0.332031,0.386719 0.5,0.945313 0.5,1.671875 V 0 h -1.53125 v -3.78125 c 0,-0.40625 -0.085937,-0.695312 -0.25,-0.875 C 4.421875,-4.832031 4.164062,-4.921875 3.8125,-4.921875 3.363281,-4.921875 3.015625,-4.78125 2.765625,-4.5 2.523438,-4.21875 2.40625,-3.769531 2.40625,-3.15625 V 0 Z m 0,0"
+ id="path676" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/sources/shiboken6/doc/images/shibokenqtarch.png b/sources/shiboken6/doc/images/shibokenqtarch.png
index 359413373..c20ba4624 100644
--- a/sources/shiboken6/doc/images/shibokenqtarch.png
+++ b/sources/shiboken6/doc/images/shibokenqtarch.png
Binary files differ
diff --git a/sources/shiboken6/doc/images/shibokenqtarch.svg b/sources/shiboken6/doc/images/shibokenqtarch.svg
index d9212f18c..8f52b8db4 100644
--- a/sources/shiboken6/doc/images/shibokenqtarch.svg
+++ b/sources/shiboken6/doc/images/shibokenqtarch.svg
@@ -2,24 +2,24 @@
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="275"
height="197.55103"
id="svg2"
sodipodi:version="0.32"
- inkscape:version="0.92.2 2405546, 2018-03-11"
+ inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
version="1.0"
sodipodi:docname="shibokenqtarch.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-filename="shibokenqtarch.png"
inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
+ inkscape:export-ydpi="90"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs4">
<marker
@@ -54,23 +54,26 @@
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="1.0474359"
- inkscape:cx="110.19617"
- inkscape:cy="69.09871"
+ inkscape:zoom="2.0948718"
+ inkscape:cx="130.07956"
+ inkscape:cy="99.051407"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
- inkscape:window-width="1002"
- inkscape:window-height="1042"
- inkscape:window-x="10"
- inkscape:window-y="28"
+ inkscape:window-width="2552"
+ inkscape:window-height="1432"
+ inkscape:window-x="1924"
+ inkscape:window-y="4"
showguides="true"
inkscape:guide-bbox="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
- inkscape:window-maximized="0">
+ inkscape:window-maximized="0"
+ inkscape:showpageshadow="2"
+ inkscape:pagecheckerboard="0"
+ inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid44"
@@ -85,7 +88,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
+ <dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@@ -114,7 +117,7 @@
sodipodi:nodetypes="ccccccc" />
<text
xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:16.68707466px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.12244904;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:16.6871px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.12245;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="120.87232"
y="334.88406"
id="text153"><tspan
@@ -122,10 +125,10 @@
id="tspan151"
x="120.87232"
y="334.88406"
- style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:16.68707466px;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.12244904;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">Qt for Python</tspan></text>
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:16.6871px;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.12245;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">Qt for Python</tspan></text>
<text
xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.74510956px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:Titillium;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.31862774"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.7451px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:Titillium;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.318628"
x="121.09701"
y="354.01886"
id="text157"><tspan
@@ -133,7 +136,7 @@
x="121.09701"
y="354.01886"
id="tspan159"
- style="fill:#ffffff;fill-opacity:1;stroke-width:0.31862774">Qt classes and functions exported to Python</tspan></text>
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.318628">Qt classes and functions exported to Python</tspan></text>
<path
style="fill:#53586b;fill-opacity:1;stroke:none;stroke-width:2.20567369;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 106.0768,391.19877 v 44.89796 h 262.2093 l 12.7907,-11.22449 V 379.97428 H 117.53514 Z"
@@ -142,7 +145,7 @@
sodipodi:nodetypes="ccccccc" />
<text
xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:16.68707466px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.41717955"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:16.6871px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.41718"
x="121.0225"
y="403.38095"
id="text153-2"><tspan
@@ -150,10 +153,10 @@
id="tspan151-9"
x="121.0225"
y="403.38095"
- style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:16.68707466px;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.41717955">Shiboken</tspan></text>
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:16.6871px;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.41718">Shiboken</tspan></text>
<text
xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.74510956px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:Titillium;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.31862774"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.7451px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:Titillium;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.318628"
x="121.09701"
y="421.95245"
id="text157-1"><tspan
@@ -161,10 +164,10 @@
x="121.09701"
y="421.95245"
id="tspan159-2"
- style="fill:#ffffff;fill-opacity:1;stroke-width:0.31862774">Generator that exposes C++ classes to Python</tspan></text>
+ style="fill:#ffffff;fill-opacity:1;stroke-width:0.318628">Generator that exposes C++ classes to Python</tspan></text>
<text
xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:17.95918465px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.31862774"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:17.9592px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.318628"
x="123.35368"
y="482.61551"
id="text157-1-7"><tspan
@@ -172,17 +175,17 @@
x="123.35368"
y="482.61551"
id="tspan159-2-0"
- style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:17.95918465px;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.31862774">CPython API</tspan></text>
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:17.9592px;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.318628">CPython API</tspan></text>
<text
xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:17.95918465px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.4132798"
- x="265.1445"
- y="483.19019"
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:17.9592px;line-height:1.25;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.41328"
+ x="271.38934"
+ y="483.42886"
id="text157-1-9"><tspan
sodipodi:role="line"
- x="265.1445"
- y="483.19019"
+ x="271.38934"
+ y="483.42886"
id="tspan159-2-3"
- style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:17.95918465px;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.4132798">Qt 5 Libraries</tspan></text>
+ style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-size:17.9592px;font-family:Titillium;-inkscape-font-specification:'Titillium, Semi-Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke-width:0.41328">Qt Libraries</tspan></text>
</g>
</svg>
diff --git a/sources/shiboken6/doc/index.rst b/sources/shiboken6/doc/index.rst
index d7cb4c2b1..68f96dded 100644
--- a/sources/shiboken6/doc/index.rst
+++ b/sources/shiboken6/doc/index.rst
@@ -25,73 +25,92 @@ Shiboken
Documentation
=============
-.. panels::
- :body: text-center
- :container: container-lg pb-3
- :column: col-lg-4 col-md-4 col-sm-6 col-xs-12 p-2
+.. grid:: 1 3 3 3
+ :gutter: 2
- Install and build from source.
+ .. grid-item-card::
+ :class-item: text-center
- +++
+ Install and build from source.
+ +++
+ .. button-ref:: gettingstarted
+ :color: primary
+ :outline:
+ :expand:
- .. link-button:: gettingstarted
- :type: ref
- :text: Getting Started
- :classes: btn-qt btn-block stretched-link
- ---
+ Getting Started
- Binding generator executable.
+ .. grid-item-card::
+ :class-item: text-center
- +++
+ Binding generator executable.
+ +++
+ .. button-ref:: shibokengenerator
+ :color: primary
+ :outline:
+ :expand:
- .. link-button:: shibokengenerator
- :type: ref
- :text: Shiboken Generator
- :classes: btn-qt btn-block stretched-link
- ---
+ Shiboken Generator
- Python utility module.
+ .. grid-item-card::
+ :class-item: text-center
- +++
+ Python utility module.
+ +++
+ .. button-ref:: shibokenmodule
+ :color: primary
+ :outline:
+ :expand:
- .. link-button:: shibokenmodule
- :type: ref
- :text: Shiboken Module
- :classes: btn-qt btn-block stretched-link
+ Shiboken Module
- ---
+ .. grid-item-card::
+ :class-item: text-center
- Reference and functionallities.
+ Reference and functionallities.
+ +++
+ .. button-ref:: typesystem
+ :color: primary
+ :outline:
+ :expand:
- +++
+ Type System
- .. link-button:: typesystem
- :type: ref
- :text: Type System
- :classes: btn-qt btn-block stretched-link
+ .. grid-item-card::
+ :class-item: text-center
- ---
+ Using Shiboken.
+ +++
+ .. button-ref:: examples/index
+ :color: primary
+ :outline:
+ :expand:
- Using Shiboken.
+ Examples
- +++
+ .. grid-item-card::
+ :class-item: text-center
- .. link-button:: examples/index
- :type: ref
- :text: Examples
- :classes: btn-qt btn-block stretched-link
+ Generating Python stub files.
+ +++
+ .. button-ref:: shiboken-genpyi
+ :color: primary
+ :outline:
+ :expand:
- ---
+ shiboken6-genpyi
- Known issues and FAQ.
+ .. grid-item-card::
+ :class-item: text-center
- +++
-
- .. link-button:: considerations
- :type: ref
- :text: Considerations
- :classes: btn-qt btn-block stretched-link
+ Known issues and FAQ.
+ +++
+ .. button-ref:: considerations
+ :color: primary
+ :outline:
+ :expand:
+ Considerations
.. toctree::
:hidden:
@@ -102,4 +121,5 @@ Documentation
shibokenmodule.rst
typesystem.rst
examples/index.rst
+ shiboken-genpyi.rst
considerations.rst
diff --git a/sources/shiboken6/doc/shiboken-genpyi.rst b/sources/shiboken6/doc/shiboken-genpyi.rst
new file mode 100644
index 000000000..44d0edb97
--- /dev/null
+++ b/sources/shiboken6/doc/shiboken-genpyi.rst
@@ -0,0 +1,32 @@
+.. _shiboken6-genpyi:
+
+shiboken6-genpyi
+================
+
+`shiboken6-genpyi` is a command line tool to generate Python stub files
+(.pyi) for any shiboken binding-based module (not just PySide). Stub
+files define signatures of all classes, methods (including overloads),
+constants and enums of a module. Signatures also contain type hints.
+This helps your module integrate with Python type checkers and IDEs.
+For example, if you use any function from your module, your IDE's
+function lookup feature will show you the function signature and its
+parameters and return value including types.
+
+
+Usage
+-----
+
+To generate stub files for a module, run the following command:
+
+.. code-block:: bash
+
+ shiboken6-genpyi <module_names> [OPTIONS]
+
+where `<module_names>` is a space-separated list of module names (the
+modules must be importable from the working directory) and where
+`[OPTIONS]` can be one of the following:
+
+* **--quiet**: Run the tool quietly without output to stdout.
+* **--outpath <output_dir>**: Specify the output directory for the
+ generated stub files. If not specified, the stub files are generated
+ in the location of the module binary.
diff --git a/sources/shiboken6/doc/shibokengenerator.rst b/sources/shiboken6/doc/shibokengenerator.rst
index 01b4420ee..14340ab69 100644
--- a/sources/shiboken6/doc/shibokengenerator.rst
+++ b/sources/shiboken6/doc/shibokengenerator.rst
@@ -52,13 +52,13 @@ Handwritten inputs
Creating new bindings involves creating several pieces of "code": the header,
the typesystem and, in most cases, the injected code.
-:header: A header with ``#include`` directives listing all the headers of the
- desired classes. This header is not referenced by the generated code.
- Alternatively, it is possible to pass a list of the headers of the
- desired classes directly on the command line. In this case,
- the command line option ``--use-global-header`` should be passed as
- well to prevent the headers from being suppressed in the generated
- code.
+**header** A header with ``#include`` directives listing all the headers of the
+ desired classes. This header is not referenced by the generated code.
+ Alternatively, it is possible to pass a list of the headers of the
+ desired classes directly on the command line. In this case,
+ the command line option ``--use-global-header`` should be passed as
+ well to prevent the headers from being suppressed in the generated
+ code.
::ref:`typesystem`: XML files that provides the developer with a tool to customize the
way that the generators will see the classes and functions. For
@@ -112,21 +112,25 @@ Options
``--avoid-protected-hack``
Avoid the use of the '#define protected public' hack.
-.. _use-isnull-as-nb-nonzero:
+.. _use-isnull-as-nb-bool:
-``--use-isnull-as-nb_nonzero``
+``--use-isnull-as-nb-bool``
If a class has an isNull() const method, it will be used to
compute the value of boolean casts (see :ref:`bool-cast`).
+ The legacy option ``--use-isnull-as-nb_nonzero`` has the
+ same effect, but should not be used any more.
``--lean-headers``
Forward declare classes in module headers instead of including their class
headers where possible.
-.. _use-operator-bool-as-nb-nonzero:
+.. _use-operator-bool-as-nb-bool:
-``--use-operator-bool-as-nb_nonzero``
+``--use-operator-bool-as-nb-bool``
If a class has an operator bool, it will be used to compute
the value of boolean casts (see :ref:`bool-cast`).
+ The legacy option ``--use-operator-bool-as-nb_nonzero`` has the
+ same effect, but should not be used any more.
.. _no-implicit-conversions:
@@ -212,7 +216,7 @@ Options
``-I<path>, --include-paths=<path>[:<path>:...]``
Include paths used by the C++ parser.
-... _system-include-paths:
+.. _system-include-paths:
``-isystem<path>, --system-include-paths=<path>[:<path>:...]``
System include paths used by the C++ parser
@@ -222,6 +226,12 @@ Options
``-F<path>, --framework-include-paths=<path>[:<path>:...]``
Framework include paths used by the C++ parser
+.. _force-process-system-include-paths:
+
+``--force-process-system-include-paths=<path>[:<path>:...]``
+ Include paths that are considered as system headers by the C++ parser,
+ but should still be processed to extract types
+
.. _language-level:
``--language-level=, -std=<level>``
@@ -247,6 +257,10 @@ Options
``--no-suppress-warnings``
Show all warnings.
+``--log-unmatched``
+ Prints :ref:`suppress-warning` and :ref:`rejection` elements that were
+ not matched. This is useful for cleaning up old type system files.
+
.. _silent:
``--silent``
@@ -308,6 +322,9 @@ QtDocGenerator Options
``--inheritance-file=<file>``
Generate a JSON file containing the class inheritance.
+``--disable-inheritance-diagram``
+ Disable the generation of the inheritance diagram.
+
.. _project-file:
********************
@@ -325,18 +342,18 @@ The project file structure
Here follows a comprehensive example of a generator project file.
- .. code-block:: ini
+.. code-block:: ini
- [generator-project]
- generator-set = path/to/generator/CHOICE_GENERATOR
- header-file = DIR/global.h" />
- typesystem-file = DIR/typesystem_for_your_binding.xml
- output-directory location="OUTPUTDIR" />
- include-path = path/to/library/being/wrapped/headers/1
- include-path = path/to/library/being/wrapped/headers/2
- typesystem-path = path/to/directory/containing/type/system/files/1
- typesystem-path = path/to/directory/containing/type/system/files/2
- enable-parent-ctor-heuristic
+ [generator-project]
+ generator-set = path/to/generator/CHOICE_GENERATOR
+ header-file = DIR/global.h" />
+ typesystem-file = DIR/typesystem_for_your_binding.xml
+ output-directory location="OUTPUTDIR" />
+ include-path = path/to/library/being/wrapped/headers/1
+ include-path = path/to/library/being/wrapped/headers/2
+ typesystem-path = path/to/directory/containing/type/system/files/1
+ typesystem-path = path/to/directory/containing/type/system/files/2
+ enable-parent-ctor-heuristic
Project file tags
@@ -352,26 +369,25 @@ generator project file following simple conversion rules.
For tags without options, just write as an empty tag without any attributes.
Example:
- .. code-block:: bash
+.. code-block:: bash
- --BOOLEAN-ARGUMENT
+ --BOOLEAN-ARGUMENT
becomes
- .. code-block:: ini
+.. code-block:: ini
- BOOLEAN-ARGUMENT
+ BOOLEAN-ARGUMENT
and
- .. code-block:: bash
+.. code-block:: bash
- --VALUE-ARGUMENT=VALUE
+ --VALUE-ARGUMENT=VALUE
becomes
- .. code-block:: ini
-
- VALUE-ARGUMENT = VALUE
+.. code-block:: ini
+ VALUE-ARGUMENT = VALUE
diff --git a/sources/shiboken6/doc/shibokenmodule.rst b/sources/shiboken6/doc/shibokenmodule.rst
index 91cb3fa6e..3bc4fa6ba 100644
--- a/sources/shiboken6/doc/shibokenmodule.rst
+++ b/sources/shiboken6/doc/shibokenmodule.rst
@@ -1,4 +1,4 @@
-. module:: shiboken
+.. module:: Shiboken
.. |maya| unicode:: Maya U+2122
@@ -32,6 +32,11 @@ or just for debug purposes.
Some function description refer to "Shiboken based objects", wich means
Python objects instances of any Python Type created using Shiboken.
+To import the module:
+
+.. code-block:: python
+
+ from shiboken6 import Shiboken
.. function:: isValid(obj)
@@ -110,3 +115,33 @@ Python objects instances of any Python Type created using Shiboken.
internally the `str` function is called with it.
This method should be used **only** for debug purposes by developers.
+
+ .. function:: dumpTypeGraph(file_name)
+
+ Dumps the inheritance graph of the types existing in libshiboken
+ to ``.dot`` file for use with `Graphviz <https://graphviz.org/>`_.
+
+.. function:: dumpWrapperMap()
+
+ Dumps the map of wrappers existing in libshiboken to standard error.
+
+.. function:: dumpConverters()
+
+ Dumps the map of named converters existing in libshiboken to standard
+ error.
+
+ .. py:class:: VoidPtr(address, size = -1, writeable = 0)
+
+ :param address: (PyBuffer, SbkObject, int, VoidPtr)
+ :param size: int
+ :param writeable: int
+
+ Represents a chunk of memory by address and size and implements the ``buffer`` protocol.
+ It can be constructed from a ``buffer``, a Shiboken based object, a memory address
+ or another VoidPtr instance.
+
+ .. py:method:: toBytes()
+
+ :rtype: bytes
+
+ Returns the contents as ``bytes``.
diff --git a/sources/shiboken6/doc/typediscovery.rst b/sources/shiboken6/doc/typediscovery.rst
new file mode 100644
index 000000000..76d3adf7b
--- /dev/null
+++ b/sources/shiboken6/doc/typediscovery.rst
@@ -0,0 +1,145 @@
+.. _typediscovery:
+
+**************
+Type Discovery
+**************
+
+When converting objects which are part of a class hierarchy from a pointer to a
+base class, it is expected to get the Python type of the actual, most derived
+type, as opposed to C++ which requires a cast for this:
+
+.. code-block:: python
+
+ def event(self, event):
+ if event.type() == QEvent.Type.MousePress:
+ self.do_things(event.position())
+ ...
+
+
+.. code-block:: c++
+
+ bool event(QEvent *event) override
+ {
+ if (event->type() == QEvent::MousePress) {
+ auto *mouseEvent = static_cast<QMouseEvent *>(event);
+ doThings(mouseEvent->position());
+ ...
+ }
+
+The process of determining the type of the event is called `type discovery`.
+
+Shiboken generates code to automatically detect the type. First, it tries to
+find a converter for the name obtained by ``typeid(*pointer).name()``. This
+should normally work as this name is registered by the binding. If that fails,
+it starts walking a type inheritance graph built up in libshiboken to find the
+most derived class by using a cast function (``dynamic_cast<>`` by default) to
+check.
+
+For normal class hierarchies with virtual destructors, no special handling
+is required since ``typeid()`` usually detects the proper class name.
+
+Multiple inheritance
+====================
+
+In case of multiple inheritance in C++, the conversion to the derived class is
+not done in case it is not a single-line direct inheritance. For example, in
+Qt, the class ``QWidget`` inherits both ``QObject`` (base of the ``QObject``
+hierarchy) and ``QPaintDevice``.
+
+When calling a function returning a ``QPaintDevice *``, for example
+``QPainter.device()``, a Python type representing ``QPaintDevice`` is returned
+instead of the underlying widget type. This restriction exists because the
+underlying pointer in C++ is a pointer to a ``QPaintDevice *`` and differs from
+the pointer to the ``QWidget``.
+
+Hierarchies of classes with non-virtual destructors
+===================================================
+
+There are some hierarchies of value-ish C++ classes that do not have virtual
+destructors. This makes type discovery based on ``typeid()`` and
+``dynamic_cast<>`` impossible.
+
+Examples in Qt are the ``QStyleOption``-derived or the ``QGradient``
+-derived classes.
+
+For such classes, some attributes need to be specified on the type entries:
+
+Primarily, a :ref:`polymorphic-id-expression` attribute
+must be specified to be used as a check replacing ``dynamic_cast<>``.
+
+In addition, a :ref:`polymorphic-name-function` attribute can be specified.
+This replaces the type name guess obtained by ``typeid()`` and is mainly a hint
+to speed things up by skipping the checks for each type in the inheritance
+graph.
+
+A :ref:`polymorphic-base` attribute identifies the base class of a hierarchy.
+It should be given in case the base class inherits from another class to
+prevent the logic from going below the base class.
+
+Using type discovery attributes for class hierarchies with virtual destructors
+==============================================================================
+
+It is possible to use :ref:`polymorphic-id-expression` and
+:ref:`polymorphic-name-function` for normal class hierarchies with virtual
+destructors as well since they basically replace ``typeid()`` and
+``dynamic_cast<>``. This makes sense if expressions can be specified that are
+faster than the checks on virtual tables.
+
+Specifying :ref:`polymorphic-base` can also make sense for generating special
+cast functions in case of multiple inheritance. For example, in Qt,
+``QWindow``, ``QLayout``, ``QWidget`` are base classes of hierarchies. Since
+they all inherit from ``QObject``, indicating the base classes prevents
+the logic from using ``QObject`` as a base class.
+
+.. _typediscovery-attributes:
+
+Type discovery attributes reference
+===================================
+
+The following attributes related to type discovery may be be specified on the
+:ref:`object-type` or :ref:`value-type` elements:
+
+.. _polymorphic-id-expression:
+
+polymorphic-id-expression
++++++++++++++++++++++++++
+
+The **polymorphic-id-expression** attribute specifies an expression checking
+whether a base class pointer is of the matching type. For example, in a
+``virtual eventHandler(BaseEvent *e)`` function, this is used to construct a
+Python wrapper matching the derived class (for example, a ``MouseEvent`` or
+similar). The attribute value may contain placeholders:
+
+%1
+ Fully qualified class name
+
+%B
+ Fully qualified name of the base class (found by base class
+ search or as indicated by **polymorphic-base**).
+
+To check for a class inheriting ``BaseEvent``, specify:
+
+.. code-block:: xml
+
+ <object-type name="MouseEvent"
+ polymorphic-id-expression="%B-&gt;type() == BaseEvent::MouseEvent"/>
+
+.. _polymorphic-name-function:
+
+polymorphic-name-function
++++++++++++++++++++++++++
+
+The **polymorphic-name-function** attribute specifies the name of a function
+returning the type name of a derived class on the base class type entry.
+Normally, ``typeid(ptr).name()`` is used for this.
+
+The function is expected to return ``const char *``.
+
+.. _polymorphic-base:
+
+polymorphic-base
+++++++++++++++++
+
+The boolean **polymorphic-base** attribute indicates whether the class is the
+base class of a class hierarchy. It is used for the *%B* placeholder in
+**polymorphic-id-expression** and for cast operations in multiple inheritance.
diff --git a/sources/shiboken6/doc/typesystem.rst b/sources/shiboken6/doc/typesystem.rst
index e1e4fdda2..26f929801 100644
--- a/sources/shiboken6/doc/typesystem.rst
+++ b/sources/shiboken6/doc/typesystem.rst
@@ -65,3 +65,4 @@ Extra options and Python caveats
typesystem_solving_compilation.rst
typesystem_specialfunctions.rst
+ typediscovery.rst
diff --git a/sources/shiboken6/doc/typesystem_arguments.rst b/sources/shiboken6/doc/typesystem_arguments.rst
index b6967e721..d950b6c32 100644
--- a/sources/shiboken6/doc/typesystem_arguments.rst
+++ b/sources/shiboken6/doc/typesystem_arguments.rst
@@ -8,77 +8,77 @@ Modifying Arguments
conversion-rule
^^^^^^^^^^^^^^^
- The ``conversion-rule`` node allows you to write customized code to convert
- the given argument between the target language and C++.
- It is then a child of the :ref:`modify-argument` node:
+The ``conversion-rule`` node allows you to write customized code to convert
+the given argument between the target language and C++.
+It is then a child of the :ref:`modify-argument` node:
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument index="2">
- <!-- for the second argument of the function -->
- <conversion-rule class="target | native">
- // the code
- </conversion-rule>
- </modify-argument>
+ <modify-argument index="2">
+ <!-- for the second argument of the function -->
+ <conversion-rule class="target | native">
+ // the code
+ </conversion-rule>
+ </modify-argument>
- The ``class`` attribute accepts one of the following values to define the
- conversion direction to be either ``target-to-native`` or ``native-to-target``:
+The ``class`` attribute accepts one of the following values to define the
+conversion direction to be either ``target-to-native`` or ``native-to-target``:
- * ``native``: Defines the conversion direction to be ``target-to-native``.
- It is similar to the existing ``<target-to-native>`` element.
- See :ref:`Conversion Rule Tag <conversion-rule-tag>` for more information.
+* ``native``: Defines the conversion direction to be ``target-to-native``.
+ It is similar to the existing ``<target-to-native>`` element.
+ See :ref:`Conversion Rule Tag <conversion-rule-tag>` for more information.
- * ``target``: Defines the conversion direction to be ``native-to-target``.
- It is similar to the existing ``<native-to-target>`` element.
- See :ref:`Conversion Rule Tag <conversion-rule-tag>` for more information.
+* ``target``: Defines the conversion direction to be ``native-to-target``.
+ It is similar to the existing ``<native-to-target>`` element.
+ See :ref:`Conversion Rule Tag <conversion-rule-tag>` for more information.
- This node is typically used in combination with the :ref:`replace-type` and
- :ref:`remove-argument` nodes. The given code is used instead of the generator's
- conversion code.
+This node is typically used in combination with the :ref:`replace-type` and
+:ref:`remove-argument` nodes. The given code is used instead of the generator's
+conversion code.
- Writing %N in the code (where N is a number), will insert the name of the
- nth argument. Alternatively, %in and %out which will be replaced with the
- name of the conversion's input and output variable, respectively. Note the
- output variable must be declared explicitly, for example:
+Writing %N in the code (where N is a number), will insert the name of the
+nth argument. Alternatively, %in and %out which will be replaced with the
+name of the conversion's input and output variable, respectively. Note the
+output variable must be declared explicitly, for example:
- .. code-block:: xml
+.. code-block:: xml
- <conversion-rule class="native">
- bool %out = (bool) %in;
- </conversion-rule>
+ <conversion-rule class="native">
+ bool %out = (bool) %in;
+ </conversion-rule>
- .. note::
+.. note::
- You can also use the ``conversion-rule`` node to specify
- :ref:`a conversion code which will be used instead of the generator's conversion code everywhere for a given type <conversion-rule-tag>`.
+ You can also use the ``conversion-rule`` node to specify
+ :ref:`a conversion code which will be used instead of the generator's conversion code everywhere for a given type <conversion-rule-tag>`.
.. _remove-argument:
remove-argument
^^^^^^^^^^^^^^^
- The ``remove-argument`` node removes the given argument from the function's
- signature, and it is a child of the :ref:`modify-argument` node.
+The ``remove-argument`` node removes the given argument from the function's
+signature, and it is a child of the :ref:`modify-argument` node.
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument>
- <remove-argument />
- </modify-argument>
+ <modify-argument>
+ <remove-argument />
+ </modify-argument>
.. _rename-to:
rename to
^^^^^^^^^
- The ``rename to`` node is used to rename a argument and use this new name in
- the generated code, and it is a child of the :ref:`modify-argument` node.
+The ``rename to`` node is used to rename a argument and use this new name in
+the generated code, and it is a child of the :ref:`modify-argument` node.
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument>
- <rename to='...' />
- </modify-argument>
+ <modify-argument>
+ <rename to='...' />
+ </modify-argument>
.. warning:: This tag is deprecated, use the ``rename`` attribute from :ref:`modify-argument` tag instead.
@@ -87,143 +87,143 @@ rename to
remove-default-expression
^^^^^^^^^^^^^^^^^^^^^^^^^
- The ``remove-default-expression`` node disables the use of the default expression
- for the given argument, and it is a child of the :ref:`modify-argument` node.
+The ``remove-default-expression`` node disables the use of the default expression
+for the given argument, and it is a child of the :ref:`modify-argument` node.
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument...>
- <remove-default-expression />
- </modify-argument>
+ <modify-argument...>
+ <remove-default-expression />
+ </modify-argument>
.. _replace-default-expression:
replace-default-expression
^^^^^^^^^^^^^^^^^^^^^^^^^^
- The ``replace-default-expression`` node replaces the specified argument with the
- expression specified by the ``with`` attribute, and it is a child of the
- :ref:`modify-argument` node.
+The ``replace-default-expression`` node replaces the specified argument with the
+expression specified by the ``with`` attribute, and it is a child of the
+:ref:`modify-argument` node.
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument>
- <replace-default-expression with="..." />
- </modify-argument>
+ <modify-argument>
+ <replace-default-expression with="..." />
+ </modify-argument>
.. _replace-type:
replace-type
^^^^^^^^^^^^
- The ``replace-type`` node replaces the type of the given argument to the one
- specified by the ``modified-type`` attribute, and it is a child of the
- :ref:`modify-argument` node.
+The ``replace-type`` node replaces the type of the given argument to the one
+specified by the ``modified-type`` attribute, and it is a child of the
+:ref:`modify-argument` node.
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument>
- <replace-type modified-type="..." />
- </modify-argument>
+ <modify-argument>
+ <replace-type modified-type="..." />
+ </modify-argument>
- If the new type is a class, the ``modified-type`` attribute must be set to
- the fully qualified name (including name of the package as well as the class
- name).
+If the new type is a class, the ``modified-type`` attribute must be set to
+the fully qualified name (including name of the package as well as the class
+name).
.. _define-ownership:
define-ownership
^^^^^^^^^^^^^^^^
- The ``define-ownership`` tag indicates that the function changes the ownership
- rules of the argument object, and it is a child of the
- :ref:`modify-argument` node.
- The ``class`` attribute specifies the class of
- function where to inject the ownership altering code
- (see :ref:`codegenerationterminology`). The ``owner`` attribute
- specifies the new ownership of the object. It accepts the following values:
-
- * target: the target language will assume full ownership of the object.
- The native resources will be deleted when the target language
- object is finalized.
- * c++: The native code assumes full ownership of the object. The target
- language object will not be garbage collected.
- * default: The object will get default ownership, depending on how it
- was created.
-
- .. code-block:: xml
-
- <modify-argument>
- <define-ownership class="target | native"
- owner="target | c++ | default" />
- </modify-argument>
+The ``define-ownership`` tag indicates that the function changes the ownership
+rules of the argument object, and it is a child of the
+:ref:`modify-argument` node.
+The ``class`` attribute specifies the class of
+function where to inject the ownership altering code
+(see :ref:`codegenerationterminology`). The ``owner`` attribute
+specifies the new ownership of the object. It accepts the following values:
+
+* target: the target language will assume full ownership of the object.
+ The native resources will be deleted when the target language
+ object is finalized.
+* c++: The native code assumes full ownership of the object. The target
+ language object will not be garbage collected.
+* default: The object will get default ownership, depending on how it
+ was created.
+
+.. code-block:: xml
+
+ <modify-argument>
+ <define-ownership class="target | native"
+ owner="target | c++ | default" />
+ </modify-argument>
.. _reference-count:
reference-count
^^^^^^^^^^^^^^^
- The ``reference-count`` tag dictates how an argument should be handled by the
- target language reference counting system (if there is any), it also indicates
- the kind of relationship the class owning the function being modified has with
- the argument. It is a child of the :ref:`modify-argument` node.
- For instance, in a model/view relation a view receiving a model
- as argument for a **setModel** method should increment the model's reference
- counting, since the model should be kept alive as much as the view lives.
- Remember that out hypothetical view could not become parent of the model,
- since the said model could be used by other views as well.
- The ``action`` attribute specifies what should be done to the argument
- reference counting when the modified method is called. It accepts the
- following values:
-
- * add: increments the argument reference counter.
- * add-all: increments the reference counter for each item in a collection.
- * remove: decrements the argument reference counter.
- * set: will assign the argument to the variable containing the reference.
- * ignore: does nothing with the argument reference counter
- (sounds worthless, but could be used in situations
- where the reference counter increase is mandatory
- by default).
-
- .. code-block:: xml
-
- <modify-argument>
- <reference-count action="add|add-all|remove|set|ignore" variable-name="..." />
- </modify-argument>
-
-
- The variable-name attribute specifies the name used for the variable that
- holds the reference(s).
+The ``reference-count`` tag dictates how an argument should be handled by the
+target language reference counting system (if there is any), it also indicates
+the kind of relationship the class owning the function being modified has with
+the argument. It is a child of the :ref:`modify-argument` node.
+For instance, in a model/view relation a view receiving a model
+as argument for a **setModel** method should increment the model's reference
+counting, since the model should be kept alive as much as the view lives.
+Remember that out hypothetical view could not become parent of the model,
+since the said model could be used by other views as well.
+The ``action`` attribute specifies what should be done to the argument
+reference counting when the modified method is called. It accepts the
+following values:
+
+* add: increments the argument reference counter.
+* add-all: increments the reference counter for each item in a collection.
+* remove: decrements the argument reference counter.
+* set: will assign the argument to the variable containing the reference.
+* ignore: does nothing with the argument reference counter
+ (sounds worthless, but could be used in situations
+ where the reference counter increase is mandatory
+ by default).
+
+.. code-block:: xml
+
+ <modify-argument>
+ <reference-count action="add|add-all|remove|set|ignore" variable-name="..." />
+ </modify-argument>
+
+
+The variable-name attribute specifies the name used for the variable that
+holds the reference(s).
.. _replace-value:
replace-value
^^^^^^^^^^^^^
- The ``replace-value`` attribute lets you replace the return statement of a
- function with a fixed string. This attribute can only be used for the
- argument at ``index`` 0, which is always the function's return value.
+The ``replace-value`` attribute lets you replace the return statement of a
+function with a fixed string. This attribute can only be used for the
+argument at ``index`` 0, which is always the function's return value.
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument index="0" replace-value="this"/>
+ <modify-argument index="0" replace-value="this"/>
.. _parent:
parent
^^^^^^
- The ``parent`` node lets you define the argument parent which will
- take ownership of argument and will destroy the C++ child object when the
- parent is destroyed (see :ref:`ownership-parent`).
- It is a child of the :ref:`modify-argument` node.
+The ``parent`` node lets you define the argument parent which will
+take ownership of argument and will destroy the C++ child object when the
+parent is destroyed (see :ref:`ownership-parent`).
+It is a child of the :ref:`modify-argument` node.
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument index="1">
- <parent index="this" action="add | remove" />
- </modify-argument>
+ <modify-argument index="1">
+ <parent index="this" action="add | remove" />
+ </modify-argument>
- In the ``index`` argument you must specify the parent argument. The action
- *add* creates a parent link between objects, while *remove* will undo the
- parentage relationship.
+In the ``index`` argument you must specify the parent argument. The action
+*add* creates a parent link between objects, while *remove* will undo the
+parentage relationship.
diff --git a/sources/shiboken6/doc/typesystem_builtin_types.rst b/sources/shiboken6/doc/typesystem_builtin_types.rst
index ba9a576a6..dea253930 100644
--- a/sources/shiboken6/doc/typesystem_builtin_types.rst
+++ b/sources/shiboken6/doc/typesystem_builtin_types.rst
@@ -26,6 +26,20 @@ on platform.
`std::string`, `std::wstring` and their associated view types
`std::string_view`, `std::wstring_view` are also supported.
+
+.. _builtin-cpp-container-types:
+
+C++ Container Types
+^^^^^^^^^^^^^^^^^^^
+
+The C++ containers ``std::list``\, ``std::vector``\,
+``std::pair``\, ``std::map``\, ``std::span`` and ``std::unordered_map`` are
+built-in.
+To specify :ref:`opaque-containers`, use the :ref:`opaque-container` element.
+:ref:`container-type` can still be specified to modify the built-in behavior.
+For this case, a number of pre-defined conversion templates
+are provided (see :ref:`predefined_templates`).
+
.. _cpython-types:
CPython Types
diff --git a/sources/shiboken6/doc/typesystem_codeinjection.rst b/sources/shiboken6/doc/typesystem_codeinjection.rst
index 055e876a8..03d5f4b16 100644
--- a/sources/shiboken6/doc/typesystem_codeinjection.rst
+++ b/sources/shiboken6/doc/typesystem_codeinjection.rst
@@ -12,11 +12,11 @@ should be written to depends upon the technology used on the generated binding c
This is the ``inject-code`` tag options that matters to |project|.
- .. code-block:: xml
+.. code-block:: xml
- <inject-code class="native | target" position="beginning | end">
- // custom code
- </inject-code>
+ <inject-code class="native | target" position="beginning | end">
+ // custom code
+ </inject-code>
inject-code tag
@@ -30,76 +30,79 @@ The ``position`` attribute specifies the location of the custom code in the
function.
- +---------------+------+-----------+--------------------------------------------------------------+
- |Parent Tag |Class |Position |Meaning |
- +===============+======+===========+==============================================================+
- |value-type, |native|beginning |Write to the beginning of a class wrapper ``.cpp`` file, right|
- |object-type | | |after the ``#include`` clauses. A common use would be to write|
- | | | |prototypes for custom functions whose definitions are put on a|
- | | | |``native/end`` code injection. |
- | | +-----------+--------------------------------------------------------------+
- | | |end |Write to the end of a class wrapper ``.cpp`` file. Could be |
- | | | |used to write custom/helper functions definitions for |
- | | | |prototypes declared on ``native/beginning``. |
- | +------+-----------+--------------------------------------------------------------+
- | |target|beginning |Put custom code on the beginning of the wrapper initializer |
- | | | |function (``init_CLASS(PyObject *module)``). This could be |
- | | | |used to manipulate the ``PyCLASS_Type`` structure before |
- | | | |registering it on Python. |
- | | +-----------+--------------------------------------------------------------+
- | | |end |Write the given custom code at the end of the class wrapper |
- | | | |initializer function (``init_CLASS(PyObject *module)``). The |
- | | | |code here will be executed after all the wrapped class |
- | | | |components have been initialized. |
- +---------------+------+-----------+--------------------------------------------------------------+
- |modify-function|native|beginning |Code here is put on the virtual method override of a C++ |
- | | | |wrapper class (the one responsible for passing C++ calls to a |
- | | | |Python override, if there is any), right after the C++ |
- | | | |arguments have been converted but before the Python call. |
- | | +-----------+--------------------------------------------------------------+
- | | |end |This code injection is put in a virtual method override on the|
- | | | |C++ wrapper class, after the call to Python and before |
- | | | |dereferencing the Python method and tuple of arguments. |
- | +------+-----------+--------------------------------------------------------------+
- | |target|beginning |This code is injected on the Python method wrapper |
- | | | |(``PyCLASS_METHOD(...)``), right after the decisor have found |
- | | | |which signature to call and also after the conversion of the |
- | | | |arguments to be used, but before the actual call. |
- | | +-----------+--------------------------------------------------------------+
- | | |end |This code is injected on the Python method wrapper |
- | | | |(``PyCLASS_METHOD(...)``), right after the C++ method call, |
- | | | |but still inside the scope created by the overload for each |
- | | | |signature. |
- | +------+-----------+--------------------------------------------------------------+
- | |shell |declaration|Used only for virtual functions. This code is injected at the |
- | | | |top. |
- | | +-----------+--------------------------------------------------------------+
- | | |beginning |Used only for virtual functions. The code is injected when the|
- | | | |function does not has a Python implementation, then the code |
- | | | |is inserted before c++ call |
- | | +-----------+--------------------------------------------------------------+
- | | |end |Same as above, but the code is inserted after c++ call |
- +---------------+------+-----------+--------------------------------------------------------------+
- |typesystem |native|beginning |Write code to the beginning of the module ``.cpp`` file, right|
- | | | |after the ``#include`` clauses. This position has a similar |
- | | | |purpose as the ``native/beginning`` position on a wrapper |
- | | | |class ``.cpp`` file, namely write function prototypes, but not|
- | | | |restricted to this use. |
- | | +-----------+--------------------------------------------------------------+
- | | |end |Write code to the end of the module ``.cpp`` file. Usually |
- | | | |implementations for function prototypes inserted at the |
- | | | |beginning of the file with a ``native/beginning`` code |
- | | | |injection. |
- | +------+-----------+--------------------------------------------------------------+
- | |target|beginning |Insert code at the start of the module initialization function|
- | | | |(``initMODULENAME()``), before the calling ``Py_InitModule``. |
- | | +-----------+--------------------------------------------------------------+
- | | |end |Insert code at the end of the module initialization function |
- | | | |(``initMODULENAME()``), but before the checking that emits a |
- | | | |fatal error in case of problems importing the module. |
- | | +-----------+--------------------------------------------------------------+
- | | |declaration|Insert code into module header. |
- +---------------+------+-----------+--------------------------------------------------------------+
++---------------+------+-----------+--------------------------------------------------------------+
+|Parent Tag |Class |Position |Meaning |
++===============+======+===========+==============================================================+
+|value-type, |native|beginning |Write to the beginning of a class wrapper ``.cpp`` file, right|
+|object-type | | |after the ``#include`` clauses. A common use would be to write|
+| | | |prototypes for custom functions whose definitions are put on a|
+| | | |``native/end`` code injection. |
+| | +-----------+--------------------------------------------------------------+
+| | |end |Write to the end of a class wrapper ``.cpp`` file. Could be |
+| | | |used to write custom/helper functions definitions for |
+| | | |prototypes declared on ``native/beginning``. |
+| +------+-----------+--------------------------------------------------------------+
+| |target|beginning |Put custom code on the beginning of the wrapper initializer |
+| | | |function (``init_CLASS(PyObject *module)``). This could be |
+| | | |used to manipulate the ``PyCLASS_Type`` structure before |
+| | | |registering it on Python. |
+| | +-----------+--------------------------------------------------------------+
+| | |end |Write the given custom code at the end of the class wrapper |
+| | | |initializer function (``init_CLASS(PyObject *module)``). The |
+| | | |code here will be executed after all the wrapped class |
+| | | |components have been initialized. |
++---------------+------+-----------+--------------------------------------------------------------+
+|modify-function|native|beginning |Code here is put on the virtual method override of a C++ |
+| | | |wrapper class (the one responsible for passing C++ calls to a |
+| | | |Python override, if there is any), right after the C++ |
+| | | |arguments have been converted but before the Python call. |
+| | +-----------+--------------------------------------------------------------+
+| | |end |This code injection is put in a virtual method override on the|
+| | | |C++ wrapper class, after the call to Python and before |
+| | | |dereferencing the Python method and tuple of arguments. |
+| +------+-----------+--------------------------------------------------------------+
+| |target|beginning |This code is injected on the Python method wrapper |
+| | | |(``PyCLASS_METHOD(...)``), right after the decisor have found |
+| | | |which signature to call and also after the conversion of the |
+| | | |arguments to be used, but before the actual call. |
+| | +-----------+--------------------------------------------------------------+
+| | |end |This code is injected on the Python method wrapper |
+| | | |(``PyCLASS_METHOD(...)``), right after the C++ method call, |
+| | | |but still inside the scope created by the overload for each |
+| | | |signature. |
+| +------+-----------+--------------------------------------------------------------+
+| |shell |declaration|Used only for virtual functions. This code is injected at the |
+| | | |top. |
+| | +-----------+--------------------------------------------------------------+
+| | |override |Used only for virtual functions. The code is injected before |
+| | | |the code calling the Python override. |
+| | +-----------+--------------------------------------------------------------+
+| | |beginning |Used only for virtual functions. The code is injected when the|
+| | | |function does not has a Python implementation, then the code |
+| | | |is inserted before c++ call |
+| | +-----------+--------------------------------------------------------------+
+| | |end |Same as above, but the code is inserted after c++ call |
++---------------+------+-----------+--------------------------------------------------------------+
+|typesystem |native|beginning |Write code to the beginning of the module ``.cpp`` file, right|
+| | | |after the ``#include`` clauses. This position has a similar |
+| | | |purpose as the ``native/beginning`` position on a wrapper |
+| | | |class ``.cpp`` file, namely write function prototypes, but not|
+| | | |restricted to this use. |
+| | +-----------+--------------------------------------------------------------+
+| | |end |Write code to the end of the module ``.cpp`` file. Usually |
+| | | |implementations for function prototypes inserted at the |
+| | | |beginning of the file with a ``native/beginning`` code |
+| | | |injection. |
+| +------+-----------+--------------------------------------------------------------+
+| |target|beginning |Insert code at the start of the module initialization function|
+| | | |(``initMODULENAME()``), before the calling ``Py_InitModule``. |
+| | +-----------+--------------------------------------------------------------+
+| | |end |Insert code at the end of the module initialization function |
+| | | |(``initMODULENAME()``), but before the checking that emits a |
+| | | |fatal error in case of problems importing the module. |
+| | +-----------+--------------------------------------------------------------+
+| | |declaration|Insert code into module header. |
++---------------+------+-----------+--------------------------------------------------------------+
Anatomy of Code Injection
@@ -110,16 +113,16 @@ and the places where each kind of code injection goes.
Below is the example C++ class for whom wrapper code will be generated.
- .. code-block:: c++
+.. code-block:: c++
- class InjectCode
- {
- public:
- InjectCode();
- double overloadedMethod(int arg);
- double overloadedMethod(double arg);
- virtual int virtualMethod(int arg);
- };
+ class InjectCode
+ {
+ public:
+ InjectCode();
+ double overloadedMethod(int arg);
+ double overloadedMethod(double arg);
+ virtual int virtualMethod(int arg);
+ };
From the C++ class, |project| will generate a ``injectcode_wrapper.cpp`` file
with the binding code. The next section will use a simplified version of the
@@ -168,21 +171,21 @@ of writing the actual name of the wrapped method/function.
In other words, use
- .. code-block:: xml
+.. code-block:: xml
- <inject-code class="target" position="beginning | end">
- %CPPSELF.originalMethodName();
- </inject-code>
+ <inject-code class="target" position="beginning | end">
+ %CPPSELF.originalMethodName();
+ </inject-code>
instead of
- .. code-block:: xml
+.. code-block:: xml
- <inject-code class="target" position="beginning | end">
- %CPPSELF.%FUNCTION_NAME();
- </inject-code>
+ <inject-code class="target" position="beginning | end">
+ %CPPSELF.%FUNCTION_NAME();
+ </inject-code>
Code Injection for Functions/Methods
@@ -197,30 +200,30 @@ On The Native Side
Notice that this is only used when there is a C++ wrapper, i.e. the wrapped
class is polymorphic.
- .. code-block:: c++
+.. code-block:: c++
- int InjectCodeWrapper::virtualMethod(int arg)
- {
- PyObject *method = BindingManager::instance().getOverride(this, "virtualMethod");
- if (!py_override)
- return this->InjectCode::virtualMethod(arg);
+ int InjectCodeWrapper::virtualMethod(int arg)
+ {
+ PyObject *method = BindingManager::instance().getOverride(this, "virtualMethod");
+ if (!py_override)
+ return this->InjectCode::virtualMethod(arg);
- (... here C++ arguments are converted to Python ...)
+ (... here C++ arguments are converted to Python ...)
- // INJECT-CODE: <modify-function><inject-code class="native" position="beginning">
- // Uses: pre method call custom code, modify the argument before the
- // Python call.
+ // INJECT-CODE: <modify-function><inject-code class="native" position="beginning">
+ // Uses: pre method call custom code, modify the argument before the
+ // Python call.
- (... Python method call goes in here ...)
+ (... Python method call goes in here ...)
- // INJECT-CODE: <modify-function><inject-code class="native" position="end">
- // Uses: post method call custom code, modify the result before delivering
- // it to C++ caller.
+ // INJECT-CODE: <modify-function><inject-code class="native" position="end">
+ // Uses: post method call custom code, modify the result before delivering
+ // it to C++ caller.
- (... Python method and argument tuple are dereferenced here ...)
+ (... Python method and argument tuple are dereferenced here ...)
- return Shiboken::Converter<int>::toCpp(method_result);
- }
+ return Shiboken::Converter<int>::toCpp(method_result);
+ }
On The Target Side
@@ -231,37 +234,37 @@ method that uses an overload decisor to call the correct C++ method based on the
arguments passed by the Python call. Each overloaded method signature has its
own ``beginning`` and ``end`` code injections.
- .. code-block:: c++
+.. code-block:: c++
- static PyObject *PyInjectCode_overloadedMethod(PyObject *self, PyObject *arg)
- {
- PyObject* py_result{};
- if (PyFloat_Check(arg)) {
- double cpp_arg0 = Shiboken::Converter<double >::toCpp(arg);
+ static PyObject *PyInjectCode_overloadedMethod(PyObject *self, PyObject *arg)
+ {
+ PyObject* py_result{};
+ if (PyFloat_Check(arg)) {
+ double cpp_arg0 = Shiboken::Converter<double >::toCpp(arg);
- // INJECT-CODE: <modify-function><inject-code class="target" position="beginning">
- // Uses: pre method call custom code.
+ // INJECT-CODE: <modify-function><inject-code class="target" position="beginning">
+ // Uses: pre method call custom code.
- py_result = Shiboken::Converter<double >::toPython(
- PyInjectCode_cptr(self)->InjectCode::overloadedMethod(cpp_arg0)
- );
+ py_result = Shiboken::Converter<double >::toPython(
+ PyInjectCode_cptr(self)->InjectCode::overloadedMethod(cpp_arg0)
+ );
- // INJECT-CODE: <modify-function><inject-code class="target" position="end">
- // Uses: post method call custom code.
+ // INJECT-CODE: <modify-function><inject-code class="target" position="end">
+ // Uses: post method call custom code.
- } else if (PyNumber_Check(arg)) {
- (... other overload calling code ...)
- } else goto PyInjectCode_overloadedMethod_TypeError;
+ } else if (PyNumber_Check(arg)) {
+ (... other overload calling code ...)
+ } else goto PyInjectCode_overloadedMethod_TypeError;
- if (PyErr_Occurred() || !py_result)
- return {};
+ if (PyErr_Occurred() || !py_result)
+ return {};
- return py_result;
+ return py_result;
- PyInjectCode_overloadedMethod_TypeError:
- PyErr_SetString(PyExc_TypeError, "'overloadedMethod()' called with wrong parameters.");
- return {};
- }
+ PyInjectCode_overloadedMethod_TypeError:
+ PyErr_SetString(PyExc_TypeError, "'overloadedMethod()' called with wrong parameters.");
+ return {};
+ }
.. _codeinjecting_classes:
@@ -277,35 +280,35 @@ On The Native Side
Those injections go in the body of the ``CLASSNAME_wrapper.cpp`` file for the
wrapped class.
- .. code-block:: c++
+.. code-block:: c++
- // Start of ``CLASSNAME_wrapper.cpp``
- #define protected public
- // default includes
- #include <shiboken.h>
- (...)
- #include "injectcode_wrapper.h"
- using namespace Shiboken;
-
- // INJECT-CODE: <value/object-type><inject-code class="native" position="beginning">
- // Uses: prototype declarations
+ // Start of ``CLASSNAME_wrapper.cpp``
+ #define protected public
+ // default includes
+ #include <shiboken.h>
+ (...)
+ #include "injectcode_wrapper.h"
+ using namespace Shiboken;
- (... C++ wrapper virtual methods, if any ...)
+ // INJECT-CODE: <value/object-type><inject-code class="native" position="beginning">
+ // Uses: prototype declarations
- (... Python wrapper code ...)
+ (... C++ wrapper virtual methods, if any ...)
- PyAPI_FUNC(void)
- init_injectcode(PyObject *module)
- {
- (...)
- }
+ (... Python wrapper code ...)
+ PyAPI_FUNC(void)
+ init_injectcode(PyObject *module)
+ {
(...)
+ }
- // INJECT-CODE: <value/object-type><inject-code class="native" position="end">
- // Uses: definition of functions prototyped at ``native/beginning``.
+ (...)
- // End of ``CLASSNAME_wrapper.cpp``
+ // INJECT-CODE: <value/object-type><inject-code class="native" position="end">
+ // Uses: definition of functions prototyped at ``native/beginning``.
+
+ // End of ``CLASSNAME_wrapper.cpp``
.. _codeinjecting_classes_target:
@@ -315,34 +318,34 @@ On The Target Side
Code injections to the class Python initialization function.
- .. code-block:: c++
+.. code-block:: c++
- // Start of ``CLASSNAME_wrapper.cpp``
+ // Start of ``CLASSNAME_wrapper.cpp``
- (...)
+ (...)
- PyAPI_FUNC(void)
- init_injectcode(PyObject *module)
- {
- // INJECT-CODE: <value/object-type><inject-code class="target" position="beginning">
- // Uses: Alter something in the PyInjectCode_Type (tp_flags value for example)
- // before registering it.
+ PyAPI_FUNC(void)
+ init_injectcode(PyObject *module)
+ {
+ // INJECT-CODE: <value/object-type><inject-code class="target" position="beginning">
+ // Uses: Alter something in the PyInjectCode_Type (tp_flags value for example)
+ // before registering it.
- if (PyType_Ready(&PyInjectCode_Type) < 0)
- return;
+ if (PyType_Ready(&PyInjectCode_Type) < 0)
+ return;
- Py_INCREF(&PyInjectCode_Type);
- PyModule_AddObject(module, "InjectCode",
- ((PyObject*)&PyInjectCode_Type));
+ Py_INCREF(&PyInjectCode_Type);
+ PyModule_AddObject(module, "InjectCode",
+ ((PyObject*)&PyInjectCode_Type));
- // INJECT-CODE: <value/object-type><inject-code class="target" position="end">
- // Uses: do something right after the class is registered, like set some static
- // variable injected on this same file elsewhere.
- }
+ // INJECT-CODE: <value/object-type><inject-code class="target" position="end">
+ // Uses: do something right after the class is registered, like set some static
+ // variable injected on this same file elsewhere.
+ }
- (...)
+ (...)
- // End of ``CLASSNAME_wrapper.cpp``
+ // End of ``CLASSNAME_wrapper.cpp``
Code Injection for Modules
==========================
@@ -365,30 +368,30 @@ This is very similar to class wrapper code injections :ref:`codeinjecting_classe
Notice that the inject code at ``target/end`` is inserted before the check for errors
to prevent bad custom code to pass unnoticed.
- .. code-block:: c++
+.. code-block:: c++
- // Start of ``MODULENAME_module_wrapper.cpp``
+ // Start of ``MODULENAME_module_wrapper.cpp``
- (...)
- initMODULENAME()
- {
- // INJECT-CODE: <typesystem><inject-code class="target" position="beginning">
- // Uses: do something before the module is created.
+ (...)
+ initMODULENAME()
+ {
+ // INJECT-CODE: <typesystem><inject-code class="target" position="beginning">
+ // Uses: do something before the module is created.
- PyObject *module = Py_InitModule("MODULENAME", MODULENAME_methods);
+ PyObject *module = Py_InitModule("MODULENAME", MODULENAME_methods);
- (... initialization of wrapped classes, namespaces, functions and enums ...)
+ (... initialization of wrapped classes, namespaces, functions and enums ...)
- // INJECT-CODE: <typesystem><inject-code class="target" position="end">
- // Uses: do something after the module is registered and initialized.
+ // INJECT-CODE: <typesystem><inject-code class="target" position="end">
+ // Uses: do something after the module is registered and initialized.
- if (PyErr_Occurred())
- Py_FatalError("can't initialize module sample");
- }
+ if (PyErr_Occurred())
+ Py_FatalError("can't initialize module sample");
+ }
- (...)
+ (...)
- // Start of ``MODULENAME_module_wrapper.cpp``
+ // Start of ``MODULENAME_module_wrapper.cpp``
In addition, code can be injected into the module header by specifying ``target``
and ``declaration``. This is useful for type definitions.
diff --git a/sources/shiboken6/doc/typesystem_containers.rst b/sources/shiboken6/doc/typesystem_containers.rst
index 5c4abee44..b5593e20f 100644
--- a/sources/shiboken6/doc/typesystem_containers.rst
+++ b/sources/shiboken6/doc/typesystem_containers.rst
@@ -19,7 +19,8 @@ instead of a Python list. Manipulations like adding or removing elements
can applied directly to them using the C++ container functions.
This is achieved by specifying the name and the instantiated type
-in the ``opaque-containers`` attribute of :ref:`container-type`.
+in the ``opaque-containers`` attribute of :ref:`container-type`
+or using the :ref:`opaque-container` element for existing container types.
A second use case are public fields of container types. In the normal case,
they are converted to Python containers on read access. By a field modification,
@@ -34,41 +35,50 @@ The table below lists the functions supported for opaque sequence containers
besides the sequence protocol (element access via index and ``len()``). Both
the STL and the Qt naming convention (which resembles Python's) are supported:
- +-------------------------------------------+-----------------------------------+
- |Function | Description |
- +-------------------------------------------+-----------------------------------+
- | ``push_back(value)``, ``append(value)`` | Appends *value* to the sequence. |
- +-------------------------------------------+-----------------------------------+
- | ``push_front(value)``, ``prepend(value)`` | Prepends *value* to the sequence. |
- +-------------------------------------------+-----------------------------------+
- | ``clear()`` | Clears the sequence. |
- +-------------------------------------------+-----------------------------------+
- | ``pop_back()``, ``removeLast()`` | Removes the last element. |
- +-------------------------------------------+-----------------------------------+
- | ``pop_front()``, ``removeFirst()`` | Removes the first element. |
- +-------------------------------------------+-----------------------------------+
- | ``reserve(size)`` | For containers that support it |
- | | (``std::vector``, ``QList``), |
- | | allocate memory for at least |
- | | ``size`` elements, preventing |
- | | reallocations. |
- +-------------------------------------------+-----------------------------------+
- | ``capacity()`` | For containers that support it |
- | | (``std::vector``, ``QList``), |
- | | return the number of elements |
- | | that can be stored without |
- | | reallocation. |
- +-------------------------------------------+-----------------------------------+
- | ``data()`` | For containers that support it |
- | | (``std::vector``, ``QList``), |
- | | return a buffer viewing the |
- | | memory. |
- +-------------------------------------------+-----------------------------------+
- | ``constData()`` | For containers that support it |
- | | (``std::vector``, ``QList``), |
- | | return a read-only buffer viewing |
- | | the memory. |
- +-------------------------------------------+-----------------------------------+
++-------------------------------------------+-----------------------------------+
+|Function | Description |
++-------------------------------------------+-----------------------------------+
+| ``push_back(value)``, ``append(value)`` | Appends *value* to the sequence. |
++-------------------------------------------+-----------------------------------+
+| ``push_front(value)``, ``prepend(value)`` | Prepends *value* to the sequence. |
++-------------------------------------------+-----------------------------------+
+| ``clear()`` | Clears the sequence. |
++-------------------------------------------+-----------------------------------+
+| ``pop_back()``, ``removeLast()`` | Removes the last element. |
++-------------------------------------------+-----------------------------------+
+| ``pop_front()``, ``removeFirst()`` | Removes the first element. |
++-------------------------------------------+-----------------------------------+
+| ``reserve(size)`` | For containers that support it |
+| | (``std::vector``, ``QList``), |
+| | allocate memory for at least |
+| | ``size`` elements, preventing |
+| | reallocations. |
++-------------------------------------------+-----------------------------------+
+| ``capacity()`` | For containers that support it |
+| | (``std::vector``, ``QList``), |
+| | return the number of elements |
+| | that can be stored without |
+| | reallocation. |
++-------------------------------------------+-----------------------------------+
+| ``data()`` | For containers that support it |
+| | (``std::vector``, ``QList``), |
+| | return a buffer viewing the |
+| | memory. |
++-------------------------------------------+-----------------------------------+
+| ``constData()`` | For containers that support it |
+| | (``std::vector``, ``QList``), |
+| | return a read-only buffer viewing |
+| | the memory. |
++-------------------------------------------+-----------------------------------+
+
+
+.. note:: ``std::span``, being a non-owning container, is currently replaced by a
+ ``std::vector`` for argument passing. This means that an opaque container
+ wrapping a ``std::span`` obtained from a function will be converted
+ to a ``std::vector`` by sequence conversion when passed to a function
+ taking a ``std::span``.
+ Opaque containers wrapping a ``std::vector`` can be passed without conversion.
+ This is currently experimental and subject to change.
Following is an example on creating an opaque container named ``IntVector``
from `std::vector<int>`, and using it in Python.
@@ -76,7 +86,7 @@ from `std::vector<int>`, and using it in Python.
We will consider three separate use cases.
**Case 1** - When a Python list is passed to C++ function
-`TestOpaqueContainer.getVectorSum(const std::vector<int>&)` as an opaque container
+``TestOpaqueContainer.getVectorSum(const std::vector<int>&)`` as an opaque container
.. code-block:: c
@@ -89,7 +99,7 @@ We will consider three separate use cases.
}
};
-**Case 2** - When we have a C++ class named `TestOpaqueContainer` with a `std::vector<int>`
+**Case 2** - When we have a C++ class named ``TestOpaqueContainer`` with a ``std::vector<int>``
public variable
.. code-block:: c
@@ -101,7 +111,7 @@ public variable
};
-**Case 3** - When we have a C++ class named `TestOpaqueContainer` with a `std::vector<int>` as
+**Case 3** - When we have a C++ class named ``TestOpaqueContainer`` with a ``std::vector<int>`` as
private variable and the variable is returned by a reference through a getter.
.. code-block:: c
@@ -123,9 +133,9 @@ private variable and the variable is returned by a reference through a getter.
of these examples are rather to show the different possibilities with opaque containers in
Shiboken than the class design.
-In all the three cases, we want to use `intVector` in Python through an opaque-container. The
-first thing to do is to create the corresponding `<container-type />` attribute in the typesystem
-file, making Shiboken aware of the `IntVector`.
+In all the three cases, we want to use ``intVector`` in Python through an opaque-container. The
+first thing to do is to create the corresponding ``<container-type />`` attribute in the typesystem
+file, making Shiboken aware of the ``IntVector``.
.. code-block:: xml
@@ -147,17 +157,17 @@ For the rest of the steps, we consider the three cases separately.
**Case 1** - When a Python list is passed to a C++ function
-As the next step, we create a typesystem entry for the class `TestOpaqueContainer`.
+As the next step, we create a typesystem entry for the class ``TestOpaqueContainer``.
.. code-block:: xml
<value-type name="TestOpaqueContainer" />
In this case, the typesystem entry is simple and the function
-`getVectorSum(const std::vector<int>&)` accepts `IntVector` as the parameter. This is
-because inherantly `IntVector` is the same as `std::vector<int>`.
+``getVectorSum(const std::vector<int>&)`` accepts ``IntVector`` as the parameter. This is
+because inherantly ``IntVector`` is the same as ``std::vector<int>``.
-Now, build the code to create the \*_wrapper.cpp and \*.so files which we import into Python.
+Now, build the code to create the ``*_wrapper.cpp`` and ``*.so`` files which we import into Python.
Verifying the usage in Python
@@ -173,7 +183,7 @@ Verifying the usage in Python
**Case 2** - When the variable is public
-We create a typesystem entry for the class `TestOpaqueContainer`.
+We create a typesystem entry for the class ``TestOpaqueContainer``.
.. code-block:: xml
@@ -181,11 +191,11 @@ We create a typesystem entry for the class `TestOpaqueContainer`.
<modify-field name="intVector" opaque-container="yes"/>
</value-type>
-In the `<modify-field />` notice the `opaque-container="yes"`. Since the type
-of `intVector' is `std::vector<int>`, it picks up the ``IntVector`` opaque
+In the ``<modify-field />`` notice the ``opaque-container="yes"``. Since the type
+of ``intVector`` is ``std::vector<int>``, it picks up the ``IntVector`` opaque
container.
-Build the code to create the \*_wrapper.cpp and \*.so files which we import into Python.
+Build the code to create the ``*_wrapper.cpp`` and ``*.so`` files which we import into Python.
Verifying the usage in Python
@@ -206,7 +216,7 @@ Verifying the usage in Python
**Case 3** - When the variable is private and returned by reference through a getter
-Similar to the previous cases, we create a typesystem entry for the class `TestOpaqueContainer`.
+Similar to the previous cases, we create a typesystem entry for the class ``TestOpaqueContainer``.
.. code-block:: xml
@@ -218,7 +228,7 @@ Similar to the previous cases, we create a typesystem entry for the class `TestO
</modify-function>
</value-type>
-In this case, we specify the name of the opaque container `IntVector` in the <replace-type />
+In this case, we specify the name of the opaque container ``IntVector`` in the ``<replace-type />``
field.
Build the code to create the \*_wrapper.cpp and \*.so files which we import into Python.
diff --git a/sources/shiboken6/doc/typesystem_conversionrule.rst b/sources/shiboken6/doc/typesystem_conversionrule.rst
index 4ac2bd365..9a8f51c18 100644
--- a/sources/shiboken6/doc/typesystem_conversionrule.rst
+++ b/sources/shiboken6/doc/typesystem_conversionrule.rst
@@ -8,99 +8,99 @@ Conversion Rule Tag
conversion-rule
^^^^^^^^^^^^^^^
- The **conversion-rule** tag specifies how a **primitive-type**, a **container-type**,
- or a **value-type** may be converted to and from the native C++ language types to the
- target language types (see also :ref:`user-defined-type-conversion`).
-
- It is a child of the :ref:`container-type`, :ref:`primitive-type` or
- :ref:`value-type` and may contain :ref:`native-to-target` or
- :ref:`native-to-target` child nodes.
-
- .. code-block:: xml
-
- <value-type>
- <conversion-rule>
- <native-to-target>
- // Code to convert a native value to a target language object.
- </native-to-target>
- <target-to-native>
- <add-conversion type='TARGETTYPEA' check='TARGETTYPEA_CHECK(%in)'>
- // Code to convert target language type object of type TARGETTYPEA
- // to the C++ native type represented by the value/primitive/container-type.
- </add-conversion>
- <add-conversion type='TARGETTYPEB' check='TARGETTYPEB_CHECK(%in)'>
- // Code to convert target language type object of type TARGETTYPEB
- // to the C++ native type represented by the value/primitive/container-type.
- </add-conversion>
- </target-to-native>
- </conversion-rule>
- </value-type>
-
- The code can be inserted directly, via :ref:`add-conversion` (providing snippet
- functionality) or via :ref:`insert-template` (XML template,
- see :ref:`using-code-templates`).
-
- The example above show the structure of a complete conversion rule. Each of the
- child tags comprising the conversion rule are described in their own sections
- below.
-
- .. note::
-
- You can also use the ``conversion-rule`` node to specify customized code
- to convert a function argument between the target language and C++
- (see :ref:`conversionrule-on-arguments`).
+The **conversion-rule** tag specifies how a **primitive-type**, a **container-type**,
+or a **value-type** may be converted to and from the native C++ language types to the
+target language types (see also :ref:`user-defined-type-conversion`).
-.. _native-to-target:
-
-native-to-target
-^^^^^^^^^^^^^^^^
-
- The **native-to-target** tag tells how to convert a native C++ value to its
- target language equivalent. It is a child of the :ref:`conversion-rule` node.
- The text inside the tag is a C++ code the takes
- an input value an does what's needed to convert it to the output value.
- :ref:`insert-template` tags may be used to insert commonly repeating code.
+It is a child of the :ref:`container-type`, :ref:`primitive-type` or
+:ref:`value-type` and may contain :ref:`native-to-target` or
+:ref:`native-to-target` child nodes.
- .. code-block:: xml
+.. code-block:: xml
+ <value-type>
<conversion-rule>
<native-to-target>
// Code to convert a native value to a target language object.
</native-to-target>
+ <target-to-native>
+ <add-conversion type='TARGETTYPEA' check='TARGETTYPEA_CHECK(%in)'>
+ // Code to convert target language type object of type TARGETTYPEA
+ // to the C++ native type represented by the value/primitive/container-type.
+ </add-conversion>
+ <add-conversion type='TARGETTYPEB' check='TARGETTYPEB_CHECK(%in)'>
+ // Code to convert target language type object of type TARGETTYPEB
+ // to the C++ native type represented by the value/primitive/container-type.
+ </add-conversion>
+ </target-to-native>
</conversion-rule>
+ </value-type>
- Use the replace node to modify the template code.
- Notice that the generator must provide type system variables for the input
- and output values and types, namely **%in**, **%out**, **%INTYPE** and
- **%OUTTYPE**. In the case of container types, **%INTYPE** refers to the
- full container type (e.g. **"list<int>"**) and **%INTYPE_0**, **%INTYPE_1**,
- **%INTYPE_#**, should be replaced by the types used in the container template
- (e.g. **%INTYPE_0** correspondes to **"int"** for **"list<int>"**).
+The code can be inserted directly, via :ref:`add-conversion` (providing snippet
+functionality) or via :ref:`insert-template` (XML template,
+see :ref:`using-code-templates`).
- The ``file`` and ``snippet`` attributes are also supported (see :ref:`inject-code` nodes).
+The example above show the structure of a complete conversion rule. Each of the
+child tags comprising the conversion rule are described in their own sections
+below.
+
+.. note::
+
+ You can also use the ``conversion-rule`` node to specify customized code
+ to convert a function argument between the target language and C++
+ (see :ref:`conversionrule-on-arguments`).
+
+.. _native-to-target:
+
+native-to-target
+^^^^^^^^^^^^^^^^
+
+The **native-to-target** tag tells how to convert a native C++ value to its
+target language equivalent. It is a child of the :ref:`conversion-rule` node.
+The text inside the tag is a C++ code the takes
+an input value an does what's needed to convert it to the output value.
+:ref:`insert-template` tags may be used to insert commonly repeating code.
+
+.. code-block:: xml
+
+ <conversion-rule>
+ <native-to-target>
+ // Code to convert a native value to a target language object.
+ </native-to-target>
+ </conversion-rule>
+
+Use the replace node to modify the template code.
+Notice that the generator must provide type system variables for the input
+and output values and types, namely **%in**, **%out**, **%INTYPE** and
+**%OUTTYPE**. In the case of container types, **%INTYPE** refers to the
+full container type (e.g. **"list<int>"**) and **%INTYPE_0**, **%INTYPE_1**,
+**%INTYPE_#**, should be replaced by the types used in the container template
+(e.g. **%INTYPE_0** correspondes to **"int"** for **"list<int>"**).
+
+The ``file`` and ``snippet`` attributes are also supported (see :ref:`inject-code` nodes).
.. _target-to-native:
target-to-native
^^^^^^^^^^^^^^^^
- The **target-to-native** tag encloses at least one, but usually many, conversions
- from target language values to C++ native values. It is a child of the
- :ref:`conversion-rule` node and may have one or several :ref:`add-conversion`
- child nodes. The *optional* attribute ``replace`` tells if the target
- language to C++ conversions will be added to, or if they will replace the
- implicit conversions collected by *ApiExtractor*. The default
- value for it is *yes*.
+The **target-to-native** tag encloses at least one, but usually many, conversions
+from target language values to C++ native values. It is a child of the
+:ref:`conversion-rule` node and may have one or several :ref:`add-conversion`
+child nodes. The *optional* attribute ``replace`` tells if the target
+language to C++ conversions will be added to, or if they will replace the
+implicit conversions collected by *ApiExtractor*. The default
+value for it is *yes*.
- .. code-block:: xml
+.. code-block:: xml
- <conversion-rule>
- <target-to-native replace='yes|no'>\
- // List of target to native conversions meant to replace or expand
- // the already existing implicit conversions.
- </target-to-native>
- </conversion-rule>
+ <conversion-rule>
+ <target-to-native replace='yes|no'>
+ // List of target to native conversions meant to replace or expand
+ // the already existing implicit conversions.
+ </target-to-native>
+ </conversion-rule>
.. _add-conversion:
@@ -108,26 +108,26 @@ target-to-native
add-conversion
^^^^^^^^^^^^^^
- Each **add-conversion** tag adds a rule for conversion of a target language type,
- indicated by the ``type`` attribute, to the C++ native type represented by the
- **primitive-type**, a **container-type**, or **value-type**, to which the parent
- **conversion-rule** belongs.
- It is a child of the :ref:`target-to-native` node.
+Each **add-conversion** tag adds a rule for conversion of a target language type,
+indicated by the ``type`` attribute, to the C++ native type represented by the
+**primitive-type**, a **container-type**, or **value-type**, to which the parent
+**conversion-rule** belongs.
+It is a child of the :ref:`target-to-native` node.
- .. code-block:: xml
+.. code-block:: xml
- <target-to-native>
- <add-conversion type='TARGETTYPE' check='TARGETTYPECHECK(%in)'>
- // Code to convert target language type object of type TARGETTYPE_A
- // to the C++ native type represented by the value/primitive/container-type.
- </add-conversion>
- <target-to-native>
+ <target-to-native>
+ <add-conversion type='TARGETTYPE' check='TARGETTYPECHECK(%in)'>
+ // Code to convert target language type object of type TARGETTYPE_A
+ // to the C++ native type represented by the value/primitive/container-type.
+ </add-conversion>
+ <target-to-native>
- The ``check`` attribute tells how a target value should be checked to see if it belongs to
- the type expected. This attribute is *optional*, for it can be derived from the ``type``
- attribute, but it isn't unusual that some special check is needed. The variables
- **%in**, **%out**, **%INTYPE**, **%INTYPE_#**, and **%OUTTYPE**, must be provided by
- the generator as in the ``native-to-target`` tag.
+The ``check`` attribute tells how a target value should be checked to see if it belongs to
+the type expected. This attribute is *optional*, for it can be derived from the ``type``
+attribute, but it isn't unusual that some special check is needed. The variables
+**%in**, **%out**, **%INTYPE**, **%INTYPE_#**, and **%OUTTYPE**, must be provided by
+the generator as in the ``native-to-target`` tag.
- The ``file`` and ``snippet`` attributes are also supported (see :ref:`inject-code` nodes).
+The ``file`` and ``snippet`` attributes are also supported (see :ref:`inject-code` nodes).
diff --git a/sources/shiboken6/doc/typesystem_converters.rst b/sources/shiboken6/doc/typesystem_converters.rst
index 02600e7b1..ab6fba930 100644
--- a/sources/shiboken6/doc/typesystem_converters.rst
+++ b/sources/shiboken6/doc/typesystem_converters.rst
@@ -12,51 +12,51 @@ numbers, has a Python equivalent in the "complex" type.) Such classes, instead
of getting a Python wrapper, normally have conversions rules, from Python to
C++ and vice-versa.
- .. code-block:: c++
+.. code-block:: c++
- // C++ class
- struct Complex {
- Complex(double real, double imag);
- double real() const;
- double imag() const;
- };
+ // C++ class
+ struct Complex {
+ Complex(double real, double imag);
+ double real() const;
+ double imag() const;
+ };
- // Converting from C++ to Python using the CPython API:
- PyObject* pyCpxObj = PyComplex_FromDoubles(complex.real(), complex.imag());
+ // Converting from C++ to Python using the CPython API:
+ PyObject* pyCpxObj = PyComplex_FromDoubles(complex.real(), complex.imag());
- // Converting from Python to C++:
- double real = PyComplex_RealAsDouble(pyCpxObj);
- double imag = PyComplex_ImagAsDouble(pyCpxObj);
- Complex cpx(real, imag);
+ // Converting from Python to C++:
+ double real = PyComplex_RealAsDouble(pyCpxObj);
+ double imag = PyComplex_ImagAsDouble(pyCpxObj);
+ Complex cpx(real, imag);
For the user defined conversion code to be inserted in the proper places,
the :ref:`conversion-rule` tag must be used.
- .. code-block:: xml
+.. code-block:: xml
- <primitive-type name="Complex" target-lang-api-name="PyComplex">
- <include file-name="complex.h" location="global"/>
+ <primitive-type name="Complex" target-lang-api-name="PyComplex">
+ <include file-name="complex.h" location="global"/>
- <conversion-rule>
+ <conversion-rule>
- <native-to-target>
- return PyComplex_FromDoubles(%in.real(), %in.imag());
- </native-to-target>
+ <native-to-target>
+ return PyComplex_FromDoubles(%in.real(), %in.imag());
+ </native-to-target>
- <target-to-native>
- <!-- The 'check' attribute can be derived from the 'type' attribute,
- it is defined here to test the CHECKTYPE type system variable. -->
- <add-conversion type="PyComplex" check="%CHECKTYPE[Complex](%in)">
- double real = PyComplex_RealAsDouble(%in);
- double imag = PyComplex_ImagAsDouble(%in);
- %out = %OUTTYPE(real, imag);
- </add-conversion>
- </target-to-native>
+ <target-to-native>
+ <!-- The 'check' attribute can be derived from the 'type' attribute,
+ it is defined here to test the CHECKTYPE type system variable. -->
+ <add-conversion type="PyComplex" check="%CHECKTYPE[Complex](%in)">
+ double real = PyComplex_RealAsDouble(%in);
+ double imag = PyComplex_ImagAsDouble(%in);
+ %out = %OUTTYPE(real, imag);
+ </add-conversion>
+ </target-to-native>
- </conversion-rule>
+ </conversion-rule>
- </primitive-type>
+ </primitive-type>
The details will be given later, but the gist of it are the tags
@@ -78,53 +78,53 @@ of numbers to be accepted by wrapped C++ functions with "Complex" arguments,
an :ref:`add-conversion <add-conversion>` tag and a custom check must be added.
Here's how to do it:
- .. code-block:: xml
+.. code-block:: xml
- <!-- Code injection at module level. -->
- <inject-code class="native" position="beginning">
- static bool Check2TupleOfNumbers(PyObject* pyIn) {
- if (!PySequence_Check(pyIn) || !(PySequence_Size(pyIn) == 2))
- return false;
- Shiboken::AutoDecRef pyReal(PySequence_GetItem(pyIn, 0));
- if (!PyNumber_Check(pyReal))
- return false;
- Shiboken::AutoDecRef pyImag(PySequence_GetItem(pyIn, 1));
- if (!PyNumber_Check(pyImag))
- return false;
- return true;
- }
- </inject-code>
+ <!-- Code injection at module level. -->
+ <inject-code class="native" position="beginning">
+ static bool Check2TupleOfNumbers(PyObject* pyIn) {
+ if (!PySequence_Check(pyIn) || !(PySequence_Size(pyIn) == 2))
+ return false;
+ Shiboken::AutoDecRef pyReal(PySequence_GetItem(pyIn, 0));
+ if (!PyNumber_Check(pyReal))
+ return false;
+ Shiboken::AutoDecRef pyImag(PySequence_GetItem(pyIn, 1));
+ if (!PyNumber_Check(pyImag))
+ return false;
+ return true;
+ }
+ </inject-code>
- <primitive-type name="Complex" target-lang-api-name="PyComplex">
- <include file-name="complex.h" location="global"/>
+ <primitive-type name="Complex" target-lang-api-name="PyComplex">
+ <include file-name="complex.h" location="global"/>
- <conversion-rule>
+ <conversion-rule>
- <native-to-target>
- return PyComplex_FromDoubles(%in.real(), %in.imag());
- </native-to-target>
+ <native-to-target>
+ return PyComplex_FromDoubles(%in.real(), %in.imag());
+ </native-to-target>
- <target-to-native>
+ <target-to-native>
- <add-conversion type="PyComplex">
- double real = PyComplex_RealAsDouble(%in);
- double imag = PyComplex_ImagAsDouble(%in);
- %out = %OUTTYPE(real, imag);
- </add-conversion>
+ <add-conversion type="PyComplex">
+ double real = PyComplex_RealAsDouble(%in);
+ double imag = PyComplex_ImagAsDouble(%in);
+ %out = %OUTTYPE(real, imag);
+ </add-conversion>
- <add-conversion type="PySequence" check="Check2TupleOfNumbers(%in)">
- Shiboken::AutoDecRef pyReal(PySequence_GetItem(%in, 0));
- Shiboken::AutoDecRef pyImag(PySequence_GetItem(%in, 1));
- double real = %CONVERTTOCPP[double](pyReal);
- double imag = %CONVERTTOCPP[double](pyImag);
- %out = %OUTTYPE(real, imag);
- </add-conversion>
+ <add-conversion type="PySequence" check="Check2TupleOfNumbers(%in)">
+ Shiboken::AutoDecRef pyReal(PySequence_GetItem(%in, 0));
+ Shiboken::AutoDecRef pyImag(PySequence_GetItem(%in, 1));
+ double real = %CONVERTTOCPP[double](pyReal);
+ double imag = %CONVERTTOCPP[double](pyImag);
+ %out = %OUTTYPE(real, imag);
+ </add-conversion>
- </target-to-native>
+ </target-to-native>
- </conversion-rule>
+ </conversion-rule>
- </primitive-type>
+ </primitive-type>
.. _container_conversions:
@@ -138,48 +138,48 @@ except that they make use of the type system variables
|project| combines the conversion code for containers with the conversion
defined (or automatically generated) for the containers.
- .. code-block:: xml
-
- <container-type name="std::map" type="map">
- <include file-name="map" location="global"/>
-
- <conversion-rule>
-
- <native-to-target>
- PyObject* %out = PyDict_New();
- %INTYPE::const_iterator it = %in.begin();
- for (; it != %in.end(); ++it) {
- %INTYPE_0 key = it->first;
- %INTYPE_1 value = it->second;
- PyDict_SetItem(%out,
- %CONVERTTOPYTHON[%INTYPE_0](key),
- %CONVERTTOPYTHON[%INTYPE_1](value));
- }
- return %out;
- </native-to-target>
-
- <target-to-native>
-
- <add-conversion type="PyDict">
- PyObject* key;
- PyObject* value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(%in, &amp;pos, &amp;key, &amp;value)) {
- %OUTTYPE_0 cppKey = %CONVERTTOCPP[%OUTTYPE_0](key);
- %OUTTYPE_1 cppValue = %CONVERTTOCPP[%OUTTYPE_1](value);
- %out.insert(%OUTTYPE::value_type(cppKey, cppValue));
- }
- </add-conversion>
-
- </target-to-native>
- </conversion-rule>
- </container-type>
-
-.. note:: From version 6.3, we do not have to explicitly specify the
- `<container-type/>` for C++ containers ``std::list``\, ``std::vector``\,
- ``std::pair``\, ``std::map`` and ``std::unordered_map``\. They are
- now built-in. However, they still have to be added for opaque
- containers or when modifying the built-in behavior.
+.. code-block:: xml
+
+ <container-type name="std::map" type="map">
+ <include file-name="map" location="global"/>
+
+ <conversion-rule>
+
+ <native-to-target>
+ PyObject* %out = PyDict_New();
+ %INTYPE::const_iterator it = %in.begin();
+ for (; it != %in.end(); ++it) {
+ %INTYPE_0 key = it->first;
+ %INTYPE_1 value = it->second;
+ PyDict_SetItem(%out,
+ %CONVERTTOPYTHON[%INTYPE_0](key),
+ %CONVERTTOPYTHON[%INTYPE_1](value));
+ }
+ return %out;
+ </native-to-target>
+
+ <target-to-native>
+
+ <add-conversion type="PyDict">
+ PyObject* key;
+ PyObject* value;
+ Py_ssize_t pos = 0;
+ while (PyDict_Next(%in, &amp;pos, &amp;key, &amp;value)) {
+ %OUTTYPE_0 cppKey = %CONVERTTOCPP[%OUTTYPE_0](key);
+ %OUTTYPE_1 cppValue = %CONVERTTOCPP[%OUTTYPE_1](value);
+ %out.insert(%OUTTYPE::value_type(cppKey, cppValue));
+ }
+ </add-conversion>
+
+ </target-to-native>
+ </conversion-rule>
+ </container-type>
+
+.. note:: The C++ containers ``std::list``\, ``std::vector``\,
+ ``std::pair``\, ``std::map``\, ``std::span`` and ``std::unordered_map`` are
+ built-in.
+ To specify :ref:`opaque-containers`, use the :ref:`opaque-container` element.
+ :ref:`container-type` can still be specified to modify the built-in behavior.
For this case, a number of pre-defined conversion templates
are provided (see :ref:`predefined_templates`).
@@ -192,14 +192,12 @@ Variables & Functions
.. _in:
**%in**
-
Variable replaced by the C++ input variable.
.. _out:
**%out**
-
Variable replaced by the C++ output variable. Needed to convey the
result of a Python to C++ conversion.
@@ -207,7 +205,6 @@ Variables & Functions
.. _intype:
**%INTYPE**
-
Used in Python to C++ conversions. It is replaced by the name of type for
which the conversion is being defined. Don't use the type's name directly.
@@ -215,14 +212,12 @@ Variables & Functions
.. _intype_n:
**%INTYPE_#**
-
Replaced by the name of the #th type used in a container.
.. _outtype:
**%OUTTYPE**
-
Used in Python to C++ conversions. It is replaced by the name of type for
which the conversion is being defined. Don't use the type's name directly.
@@ -230,71 +225,11 @@ Variables & Functions
.. _outtype_n:
**%OUTTYPE_#**
-
Replaced by the name of the #th type used in a container.
.. _checktype:
**%CHECKTYPE[CPPTYPE]**
-
Replaced by a |project| type checking function for a Python variable.
The C++ type is indicated by ``CPPTYPE``.
-
-
-.. _oldconverters:
-
-Converting The Old Converters
-=============================
-
-If you use |project| for your bindings, and has defined some type conversions
-using the ``Shiboken::Converter`` template, then you must update your converters
-to the new scheme.
-
-Previously your conversion rules were declared in one line, like this:
-
-
- .. code-block:: xml
-
- <primitive-type name="Complex" target-lang-api-name="PyComplex">
- <include file-name="complex.h" location="global"/>
- <conversion-rule file="complex_conversions.h"/>
- </primitive-type>
-
-
-And implemented in a separate C++ file, like this:
-
-
- .. code-block:: c++
-
- namespace Shiboken {
- template<> struct Converter<Complex>
- {
- static inline bool checkType(PyObject* pyObj) {
- return PyComplex_Check(pyObj);
- }
- static inline bool isConvertible(PyObject* pyObj) {
- return PyComplex_Check(pyObj);
- }
- static inline PyObject* toPython(void* cppobj) {
- return toPython(*reinterpret_cast<Complex*>(cppobj));
- }
- static inline PyObject* toPython(const Complex& cpx) {
- return PyComplex_FromDoubles(cpx.real(), cpx.imag());
- }
- static inline Complex toCpp(PyObject* pyobj) {
- double real = PyComplex_RealAsDouble(pyobj);
- double imag = PyComplex_ImagAsDouble(pyobj);
- return Complex(real, imag);
- }
- };
- }
-
-
-In this case, the parts of the implementation that will be used in the new
-conversion-rule are the ones in the two last method
-``static inline PyObject* toPython(const Complex& cpx)`` and
-``static inline Complex toCpp(PyObject* pyobj)``. The ``isConvertible`` method
-is gone, and the ``checkType`` is now an attribute of the :ref:`add-conversion <add-conversion>`
-tag. Refer back to the first example in this page and you will be able to
-correlate the above template with the new scheme of conversion rule definition.
diff --git a/sources/shiboken6/doc/typesystem_documentation.rst b/sources/shiboken6/doc/typesystem_documentation.rst
index f03d8b70a..4e7d18b99 100644
--- a/sources/shiboken6/doc/typesystem_documentation.rst
+++ b/sources/shiboken6/doc/typesystem_documentation.rst
@@ -4,48 +4,59 @@ Manipulating Documentation
inject-documentation
^^^^^^^^^^^^^^^^^^^^
- The inject-documentation node inserts the documentation into the generated
- documentation. This node is a child of the :ref:`object-type`,
- :ref:`value-type` and :ref:`modify-function` nodes.
+The inject-documentation node inserts the documentation into the generated
+documentation. This node is a child of the :ref:`object-type`,
+:ref:`value-type` and :ref:`modify-function` nodes.
- .. code-block:: xml
+.. code-block:: xml
- <value-type>
- <inject-documentation mode="append | prepend | replace" format="native | target" >
- // the documentation
- </inject-code>
- </value-type>
+ <value-type>
+ <inject-documentation mode="append | prepend | replace" format="native | target"
+ file="[file]" snippet="[label]">
+ // the documentation
+ </inject-code>
+ </value-type>
- The **mode** attribute default value is *replace*.
+The **mode** attribute default value is *replace*.
- The **format** attribute specifies when the documentation injection will
- occur and it accepts the following values:
+The **format** attribute specifies when the documentation injection will
+occur and it accepts the following values:
- * native: Before XML<->Backend transformation occur, so the injected code *must* be a valid XML.
- * target: After XML<->Backend transformation occur, so the injected code *must* be a valid backend format.
+* native: Before XML<->Backend transformation occur, so the injected code *must* be a valid XML.
+* target: After XML<->Backend transformation occur, so the injected code *must* be a valid backend format.
- At the moment the only supported backend is Sphinx.
+The optional ``file`` attribute specifies the file name
+(see :ref:`external-snippets`).
+
+The optional ``snippet`` attribute specifies the snippet label
+(see :ref:`external-snippets`).
+
+At the moment the only supported backend is Sphinx.
+
+If the injected documentation contains a Sphinx function directive, no
+directive will be auto-generated. This can be used to add parameter
+documentation to added functions.
modify-documentation
^^^^^^^^^^^^^^^^^^^^
- The modify-documentation node allows you to change the auto-generated
- documentation. . This node is a child of the :ref:`object-type`,
- :ref:`value-type` and :ref:`modify-function` nodes.
- API Extractor transforms XML's from `qdoc`_ (the Qt documentation
- tool) into .rst files to be processed later using `Sphinx`_. You can modify
- the XML before the transformation takes place.
+The modify-documentation node allows you to change the auto-generated
+documentation. . This node is a child of the :ref:`object-type`,
+:ref:`value-type` and :ref:`modify-function` nodes.
+API Extractor transforms XML's from `qdoc`_ (the Qt documentation
+tool) into .rst files to be processed later using `Sphinx`_. You can modify
+the XML before the transformation takes place.
.. _`qdoc`: https://doc.qt.io/qt-6/qdoc-index.html
.. _`Sphinx`: https://www.sphinx-doc.org/en/master
- .. code-block:: xml
+.. code-block:: xml
- <modify-documentation xpath="...">
- <!-- new documentation -->
- </modify-documentation>
+ <modify-documentation xpath="...">
+ <!-- new documentation -->
+ </modify-documentation>
- The **xpath** attribute is the `XPath`_ to the node that you want to modify.
+The **xpath** attribute is the `XPath`_ to the node that you want to modify.
.. _`XPath`: https://www.w3.org/TR/1999/REC-xpath-19991116/
diff --git a/sources/shiboken6/doc/typesystem_manipulating_objects.rst b/sources/shiboken6/doc/typesystem_manipulating_objects.rst
index c8d35cf9c..e024cdf00 100644
--- a/sources/shiboken6/doc/typesystem_manipulating_objects.rst
+++ b/sources/shiboken6/doc/typesystem_manipulating_objects.rst
@@ -8,75 +8,75 @@ Manipulating Object and Value Types
inject-code
^^^^^^^^^^^
- The ``inject-code`` node inserts the given code into the generated code for the
- given type or function, and it is a child of the :ref:`object-type`, :ref:`value-type`,
- :ref:`modify-function` and :ref:`add-function` nodes.
- It may contain :ref:`insert-template` child nodes.
+The ``inject-code`` node inserts the given code into the generated code for the
+given type or function, and it is a child of the :ref:`object-type`, :ref:`value-type`,
+:ref:`modify-function` and :ref:`add-function` nodes.
+It may contain :ref:`insert-template` child nodes.
- .. code-block:: xml
+.. code-block:: xml
- <inject-code class="native | target"
- position="beginning | end" since="..."
- file="[file]"
- snippet="[label]"/>
+ <inject-code class="native | target"
+ position="beginning | end" since="..."
+ file="[file]"
+ snippet="[label]"/>
- The ``class`` attribute specifies which module of the generated code that
- will be affected by the code injection
- (see :ref:`codegenerationterminology`). The ``class`` attribute accepts the
- following values:
+The ``class`` attribute specifies which module of the generated code that
+will be affected by the code injection
+(see :ref:`codegenerationterminology`). The ``class`` attribute accepts the
+following values:
- * ``native``: The c++ code
- * ``target``: The binding code
+* ``native``: The c++ code
+* ``target``: The binding code
- If the ``position`` attribute is set to *beginning* (the default), the code
- is inserted at the beginning of the function. If it is set to *end*, the code
- is inserted at the end of the function.
+If the ``position`` attribute is set to *beginning* (the default), the code
+is inserted at the beginning of the function. If it is set to *end*, the code
+is inserted at the end of the function.
- For a detailed description of how to above attributes interact,
- see :ref:`codeinjectionsemantics`.
+For a detailed description of how to above attributes interact,
+see :ref:`codeinjectionsemantics`.
- The optional ``file`` attribute specifies the file name
- (see :ref:`external-snippets`).
+The optional ``file`` attribute specifies the file name
+(see :ref:`external-snippets`).
- The optional ``snippet`` attribute specifies the snippet label
- (see :ref:`external-snippets`).
+The optional ``snippet`` attribute specifies the snippet label
+(see :ref:`external-snippets`).
- There are a number of placeholders which are replaced when injecting
- code (see :ref:`typesystemvariables`).
+There are a number of placeholders which are replaced when injecting
+code (see :ref:`typesystemvariables`).
- There are severals ways to specify the code:
+There are severals ways to specify the code:
Embedding Code into XML
=======================
- The code can be embedded into XML (be careful to use the correct XML entities
- for characters like '<', '>', '&'):
+The code can be embedded into XML (be careful to use the correct XML entities
+for characters like '<', '>', '&'):
- .. code-block:: xml
+.. code-block:: xml
- <value-type>
- <inject-code class="native | target"
- position="beginning | end" since="...">
- // the code
- </inject-code>
- </value-type>
+ <value-type>
+ <inject-code class="native | target"
+ position="beginning | end" since="...">
+ // the code
+ </inject-code>
+ </value-type>
Using a Template Specified in XML
=================================
- It is possible to create code templates for reuse in XML
- (see :ref:`using-code-templates`). This allows for replacing of custom
- placeholders.
+It is possible to create code templates for reuse in XML
+(see :ref:`using-code-templates`). This allows for replacing of custom
+placeholders.
- .. code-block:: xml
+.. code-block:: xml
- <value-type>
- <inject-code class="native | target" class="native | target">
- <insert-template name="template_name"/>
- </inject-code>
- </value-type>
+ <value-type>
+ <inject-code class="native | target" class="native | target">
+ <insert-template name="template_name"/>
+ </inject-code>
+ </value-type>
.. _external-snippets:
@@ -84,272 +84,291 @@ Using a Template Specified in XML
Using Snippets From External Files
==================================
- Code snippets can also be retrieved from external files found in the
- typesystem search path (see :ref:`typesystem-paths`).
+Code or documentation snippets can also be retrieved from external
+files found in the typesystem search path (see :ref:`typesystem-paths`).
- .. code-block:: xml
+.. code-block:: xml
- <value-type>
- <inject-code class="native | target"
- position="beginning | end" since="..."
- file="external_source.cpp"
- snippet="label"/>
- </value-type>
+ <value-type>
+ <inject-code class="native | target"
+ position="beginning | end" since="..."
+ file="external_source.cpp"
+ snippet="label"/>
+ </value-type>
- In the external file ``external_source.cpp``, the code between annotations
- of the form:
+In the external file ``external_source.cpp``, the code between annotations
+of the form:
- .. code-block:: c++
+.. code-block:: c++
- // @snippet label
- ...
- // @snippet label
+ // @snippet label
+ ...
+ // @snippet label
- will be extracted.
+will be extracted.
.. _modify-field:
modify-field
^^^^^^^^^^^^
- The ``modify-field`` node allows you to alter the access privileges for a given
- C++ field when mapping it onto the target language, and it is a child of an
- :ref:`object-type` or a :ref:`value-type` node.
+The ``modify-field`` node allows you to alter the access privileges for a given
+C++ field when mapping it onto the target language, and it is a child of an
+:ref:`object-type` or a :ref:`value-type` node.
- .. code-block:: xml
+.. code-block:: xml
- <object-type>
- <modify-field name="..."
- write="true | false"
- read="true | false"
- remove="true | false"
- opaque-container = "yes | no"
- snake-case="yes | no | both" />
- </object-type>
+ <object-type>
+ <modify-field name="..."
+ write="true | false"
+ read="true | false"
+ remove="true | false"
+ opaque-container = "yes | no"
+ snake-case="yes | no | both" />
+ </object-type>
- The ``name`` attribute is the name of the field, the *optional* ``write``
- and ``read`` attributes specify the field's access privileges in the target
- language API (both are set to true by default).
+The ``name`` attribute is the name of the field, the *optional* ``write``
+and ``read`` attributes specify the field's access privileges in the target
+language API (both are set to true by default).
- The ``remove`` attribute is an *optional* boolean attribute, which can
- mark the field to be discarded on generation.
+The ``remove`` attribute is an *optional* boolean attribute, which can
+mark the field to be discarded on generation.
- The *optional* ``rename`` attribute can be used to change the name of the
- given field in the generated target language API.
+The *optional* ``rename`` attribute can be used to change the name of the
+given field in the generated target language API.
- The *optional* ``opaque-container`` attribute specifies whether
- an opaque container should be returned on read access
- (see :ref:`opaque-containers`).
+The *optional* ``opaque-container`` attribute specifies whether
+an opaque container should be returned on read access
+(see :ref:`opaque-containers`).
- The *optional* **snake-case** attribute allows for overriding the value
- specified on the class entry or **typesystem** element.
+The *optional* **snake-case** attribute allows for overriding the value
+specified on the class entry or **typesystem** element.
.. _modify-function:
modify-function
^^^^^^^^^^^^^^^
- The ``modify-function`` node allows you to modify a given C++ function when
- mapping it onto the target language, and it is a child of a :ref:`function`,
- :ref:`namespace`, :ref:`object-type` or a :ref:`value-type` node.
- Use the :ref:`modify-argument` node to specify which argument the
- modification affects.
-
- .. code-block:: xml
-
- <object-type>
- <modify-function signature="..."
- since="..."
- remove="true | false"
- access="public | private | protected"
- allow-thread="true | auto | false"
- exception-handling="off | auto-off | auto-on | on"
- final="true | false"
- overload-number="number"
- rename="..."
- snake-case="yes | no | both" />
- </object-type>
-
- The ``signature`` attribute is a normalized C++ signature, excluding return
- values but including potential const declarations. It is not required
- when ``modify-function`` appears as a child of a :ref:`function` node to
- modify a global function.
-
- The ``since`` attribute specify the API version when this function was modified.
-
- The ``allow-thread`` attribute specifies whether a function should be wrapped
- into ``Py_BEGIN_ALLOW_THREADS`` and ``Py_END_ALLOW_THREADS``, that is,
- temporarily release the GIL (global interpreter lock). Doing so is required
- for any thread-related function (wait operations), functions that might call
- a virtual function (potentially reimplemented in Python), and recommended for
- lengthy I/O operations or similar. It has performance costs, though.
- The value ``auto`` means that it will be turned off for functions for which
- it is deemed to be safe, for example, simple getters.
- The attribute defaults to ``false``.
-
- The ``exception-handling`` attribute specifies whether to generate exception
- handling code (nest the function call into try / catch statements). It accepts
- the following values:
-
- * no, false: Do not generate exception handling code
- * auto-off: Generate exception handling code for functions
- declaring a non-empty ``throw`` list
- * auto-on: Generate exception handling code unless function
- declares ``noexcept``
- * yes, true: Always generate exception handling code
-
- The optional ``overload-number`` attribute specifies the position of the
- overload when checking arguments. Typically, when a number of overloads
- exists, as for in example in Qt:
-
- .. code-block:: c++
-
- void QPainter::drawLine(QPointF, QPointF);
- void QPainter::drawLine(QPoint, QPoint);
-
- they will be reordered such that the check for matching arguments for the
- one taking a ``QPoint`` is done first. This is to avoid a potentially
- costly implicit conversion from ``QPoint`` to ``QPointF`` when using the
- 2nd overload. There are cases though in which this is not desired;
- most prominently when a class inherits from a container and overloads exist
- for both types as is the case for the ``QPolygon`` class:
-
- .. code-block:: c++
-
- class QPolygon : public QList<QPoint> {};
-
- void QPainter::drawPolygon(QPolygon);
- void QPainter::drawPolygon(QList<QPoint>);
-
- By default, the overload taking a ``QList`` will be checked first, trying
- to avoid constructing a ``QPolygon`` from ``QList``. The type check for a
- list of points will succeed for a parameter of type ``QPolygon``, too,
- since it inherits ``QList``. This presents a problem since the sequence
- type check is costly due to it checking that each container element is a
- ``QPoint``. It is thus preferable to check for the ``QPolygon`` overload
- first. This is achieved by specifying numbers as follows:
-
- .. code-block:: xml
-
- <object-type name="QPainter">
- <modify-function signature="drawPolygon(QPolygon)" overload-number="0"/>
- <modify-function signature="drawPolygon(QList&lt;QPoint&gt;)" overload-number="1"/>
- </object-type>
-
- Numbers should be given for all overloads; otherwise, the order will be in
- declaration order.
-
- The optional ``final`` attribute can be specified for virtual functions
- and disables generating the code for overriding the function in Python
- (native call). This is useful when the result type is not constructible.
-
- The ``remove`` attribute is an *optional* boolean attribute, which can
- mark the function to be discarded on generation.
-
- The *optional* ``rename`` attribute can be used to change the name of the
- given function in the generated target language API.
-
- The *optional* ``access`` attribute changes the access privileges of the
- given function in the generated target language API.
-
- The *optional* **snake-case** attribute allows for overriding the value
- specified on the class entry or **typesystem** element.
+The ``modify-function`` node allows you to modify a given C++ function when
+mapping it onto the target language, and it is a child of a :ref:`function`,
+:ref:`namespace`, :ref:`object-type` or a :ref:`value-type` node.
+Use the :ref:`modify-argument` node to specify which argument the
+modification affects.
+
+.. code-block:: xml
+
+ <object-type>
+ <modify-function signature="..."
+ since="..."
+ remove="true | false"
+ access="public | private | protected"
+ allow-thread="true | auto | false"
+ exception-handling="no | auto-off | auto-on | yes"
+ final="true | false"
+ overload-number="number"
+ rename="..."
+ snake-case="yes | no | both"
+ deprecated = "true | false" />
+ </object-type>
+
+The ``signature`` attribute is a normalized C++ signature, excluding return
+values but including potential const declarations. It is not required
+when ``modify-function`` appears as a child of a :ref:`function` node to
+modify a global function.
+
+The ``since`` attribute specify the API version when this function was modified.
+
+The ``allow-thread`` attribute specifies whether a function should be wrapped
+into ``Py_BEGIN_ALLOW_THREADS`` and ``Py_END_ALLOW_THREADS``, that is,
+temporarily release the GIL (global interpreter lock). Doing so is required
+for any thread-related function (wait operations), functions that might call
+a virtual function (potentially reimplemented in Python), and recommended for
+lengthy I/O operations or similar. It has performance costs, though.
+The value ``auto`` means that it will be turned off for functions for which
+it is deemed to be safe, for example, simple getters.
+The attribute defaults to ``false``.
+
+The ``exception-handling`` attribute specifies whether to generate exception
+handling code (nest the function call into try / catch statements). It accepts
+the following values:
+
+* no, false: Do not generate exception handling code
+* auto-off: Generate exception handling code for functions
+ declaring a non-empty ``throw`` list
+* auto-on: Generate exception handling code unless function
+ declares ``noexcept``
+* yes, true: Always generate exception handling code
+
+The optional ``overload-number`` attribute specifies the position of the
+overload when checking arguments. Typically, when a number of overloads
+exists, as for in example in Qt:
+
+.. code-block:: c++
+
+ void QPainter::drawLine(QPointF, QPointF);
+ void QPainter::drawLine(QPoint, QPoint);
+
+they will be reordered such that the check for matching arguments for the
+one taking a ``QPoint`` is done first. This is to avoid a potentially
+costly implicit conversion from ``QPoint`` to ``QPointF`` when using the
+2nd overload. There are cases though in which this is not desired;
+most prominently when a class inherits from a container and overloads exist
+for both types as is the case for the ``QPolygon`` class:
+
+.. code-block:: c++
+
+ class QPolygon : public QList<QPoint> {};
+
+ void QPainter::drawPolygon(QPolygon);
+ void QPainter::drawPolygon(QList<QPoint>);
+
+By default, the overload taking a ``QList`` will be checked first, trying
+to avoid constructing a ``QPolygon`` from ``QList``. The type check for a
+list of points will succeed for a parameter of type ``QPolygon``, too,
+since it inherits ``QList``. This presents a problem since the sequence
+type check is costly due to it checking that each container element is a
+``QPoint``. It is thus preferable to check for the ``QPolygon`` overload
+first. This is achieved by specifying numbers as follows:
+
+.. code-block:: xml
+
+ <object-type name="QPainter">
+ <modify-function signature="drawPolygon(QPolygon)" overload-number="0"/>
+ <modify-function signature="drawPolygon(QList&lt;QPoint&gt;)" overload-number="1"/>
+ </object-type>
+
+Numbers should be given for all overloads; otherwise, the order will be in
+declaration order.
+
+The optional ``final`` attribute can be specified for virtual functions
+and disables generating the code for overriding the function in Python
+(native call). This is useful when the result type is not constructible.
+
+The ``remove`` attribute is an *optional* boolean attribute, which can
+mark the function to be discarded on generation.
+
+The *optional* ``rename`` attribute can be used to change the name of the
+given function in the generated target language API.
+
+The *optional* ``access`` attribute changes the access privileges of the
+given function in the generated target language API.
+
+The *optional* **snake-case** attribute allows for overriding the value
+specified on the class entry or **typesystem** element.
+
+The *optional* **deprecated** attribute allows for overriding deprecation
+as detected by the C++ attribute. It works in both ways.
.. _add-function:
add-function
^^^^^^^^^^^^
- The ``add-function`` node allows you to add a given function onto the target
- language, and it is a child of an :ref:`object-type` or :ref:`value-type` nodes if the
- function is supposed to be a method, or :ref:`namespace` and :ref:`typesystem` if
- the function is supposed to be a function inside a namespace or a global function.
- It may contain :ref:`modify-argument` nodes.
+The ``add-function`` node allows you to add a given function onto the target
+language, and it is a child of an :ref:`object-type` or :ref:`value-type` nodes if the
+function is supposed to be a method, or :ref:`namespace` and :ref:`typesystem` if
+the function is supposed to be a function inside a namespace or a global function.
+It may contain :ref:`modify-argument` nodes.
- Typically when adding a function some code must be injected to provide the function
- logic. This can be done using the :ref:`inject-code` node.
+Typically when adding a function some code must be injected to provide the function
+logic. This can be done using the :ref:`inject-code` node.
- .. code-block:: xml
+.. code-block:: xml
- <object-type>
- <add-function signature="..." return-type="..."
- access="public | protected"
- static="yes | no" classmethod="yes | no"
- since="..."/>
- </object-type>
+ <object-type>
+ <add-function signature="..." return-type="..."
+ access="public | protected"
+ overload-number="number"
+ static="yes | no" classmethod="yes | no"
+ python-override ="yes | no"
+ since="..."/>
+ </object-type>
- The ``return-type`` attribute defaults to *void*, the ``access`` to *public* and the ``static`` one to *no*.
+The ``return-type`` attribute defaults to *void*, the ``access`` to *public* and the ``static`` one to *no*.
- The ``since`` attribute specifies the API version when this function was added.
+The ``since`` attribute specifies the API version when this function was added.
- The ``classmethod`` attribute specifies whether the function should be a Python class method.
- It sets the METH_CLASS flag which means that ``PyTypeObject`` instead of an instance
- ``PyObject`` is passed as self, which needs to be handled in injected code.
+The ``classmethod`` attribute specifies whether the function should be a Python class method.
+It sets the METH_CLASS flag which means that ``PyTypeObject`` instead of an instance
+``PyObject`` is passed as self, which needs to be handled in injected code.
- Note that the label "static" in Qt's class documentation almost always means that a Python
- ``classmethod`` should be generated, because an object's class is always accessible from the
- static C++ code, while Python needs the explicit "self" parameter that ``classmethod``
- provides.
+For the *optional* attribute ``overload-number``, see :ref:`modify-function`.
- In order to create keyword argument supporting function parameters, enclose the specific
- function parameter with a *@* in the `signature` field.
+Note that the label "static" in Qt's class documentation almost always means that a Python
+``classmethod`` should be generated, because an object's class is always accessible from the
+static C++ code, while Python needs the explicit "self" parameter that ``classmethod``
+provides.
- .. code-block:: xml
+In order to create keyword argument supporting function parameters, enclose the specific
+function parameter with a *@* in the `signature` field.
- <add-function signature="foo(int @parameter1@,float @parameter2@)">
- ...
- </add-function>
+.. code-block:: xml
- With keyword arguments, ``add-function`` makes it easy to specify a default argument
- within the `signature` field
+ <add-function signature="foo(int @parameter1@,float @parameter2@)">
+ ...
+ </add-function>
- .. code-block:: xml
+With keyword arguments, ``add-function`` makes it easy to specify a default argument
+within the `signature` field
- <add-function signature="foo(int @parameter1@=1,float @parameter2@=2)">
- ...
- </add-function>
+.. code-block:: xml
+
+ <add-function signature="foo(int @parameter1@=1,float @parameter2@=2)">
+ ...
+ </add-function>
+
+See :ref:`sequence-protocol` for adding the respective functions.
- See :ref:`sequence-protocol` for adding the respective functions.
+The *optional* attribute ``python-override`` indicates a special type
+of added function, a python-override that will be generated into
+the native wrapper (see :ref:`modifying-virtual-functions`).
.. _declare-function:
declare-function
^^^^^^^^^^^^^^^^
- The ``declare-function`` node allows you to declare a function present in
- the type and it is a child of an :ref:`object-type` or :ref:`value-type` nodes
- if the function is supposed to be a method, or :ref:`namespace` and
- :ref:`typesystem` if the function is supposed to be a function inside a
- namespace or a global function. It may contain :ref:`modify-argument` nodes.
+The ``declare-function`` node allows you to declare a function present in
+the type and it is a child of an :ref:`object-type` or :ref:`value-type` nodes
+if the function is supposed to be a method, or :ref:`namespace` and
+:ref:`typesystem` if the function is supposed to be a function inside a
+namespace or a global function. It may contain :ref:`modify-argument` nodes.
- .. code-block:: xml
+.. code-block:: xml
+
+ <container-type>
+ <declare-function signature="..." return-type="..." since="..."
+ allow-thread="true | auto | false"
+ exception-handling="off | auto-off | auto-on | on"
+ overload-number="number"
+ snake-case="yes | no | both"/>
+ </container-type>
- <container-type>
- <declare-function signature="..." return-type="..." since="..."/>
- </container-type>
+The ``return-type`` attribute defaults to *void*.
- The ``return-type`` attribute defaults to *void*.
+The ``since`` attribute specifies the API version when this function was
+added.
- The ``since`` attribute specifies the API version when this function was
- added.
+For the *optional* attributes ``allow-thread``, ``exception-handling``,
+``overload-number`` and ``snake-case``, see :ref:`modify-function`.
- This is useful to make functions known to shiboken which its code parser
- does not detect. For example, in Qt 6, the ``append()`` function of the
- ``QList<T>`` container takes an argument of ``parameter_type`` which is
- specialized to ``T`` for simple types and ``const T &`` for complex types
- by some template expression which the code parser cannot resolve.
- In that case, the function can be declared with a simple signature:
+This is useful to make functions known to shiboken which its code parser
+does not detect. For example, in Qt 6, the ``append()`` function of the
+``QList<T>`` container takes an argument of ``parameter_type`` which is
+specialized to ``T`` for simple types and ``const T &`` for complex types
+by some template expression which the code parser cannot resolve.
+In that case, the function can be declared with a simple signature:
- .. code-block:: xml
+.. code-block:: xml
- <container-type name="QList">
- <declare-function signature="append(T)"/>
- </container-type>
+ <container-type name="QList">
+ <declare-function signature="append(T)"/>
+ </container-type>
- This tells shiboken a public function of that signature exists and
- bindings will be created in specializations of ``QList``.
+This tells shiboken a public function of that signature exists and
+bindings will be created in specializations of ``QList``.
.. _add-pymethoddef:
@@ -388,75 +407,150 @@ of signatures of the function.
property
^^^^^^^^
- The ``property`` element allows you to specify properties consisting of
- a type and getter and setter functions.
+The ``property`` element allows you to specify properties consisting of
+a type and getter and setter functions.
- It may appear as a child of a complex type such as :ref:`object-type` or
- :ref:`value-type`.
+It may appear as a child of a complex type such as :ref:`object-type` or
+:ref:`value-type`.
- If the PySide6 extension is not present, code will be generated using the
- ``PyGetSetDef`` struct, similar to what is generated for fields.
+If the PySide6 extension is not present, code will be generated using the
+``PyGetSetDef`` struct, similar to what is generated for fields.
- If the PySide6 extension is present, those properties complement the
- properties obtained from the ``Q_PROPERTY`` macro in Qt-based code.
- The properties will be handled in ``libpyside`` unless code generation
- is forced.
+If the PySide6 extension is present, those properties complement the
+properties obtained from the ``Q_PROPERTY`` macro in Qt-based code.
+The properties will be handled in ``libpyside`` unless code generation
+is forced.
- .. code-block:: xml
+.. code-block:: xml
+
+ <property name="..." type="..." get="..." set="..."
+ generate-getsetdef="yes | no" since="..."/>
+
+The ``name`` attribute specifies the name of the property, the ``type``
+attribute specifies the C++ type and the ``get`` attribute specifies the
+name of the accessor function.
+
+The optional ``set`` attribute specifies name of the setter function.
+
+The optional ``generate-getsetdef`` attribute specifies whether to generate
+code for if the PySide6 extension is present (indicating this property is not
+handled by libpyside). It defaults to *no*.
+
+The optional ``since`` attribute specifies the API version when this
+property appears.
+
+For a typical C++ class, like:
+
+.. code-block:: c++
+
+ class Test {
+ public:
+ int getValue() const;
+ void setValue();
+ };
+
+``value`` can then be specified to be a property:
+
+.. code-block:: xml
+
+ <value-type name="Test">
+ <property name="value" type="int" get="getValue" set="setValue"/>
+
+With that, a more pythonic style can be used:
+
+.. code-block:: python
- <property name="..." type="..." get="..." set="..."
- generate-getsetdef="yes | no" since="..."/>
+ test = Test()
+ test.value = 42
- The ``name`` attribute specifies the name of the property, the ``type``
- attribute specifies the C++ type and the ``get`` attribute specifies the
- name of the accessor function.
+For Qt classes (with the PySide6 extension present), additional setters
+and getters that do not appear as ``Q_PROPERTY``, can be specified to
+be properties:
- The optional ``set`` attribute specifies name of the setter function.
+.. code-block:: xml
+
+ <object-type name="QMainWindow">
+ <property name="centralWidget" type="QWidget *"
+ get="centralWidget" set="setCentralWidget"/>
+
+in addition to the normal properties of ``QMainWindow`` defined for
+Qt Designer usage.
+
+.. note:: In the *Qt* coding style, the property name typically conflicts
+ with the getter name. It is recommended to exclude the getter from the
+ wrapper generation using the ``remove`` function modification.
- The optional ``generate-getsetdef`` attribute specifies whether to generate
- code for if the PySide6 extension is present (indicating this property is not
- handled by libpyside). It defaults to *no*.
+.. _configuration-element:
- The optional ``since`` attribute specifies the API version when this
- property appears.
+configuration
+^^^^^^^^^^^^^
+
+The ``configuration`` element allows you to generate a preprocessor
+condition excluding a type depending on an expression into the module
+header. This is specifically tailored to the
+`Qt Feature system <https://doc.qt.io/qt-6/configure-options.html>`_ ,
+but may also be used for similar systems.
+
+It may appear as a child of a complex type such as :ref:`object-type` or
+:ref:`value-type`.
+
+.. code-block:: xml
- For a typical C++ class, like:
+ <configuration condition="..."/>
- .. code-block:: c++
+The ``condition`` attribute specifies the preprocessor condition.
- class Test {
- public:
- int getValue() const;
- void setValue();
- };
+This is an alternative way of omitting classes depending on some
+configuration (see also option :ref:`drop-type-entries`) intended
+for building several configurations from one generated source tree,
+but still requires listing the correct source files in the
+``CMakeLists.txt`` file.
- ``value`` can then be specified to be a property:
+.. _modifying-virtual-functions:
- .. code-block:: xml
+Modifying virtual functions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
- <value-type name="Test">
- <property name="value" type="int" get="getValue" set="setValue"/>
+Some C++ virtual functions are unsuitable for Python bindings:
- With that, a more pythonic style can be used:
+.. code-block:: c
- .. code-block:: python
+ virtual void getInt(int *result) const;
- test = Test()
- test.value = 42
+In that case, you would modify it to return the integer instead (or a tuple
+in case of several out-parameters):
- For Qt classes (with the PySide6 extension present), additional setters
- and getters that do not appear as ``Q_PROPERTY``, can be specified to
- be properties:
+.. code-block:: c
- .. code-block:: xml
+ virtual int getInt() const;
- <object-type name="QMainWindow">
- <property name="centralWidget" type="QWidget *"
- get="centralWidget" set="setCentralWidget"/>
+For the binding itself, use the common argument modifications (removing
+arguments, modifying return types with injected code snippets) to modify the
+signature.
- in addition to the normal properties of ``QMainWindow`` defined for
- Qt Designer usage.
+To make it possible to reimplement the function in Python with the modified
+signature, add a ``python-override`` function with that signature, using an
+arbitrary name for disambiguation:
+
+.. code-block:: xml
+
+ <add-function signature="getIntPyOverride()"
+ return-type="int" python-override="true"/>
+
+This causes a static function performing the call into Python for the override
+to be generated into the native wrapper.
+
+In the existing virtual function, inject a code snippet at the ``shell`` /
+``override`` position which calls the newly added function. The first 2
+arguments are the `Global interpreter lock handle` (``Shiboken::GilState``) and
+the Python method determined by the override check (``PyObject *``). The
+snippet then converts the arguments and return values and returns after that:
+
+.. code-block:: xml
- .. note:: In the *Qt* coding style, the property name typically conflicts
- with the getter name. It is recommended to exclude the getter from the
- wrapper generation using the ``remove`` function modification.
+ <modify-function signature="getInt(int*)const">
+ <inject-code class="shell" position="override">
+ *result = getIntPyOverride(gil, pyOverride.object());
+ return;
+ </inject-code>
+ </modify-function>
diff --git a/sources/shiboken6/doc/typesystem_modify_function.rst b/sources/shiboken6/doc/typesystem_modify_function.rst
index 1e882f9c7..54ac6412f 100644
--- a/sources/shiboken6/doc/typesystem_modify_function.rst
+++ b/sources/shiboken6/doc/typesystem_modify_function.rst
@@ -8,37 +8,37 @@ Modifying Functions
modify-argument
^^^^^^^^^^^^^^^
- Function modifications consist of a list of ``modify-argument`` nodes
- contained in :ref:`modify-function`, :ref:`add-function` or
- :ref:`declare-function` nodes. Use the :ref:`remove-argument`,
- :ref:`replace-default-expression`, :ref:`remove-default-expression`,
- :ref:`replace-type`, :ref:`reference-count` and :ref:`define-ownership`
- nodes to specify the details of the modification.
-
- .. code-block:: xml
-
- <modify-function>
- <modify-argument index="return | this | 1 ..." rename="..."
- invalidate-after-use = "true | false" pyi-type="...">
- // modifications
- </modify-argument>
- </modify-function>
-
- Set the ``index`` attribute to "1" for the first argument, "2" for the second
- one and so on. Alternatively, set it to "return" or "this" if you want to
- modify the function's return value or the object the function is called upon,
- respectively.
-
- The optional ``rename`` attribute is used to rename a argument and use this
- new name in the generated code. This attribute can be used to enable the usage
- of ``keyword arguments``.
-
- The optional ``pyi-type`` attribute specifies the type to appear in the
- signature strings and ``.pyi`` files. The type string is determined by
- checking this attribute value, the :ref:`replace-type` modification and
- the C++ type. The attribute can be used for example to enclose
- a pointer return value within ``Optional[]`` to indicate that ``None``
- can occur.
-
- For the optional ``invalidate-after-use`` attribute,
- see :ref:`invalidationafteruse` .
+Function modifications consist of a list of ``modify-argument`` nodes
+contained in :ref:`modify-function`, :ref:`add-function` or
+:ref:`declare-function` nodes. Use the :ref:`remove-argument`,
+:ref:`replace-default-expression`, :ref:`remove-default-expression`,
+:ref:`replace-type`, :ref:`reference-count` and :ref:`define-ownership`
+nodes to specify the details of the modification.
+
+.. code-block:: xml
+
+ <modify-function>
+ <modify-argument index="return | this | 1 ..." rename="..."
+ invalidate-after-use = "true | false" pyi-type="...">
+ // modifications
+ </modify-argument>
+ </modify-function>
+
+Set the ``index`` attribute to "1" for the first argument, "2" for the second
+one and so on. Alternatively, set it to "return" or "this" if you want to
+modify the function's return value or the object the function is called upon,
+respectively.
+
+The optional ``rename`` attribute is used to rename a argument and use this
+new name in the generated code. This attribute can be used to enable the usage
+of ``keyword arguments``.
+
+The optional ``pyi-type`` attribute specifies the type to appear in the
+signature strings and ``.pyi`` files. The type string is determined by
+checking this attribute value, the :ref:`replace-type` modification and
+the C++ type. The attribute can be used for example to enclose
+a pointer return value within ``Optional[]`` to indicate that ``None``
+can occur.
+
+For the optional ``invalidate-after-use`` attribute,
+see :ref:`invalidationafteruse` .
diff --git a/sources/shiboken6/doc/typesystem_ownership.rst b/sources/shiboken6/doc/typesystem_ownership.rst
index f412fc609..a5440e49e 100644
--- a/sources/shiboken6/doc/typesystem_ownership.rst
+++ b/sources/shiboken6/doc/typesystem_ownership.rst
@@ -58,39 +58,39 @@ The following situations can invalidate an object:
C++ taking ownership
--------------------
- When an object is passed to a function or method that takes ownership of it, the wrapper
- is invalidated as we can't be sure of when the object is destroyed, unless it has a
- :ref:`virtual destructor <ownership-virt-method>` or the transfer is due to the special case
- of :ref:`parent ownership <ownership-parent>`.
+When an object is passed to a function or method that takes ownership of it, the wrapper
+is invalidated as we can't be sure of when the object is destroyed, unless it has a
+:ref:`virtual destructor <ownership-virt-method>` or the transfer is due to the special case
+of :ref:`parent ownership <ownership-parent>`.
- Besides being passed as argument, the called object can have its ownership changed, like
- the `setParent` method in Qt's `QObject`.
+Besides being passed as argument, the called object can have its ownership changed, like
+the `setParent` method in Qt's `QObject`.
Invalidate after use
--------------------
- Objects marked with *invalidate-after-use* in the type system description always are
- virtual method arguments provided by a C++ originated call. They should be
- invalidated right after the Python function returns (see :ref:`invalidationafteruse`).
+Objects marked with *invalidate-after-use* in the type system description always are
+virtual method arguments provided by a C++ originated call. They should be
+invalidated right after the Python function returns (see :ref:`invalidationafteruse`).
.. _ownership-virt-method:
Objects with virtual methods
----------------------------
- A little bit of implementation details (see also :ref:`codegenerationterminology`):
- virtual methods are supported by creating a C++ class, the **shell**, that inherits
- from the class with virtual methods, the native one, and override those methods to check if
- any derived class in Python also override it.
+A little bit of implementation details (see also :ref:`codegenerationterminology`):
+virtual methods are supported by creating a C++ class, the **shell**, that inherits
+from the class with virtual methods, the native one, and override those methods to check if
+any derived class in Python also override it.
- If the class has a virtual destructor (and C++ classes with virtual methods should have), this
- C++ instance invalidates the wrapper only when the overridden destructor is called.
+If the class has a virtual destructor (and C++ classes with virtual methods should have), this
+C++ instance invalidates the wrapper only when the overridden destructor is called.
- An instance of the **shell** is created when created in Python. However,
- when the object is created in C++, like in a factory method or a parameter
- to a virtual function like ``QObject::event(QEvent *)``, the wrapped object
- is a C++ instance of the native class, not the **shell** one, and we cannot
- know when it is destroyed.
+An instance of the **shell** is created when created in Python. However,
+when the object is created in C++, like in a factory method or a parameter
+to a virtual function like ``QObject::event(QEvent *)``, the wrapped object
+is a C++ instance of the native class, not the **shell** one, and we cannot
+know when it is destroyed.
.. _ownership-parent:
@@ -108,45 +108,45 @@ for any C++ library with similar behavior.
Parentship heuristics
---------------------
- As the parent-child relationship is very common, |project| tries to automatically
- infer what methods falls into the parent-child scheme, adding the extra
- directives related to ownership.
+As the parent-child relationship is very common, |project| tries to automatically
+infer what methods falls into the parent-child scheme, adding the extra
+directives related to ownership.
- This heuristic will be triggered when generating code for a method and:
+This heuristic will be triggered when generating code for a method and:
- * The function is a constructor.
- * The argument name is `parent`.
- * The argument type is a pointer to an object.
+* The function is a constructor.
+* The argument name is `parent`.
+* The argument type is a pointer to an object.
- When triggered, the heuristic will set the argument named "parent"
- as the parent of the object being created by the constructor.
+When triggered, the heuristic will set the argument named "parent"
+as the parent of the object being created by the constructor.
- The main focus of this process was to remove a lot of hand written code from
- type system when binding Qt libraries. For Qt, this heuristic works in all cases,
- but be aware that it might not when binding your own libraries.
+The main focus of this process was to remove a lot of hand written code from
+type system when binding Qt libraries. For Qt, this heuristic works in all cases,
+but be aware that it might not when binding your own libraries.
- To activate this heuristic, use the :ref:`--enable-parent-ctor-heuristic <parent-heuristic>`
- command line switch.
+To activate this heuristic, use the :ref:`--enable-parent-ctor-heuristic <parent-heuristic>`
+command line switch.
.. _return-value-heuristics:
Return value heuristics
-----------------------
- When enabled, object returned as pointer in C++ will become child of the object on which the method
- was called.
+When enabled, object returned as pointer in C++ will become child of the object on which the method
+was called.
- To activate this heuristic, use the command line switch
- :ref:`--enable-return-value-heuristic <return-heuristic>`.
+To activate this heuristic, use the command line switch
+:ref:`--enable-return-value-heuristic <return-heuristic>`.
- To disable this heuristic for specific cases, specify ``default`` as
- ownership:
+To disable this heuristic for specific cases, specify ``default`` as
+ownership:
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument index="0">
- <define-ownership class="target" owner="default" />
- </modify-argument>
+ <modify-argument index="0">
+ <define-ownership class="target" owner="default" />
+ </modify-argument>
Common pitfalls
===============
@@ -154,32 +154,32 @@ Common pitfalls
Not saving unowned objects references
-------------------------------------
- Sometimes when you pass an instance as argument to a method and the receiving
- instance will need that object to live indefinitely, but will not take ownership
- of the argument instance. In this case, you should hold a reference to the argument
- instance.
+Sometimes when you pass an instance as argument to a method and the receiving
+instance will need that object to live indefinitely, but will not take ownership
+of the argument instance. In this case, you should hold a reference to the argument
+instance.
- For example, let's say that you have a renderer class that will use a source class
- in a setSource method but will not take ownership of it. The following code is wrong,
- because when `render` is called the `Source` object created during the call to `setSource`
- is already destroyed.
+For example, let's say that you have a renderer class that will use a source class
+in a setSource method but will not take ownership of it. The following code is wrong,
+because when `render` is called the `Source` object created during the call to `setSource`
+is already destroyed.
- .. code-block:: python
+.. code-block:: python
- renderer.setModel(Source())
- renderer.render()
+ renderer.setModel(Source())
+ renderer.render()
- To solve this, you should hold a reference to the source object, like in
+To solve this, you should hold a reference to the source object, like in
- .. code-block:: python
+.. code-block:: python
- source = Source()
- renderer.setSource(source)
- renderer.render()
+ source = Source()
+ renderer.setSource(source)
+ renderer.render()
-Ownership Management in the Typesystem
-=======================================
+Ownership Management in the Typesystem
+======================================
Python Wrapper Code
-------------------
@@ -190,44 +190,44 @@ For this code, the ``class`` attribute takes the value ``target``
Ownership transfer from C++ to target
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- When an object currently owned by C++ has its ownership transferred
- back to the target language, the binding can know for sure when the object will be deleted and
- tie the C++ instance existence to the wrapper, calling the C++ destructor normally when the
- wrapper is deleted.
+When an object currently owned by C++ has its ownership transferred
+back to the target language, the binding can know for sure when the object will be deleted and
+tie the C++ instance existence to the wrapper, calling the C++ destructor normally when the
+wrapper is deleted.
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument index="1">
- <define-ownership class="target" owner="target" />
- </modify-argument>
+ <modify-argument index="1">
+ <define-ownership class="target" owner="target" />
+ </modify-argument>
- A typical use case would be returning an object allocated in C++, for
- example from ``clone()`` or other factory methods.
+A typical use case would be returning an object allocated in C++, for
+example from ``clone()`` or other factory methods.
Ownership transfer from target to C++
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- In the opposite direction, when an object ownership is transferred from the target language
- to C++, the native code takes full control of the object life and you don't
- know when that object will be deleted, rendering the wrapper object invalid,
- unless you're wrapping an object with a virtual destructor,
- so you can override it and be notified of its destruction.
+In the opposite direction, when an object ownership is transferred from the target language
+to C++, the native code takes full control of the object life and you don't
+know when that object will be deleted, rendering the wrapper object invalid,
+unless you're wrapping an object with a virtual destructor,
+so you can override it and be notified of its destruction.
- By default it's safer to just render the wrapper
- object invalid and raise some error if the user tries to access
- one of this objects members or pass it as argument to some function, to avoid unpleasant segfaults.
- Also you should avoid calling the C++ destructor when deleting the wrapper.
+By default it's safer to just render the wrapper
+object invalid and raise some error if the user tries to access
+one of this objects members or pass it as argument to some function, to avoid unpleasant segfaults.
+Also you should avoid calling the C++ destructor when deleting the wrapper.
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument index="1">
- <define-ownership class="target" owner="c++" />
- </modify-argument>
+ <modify-argument index="1">
+ <define-ownership class="target" owner="c++" />
+ </modify-argument>
- Use cases would be an returning a member object by pointer
- or passing an object by pointer into a function where the class
- takes ownership, for example
- ``QNetworkAccessManager::setCookieJar(QNetworkCookieJar *)``.
+Use cases would be an returning a member object by pointer
+or passing an object by pointer into a function where the class
+takes ownership, for example
+``QNetworkAccessManager::setCookieJar(QNetworkCookieJar *)``.
Parent-child relationship
^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -240,11 +240,11 @@ as long as the parent is, unless some other method can take the C++ ownership aw
One of the main uses of this scheme is Qt's object system, with ownership among QObject-derived
classes, creating "trees" of instances.
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument index="this">
- <parent index="1" action="add"/>
- </modify-argument>
+ <modify-argument index="this">
+ <parent index="1" action="add"/>
+ </modify-argument>
In this example, the instance with the method that is being invoked (indicated by 'index="this"' on
modify-argument) will be marked as a child
@@ -284,8 +284,8 @@ In this case, you should use the ``invalidate-after-use`` attribute in the
:ref:`modify-argument` tag to mark the wrapper as invalid right after the
virtual method returns.
- .. code-block:: xml
+.. code-block:: xml
- <modify-argument index="2" invalidate-after-use="yes"/>
+ <modify-argument index="2" invalidate-after-use="yes"/>
In this example the second argument will be invalidated after this method call.
diff --git a/sources/shiboken6/doc/typesystem_solving_compilation.rst b/sources/shiboken6/doc/typesystem_solving_compilation.rst
index 37771396b..705c2cd26 100644
--- a/sources/shiboken6/doc/typesystem_solving_compilation.rst
+++ b/sources/shiboken6/doc/typesystem_solving_compilation.rst
@@ -6,75 +6,75 @@ Solving compilation problems
suppress-warning
^^^^^^^^^^^^^^^^
- The generator will generate several warnings which may be irrelevant to the
- user. The ``suppress-warning`` node suppresses the specified warning, and it is
- a child of the :ref:`typesystem` node.
+The generator will generate several warnings which may be irrelevant to the
+user. The ``suppress-warning`` node suppresses the specified warning, and it is
+a child of the :ref:`typesystem` node.
- .. code-block:: xml
+.. code-block:: xml
- <typesystem>
- <suppress-warning text="..." />
- </typesystem>
+ <typesystem>
+ <suppress-warning text="..." />
+ </typesystem>
- The **text** attribute is the warning text to suppress, and may contain the *
- wildcard (use "" to escape regular expression matching if the warning contain
- a regular "*").
+The **text** attribute is the warning text to suppress, and may contain the *
+wildcard (use "" to escape regular expression matching if the warning contain
+a regular "*").
.. _extra-includes:
extra-includes
^^^^^^^^^^^^^^
- The ``extra-includes`` node contains declarations of additional include files,
- and it can be a child of the :ref:`namespace`, :ref:`value-type`,
- :ref:`object-type` and :ref:`typesystem` and nodes.
+The ``extra-includes`` node contains declarations of additional include files,
+and it can be a child of the :ref:`namespace`, :ref:`value-type`,
+:ref:`object-type` and :ref:`typesystem` and nodes.
- The generator automatically tries to read the global header for each type but
- sometimes it is required to include extra files in the generated C++ code to
- make sure that the code compiles. These files must be listed using include
- nodes within the extra-include node:
+The generator automatically tries to read the global header for each type but
+sometimes it is required to include extra files in the generated C++ code to
+make sure that the code compiles. These files must be listed using include
+nodes within the extra-include node:
- .. code-block:: xml
+.. code-block:: xml
- <value-type>
- <extra-includes>
- <include file-name="..." location="global | local"/>
- </extra-includes>
- </value-type>
+ <value-type>
+ <extra-includes>
+ <include file-name="..." location="global | local"/>
+ </extra-includes>
+ </value-type>
- The **file-name** attribute is the file to include, such as "QStringList".
- The **location** attribute is where the file is located: *global* means that
- the file is located in $INCLUDEPATH and will be included using #include <...>,
- *local* means that the file is in a local directory and will be included
- using #include "...".
+The **file-name** attribute is the file to include, such as "QStringList".
+The **location** attribute is where the file is located: *global* means that
+the file is located in $INCLUDEPATH and will be included using #include <...>,
+*local* means that the file is in a local directory and will be included
+using #include "...".
- When specified as a child of the :ref:`typesystem` node, the include
- directives are added to the module source file which contains
- the type converter and registration code. It can be used to specify
- additional includes required for the converter code snippets.
+When specified as a child of the :ref:`typesystem` node, the include
+directives are added to the module source file which contains
+the type converter and registration code. It can be used to specify
+additional includes required for the converter code snippets.
.. _include-element:
include
^^^^^^^
- The ``include`` node specifies the name and location of a file that must be
- included, and it is a child of the :ref:`namespace`, :ref:`value-type`,
- :ref:`object-type` or :ref:`extra-includes` node.
+The ``include`` node specifies the name and location of a file that must be
+included, and it is a child of the :ref:`namespace`, :ref:`value-type`,
+:ref:`object-type` or :ref:`extra-includes` node.
- The generator automatically tries to read the global header for each type. Use
- the include node to override this behavior, providing an alternative file. The
- include node can also be used to specify extra include files.
+The generator automatically tries to read the global header for each type. Use
+the include node to override this behavior, providing an alternative file. The
+include node can also be used to specify extra include files.
- .. code-block:: xml
+.. code-block:: xml
- <value-type>
- <include file-name="..."
- location="global | local"/>
- </value-type>
+ <value-type>
+ <include file-name="..."
+ location="global | local"/>
+ </value-type>
- The **file-name** attribute is the file to include, such as "QStringList".
- The **location** attribute is where the file is located: *global* means that
- the file is located in $INCLUDEPATH and will be included using #include <...>,
- *local* means that the file is in a local directory and will be included
- using #include "...".
+The **file-name** attribute is the file to include, such as "QStringList".
+The **location** attribute is where the file is located: *global* means that
+the file is located in $INCLUDEPATH and will be included using #include <...>,
+*local* means that the file is in a local directory and will be included
+using #include "...".
diff --git a/sources/shiboken6/doc/typesystem_specialfunctions.rst b/sources/shiboken6/doc/typesystem_specialfunctions.rst
index 5c0c52663..78a6ff489 100644
--- a/sources/shiboken6/doc/typesystem_specialfunctions.rst
+++ b/sources/shiboken6/doc/typesystem_specialfunctions.rst
@@ -13,15 +13,15 @@ names, this is done using the :ref:`add-function` tag.
The special function names are:
- ============= =============================================== ==================== ===================
- Function name Parameters Return type CPython equivalent
- ============= =============================================== ==================== ===================
- __len__ PyObject* self Py_ssize_t PySequence_Size
- __getitem__ PyObject* self, Py_ssize_t _i PyObject* PySequence_GetItem
- __setitem__ PyObject* self, Py_ssize_t _i, PyObject* _value int PySequence_SetItem
- __contains__ PyObject* self, PyObject* _value int PySequence_Contains
- __concat__ PyObject* self, PyObject* _other PyObject* PySequence_Concat
- ============= =============================================== ==================== ===================
+============= =============================================== ==================== ===================
+Function name Parameters Return type CPython equivalent
+============= =============================================== ==================== ===================
+__len__ PyObject* self Py_ssize_t PySequence_Size
+__getitem__ PyObject* self, Py_ssize_t _i PyObject* PySequence_GetItem
+__setitem__ PyObject* self, Py_ssize_t _i, PyObject* _value int PySequence_SetItem
+__contains__ PyObject* self, PyObject* _value int PySequence_Contains
+__concat__ PyObject* self, PyObject* _other PyObject* PySequence_Concat
+============= =============================================== ==================== ===================
You just need to inform the function name to the :ref:`add-function` tag, without any
parameter or return type information, when you do it, |project| will create a C
@@ -47,8 +47,8 @@ in boolean expressions. In C++, this is commonly implemented as
In Python, the function ``__bool__`` is used for this. shiboken can generate
this functions depending on the command line options
-:ref:`--use-operator-bool-as-nb_nonzero <use-operator-bool-as-nb-nonzero>`
-and :ref:`--use-isnull-as-nb_nonzero <use-isnull-as-nb-nonzero>`,
+:ref:`--use-operator-bool-as-nb-bool <use-operator-bool-as-nb-bool>`
+and :ref:`--use-isnull-as-nb-bool <use-isnull-as-nb-bool>`,
which can be overridden by specifying the boolean attributes
**isNull** or **operator-bool** on the :ref:`value-type` or :ref:`object-type`
elements in typesystem XML.
diff --git a/sources/shiboken6/doc/typesystem_specifying_types.rst b/sources/shiboken6/doc/typesystem_specifying_types.rst
index f7409f3b3..f65b79bb4 100644
--- a/sources/shiboken6/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken6/doc/typesystem_specifying_types.rst
@@ -30,770 +30,835 @@ of the underlying parser.
typesystem
^^^^^^^^^^
- This is the root node containing all the type system information.
- It may contain :ref:`add-function`, :ref:`container-type`,
- :ref:`custom-type`, :ref:`enum-type`, :ref:`extra-includes`, :ref:`function`,
- :ref:`load-typesystem`, :ref:`namespace`, :ref:`object-type`,
- :ref:`primitive-type`, :ref:`rejection`, :ref:`smart-pointer-type`,
- :ref:`suppress-warning`, :ref:`template`, :ref:`system_include`,
- :ref:`typedef-type` or :ref:`value-type` child nodes.
+This is the root node containing all the type system information.
+It may contain :ref:`add-function`, :ref:`container-type`,
+:ref:`custom-type`, :ref:`enum-type`, :ref:`extra-includes`, :ref:`function`,
+:ref:`load-typesystem`, :ref:`namespace`, :ref:`object-type`,
+:ref:`opaque-container`,
+:ref:`primitive-type`, :ref:`rejection`, :ref:`smart-pointer-type`,
+:ref:`suppress-warning`, :ref:`template`, :ref:`system_include`,
+:ref:`typedef-type` or :ref:`value-type` child nodes.
- It can have a number of attributes, described below.
+It can have a number of attributes, described below.
- .. code-block:: xml
+.. code-block:: xml
- <typesystem package="..." default-superclass="..." allow-thread="..."
- exception-handling="..." snake-case="yes | no | both" >
- </typesystem>
+ <typesystem package="..."
+ submodule-of="..."
+ allow-thread="..."
+ exception-handling="..."
+ snake-case="yes | no | both"
+ namespace-begin="..."
+ namespace-end="..." >
+ </typesystem>
+
+The **package** attribute is a string describing the package to be used,
+e.g. "QtCore".
- The **package** attribute is a string describing the package to be used,
- e.g. "QtCore".
- The *optional* **default-superclass** attribute is the canonical C++ base class
- name of all objects, e.g., "object".
+The *optional* **submodule-of** attribute specifies the name of a module to
+which the module is added as a sub-module. This requires adapting the
+installation directory of the module accordingly.
- The *optional* attributes **allow-thread** and **exception-handling**
- specify the default handling for the corresponding function modification
- (see :ref:`modify-function`).
+The *optional* attributes **allow-thread** and **exception-handling**
+specify the default handling for the corresponding function modification
+(see :ref:`modify-function`).
- The *optional* **snake-case** attribute specifies whether function
- and field names will be automatically changed to the snake case
- style that is common in Python (for example, ``snakeCase`` will be
- changed to ``snake_case``).
+The *optional* **snake-case** attribute specifies whether function
+and field names will be automatically changed to the snake case
+style that is common in Python (for example, ``snakeCase`` will be
+changed to ``snake_case``).
- The value ``both`` means that the function or field will be exposed
- under both its original name and the snake case version. There are
- limitations to this though:
+The value ``both`` means that the function or field will be exposed
+under both its original name and the snake case version. There are
+limitations to this though:
- - When overriding a virtual function of a C++ class in Python,
- the snake case name must be used.
+- When overriding a virtual function of a C++ class in Python,
+ the snake case name must be used.
- - When static and non-static overloads of a class member function
- exist (as is the case for example for ``QFileInfo::exists()``),
- the snake case name must be used.
+- When static and non-static overloads of a class member function
+ exist (as is the case for example for ``QFileInfo::exists()``),
+ the snake case name must be used.
+
+The *optional* **namespace-begin** and **namespace-end** attributes will be
+generated around the forward declarations in the module header. This is
+intended for libraries which can optionally use inline namespaces
+to allow for linking several versions of them together.
+For example, for *Qt*, one would specify ``QT_BEGIN_NAMESPACE``,
+``QT_END_NAMESPACE``, respectively.
.. _load-typesystem:
load-typesystem
^^^^^^^^^^^^^^^
- The ``load-typesystem`` node specifies which type systems to load when mapping
- multiple libraries to another language or basing one library on another, and
- it is a child of the :ref:`typesystem` node.
+The ``load-typesystem`` node specifies which type systems to load when mapping
+multiple libraries to another language or basing one library on another, and
+it is a child of the :ref:`typesystem` node.
- .. code-block:: xml
+.. code-block:: xml
- <typesystem>
- <load-typesystem name="..." generate="yes | no" />
- </typesystem>
+ <typesystem>
+ <load-typesystem name="..." generate="yes | no" />
+ </typesystem>
- The **name** attribute is the filename of the typesystem to load, the
- **generate** attribute specifies whether code should be generated or not. The
- later must be specified when basing one library on another, making the generator
- able to understand inheritance hierarchies, primitive mapping, parameter types
- in functions, etc.
+The **name** attribute is the filename of the typesystem to load, the
+**generate** attribute specifies whether code should be generated or not. The
+later must be specified when basing one library on another, making the generator
+able to understand inheritance hierarchies, primitive mapping, parameter types
+in functions, etc.
- Most libraries will be based on both the QtCore and QtGui modules, in which
- case code generation for these libraries will be disabled.
+Most libraries will be based on both the QtCore and QtGui modules, in which
+case code generation for these libraries will be disabled.
.. _rejection:
rejection
^^^^^^^^^
- The ``rejection`` node rejects the given class, or the specified function
- or field, and it is a child of the :ref:`typesystem` node.
+The ``rejection`` node rejects the given class, or the specified function
+or field, and it is a child of the :ref:`typesystem` node.
- .. code-block:: xml
+.. code-block:: xml
- <typesystem>
- <rejection class="..."
- function-name="..."
- argument-type="..."
- field-name="..." />
- </typesystem>
+ <typesystem>
+ <rejection class="..."
+ function-name="..."
+ argument-type="..."
+ field-name="..." />
+ </typesystem>
- The **class** attribute is the C++ class name of the class to reject. Use
- the *optional* **function-name**, **argument-type**, or **field-name**
- attributes to reject a particular function, function with arguments of a
- particular type, or a field. Note that the **field-name** and
- **function-name**/**argument-type** cannot be specified at the same time.
- To remove all occurrences of a given field or function, set the class
- attribute to \*.
+The **class** attribute is the C++ class name of the class to reject. Use
+the *optional* **function-name**, **argument-type**, or **field-name**
+attributes to reject a particular function, function with arguments of a
+particular type, or a field. Note that the **field-name** and
+**function-name**/**argument-type** cannot be specified at the same time.
+To remove all occurrences of a given field or function, set the class
+attribute to \*.
.. _primitive-type:
primitive-type
^^^^^^^^^^^^^^
- The ``primitive-type`` node describes how a primitive type is mapped from C++ to
- the target language, and is a child of the :ref:`typesystem` node. It may
- contain :ref:`conversion-rule` child nodes. Note that most primitives are
- already specified in the QtCore typesystem (see :ref:`primitive-cpp-types`).
-
- .. code-block:: xml
-
- <typesystem>
- <primitive-type name="..."
- since="..."
- until="..."
- target-lang-api-name="..."
- default-constructor="..."
- preferred-conversion="yes | no" />
- view-on="..."
- </typesystem>
+The ``primitive-type`` node describes how a primitive type is mapped from C++ to
+the target language, and is a child of the :ref:`typesystem` node. It may
+contain :ref:`conversion-rule` child nodes. Note that most primitives are
+already specified in the QtCore typesystem (see :ref:`primitive-cpp-types`).
- The **name** attribute is the name of the primitive in C++.
+.. code-block:: xml
+
+ <typesystem>
+ <primitive-type name="..."
+ since="..."
+ until="..."
+ target-lang-api-name="..."
+ default-constructor="..."
+ preferred-conversion="yes | no"
+ view-on="..." />
+ </typesystem>
- The optional **target-lang-api-name** attribute is the name of the
- primitive type in the target language, defaulting to the **name** attribute.
+The **name** attribute is the name of the primitive in C++.
- The *optional* **since** value is used to specify the API version in which
- the type was introduced.
+The optional **target-lang-api-name** attribute is the name of the
+primitive type in the target language, defaulting to the **name** attribute.
- Similarly, the *optional* **until** value can be used to specify the API
- version in which the type will be obsoleted.
+The *optional* **since** value is used to specify the API version in which
+the type was introduced.
- If the *optional* **preferred-conversion** attribute is set to *no*, it
- indicates that this version of the primitive type is not the preferred C++
- equivalent of the target language type. For example, in Python both "qint64"
- and "long long" become "long" but we should prefer the "qint64" version. For
- this reason we mark "long long" with preferred-conversion="no".
+Similarly, the *optional* **until** value can be used to specify the API
+version in which the type will be obsoleted.
- The *optional* **default-constructor** specifies the minimal constructor
- call to build one value of the primitive-type. This is not needed when the
- primitive-type may be built with a default constructor (the one without
- arguments).
+If the *optional* **preferred-conversion** attribute is set to *no*, it
+indicates that this version of the primitive type is not the preferred C++
+equivalent of the target language type. For example, in Python both "qint64"
+and "long long" become "long" but we should prefer the "qint64" version. For
+this reason we mark "long long" with preferred-conversion="no".
- The *optional* **preferred-conversion** attribute tells how to build a default
- instance of the primitive type. It should be a constructor call capable of
- creating a instance of the primitive type. Example: a class "Foo" could have
- a **preferred-conversion** value set to "Foo()". Usually this attribute is
- used only for classes declared as primitive types and not for primitive C++
- types, but that depends on the application using *ApiExtractor*.
+The *optional* **default-constructor** specifies the minimal constructor
+call to build one value of the primitive-type. This is not needed when the
+primitive-type may be built with a default constructor (the one without
+arguments).
- The *optional* **view-on** attribute specifies that the type is a view
- class like std::string_view or QStringView which has a constructor
- accepting another type like std::string or QString. Since typically
- no values can be assigned to view classes, no target-to-native conversion
- can be generated for them. Instead, an instance of the viewed class should
- be instantiated and passed to functions using the view class
- for argument types.
+The *optional* **preferred-conversion** attribute tells how to build a default
+instance of the primitive type. It should be a constructor call capable of
+creating a instance of the primitive type. Example: a class "Foo" could have
+a **preferred-conversion** value set to "Foo()". Usually this attribute is
+used only for classes declared as primitive types and not for primitive C++
+types, but that depends on the application using *ApiExtractor*.
- See :ref:`predefined_templates` for built-in templates for standard type
- conversion rules.
+The *optional* **view-on** attribute specifies that the type is a view
+class like std::string_view or QStringView which has a constructor
+accepting another type like std::string or QString. Since typically
+no values can be assigned to view classes, no target-to-native conversion
+can be generated for them. Instead, an instance of the viewed class should
+be instantiated and passed to functions using the view class
+for argument types.
+
+See :ref:`predefined_templates` for built-in templates for standard type
+conversion rules.
.. _namespace:
namespace-type
^^^^^^^^^^^^^^
- The ``namespace-type`` node maps the given C++ namespace to the target
- language, and it is a child of the :ref:`typesystem` node or other
- ``namespace-type`` nodes. It may contain :ref:`add-function`,
- :ref:`declare-function`, :ref:`enum-type`, :ref:`extra-includes`,
- :ref:`include-element`, :ref:`modify-function`, ``namespace-type``,
- :ref:`object-type`, :ref:`smart-pointer-type`, :ref:`typedef-type` or :ref:`value-type`
- child nodes.
-
- .. code-block:: xml
-
- <typesystem>
- <namespace-type name="..."
- visible="true | auto | false"
- generate="yes | no"
- generate-using="yes | no"
- package="..."
- since="..."
- revision="..." />
- </typesystem>
+The ``namespace-type`` node maps the given C++ namespace to the target
+language, and it is a child of the :ref:`typesystem` node or other
+``namespace-type`` nodes. It may contain :ref:`add-function`,
+:ref:`declare-function`, :ref:`enum-type`, :ref:`extra-includes`,
+:ref:`include-element`, :ref:`modify-function`, ``namespace-type``,
+:ref:`object-type`, :ref:`smart-pointer-type`, :ref:`typedef-type` or :ref:`value-type`
+child nodes.
+
+.. code-block:: xml
+
+ <typesystem>
+ <namespace-type name="..."
+ visible="true | auto | false"
+ generate="yes | no"
+ generate-using="yes | no"
+ package="..."
+ since="..."
+ extends = "..."
+ files = "..."
+ revision="..." />
+ </typesystem>
+
+The **name** attribute is the name of the namespace, e.g., "Qt".
+
+The *optional* **visible** attribute is used specify whether the
+namespace is visible in the target language name. Its default value is
+**auto**. It means that normal namespaces are visible, but inline namespaces
+(as introduced in C++ 11) will not be visible.
- The **name** attribute is the name of the namespace, e.g., "Qt".
+The detection of inline namespaces requires shiboken to be built
+using LLVM 9.0.
- The *optional* **visible** attribute is used specify whether the
- namespace is visible in the target language name. Its default value is
- **auto**. It means that normal namespaces are visible, but inline namespaces
- (as introduced in C++ 11) will not be visible.
+The *optional* **generate** is a legacy attribute. Specifying
+**no** is equivalent to **visible="false"**.
- The detection of inline namespaces requires shiboken to be built
- using LLVM 9.0.
+The *optional* **generate-using** attribute specifies whether
+``using namespace`` is generated into the wrapper code for classes within
+the namespace (default: **yes**). This ensures for example that not fully
+qualified enumeration values of default argument values compile.
+However, in rare cases, it might cause ambiguities and can then be turned
+off.
- The *optional* **generate** is a legacy attribute. Specifying
- **no** is equivalent to **visible="false"**.
+The **package** attribute can be used to override the package of the type system.
- The *optional* **generate-using** attribute specifies whether
- ``using namespace`` is generated into the wrapper code for classes within
- the namespace (default: **yes**). This ensures for example that not fully
- qualified enumeration values of default argument values compile.
- However, in rare cases, it might cause ambiguities and can then be turned
- off.
+The *optional* **since** value is used to specify the API version of this type.
- The **package** attribute can be used to override the package of the type system.
+The **revision** attribute can be used to specify a revision for each type, easing the
+production of ABI compatible bindings.
- The *optional* **since** value is used to specify the API version of this type.
+The *optional* **extends** attribute specifies the module name where the given
+namespace first occurs in case of a namespace spanning several modules. For
+example, in Qt, the namespace ``Qt`` first occurs in the ``QtCore`` module and
+is further populated in the ``QtGui`` module. ``QtGui.Qt`` will then be
+generated extending ``QtCore.Qt`` if **extends** is specified.
- The **revision** attribute can be used to specify a revision for each type, easing the
- production of ABI compatible bindings.
+The *optional* **file** attribute specifies a regular expression matching the
+include files whose contents are to be associated with the current module in
+case of a namespace spanning several modules.
.. _enum-type:
enum-type
^^^^^^^^^
- The ``enum-type`` node maps the given enum from C++ to the target language,
- and it is a child of the :ref:`typesystem` node. Use
- :ref:`reject-enum-value` child nodes to reject values.
-
- .. code-block:: xml
-
- <typesystem>
- <enum-type name="..."
- identified-by-value="..."
- class="yes | no"
- since="..."
- flags="yes | no"
- flags-revision="..."
- cpp-type = "..."
- python-type = "IntEnum | IntFlag"
- lower-bound="..."
- upper-bound="..."
- force-integer="yes | no"
- extensible="yes | no"
- revision="..." />
- </typesystem>
+The ``enum-type`` node maps the given enum from C++ to the target language,
+and it is a child of the :ref:`typesystem` node. Use
+:ref:`reject-enum-value` child nodes to reject values.
+
+.. code-block:: xml
+
+ <typesystem>
+ <enum-type name="..."
+ identified-by-value="..."
+ class="yes | no"
+ since="..."
+ flags="yes | no"
+ flags-revision="..."
+ cpp-type = "..."
+ doc-file = "..."
+ python-type = "IntEnum | IntFlag"
+ lower-bound="..."
+ upper-bound="..."
+ force-integer="yes | no"
+ extensible="yes | no"
+ revision="..." />
+ </typesystem>
+
+The **name** attribute is the fully qualified C++ name of the enum
+(e.g.,"Qt::FillRule"). If the *optional* **flags** attribute is set to *yes*
+(the default is *no*), the generator will expect an existing QFlags<T> for the
+given enum type. The **lower-bound** and **upper-bound** attributes are used
+to specify runtime bounds checking for the enum value. The value must be a
+compilable target language statement, such as "QGradient.Spread.PadSpread"
+(taking again Python as an example). If the **force-integer** attribute is
+set to *yes* (the default is *no*), the generated target language code will
+use the target language integers instead of enums. And finally, the
+**extensible** attribute specifies whether the given enum can be extended
+with user values (the default is *no*).
- The **name** attribute is the fully qualified C++ name of the enum
- (e.g.,"Qt::FillRule"). If the *optional* **flags** attribute is set to *yes*
- (the default is *no*), the generator will expect an existing QFlags<T> for the
- given enum type. The **lower-bound** and **upper-bound** attributes are used
- to specify runtime bounds checking for the enum value. The value must be a
- compilable target language statement, such as "QGradient.Spread.PadSpread"
- (taking again Python as an example). If the **force-integer** attribute is
- set to *yes* (the default is *no*), the generated target language code will
- use the target language integers instead of enums. And finally, the
- **extensible** attribute specifies whether the given enum can be extended
- with user values (the default is *no*).
+The *optional* **since** value is used to specify the API version of this type.
- The *optional* **since** value is used to specify the API version of this type.
+The attribute **identified-by-value** helps to specify anonymous enums using the
+name of one of their values, which is unique for the anonymous enum scope.
+Notice that the **enum-type** tag can either have **name** or **identified-by-value**
+but not both.
- The attribute **identified-by-value** helps to specify anonymous enums using the
- name of one of their values, which is unique for the anonymous enum scope.
- Notice that the **enum-type** tag can either have **name** or **identified-by-value**
- but not both.
+The *optional* **python-type** attribute specifies the underlying
+Python type.
- The *optional* **python-type** attribute specifies the underlying
- Python type.
+The *optional* **cpp-type** attribute specifies a C++ to be used for
+casting values. This can be useful for large values triggering MSVC
+signedness issues.
- The *optional* **cpp-type** attribute specifies a C++ to be used for
- casting values. This can be useful for large values triggering MSVC
- signedness issues.
+The *optional* **doc-file** attribute specifies the base name of the C++ or
+``.qdoc`` file indicated by ``\relates`` or ``\headerfile`` in ``qdoc``, to
+which the documentation of the enumeration is to be added and displayed in the
+case its a global enumeration. This attribute is for ``qdoc`` only.
- The **revision** attribute can be used to specify a revision for each type, easing the
- production of ABI compatible bindings.
+The **revision** attribute can be used to specify a revision for each type, easing the
+production of ABI compatible bindings.
- The **flags-revision** attribute has the same purposes of **revision** attribute but
- is used for the QFlag related to this enum.
+The **flags-revision** attribute has the same purposes of **revision** attribute but
+is used for the QFlag related to this enum.
.. _reject-enum-value:
reject-enum-value
^^^^^^^^^^^^^^^^^
- The ``reject-enum-value`` node rejects the enum value specified by the
- **name** attribute, and it is a child of the :ref:`enum-type` node.
+The ``reject-enum-value`` node rejects the enum value specified by the
+**name** attribute, and it is a child of the :ref:`enum-type` node.
- .. code-block:: xml
+.. code-block:: xml
- <enum-type>
- <reject-enum-value name="..."/>
- </enum-type>
+ <enum-type>
+ <reject-enum-value name="..."/>
+ </enum-type>
- This node is used when a C++ enum implementation has several identical numeric
- values, some of which are typically obsolete.
+This node is used when a C++ enum implementation has several identical numeric
+values, some of which are typically obsolete.
.. _value-type:
value-type
^^^^^^^^^^
- The ``value-type`` node indicates that the given C++ type is mapped onto the target
- language as a value type. This means that it is an object passed by value on C++,
- i.e. it is stored in the function call stack. It is a child of the :ref:`typesystem`
- node or other type nodes and may contain :ref:`add-function`, :ref:`add-pymethoddef`,
- :ref:`declare-function`, :ref:`conversion-rule`, :ref:`enum-type`,
- :ref:`extra-includes`, :ref:`include-element`, :ref:`modify-function`,
- :ref:`object-type`, :ref:`smart-pointer-type`, :ref:`typedef-type` or further
- ``value-type`` child nodes.
-
- .. code-block:: xml
-
- <typesystem>
- <value-type name="..." since="..."
- copyable="yes | no"
- allow-thread="..."
- disable-wrapper="yes | no"
- exception-handling="..."
- generate-functions="..."
- isNull ="yes | no"
- operator-bool="yes | no"
- hash-function="..."
- private="yes | no"
- qt-register-metatype = "yes | no | base"
- stream="yes | no"
- default-constructor="..."
- revision="..."
- snake-case="yes | no | both" />
- </typesystem>
+The ``value-type`` node indicates that the given C++ type is mapped onto the target
+language as a value type. This means that it is an object passed by value on C++,
+i.e. it is stored in the function call stack. It is a child of the :ref:`typesystem`
+node or other type nodes and may contain :ref:`add-function`, :ref:`add-pymethoddef`,
+:ref:`configuration-element`, :ref:`declare-function`, :ref:`conversion-rule`,
+:ref:`enum-type`, :ref:`extra-includes`, :ref:`include-element`, :ref:`modify-function`,
+:ref:`object-type`, :ref:`smart-pointer-type`, :ref:`typedef-type` or further
+``value-type`` child nodes.
+
+.. code-block:: xml
+
+ <typesystem>
+ <value-type name="..." since="..."
+ copyable="yes | no"
+ allow-thread="..."
+ disable-wrapper="yes | no"
+ exception-handling="..."
+ generate-functions="..."
+ isNull ="yes | no"
+ operator-bool="yes | no"
+ hash-function="..."
+ private="yes | no"
+ qt-register-metatype = "yes | no | base"
+ stream="yes | no"
+ default-constructor="..."
+ revision="..."
+ snake-case="yes | no | both" />
+ </typesystem>
- The **name** attribute is the fully qualified C++ class name, such as
- "QMatrix" or "QPainterPath::Element". The **copyable** attribute is used to
- force or not specify if this type is copyable. The *optional* **hash-function**
- attribute informs the function name of a hash function for the type.
+The **name** attribute is the fully qualified C++ class name, such as
+"QMatrix" or "QPainterPath::Element". The **copyable** attribute is used to
+force or not specify if this type is copyable. The *optional* **hash-function**
+attribute informs the function name of a hash function for the type.
- 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.
+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.
- The *optional* **since** value is used to specify the API version of this type.
+The *optional* **since** value is used to specify the API version of this type.
- The *optional* **default-constructor** specifies the minimal constructor
- call to build one instance of the value-type. This is not needed when the
- value-type may be built with a default constructor (the one without arguments).
- Usually a code generator may guess a minimal constructor for a value-type based
- on its constructor signatures, thus **default-constructor** is used only in
- very odd cases.
+The *optional* **default-constructor** specifies the minimal constructor
+call to build one instance of the value-type. This is not needed when the
+value-type may be built with a default constructor (the one without arguments).
+Usually a code generator may guess a minimal constructor for a value-type based
+on its constructor signatures, thus **default-constructor** is used only in
+very odd cases.
- For the *optional* **disable-wrapper** and **generate-functions**
- attributes, see :ref:`object-type`.
+For the *optional* **disable-wrapper** and **generate-functions**
+attributes, see :ref:`object-type`.
- For the *optional* **private** attribute, see :ref:`private_types`.
+For the *optional* **private** attribute, see :ref:`private_types`.
- The *optional* **qt-register-metatype** attribute determines whether
- a Qt meta type registration is generated for ``name``. By
- default, this is generated for non-abstract, default-constructible
- types for usage in signals and slots.
- The value ``base`` means that the registration will be generated for the
- class in question but not for inheriting classes. This allows for
- restricting the registration to base classes of type hierarchies.
+The *optional* **qt-register-metatype** attribute determines whether
+a Qt meta type registration is generated for ``name``. By
+default, this is generated for non-abstract, default-constructible
+types for usage in signals and slots.
+The value ``base`` means that the registration will be generated for the
+class in question but not for inheriting classes. This allows for
+restricting the registration to base classes of type hierarchies.
- The **revision** attribute can be used to specify a revision for each type, easing the
- production of ABI compatible bindings.
+The **revision** attribute can be used to specify a revision for each type, easing the
+production of ABI compatible bindings.
- The *optional* attributes **allow-thread** and **exception-handling**
- specify the default handling for the corresponding function modification
- (see :ref:`modify-function`).
+The *optional* attributes **allow-thread** and **exception-handling**
+specify the default handling for the corresponding function modification
+(see :ref:`modify-function`).
- The *optional* **snake-case** attribute allows for overriding the value
- specified on the **typesystem** element.
+The *optional* **snake-case** attribute allows for overriding the value
+specified on the **typesystem** element.
- The *optional* **isNull** and **operator-bool** attributes can be used
- to override the command line setting for generating bool casts
- (see :ref:`bool-cast`).
+The *optional* **isNull** and **operator-bool** attributes can be used
+to override the command line setting for generating bool casts
+(see :ref:`bool-cast`).
.. _object-type:
object-type
^^^^^^^^^^^
- The object-type node indicates that the given C++ type is mapped onto the target
- language as an object type. This means that it is an object passed by pointer on
- C++ and it is stored on the heap. It is a child of the :ref:`typesystem` node
- or other type nodes and may contain :ref:`add-function`, :ref:`add-pymethoddef`,
- :ref:`declare-function`, :ref:`enum-type`, :ref:`extra-includes`,
- :ref:`include-element`, :ref:`modify-function`, ``object-type``,
- :ref:`smart-pointer-type`, :ref:`typedef-type` or :ref:`value-type` child nodes.
-
- .. code-block:: xml
-
- <typesystem>
- <object-type name="..."
- since="..."
- copyable="yes | no"
- allow-thread="..."
- disable-wrapper="yes | no"
- exception-handling="..."
- generate-functions="..."
- force-abstract="yes | no"
- hash-function="..."
- isNull ="yes | no"
- operator-bool="yes | no"
- parent-management="yes | no"
- polymorphic-id-expression="..."
- polymorphic-name-function="..."
- private="yes | no"
- qt-register-metatype = "yes | no | base"
- stream="yes | no"
- revision="..."
- snake-case="yes | no | both" />
- </typesystem>
+The object-type node indicates that the given C++ type is mapped onto the target
+language as an object type. This means that it is an object passed by pointer on
+C++ and it is stored on the heap. It is a child of the :ref:`typesystem` node
+or other type nodes and may contain :ref:`add-function`, :ref:`add-pymethoddef`,
+:ref:`configuration-element`, :ref:`declare-function`, :ref:`enum-type`,
+:ref:`extra-includes`, :ref:`include-element`, :ref:`modify-function`,
+``object-type``, :ref:`smart-pointer-type`, :ref:`typedef-type` or
+:ref:`value-type` child nodes.
- The **name** attribute is the fully qualified C++ class name. If there is no
- C++ base class, the default-superclass attribute can be used to specify a
- superclass for the given type, in the generated target language API. The
- **copyable** and **hash-function** attributes are the same as described for
- :ref:`value-type`.
-
- The *optional* **force-abstract** attribute forces the class to be
- abstract, disabling its instantiation. The generator will normally detect
- this automatically unless the class inherits from an abstract base class
- that is not in the type system.
-
- The *optional* **disable-wrapper** attribute disables the generation of a
- **C++ Wrapper** (see :ref:`codegenerationterminology`). This will
- effectively disable overriding virtuals methods in Python for the class.
- It can be used when the class cannot be instantiated from Python and
- its virtual methods pose some problem for the code generator (by returning
- 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* **qt-register-metatype** attribute determines whether
- a Qt meta type registration is generated for ``name *``. By
- default, this is only generated for non-QObject types for usage
- in signals and slots.
- The value ``base`` means that the registration will be generated for the
- class in question but not for inheriting classes. This allows for
- restricting the registration to base classes of type hierarchies.
-
- 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.
-
- The *optional* **since** value is used to specify the API version of this type.
-
- The **revision** attribute can be used to specify a revision for each type, easing the
- production of ABI compatible bindings.
-
- The *optional* attributes **allow-thread** and **exception-handling**
- specify the default handling for the corresponding function modification
- (see :ref:`modify-function`).
-
- The *optional* **generate-functions** specifies a semicolon-separated
- list of function names or minimal signatures to be generated.
- This allows for restricting the functions for which bindings are generated.
- This also applies to virtual functions; so, all abstract functions
- need to be listed to prevent non-compiling code to be generated.
- If nothing is specified, bindings for all suitable functions are
- generated. Note that special functions (constructors, etc),
- cannot be specified.
-
- The *optional* **snake-case** attribute allows for overriding the value
- specified on the **typesystem** element.
-
- The *optional* **isNull** and **operator-bool** attributes can be used
- to override the command line setting for generating bool casts
- (see :ref:`bool-cast`).
-
- The *optional* **parent-management** attribute specifies that the class is
- used for building object trees consisting of parents and children, for
- example, user interfaces like the ``QWidget`` classes. For those classes,
- the heuristics enabled by :ref:`ownership-parent-heuristics` and
- :ref:`return-value-heuristics` are applied to automatically set parent
- relationships. Compatibility note: In shiboken 6, when no class of the
- type system has this attribute set, the heuristics will be applied
- to all classes. In shiboken 7, it will be mandatory to set the
- attribute.
-
- The *optional* **polymorphic-id-expression** attribute specifies an
- expression checking whether a base class pointer is of the matching
- type. For example, in a ``virtual eventHandler(BaseEvent *e)``
- function, this is used to construct a Python wrapper matching
- the derived class (for example, a ``MouseEvent`` or similar).
-
- The *optional* **polymorphic-name-function** specifies the name of a
- function returning the type name of a derived class on the base class
- type entry. Normally, ``typeid(ptr).name()`` is used for this.
- However, this fails if the type hierarchy does not have virtual functions.
- In this case, a function is required which typically decides depending
- on some type enumeration.
+.. code-block:: xml
+
+ <typesystem>
+ <object-type name="..."
+ since="..."
+ copyable="yes | no"
+ allow-thread="..."
+ disable-wrapper="yes | no"
+ exception-handling="..."
+ generate-functions="..."
+ force-abstract="yes | no"
+ hash-function="..."
+ isNull ="yes | no"
+ operator-bool="yes | no"
+ parent-management="yes | no"
+ polymorphic-id-expression="..."
+ polymorphic-name-function="..."
+ polymorphic-base="yes | no"
+ private="yes | no"
+ qt-metaobject="yes | no"
+ qt-register-metatype = "yes | no | base"
+ stream="yes | no"
+ revision="..."
+ snake-case="yes | no | both" />
+ </typesystem>
+
+The **name** attribute is the fully qualified C++ class name. If there is no
+C++ base class, the default-superclass attribute can be used to specify a
+superclass for the given type, in the generated target language API. The
+**copyable** and **hash-function** attributes are the same as described for
+:ref:`value-type`.
+
+The *optional* **force-abstract** attribute forces the class to be
+abstract, disabling its instantiation. The generator will normally detect
+this automatically unless the class inherits from an abstract base class
+that is not in the type system.
+
+The *optional* **disable-wrapper** attribute disables the generation of a
+**C++ Wrapper** (see :ref:`codegenerationterminology`). This will
+effectively disable overriding virtuals methods in Python for the class.
+It can be used when the class cannot be instantiated from Python and
+its virtual methods pose some problem for the code generator (by returning
+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* **qt-metaobject** attribute specifies whether
+the special Qt virtual functions ``metaObject()``,
+``metaCall()``, and ``metaCast()`` are generated. For classes
+using dynamic meta objects, for example, ``QDBusInterface``,
+it can be turned off.
+
+The *optional* **qt-register-metatype** attribute determines whether
+a Qt meta type registration is generated for ``name *``. By
+default, this is only generated for non-QObject types for usage
+in signals and slots.
+The value ``base`` means that the registration will be generated for the
+class in question but not for inheriting classes. This allows for
+restricting the registration to base classes of type hierarchies.
+
+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.
+
+The *optional* **since** value is used to specify the API version of this type.
+
+The **revision** attribute can be used to specify a revision for each type, easing the
+production of ABI compatible bindings.
+
+The *optional* attributes **allow-thread** and **exception-handling**
+specify the default handling for the corresponding function modification
+(see :ref:`modify-function`).
+
+The *optional* **generate-functions** specifies a semicolon-separated
+list of function names or minimal signatures to be generated.
+This allows for restricting the functions for which bindings are generated.
+This also applies to virtual functions; so, all abstract functions
+need to be listed to prevent non-compiling code to be generated.
+If nothing is specified, bindings for all suitable functions are
+generated. Note that special functions (constructors, etc),
+cannot be specified.
+
+The *optional* **snake-case** attribute allows for overriding the value
+specified on the **typesystem** element.
+
+The *optional* **isNull** and **operator-bool** attributes can be used
+to override the command line setting for generating bool casts
+(see :ref:`bool-cast`).
+
+The *optional* **parent-management** attribute specifies that the class is
+used for building object trees consisting of parents and children, for
+example, user interfaces like the ``QWidget`` classes. For those classes,
+the heuristics enabled by :ref:`ownership-parent-heuristics` and
+:ref:`return-value-heuristics` are applied to automatically set parent
+relationships. Compatibility note: In shiboken 6, when no class of the
+type system has this attribute set, the heuristics will be applied
+to all classes. In shiboken 7, it will be mandatory to set the
+attribute.
+
+For the *optional* **polymorphic-id-expression**, **polymorphic-name-function**
+and **polymorphic-base** attributes, see :ref:`typediscovery-attributes`.
interface-type
^^^^^^^^^^^^^^
- This type is deprecated and no longer has any effect. Use object-type instead.
+This type is deprecated and no longer has any effect. Use object-type instead.
.. _container-type:
container-type
^^^^^^^^^^^^^^
- The ``container-type`` node indicates that the given class is a container and
- must be handled using one of the conversion helpers provided by attribute **type**.
- It is a child of the :ref:`typesystem` node and may contain
- :ref:`conversion-rule` child nodes.
+The ``container-type`` node indicates that the given class is a container and
+must be handled using one of the conversion helpers provided by attribute **type**.
+It is a child of the :ref:`typesystem` node and may contain
+:ref:`conversion-rule` child nodes.
- .. code-block:: xml
+.. code-block:: xml
- <typesystem>
- <container-type name="..."
- since="..."
- type ="..."
- opaque-containers ="..." />
- </typesystem>
+ <typesystem>
+ <container-type name="..."
+ since="..."
+ type ="..."
+ opaque-containers ="..." />
+ </typesystem>
+
+The **name** attribute is the fully qualified C++ class name. The **type**
+attribute is used to indicate what conversion rule will be applied to the
+container. It can be one of: *list*, *set*, *map*, *multi-map* or *pair*.
+
+Some types were deprecated in 6.2: *string-list*, *linked-list*, *vector*,
+*stack* and *queue* are equivalent to *list*. *hash* and *multi-hash*
+are equivalent to *map* and *multi-map*, respectively.
+
+The *optional* **opaque-containers** attribute specifies a semi-colon separated
+list of mappings from instantiations to a type name for
+:ref:`opaque-containers`:
- The **name** attribute is the fully qualified C++ class name. The **type**
- attribute is used to indicate what conversion rule will be applied to the
- container. It can be one of: *list*, *set*, *map*, *multi-map* or *pair*.
+.. code-block:: xml
+
+ <typesystem>
+ <container-type name="std::array"
+ opaque-containers ="int,3:IntArray3;float,4:FloatArray4">
+
+
+The *optional* **since** value is used to specify the API version of this container.
+
+Some common standard containers are :ref:`built-in <builtin-cpp-container-types>`,
+and there are also a number of useful
+:ref:`predefined conversion templates <predefined_templates>`.
+
+.. _opaque-container:
- Some types were deprecated in 6.2: *string-list*, *linked-list*, *vector*,
- *stack* and *queue* are equivalent to *list*. *hash* and *multi-hash*
- are equivalent to *map* and *multi-map*, respectively.
+opaque-container
+^^^^^^^^^^^^^^^^
- The *optional* **opaque-containers** attribute specifies a semi-colon separated
- list of colon separated pairs of instantiation and name for
- :ref:`opaque-containers`.
+The ``opaque-container`` element can be used to add further instantiations
+of :ref:`opaque containers <opaque-containers>` to existing container types
+(built-in or specified by :ref:`container-type` in included modules).
+It is a child of the :ref:`typesystem` node.
- The *optional* **since** value is used to specify the API version of this container.
+.. code-block:: xml
- See :ref:`predefined_templates` for built-in templates for standard type
- conversion rules.
+ <typesystem>
+ <oqaque-container name="..." opaque-containers ="..." />
+ </typesystem>
- Some common standard containers (``std::list``, ``std::vector``, ``std::pair``,
- ``std::map`` and ``std::unordered_map``) are built-in. They only need to be
- specified if :ref:`opaque-containers` should be generated.
+For the **name** and **opaque-containers** attributes,
+see :ref:`container-type`.
.. _typedef-type:
typedef-type
^^^^^^^^^^^^
- The ``typedef-type`` node allows for specifying typedefs in the typesystem. They
- are mostly equivalent to spelling out the typedef in the included header, which
- is often complicated when trying to wrap libraries whose source code cannot be
- easily extended.
- It is a child of the :ref:`typesystem` node or other type nodes.
+The ``typedef-type`` node allows for specifying typedefs in the typesystem. They
+are mostly equivalent to spelling out the typedef in the included header, which
+is often complicated when trying to wrap libraries whose source code cannot be
+easily extended.
+It is a child of the :ref:`typesystem` node or other type nodes.
- .. code-block:: xml
+.. code-block:: xml
- <typesystem>
- <typedef-type name="..."
- source="..."
- since="..." />
- </typesystem>
+ <typesystem>
+ <typedef-type name="..."
+ source="..."
+ since="..." />
+ </typesystem>
- The **source** attribute is the source. Example:
+The **source** attribute is the source. Example:
- .. code-block:: xml
+.. code-block:: xml
- <namespace-type name='std'>
- <value-type name='optional' generate='no'/>\n"
- </namespace-type>
- <typedef-type name="IntOptional" source="std::optional&lt;int&gt;"/>
+ <namespace-type name='std'>
+ <value-type name='optional' generate='no'/>\n"
+ </namespace-type>
+ <typedef-type name="IntOptional" source="std::optional&lt;int&gt;"/>
- is equivalent to
+is equivalent to
- .. code-block:: c++
+.. code-block:: c++
- typedef std::optional<int> IntOptional;
+ typedef std::optional<int> IntOptional;
- The *optional* **since** value is used to specify the API version of this type.
+The *optional* **since** value is used to specify the API version of this type.
.. _custom-type:
custom-type
^^^^^^^^^^^
- The ``custom-type`` node simply makes the parser aware of the existence of a target
- language type, thus avoiding errors when trying to find a type used in function
- signatures and other places. The proper handling of the custom type is meant to
- be done by a generator using the APIExractor.
- It is a child of the :ref:`typesystem` node.
+The ``custom-type`` node simply makes the parser aware of the existence of a target
+language type, thus avoiding errors when trying to find a type used in function
+signatures and other places. The proper handling of the custom type is meant to
+be done by a generator using the APIExractor.
+It is a child of the :ref:`typesystem` node.
- .. code-block:: xml
+.. code-block:: xml
- <typesystem>
- <custom-type name="..."
- check-function="..." />
- </typesystem>
+ <typesystem>
+ <custom-type name="..."
+ check-function="..." />
+ </typesystem>
- The **name** attribute is the name of the custom type, e.g., "PyObject".
+The **name** attribute is the name of the custom type, e.g., "PyObject".
- The *optional* **check-function** attribute can be used to specify a
- boolean check function that verifies if the PyObject is of the given type
- in the function overload decisor. While shiboken knows common check
- functions like ``PyLong_Check()`` or ``PyType_Check()``, it might be useful
- to provide one for function arguments modified to be custom types
- handled by injected code (see :ref:`replace-type`).
+The *optional* **check-function** attribute can be used to specify a
+boolean check function that verifies if the PyObject is of the given type
+in the function overload decisor. While shiboken knows common check
+functions like ``PyLong_Check()`` or ``PyType_Check()``, it might be useful
+to provide one for function arguments modified to be custom types
+handled by injected code (see :ref:`replace-type`).
- See :ref:`cpython-types` for built-in types.
+See :ref:`cpython-types` for built-in types.
.. _smart-pointer-type:
smart-pointer-type
^^^^^^^^^^^^^^^^^^
- The ``smart pointer`` type node indicates that the given class is a smart pointer
- and requires inserting calls to **getter** to access the pointeee.
- Currently, the usage is limited to function return values.
- **ref-count-method** specifies the name of the method used to do reference counting.
- It is a child of the :ref:`typesystem` node or other type nodes.
-
- The *optional* attribute **instantiations** specifies for which instantiations
- of the smart pointer wrappers will be generated (comma-separated list).
- By default, this will happen for all instantiations found by code parsing.
- This might be a problem when linking different modules, since wrappers for the
- same instantiation might be generated into different modules, which then clash.
- Providing an instantiations list makes it possible to specify which wrappers
- will be generated into specific modules.
-
- .. code-block:: xml
-
- <typesystem>
- <smart-pointer-type name="..."
- since="..."
- type="shared | handle | value-handle | unique"
- getter="..."
- ref-count-method="..."
- value-check-method="..."
- null-check-method="..."
- reset-method="..."
- instantiations="..."/>
- </typesystem>
-
-
- The *optional* attribute **value-check-method** specifies a method
- that can be used to check whether the pointer has a value.
-
- The *optional* attribute **null-check-method** specifies a method
- that can be used to check for ``nullptr``.
-
- The *optional* attribute **reset-method** specifies a method
- that can be used to clear the pointer.
-
- The *optional* instantiations attribute specifies a comma-separated
- list of instantiation types. When left empty, all instantiations
- found in the code will be generated. The type name might optionally
- be followed an equal sign and the Python type name, for example
- ``instantiations="int=IntPtr,double=DoublePtr"``.
- It is also possible to specify a namespace delimited by ``::``.
-
- The *optional* attribute **type** specifies the type:
-
- *shared*
- A standard shared pointer.
- *handle*
- A basic pointer handle which has a getter function and an
- ``operator->``.
- *value-handle*
- A handle which has a getter function returning a value
- (``T`` instead of ``T *`` as for the other types).
- It can be used for ``std::optional``.
- *unique*
- A standard, unique pointer (``std::unique_ptr``) or a similar
- movable pointer.
- Specifying the ``reset-method`` attribute is required for this work.
-
- The example below shows an entry for a ``std::shared_ptr``:
-
- .. code-block:: xml
+The ``smart pointer`` type node indicates that the given class is a smart pointer
+and requires inserting calls to **getter** to access the pointeee.
+Currently, the usage is limited to function return values.
+**ref-count-method** specifies the name of the method used to do reference counting.
+It is a child of the :ref:`typesystem` node or other type nodes.
- <system-include file-name="memory"/>
+The *optional* attribute **instantiations** specifies for which instantiations
+of the smart pointer wrappers will be generated (comma-separated list).
+By default, this will happen for all instantiations found by code parsing.
+This might be a problem when linking different modules, since wrappers for the
+same instantiation might be generated into different modules, which then clash.
+Providing an instantiations list makes it possible to specify which wrappers
+will be generated into specific modules.
+
+.. code-block:: xml
+
+ <typesystem>
+ <smart-pointer-type name="..."
+ since="..."
+ type="shared | handle | value-handle | unique"
+ getter="..."
+ ref-count-method="..."
+ value-check-method="..."
+ null-check-method="..."
+ reset-method="..."
+ instantiations="..."/>
+ </typesystem>
+
+
+The *optional* attribute **value-check-method** specifies a method
+that can be used to check whether the pointer has a value.
- <namespace-type name="std">
+The *optional* attribute **null-check-method** specifies a method
+that can be used to check for ``nullptr``.
+
+The *optional* attribute **reset-method** specifies a method
+that can be used to clear the pointer.
+
+The *optional* instantiations attribute specifies a comma-separated
+list of instantiation types. When left empty, all instantiations
+found in the code will be generated. The type name might optionally
+be followed an equal sign and the Python type name, for example
+``instantiations="int=IntPtr,double=DoublePtr"``.
+It is also possible to specify a namespace delimited by ``::``.
+
+The *optional* attribute **type** specifies the type:
+
+*shared*
+ A standard shared pointer.
+*handle*
+ A basic pointer handle which has a getter function and an
+ ``operator->``.
+*value-handle*
+ A handle which has a getter function returning a value
+ (``T`` instead of ``T *`` as for the other types).
+ It can be used for ``std::optional``.
+*unique*
+ A standard, unique pointer (``std::unique_ptr``) or a similar
+ movable pointer.
+ Specifying the ``reset-method`` attribute is required for this work.
+
+The example below shows an entry for a ``std::shared_ptr``:
+
+.. code-block:: xml
+
+ <system-include file-name="memory"/>
+
+ <namespace-type name="std">
+ <include file-name="memory" location="global"/>
+ <modify-function signature="^.*$" remove="all"/>
+ <enum-type name="pointer_safety"/>
+ <smart-pointer-type name="shared_ptr" type="shared" getter="get"
+ ref-count-method="use_count"
+ instantiations="Integer">
+ <include file-name="memory" location="global"/>
+ </smart-pointer-type>
+ </namespace-type>
+
+If the smart pointer is the only relevant class from namespace ``std``,
+it can also be hidden:
+
+.. code-block:: xml
+
+ <namespace-type name="std" visible="no">
+ <smart-pointer-type name="shared_ptr" type="shared" getter="get"
+ ref-count-method="use_count"
+ instantiations="Integer">
<include file-name="memory" location="global"/>
- <modify-function signature="^.*$" remove="all"/>
- <enum-type name="pointer_safety"/>
- <smart-pointer-type name="shared_ptr" type="shared" getter="get"
- ref-count-method="use_count"
- instantiations="Integer">
- <include file-name="memory" location="global"/>
- </smart-pointer-type>
- </namespace-type>
-
- If the smart pointer is the only relevant class from namespace ``std``,
- it can also be hidden:
-
- .. code-block:: xml
-
- <namespace-type name="std" visible="no">
- <smart-pointer-type name="shared_ptr" type="shared" getter="get"
- ref-count-method="use_count"
- instantiations="Integer">
- <include file-name="memory" location="global"/>
- </smart-pointer-type>
- </namespace-type>
-
- First, shiboken is told to actually parse the system include files
- containing the class definition using the :ref:`system_include`
- element. For the ``namespace-type`` and ``smart-pointer-type``, the
- standard include files are given to override the internal implementation
- header ``shared_ptr.h``.
- This creates some wrapper sources which need to be added to the
- ``CMakeLists.txt`` of the module.
+ </smart-pointer-type>
+ </namespace-type>
+
+First, shiboken is told to actually parse the system include files
+containing the class definition using the :ref:`system_include`
+element. For the ``namespace-type`` and ``smart-pointer-type``, the
+standard include files are given to override the internal implementation
+header ``shared_ptr.h``.
+This creates some wrapper sources which need to be added to the
+``CMakeLists.txt`` of the module.
.. _function:
function
^^^^^^^^
- The ``function`` node indicates that the given C++ global function is mapped
- onto the target language. It is a child of the :ref:`typesystem` node
- and may contain a :ref:`modify-function` child node.
+The ``function`` node indicates that the given C++ global function is mapped
+onto the target language. It is a child of the :ref:`typesystem` node
+and may contain a :ref:`modify-function` child node.
- .. code-block:: xml
+.. code-block:: xml
- <typesystem>
- <function signature="..." rename="..." since="..." snake-case="yes | no | both" />
- </typesystem>
+ <typesystem>
+ <function signature="..." rename="..." since="..."
+ allow-thread="true | auto | false"
+ doc-file = "..."
+ exception-handling="off | auto-off | auto-on | on"
+ overload-number="number"
+ snake-case="yes | no | both" />
+ </typesystem>
+
+There is a limitation; you cannot add a function overload using
+the :ref:`add-function` tag to an existent function.
- There is a limitation; you cannot add a function overload using
- the :ref:`add-function` tag to an existent function.
+The *optional* **since** attribute is used to specify the API version in which
+the function was introduced.
- The *optional* **since** attribute is used to specify the API version in which
- the function was introduced.
+The *optional* **rename** attribute is used to modify the function name.
- The *optional* **rename** attribute is used to modify the function name.
+The *optional* **doc-file** attribute specifies the base name of the C++ or
+``.qdoc`` file indicated by ``\relates`` or ``\headerfile`` in ``qdoc``, to
+which the documentation of the function is to be added and displayed in the
+case its a global function. This attribute is for ``qdoc`` only.
- The *optional* **snake-case** attribute allows for overriding the value
- specified on the **typesystem** element.
+For the *optional* attributes **allow-thread**, **exception-handling**,
+**overload-number** and **snake-case**, see :ref:`modify-function`.
.. _system_include:
system-include
^^^^^^^^^^^^^^
- The optional **system-include** specifies the name of a system include
- file or a system include path (indicated by a trailing slash) to be
- parsed. Normally, include files considered to be system include
- files are skipped by the C++ code parser. Its primary use case
- is exposing classes from the STL library.
- It is a child of the :ref:`typesystem` node.
+The optional **system-include** specifies the name of a system include
+file or a system include path (indicated by a trailing slash) to be
+parsed. Normally, include files considered to be system include
+files are skipped by the C++ code parser. Its primary use case
+is exposing classes from the STL library.
+It is a child of the :ref:`typesystem` node.
- .. code-block:: xml
+.. code-block:: xml
- <typesystem>
- <system-include file-name="memory"/>
- <system-include file-name="/usr/include/Qt/"/>
- </typesystem>
+ <typesystem>
+ <system-include file-name="memory"/>
+ <system-include file-name="/usr/include/Qt/"/>
+ </typesystem>
.. _conditional_processing:
Conditional Processing
^^^^^^^^^^^^^^^^^^^^^^
- Simple processing instructions are provided for including or excluding
- sections depending on the presence of keywords. The syntax is:
+Simple processing instructions are provided for including or excluding
+sections depending on the presence of keywords. The syntax is:
- .. code-block:: xml
+.. code-block:: xml
- <?if keyword !excluded_keyword ?>
- ...
- <?endif?>
+ <?if keyword !excluded_keyword ?>
+ ...
+ <?endif?>
- There are predefined keywords indicating the operating system (``windows``,
- ``unix`` and ``darwin``).
+There are predefined keywords indicating the operating system (``windows``,
+``unix`` and ``darwin``).
- The language level passed to the ``language-level`` command line option
- is reflected as ``c++11``, ``c++14``, ``c++17`` or ``c++20``.
+The language level passed to the ``language-level`` command line option
+is reflected as ``c++11``, ``c++14``, ``c++17`` or ``c++20``.
- The class names passed to the
- :ref:`--drop-type-entries <drop-type-entries>` command line option
- are also predefined, prefixed by ``no_``. This allows for example
- for enclosing added functions referring to those classes within
- ``<?if !no_ClassName?>``, ``<?endif?>``.
+The class names passed to the
+:ref:`--drop-type-entries <drop-type-entries>` command line option
+are also predefined, prefixed by ``no_``. This allows for example
+for enclosing added functions referring to those classes within
+``<?if !no_ClassName?>``, ``<?endif?>``.
- Other keywords can be specified using the
- :ref:`--keywords <conditional_keywords>` command line option.
+Other keywords can be specified using the
+:ref:`--keywords <conditional_keywords>` command line option.
.. _private_types:
@@ -802,10 +867,10 @@ Defining Entities
It is possible to define entities using a simple processing instruction:
- .. code-block:: xml
+.. code-block:: xml
- <?entity name value?>
- <text>&name;</text>
+ <?entity name value?>
+ <text>&name;</text>
This allows for defining function signatures depending on platform
in conjunction with :ref:`conditional_processing`.
diff --git a/sources/shiboken6/doc/typesystem_templates.rst b/sources/shiboken6/doc/typesystem_templates.rst
index 22056b596..c32eb97d1 100644
--- a/sources/shiboken6/doc/typesystem_templates.rst
+++ b/sources/shiboken6/doc/typesystem_templates.rst
@@ -8,52 +8,52 @@ Using Code Templates
template
^^^^^^^^
- The ``template`` node registers a template that can be used to avoid
- duplicate code when extending the generated code, and it is a child of the
- :ref:`typesystem` node.
+The ``template`` node registers a template that can be used to avoid
+duplicate code when extending the generated code, and it is a child of the
+:ref:`typesystem` node.
- .. code-block:: xml
+.. code-block:: xml
- <typesystem>
- <template name="my_template">
- // the code
- </template>
- </typesystem>
+ <typesystem>
+ <template name="my_template">
+ // the code
+ </template>
+ </typesystem>
- Use the ``insert-template`` node to insert the template code (identified
- by the template's ``name`` attribute) into the generated code base.
+Use the ``insert-template`` node to insert the template code (identified
+by the template's ``name`` attribute) into the generated code base.
.. _insert-template:
insert-template
^^^^^^^^^^^^^^^
- The ``insert-template`` node includes the code template identified by the
- name attribute, and it can be a child of the :ref:`inject-code`,
- :ref:`conversion-rule` or :ref:`template` nodes.
+The ``insert-template`` node includes the code template identified by the
+name attribute, and it can be a child of the :ref:`inject-code`,
+:ref:`conversion-rule` or :ref:`template` nodes.
- .. code-block:: xml
+.. code-block:: xml
- <inject-code class="target" position="beginning">
- <insert-template name="my_template" />
- </inject-code>
+ <inject-code class="target" position="beginning">
+ <insert-template name="my_template" />
+ </inject-code>
- Use the ``replace`` node to modify the template code.
+Use the ``replace`` node to modify the template code.
replace
^^^^^^^
- The ``replace`` node allows you to modify template code before inserting it into
- the generated code, and it can be a child of the :ref:`insert-template` node.
+The ``replace`` node allows you to modify template code before inserting it into
+the generated code, and it can be a child of the :ref:`insert-template` node.
- .. code-block:: xml
+.. code-block:: xml
- <insert-template name="my_template">
- <replace from="..." to="..." />
- </insert-template>
+ <insert-template name="my_template">
+ <replace from="..." to="..." />
+ </insert-template>
- This node will replace the attribute ``from`` with the value pointed by
- ``to``.
+This node will replace the attribute ``from`` with the value pointed by
+``to``.
.. _predefined_templates:
@@ -65,49 +65,54 @@ built into shiboken.
Templates for :ref:`primitive-type`:
- +---------------------------------------+--------------------------------+
- |Name | Description |
- +---------------------------------------+--------------------------------+
- | ``shiboken_conversion_pylong_to_cpp`` | Convert a PyLong to a C++ type |
- +---------------------------------------+--------------------------------+
++---------------------------------------+--------------------------------+
+|Name | Description |
++---------------------------------------+--------------------------------+
+| ``shiboken_conversion_pylong_to_cpp`` | Convert a PyLong to a C++ type |
++---------------------------------------+--------------------------------+
Templates for :ref:`container-type`:
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_pysequence_to_cpppair`` | Convert a PySequence to a C++ pair (std::pair/QPair) |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_cpppair_to_pytuple`` | Convert a C++ pair (std::pair/QPair) to a PyTuple |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_cppsequence_to_pylist`` | Convert a C++ sequential container to a PyList |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_cppsequence_to_pyset`` | Convert a C++ sequential container to a PySet |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_pyiterable_to_cppsequentialcontainer`` | Convert an iterable Python type to a C++ sequential container (STL/Qt) |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_pyiterable_to_cppsequentialcontainer_reserve`` | Convert an iterable Python type to a C++ sequential container supporting reserve() |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_pyiterable_to_cppsetcontainer`` | Convert a PySequence to a set-type C++ container (std::set/QSet) |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_stdmap_to_pydict`` | Convert a std::map/std::unordered_map to a PyDict |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_qmap_to_pydict`` | Convert a QMap/QHash to a PyDict |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_pydict_to_stdmap`` | Convert a PyDict to a std::map/std::unordered_map |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_pydict_to_qmap`` | Convert a PyDict to a QMap/QHash |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_stdmultimap_to_pydict`` | Convert a std::multimap to a PyDict of value lists |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_qmultimap_to_pydict`` | Convert a QMultiMap to a PyDict of value lists |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_stdunorderedmultimap_to_pydict`` | Convert a std::unordered_multimap to a PyDict of value lists |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_qmultihash_to_pydict`` | Convert a QMultiHash to a PyDict of value lists |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_pydict_to_stdmultimap`` | Convert a PyDict of value lists to std::multimap/std::unordered_multimap |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
- | ``shiboken_conversion_pydict_to_qmultihash`` | Convert a PyDict of value lists to QMultiMap/QMultiHash |
- +----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+Some container types are :ref:`built-in <builtin-cpp-container-types>`.
+In case they need to explicitly specified, the following templates can be used:
+
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_pysequence_to_cpppair`` | Convert a PySequence to a C++ pair (std::pair/QPair) |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_cpppair_to_pytuple`` | Convert a C++ pair (std::pair/QPair) to a PyTuple |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_cppsequence_to_pylist`` | Convert a C++ sequential container to a PyList |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_cppsequence_to_pyset`` | Convert a C++ sequential container to a PySet |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_pyiterable_to_cppsequentialcontainer`` | Convert an iterable Python type to a C++ sequential container (STL/Qt) |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_pyiterable_to_cppsequentialcontainer_reserve`` | Convert an iterable Python type to a C++ sequential container supporting reserve() |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_pyiterable_to_cpparray`` | Convert an iterable Python type to a fixed-size array (std::array, std::span) |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_pyiterable_to_cppsetcontainer`` | Convert a PySequence to a set-type C++ container (std::set/QSet) |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_stdmap_to_pydict`` | Convert a std::map/std::unordered_map to a PyDict |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_qmap_to_pydict`` | Convert a QMap/QHash to a PyDict |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_pydict_to_stdmap`` | Convert a PyDict to a std::map/std::unordered_map |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_pydict_to_qmap`` | Convert a PyDict to a QMap/QHash |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_stdmultimap_to_pydict`` | Convert a std::multimap to a PyDict of value lists |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_qmultimap_to_pydict`` | Convert a QMultiMap to a PyDict of value lists |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_stdunorderedmultimap_to_pydict`` | Convert a std::unordered_multimap to a PyDict of value lists |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_qmultihash_to_pydict`` | Convert a QMultiHash to a PyDict of value lists |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_pydict_to_stdmultimap`` | Convert a PyDict of value lists to std::multimap/std::unordered_multimap |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
+| ``shiboken_conversion_pydict_to_qmultihash`` | Convert a PyDict of value lists to QMultiMap/QMultiHash |
++----------------------------------------------------------------------+------------------------------------------------------------------------------------+
An entry for the type ``std::list`` using these templates looks like:
@@ -126,9 +131,3 @@ An entry for the type ``std::list`` using these templates looks like:
</target-to-native>
</conversion-rule>
</container-type>
-
-.. note:: From version 6.3, we do not have to explicitly specify the
- `<container-type/>` for C++ containers ``std::list``\, ``std::vector``\,
- ``std::pair``\, ``std::map`` and ``std::unordered_map``\. They are
- now built-in. However, they still have to be added for opaque
- containers or when modifying the built-in behavior.
diff --git a/sources/shiboken6/doc/typesystem_variables.rst b/sources/shiboken6/doc/typesystem_variables.rst
index c6564513b..d40891b9b 100644
--- a/sources/shiboken6/doc/typesystem_variables.rst
+++ b/sources/shiboken6/doc/typesystem_variables.rst
@@ -20,32 +20,30 @@ Variables
.. _cpp_return_argument:
**%0**
-
Replaced by the C++ return variable of the Python method/function wrapper.
.. _arg_number:
**%<number>**
-
Replaced by the name of a C++ argument in the position indicated by ``<number>``.
The argument counting starts with ``%1``, since ``%0`` represents the return
variable name. If the number indicates a variable that was removed in the
type system description, but there is a default value for it, this value will
be used. Consider this example:
- .. code-block:: c++
+ .. code-block:: c++
- void argRemoval(int a0, int a1 = 123);
+ void argRemoval(int a0, int a1 = 123);
- .. code-block:: xml
+ .. code-block:: xml
- <modify-function signature="argRemoval(int, int)">
- <modify-argument index="2">
- <remove-argument/>
- </modify-argument>
- </modify-function>
+ <modify-function signature="argRemoval(int, int)">
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ </modify-function>
The ``%1`` will be replaced by the C++ argument name, and ``%2`` will get the
value ``123``.
@@ -54,7 +52,6 @@ Variables
.. _argument_names:
**%ARGUMENT_NAMES**
-
Replaced by a comma separated list with the names of all C++ arguments that
were not removed on the type system description for the method/function. When
the removed argument has a default value (original or provided in the type
@@ -66,37 +63,36 @@ Variables
Take the following method and related type system description as an example:
- .. code-block:: c++
+ .. code-block:: c++
- void argRemoval(int a0, Point a1 = Point(1, 2), bool a2 = true, Point a3 = Point(3, 4), int a4 = 56);
+ void argRemoval(int a0, Point a1 = Point(1, 2), bool a2 = true, Point a3 = Point(3, 4), int a4 = 56);
- .. code-block:: xml
+ .. code-block:: xml
- <modify-function signature="argRemoval(int, Point, bool, Point, int)">
- <modify-argument index="2">
- <remove-argument/>
- <replace-default-expression with="Point(6, 9)"/>
- </modify-argument>
- <modify-argument index="4">
- <remove-argument/>
- </modify-argument>
- </modify-function>
+ <modify-function signature="argRemoval(int, Point, bool, Point, int)">
+ <modify-argument index="2">
+ <remove-argument/>
+ <replace-default-expression with="Point(6, 9)"/>
+ </modify-argument>
+ <modify-argument index="4">
+ <remove-argument/>
+ </modify-argument>
+ </modify-function>
As seen on the XML description, the function's ``a1`` and ``a3`` arguments
were removed. If any ``inject-code`` for this function uses ``%ARGUMENT_NAMES``
the resulting list will be the equivalent of using individual argument type
system variables this way:
- .. code-block:: c++
+ .. code-block:: c++
- %1, Point(6, 9), %3, Point(3, 4), %5
+ %1, Point(6, 9), %3, Point(3, 4), %5
.. _arg_type:
**%ARG#_TYPE**
-
Replaced by the type of a C++ argument in the position indicated by ``#``.
The argument counting starts with ``%1``, since ``%0`` represents the return
variable in other contexts, but ``%ARG0_TYPE`` will not translate to the
@@ -104,18 +100,18 @@ Variables
:ref:`%RETURN_TYPE <return_type>` variable.
Example:
- .. code-block:: c++
+ .. code-block:: c++
- void argRemoval(int a0, int a1 = 123);
+ void argRemoval(int a0, int a1 = 123);
- .. code-block:: xml
+ .. code-block:: xml
- <modify-function signature="argRemoval(int, int)">
- <modify-argument index="2">
- <remove-argument/>
- </modify-argument>
- </modify-function>
+ <modify-function signature="argRemoval(int, int)">
+ <modify-argument index="2">
+ <remove-argument/>
+ </modify-argument>
+ </modify-function>
The ``%1`` will be replaced by the C++ argument name, and ``%2`` will get the
value ``123``.
@@ -124,40 +120,38 @@ Variables
.. _converttocpp:
**%CONVERTTOCPP[CPPTYPE]**
-
Replaced by a |project| conversion call that converts a Python variable
to a C++ variable of the type indicated by ``CPPTYPE``.
- Typically, this is a variable assignment:
+ Typically, this is a variable assignment:
- .. code-block:: c++
+ .. code-block:: c++
- double value = %CONVERTTOCPP[double](pyValue);
+ double value = %CONVERTTOCPP[double](pyValue);
- Pointer assignments are also possible:
+ Pointer assignments are also possible:
- .. code-block:: c++
+ .. code-block:: c++
- void f(double *valuePtr)
- {
- *valuePtr = %CONVERTTOCPP[double](pyValue);
+ void f(double *valuePtr)
+ {
+ *valuePtr = %CONVERTTOCPP[double](pyValue);
- Note however, that for variable definitions, the type must
- be a space-delimited token:
+ Note however, that for variable definitions, the type must
+ be a space-delimited token:
- .. code-block:: c++
+ .. code-block:: c++
- double * valuePtr = %CONVERTTOCPP[double](pyValue);
+ double * valuePtr = %CONVERTTOCPP[double](pyValue);
- since it otherwise would be indistinguishable from the pointer assignment
- above.
+ since it otherwise would be indistinguishable from the pointer assignment
+ above.
- It is possible to use "auto" as type.
+ It is possible to use "auto" as type.
.. _converttopython:
**%CONVERTTOPYTHON[CPPTYPE]**
-
Replaced by a |project| conversion call that converts a C++ variable of the
type indicated by ``CPPTYPE`` to the proper Python object.
@@ -165,7 +159,6 @@ Variables
.. _isconvertible:
**%ISCONVERTIBLE[CPPTYPE]**
-
Replaced by a |project| "isConvertible" call that checks if a Python
variable is convertible (via an implicit conversion or cast operator call)
to a C++ variable of the type indicated by ``CPPTYPE``.
@@ -174,7 +167,6 @@ Variables
.. _checktype:
**%CHECKTYPE[CPPTYPE]**
-
Replaced by a |project| "checkType" call that verifies if a Python
if of the type indicated by ``CPPTYPE``.
@@ -182,14 +174,12 @@ Variables
.. _cppself:
**%CPPSELF**
-
Replaced by the wrapped C++ object instance that owns the method in which the
code with this variable was inserted.
.. _cpptype:
**%CPPTYPE**
-
Replaced by the original name of the C++ class, without any namespace prefix,
that owns the method in which the code with this variable was inserted. It will
work on class level code injections also. Notice that ``CPPTYPE`` differs from
@@ -202,22 +192,18 @@ Variables
.. _function_name:
**%FUNCTION_NAME**
-
Replaced by the name of a function or method.
-
.. _py_return_argument:
**%PYARG_0**
-
Replaced by the name of the Python return variable of the Python method/function wrapper.
.. _pyarg:
**%PYARG_<number>**
-
Similar to ``%<number>``, but is replaced by the Python arguments (PyObjects)
received by the Python wrapper method.
@@ -228,16 +214,16 @@ Variables
The example
- .. code-block:: c++
+ .. code-block:: c++
- long a = PyLong_AS_LONG(%PYARG_1);
+ long a = PyLong_AS_LONG(%PYARG_1);
is equivalent of
- .. code-block:: c++
+ .. code-block:: c++
- long a = PyLong_AS_LONG(PyTuple_GET_ITEM(%PYTHON_ARGUMENTS, 0));
+ long a = PyLong_AS_LONG(PyTuple_GET_ITEM(%PYTHON_ARGUMENTS, 0));
The generator tries to be smart with attributions, but it will work for the
@@ -245,24 +231,23 @@ Variables
This example
- .. code-block:: c++
+ .. code-block:: c++
- Py_DECREF(%PYARG_1);
- %PYARG_1 = PyLong_FromLong(10);
+ Py_DECREF(%PYARG_1);
+ %PYARG_1 = PyLong_FromLong(10);
is equivalent of
- .. code-block:: c++
+ .. code-block:: c++
- Py_DECREF(PyTuple_GET_ITEM(%PYTHON_ARGUMENTS, 0));
- PyTuple_SET_ITEM(%PYTHON_ARGUMENTS, 0, PyLong_FromLong(10));
+ Py_DECREF(PyTuple_GET_ITEM(%PYTHON_ARGUMENTS, 0));
+ PyTuple_SET_ITEM(%PYTHON_ARGUMENTS, 0, PyLong_FromLong(10));
.. _pyself:
**%PYSELF**
-
Replaced by the Python wrapper variable (a PyObject) representing the instance
bounded to the Python wrapper method which receives the custom code.
@@ -270,7 +255,6 @@ Variables
.. _python_arguments:
**%PYTHON_ARGUMENTS**
-
Replaced by the pointer to the Python tuple with Python objects converted from
the C++ arguments received on the binding override of a virtual method.
This tuple is the same passed as arguments to the Python method overriding the
@@ -280,7 +264,6 @@ Variables
.. _python_method_override:
**%PYTHON_METHOD_OVERRIDE**
-
This variable is used only on :ref:`native method code injections
<codeinjecting_method_native>`, i.e. on the binding overrides for C++ virtual
methods. It is replaced by a pointer to the Python method override.
@@ -289,7 +272,6 @@ Variables
.. _pythontypeobject:
**%PYTHONTYPEOBJECT**
-
Replaced by the Python type object for the context in which it is inserted:
method or class modification.
@@ -297,7 +279,6 @@ Variables
.. _beginallowthreads:
**%BEGIN_ALLOW_THREADS**
-
Replaced by a thread state saving procedure.
Must match with a :ref:`%END_ALLOW_THREADS <endallowthreads>` variable.
@@ -305,7 +286,6 @@ Variables
.. _endallowthreads:
**%END_ALLOW_THREADS**
-
Replaced by a thread state restoring procedure.
Must match with a :ref:`%BEGIN_ALLOW_THREADS <beginallowthreads>` variable.
@@ -313,14 +293,12 @@ Variables
.. _return_type:
**%RETURN_TYPE**
-
Replaced by the type returned by a function or method.
.. _type:
**%TYPE**
-
Replaced by the name of the class to which a function belongs. May be used
in code injected at method or class level.
@@ -335,27 +313,27 @@ sections, below is an excerpt from the type system description of a |project|
test. It changes a method that received ``argc/argv`` arguments into something
that expects a Python sequence instead.
- .. code-block:: xml
-
- <modify-function signature="overloadedMethod(int, char**)">
- <modify-argument index="1">
- <replace-type modified-type="PySequence" />
- </modify-argument>
- <modify-argument index="2">
- <remove-argument />
- </modify-argument>
- <inject-code class="target" position="beginning">
- int argc;
- char** argv;
- if (!PySequence_to_argc_argv(%PYARG_1, &amp;argc, &amp;argv)) {
- PyErr_SetString(PyExc_TypeError, "error");
- return 0;
- }
- %RETURN_TYPE foo = %CPPSELF.%FUNCTION_NAME(argc, argv);
- %0 = %CONVERTTOPYTHON[%RETURN_TYPE](foo);
-
- for (int i = 0; i &lt; argc; ++i)
- delete[] argv[i];
- delete[] argv;
- </inject-code>
- </modify-function>
+.. code-block:: xml
+
+ <modify-function signature="overloadedMethod(int, char**)">
+ <modify-argument index="1">
+ <replace-type modified-type="PySequence" />
+ </modify-argument>
+ <modify-argument index="2">
+ <remove-argument />
+ </modify-argument>
+ <inject-code class="target" position="beginning">
+ int argc;
+ char** argv;
+ if (!PySequence_to_argc_argv(%PYARG_1, &amp;argc, &amp;argv)) {
+ PyErr_SetString(PyExc_TypeError, "error");
+ return 0;
+ }
+ %RETURN_TYPE foo = %CPPSELF.%FUNCTION_NAME(argc, argv);
+ %0 = %CONVERTTOPYTHON[%RETURN_TYPE](foo);
+
+ for (int i = 0; i &lt; argc; ++i)
+ delete[] argv[i];
+ delete[] argv;
+ </inject-code>
+ </modify-function>
diff --git a/sources/shiboken6/generator/CMakeLists.txt b/sources/shiboken6/generator/CMakeLists.txt
index 7706c2b36..aebe2cd5e 100644
--- a/sources/shiboken6/generator/CMakeLists.txt
+++ b/sources/shiboken6/generator/CMakeLists.txt
@@ -1,29 +1,46 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(shibokengenerator)
set(package_name "Shiboken6Tools")
set(CMAKE_AUTOMOC ON)
-if(NOT (Qt${QT_MAJOR_VERSION}Core_FOUND AND PYTHONINTERP_FOUND))
+if(NOT (Qt${QT_MAJOR_VERSION}Core_FOUND AND Python_Interpreter_FOUND))
message(WARNING "Some dependencies were not found: shiboken6 generator compilation disabled!")
return()
endif()
set(shiboken6_SRC
-generator.cpp
-generatorcontext.cpp
-defaultvalue.cpp
-shiboken/cppgenerator.cpp
-shiboken/cppgenerator_container.cpp
-shiboken/generatorargument.cpp
-shiboken/headergenerator.cpp
-shiboken/overloaddata.cpp
-shiboken/shibokengenerator.cpp
+defaultvalue.cpp defaultvalue.h
+generator.cpp generator.h
+generatorcontext.cpp generatorcontext.h
main.cpp
+shiboken/configurablescope.h
+shiboken/cppgenerator.cpp shiboken/cppgenerator.h
+shiboken/cppgenerator_container.cpp
+shiboken/cppgenerator_smartpointer.cpp
+shiboken/ctypenames.h
+shiboken/generatorargument.cpp shiboken/generatorargument.h shiboken/generatorstrings.h
+shiboken/headergenerator.cpp shiboken/headergenerator.h
+shiboken/overloaddata.cpp shiboken/overloaddata.h
+shiboken/pytypenames.h
+shiboken/shibokengenerator.cpp shiboken/shibokengenerator.h
)
+find_libclang()
+
+if(${STANDALONE})
+ list(APPEND CMAKE_INSTALL_RPATH ${base}/Qt/lib)
+else()
+ list(APPEND CMAKE_INSTALL_RPATH ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_LIBS}
+ ${libclang_lib_dir})
+endif()
+
add_executable(shiboken6 ${shiboken6_SRC})
add_executable(Shiboken6::shiboken6 ALIAS shiboken6)
add_dependencies(shiboken6 apiextractor)
+
set_target_properties(shiboken6 PROPERTIES OUTPUT_NAME shiboken6${shiboken6_SUFFIX})
target_include_directories(shiboken6 PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/shiboken
@@ -34,7 +51,11 @@ target_include_directories(shiboken6 PRIVATE
)
target_link_libraries(shiboken6 apiextractor Qt::Core)
if (NOT DISABLE_DOCSTRINGS)
- target_sources(shiboken6 PRIVATE qtdoc/qtxmltosphinx.cpp qtdoc/qtdocgenerator.cpp)
+ target_sources(shiboken6 PRIVATE
+ qtdoc/qtdocgenerator.cpp qtdoc/qtdocgenerator.h
+ qtdoc/qtxmltosphinx.cpp qtdoc/qtxmltosphinx.h
+ qtdoc/qtxmltosphinxinterface.h
+ qtdoc/rstformat.h)
target_compile_definitions(shiboken6 PUBLIC DOCSTRINGS_ENABLED QT_LEAN_HEADERS=1)
endif()
diff --git a/sources/shiboken6/generator/_config.py.in b/sources/shiboken6/generator/_config.py.in
index 985735fa4..ed7e67098 100644
--- a/sources/shiboken6/generator/_config.py.in
+++ b/sources/shiboken6/generator/_config.py.in
@@ -7,3 +7,4 @@ version_info = (@shiboken_MAJOR_VERSION@, @shiboken_MINOR_VERSION@, @shiboken_MI
@PACKAGE_BUILD_COMMIT_HASH_DESCRIBED@
@PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT@
@PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT@
+@QT_MACOS_DEPLOYMENT_TARGET@
diff --git a/sources/shiboken6/generator/defaultvalue.cpp b/sources/shiboken6/generator/defaultvalue.cpp
index c3983a2e3..89cc9fa77 100644
--- a/sources/shiboken6/generator/defaultvalue.cpp
+++ b/sources/shiboken6/generator/defaultvalue.cpp
@@ -47,7 +47,7 @@ QString DefaultValue::returnValue() const
case DefaultValue::Pointer:
return u"nullptr"_s;
case DefaultValue::Void:
- return QString();
+ return {};
case DefaultValue::DefaultConstructorWithDefaultValues:
return m_value + u"()"_s;
case DefaultValue::DefaultConstructor:
@@ -76,7 +76,7 @@ QString DefaultValue::initialization() const
case DefaultValue::DefaultConstructorWithDefaultValues:
break;
}
- return QString();
+ return {};
}
QString DefaultValue::constructorParameter() const
diff --git a/sources/shiboken6/generator/generator.cpp b/sources/shiboken6/generator/generator.cpp
index b1accb74b..a01326530 100644
--- a/sources/shiboken6/generator/generator.cpp
+++ b/sources/shiboken6/generator/generator.cpp
@@ -10,6 +10,7 @@
#include "abstractmetafunction.h"
#include "abstractmetalang.h"
#include "messages.h"
+#include <optionsparser.h>
#include "reporthandler.h"
#include "fileout.h"
#include "arraytypeentry.h"
@@ -29,8 +30,14 @@
using namespace Qt::StringLiterals;
-static const char ENABLE_PYSIDE_EXTENSIONS[] = "enable-pyside-extensions";
-static const char AVOID_PROTECTED_HACK[] = "avoid-protected-hack";
+static constexpr auto ENABLE_PYSIDE_EXTENSIONS = "enable-pyside-extensions"_L1;
+static constexpr auto AVOID_PROTECTED_HACK = "avoid-protected-hack"_L1;
+
+struct GeneratorOptions
+{
+ bool usePySideExtensions = false;
+ bool avoidProtectedHack = false;
+};
struct Generator::GeneratorPrivate
{
@@ -40,10 +47,14 @@ struct Generator::GeneratorPrivate
QString licenseComment;
AbstractMetaClassCList m_invisibleTopNamespaces;
bool m_hasPrivateClasses = false;
- bool m_usePySideExtensions = false;
- bool m_avoidProtectedHack = false;
+ static GeneratorOptions m_options;
};
+GeneratorOptions Generator::GeneratorPrivate::m_options;
+
+// Kept as a variable for a potential Qt-in-namespace support
+QString Generator::m_gsp = "::"_L1;
+
Generator::Generator() : m_d(new GeneratorPrivate)
{
}
@@ -66,10 +77,10 @@ bool Generator::setup(const ApiExtractorResult &api)
return false;
}
- for (auto c : api.classes()) {
+ for (const auto &c : api.classes()) {
if (c->enclosingClass() == nullptr && c->isInvisibleNamespace()) {
m_d->m_invisibleTopNamespaces.append(c);
- c->invisibleNamespaceRecursion([&](const AbstractMetaClass *ic) {
+ c->invisibleNamespaceRecursion([&](const AbstractMetaClassCPtr &ic) {
m_d->m_invisibleTopNamespaces.append(ic);
});
}
@@ -78,33 +89,51 @@ bool Generator::setup(const ApiExtractorResult &api)
return doSetup();
}
-Generator::OptionDescriptions Generator::options() const
+QList<OptionDescription> Generator::options()
{
return {
- {QLatin1StringView(AVOID_PROTECTED_HACK),
+ {AVOID_PROTECTED_HACK,
u"Avoid the use of the '#define protected public' hack."_s},
- {QLatin1StringView(ENABLE_PYSIDE_EXTENSIONS),
+ {ENABLE_PYSIDE_EXTENSIONS,
u"Enable PySide extensions, such as support for signal/slots,\n"
"use this if you are creating a binding for a Qt-based library."_s}
};
}
-bool Generator::handleOption(const QString & key, const QString & /* value */)
+class GeneratorOptionsParser : public OptionsParser
+{
+public:
+ explicit GeneratorOptionsParser(GeneratorOptions *o) : m_options(o) {}
+
+ bool handleBoolOption(const QString &key, OptionSource source) override;
+
+private:
+ GeneratorOptions *m_options;
+};
+
+bool GeneratorOptionsParser::handleBoolOption(const QString & key, OptionSource source)
{
- if (key == QLatin1StringView(ENABLE_PYSIDE_EXTENSIONS))
- return ( m_d->m_usePySideExtensions = true);
- if (key == QLatin1StringView(AVOID_PROTECTED_HACK))
- return (m_d->m_avoidProtectedHack = true);
+ if (source == OptionSource::CommandLineSingleDash)
+ return false;
+ if (key == ENABLE_PYSIDE_EXTENSIONS)
+ return ( m_options->usePySideExtensions = true);
+ if (key == AVOID_PROTECTED_HACK)
+ return ( m_options->avoidProtectedHack = true);
return false;
}
+std::shared_ptr<OptionsParser> Generator::createOptionsParser()
+{
+ return std::make_shared<GeneratorOptionsParser>(&GeneratorPrivate::m_options);
+}
+
QString Generator::fileNameForContextHelper(const GeneratorContext &context,
const QString &suffix,
FileNameFlags flags)
{
if (!context.forSmartPointer()) {
- const AbstractMetaClass *metaClass = context.metaClass();
+ const auto metaClass = context.metaClass();
QString fileNameBase = flags.testFlag(FileNameFlag::UnqualifiedName)
? metaClass->name() : metaClass->qualifiedCppName();
if (!flags.testFlag(FileNameFlag::KeepCase))
@@ -176,7 +205,7 @@ void Generator::setOutputDirectory(const QString &outDir)
bool Generator::generateFileForContext(const GeneratorContext &context)
{
- const AbstractMetaClass *cls = context.metaClass();
+ const auto cls = context.metaClass();
auto typeEntry = cls->typeEntry();
if (!shouldGenerate(typeEntry))
@@ -202,23 +231,23 @@ QString Generator::getFileNameBaseForSmartPointer(const AbstractMetaType &smartP
const AbstractMetaType innerType = smartPointerType.getSmartPointerInnerType();
smartPointerType.typeEntry()->qualifiedCppName();
QString fileName = smartPointerType.typeEntry()->qualifiedCppName().toLower();
- fileName.replace(u"::"_s, u"_"_s);
- fileName.append(u"_"_s);
+ fileName.append(u'_');
fileName.append(innerType.name().toLower());
-
+ fileName.replace(u"::"_s, u"_"_s); // std::shared_ptr<std::string>
return fileName;
}
-GeneratorContext Generator::contextForClass(const AbstractMetaClass *c) const
+GeneratorContext Generator::contextForClass(const AbstractMetaClassCPtr &c) const
{
GeneratorContext result;
result.m_metaClass = c;
return result;
}
-GeneratorContext Generator::contextForSmartPointer(const AbstractMetaClass *c,
- const AbstractMetaType &t,
- const AbstractMetaClass *pointeeClass)
+GeneratorContext
+ Generator::contextForSmartPointer(const AbstractMetaClassCPtr &c,
+ const AbstractMetaType &t,
+ const AbstractMetaClassCPtr &pointeeClass)
{
GeneratorContext result;
result.m_metaClass = c;
@@ -230,7 +259,7 @@ GeneratorContext Generator::contextForSmartPointer(const AbstractMetaClass *c,
bool Generator::generate()
{
- for (auto cls : m_d->api.classes()) {
+ for (const auto &cls : m_d->api.classes()) {
if (!generateFileForContext(contextForClass(cls)))
return false;
auto te = cls->typeEntry();
@@ -239,7 +268,7 @@ bool Generator::generate()
}
for (const auto &smp: m_d->api.instantiatedSmartPointers()) {
- const AbstractMetaClass *pointeeClass = nullptr;
+ AbstractMetaClassCPtr pointeeClass;
const auto instantiatedType = smp.type.instantiations().constFirst().typeEntry();
if (instantiatedType->isComplex()) // not a C++ primitive
pointeeClass = AbstractMetaClass::findClass(m_d->api.classes(), instantiatedType);
@@ -266,24 +295,22 @@ bool Generator::hasPrivateClasses() const
return m_d->m_hasPrivateClasses;
}
-bool Generator::usePySideExtensions() const
+bool Generator::usePySideExtensions()
{
- return m_d->m_usePySideExtensions;
+ return GeneratorPrivate::m_options.usePySideExtensions;
}
-bool Generator::avoidProtectedHack() const
+bool Generator::avoidProtectedHack()
{
- return m_d->m_avoidProtectedHack;
+ return GeneratorPrivate::m_options.avoidProtectedHack;
}
QString Generator::getFullTypeName(TypeEntryCPtr type)
{
QString result = type->qualifiedCppName();
if (type->isArray())
- type = qSharedPointerCast<const ArrayTypeEntry>(type)->nestedTypeEntry();
- if (!isCppPrimitive(type))
- result.prepend(u"::"_s);
- return result;
+ type = std::static_pointer_cast<const ArrayTypeEntry>(type)->nestedTypeEntry();
+ return isCppPrimitive(type) ? result : addGlobalScopePrefix(result);
}
QString Generator::getFullTypeName(const AbstractMetaType &type)
@@ -293,7 +320,7 @@ QString Generator::getFullTypeName(const AbstractMetaType &type)
if (type.isVoidPointer())
return u"void*"_s;
if (type.typeEntry()->isContainer())
- return u"::"_s + type.cppSignature();
+ return addGlobalScopePrefix(type.cppSignature());
QString typeName;
if (type.typeEntry()->isComplex() && type.hasInstantiations())
typeName = getFullTypeNameWithoutModifiers(type);
@@ -302,9 +329,11 @@ QString Generator::getFullTypeName(const AbstractMetaType &type)
return typeName + QString::fromLatin1("*").repeated(type.indirections());
}
-QString Generator::getFullTypeName(const AbstractMetaClass *metaClass)
+QString Generator::getFullTypeName(const AbstractMetaClassCPtr &metaClass)
{
- return u"::"_s + metaClass->qualifiedCppName();
+ const QString &qualName = metaClass->qualifiedCppName();
+ // Typedefs are generated into the global namespace
+ return metaClass->isTypeDef() ? qualName : addGlobalScopePrefix(qualName);
}
QString Generator::getFullTypeNameWithoutModifiers(const AbstractMetaType &type)
@@ -330,7 +359,7 @@ QString Generator::getFullTypeNameWithoutModifiers(const AbstractMetaType &type)
}
while (typeName.endsWith(u'*') || typeName.endsWith(u' '))
typeName.chop(1);
- return u"::"_s + typeName;
+ return addGlobalScopePrefix(typeName);
}
std::optional<DefaultValue>
@@ -359,13 +388,13 @@ std::optional<DefaultValue>
if (type.isNativePointer())
return DefaultValue(DefaultValue::Pointer, type.typeEntry()->qualifiedCppName());
if (type.isPointer())
- return DefaultValue(DefaultValue::Pointer, u"::"_s + type.typeEntry()->qualifiedCppName());
+ return DefaultValue(DefaultValue::Pointer, getFullTypeName(type.typeEntry()));
if (type.typeEntry()->isSmartPointer())
return minimalConstructor(api, type.typeEntry());
if (type.typeEntry()->isComplex()) {
- auto cType = qSharedPointerCast<const ComplexTypeEntry>(type.typeEntry());
+ auto cType = std::static_pointer_cast<const ComplexTypeEntry>(type.typeEntry());
if (cType->hasDefaultConstructor())
return DefaultValue(DefaultValue::Custom, cType->defaultConstructor());
auto klass = AbstractMetaClass::findClass(api.classes(), cType);
@@ -404,12 +433,11 @@ std::optional<DefaultValue>
}
if (type->isEnum()) {
- const auto enumEntry = qSharedPointerCast<const EnumTypeEntry>(type);
- if (const auto nullValue = enumEntry->nullValue(); !nullValue.isNull())
+ const auto enumEntry = std::static_pointer_cast<const EnumTypeEntry>(type);
+ if (const auto nullValue = enumEntry->nullValue())
return DefaultValue(DefaultValue::Enum, nullValue->name());
return DefaultValue(DefaultValue::Custom,
- u"static_cast< ::"_s + type->qualifiedCppName()
- + u">(0)"_s);
+ "static_cast< "_L1 + getFullTypeName(type) + ">(0)"_L1);
}
if (type->isFlags()) {
@@ -418,7 +446,7 @@ std::optional<DefaultValue>
}
if (type->isPrimitive()) {
- QString ctor = qSharedPointerCast<const PrimitiveTypeEntry>(type)->defaultConstructor();
+ QString ctor = std::static_pointer_cast<const PrimitiveTypeEntry>(type)->defaultConstructor();
// If a non-C++ (i.e. defined by the user) primitive type does not have
// a default constructor defined by the user, the empty constructor is
// heuristically returned. If this is wrong the build of the generated
@@ -455,13 +483,13 @@ static QString constructorCall(const QString &qualifiedCppName, const QStringLis
std::optional<DefaultValue>
Generator::minimalConstructor(const ApiExtractorResult &api,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
QString *errorString)
{
if (!metaClass)
return {};
- auto cType = qSharedPointerCast<const ComplexTypeEntry>(metaClass->typeEntry());
+ auto cType = std::static_pointer_cast<const ComplexTypeEntry>(metaClass->typeEntry());
if (cType->hasDefaultConstructor())
return DefaultValue(DefaultValue::Custom, cType->defaultConstructor());
@@ -501,8 +529,7 @@ std::optional<DefaultValue>
for (auto it = candidates.cbegin(), end = candidates.cend(); it != end; ++it) {
const AbstractMetaArgumentList &arguments = it.value()->arguments();
QStringList args;
- for (qsizetype i = 0, size = arguments.size(); i < size; ++i) {
- const AbstractMetaArgument &arg = arguments.at(i);
+ for (const auto &arg : arguments) {
if (arg.hasModifiedDefaultValueExpression()) {
args << arg.defaultValueExpression(); // Spell out modified values
break;
@@ -521,7 +548,7 @@ std::optional<DefaultValue>
}
QString Generator::translateType(AbstractMetaType cType,
- const AbstractMetaClass *context,
+ const AbstractMetaClassCPtr &context,
Options options) const
{
QString s;
@@ -537,20 +564,20 @@ QString Generator::translateType(AbstractMetaType cType,
} else if (cType.isArray()) {
s = translateType(*cType.arrayElementType(), context, options) + u"[]"_s;
} else {
+ AbstractMetaType copyType = cType;
if (options & Generator::ExcludeConst || options & Generator::ExcludeReference) {
- AbstractMetaType copyType = cType;
-
if (options & Generator::ExcludeConst)
copyType.setConstant(false);
-
if (options & Generator::ExcludeReference)
copyType.setReferenceType(NoReference);
+ }
- s = copyType.cppSignature();
- if (!copyType.typeEntry()->isVoid() && !isCppPrimitive(copyType.typeEntry()))
- s.prepend(u"::"_s);
- } else {
- s = cType.cppSignature();
+ s = copyType.cppSignature();
+ const auto te = copyType.typeEntry();
+ if (!te->isVoid() && !isCppPrimitive(te)) { // Add scope resolution
+ const auto pos = s.indexOf(te->qualifiedCppName()); // Skip const/volatile
+ Q_ASSERT(pos >= 0);
+ s.insert(pos, u"::"_s);
}
}
@@ -574,7 +601,6 @@ static const QHash<QString, QString> &pythonOperators()
{u"operator++"_s, u"__iadd__"_s},
{u"operator--"_s, u"__isub__"_s},
{u"operator*="_s, u"__imul__"_s},
- {u"operator/="_s, u"__idiv__"_s},
{u"operator%="_s, u"__imod__"_s},
// Bitwise operators
{u"operator&"_s, u"__and__"_s},
@@ -595,7 +621,10 @@ static const QHash<QString, QString> &pythonOperators()
{u"operator<"_s, u"__lt__"_s},
{u"operator>"_s, u"__gt__"_s},
{u"operator<="_s, u"__le__"_s},
- {u"operator>="_s, u"__ge__"_s}
+ {u"operator>="_s, u"__ge__"_s},
+ // Conversion (note bool has special handling with heuristics)
+ {u"operator int"_s, u"__int__"_s},
+ {u"operator double"_s, u"__float__"_s}
};
return result;
}
@@ -605,6 +634,11 @@ QString Generator::pythonOperatorFunctionName(const QString &cppOpFuncName)
return pythonOperators().value(cppOpFuncName);
}
+bool Generator::isPythonOperatorFunctionName(const QString &cppOpFuncName)
+{
+ return pythonOperators().contains(cppOpFuncName);
+}
+
QString Generator::subDirectoryForPackage(QString packageNameIn) const
{
if (packageNameIn.isEmpty())
@@ -613,11 +647,21 @@ QString Generator::subDirectoryForPackage(QString packageNameIn) const
return packageNameIn;
}
+QString Generator::addGlobalScopePrefix(const QString &t)
+{
+ return t.startsWith("std::"_L1) ? t : m_gsp + t;
+}
+
+QString Generator::globalScopePrefix(const GeneratorContext &classContext)
+{
+ return classContext.useWrapper() ? QString{} : m_gsp;
+}
+
template<typename T>
-static QString getClassTargetFullName_(const T *t, bool includePackageName)
+static QString getClassTargetFullName_(T t, bool includePackageName)
{
QString name = t->name();
- const AbstractMetaClass *context = t->enclosingClass();
+ AbstractMetaClassCPtr context = t->enclosingClass();
while (context) {
// If the type was marked as 'visible=false' we should not use it in
// the type name
@@ -634,12 +678,14 @@ static QString getClassTargetFullName_(const T *t, bool includePackageName)
return name;
}
-QString getClassTargetFullName(const AbstractMetaClass *metaClass, bool includePackageName)
+QString getClassTargetFullName(const AbstractMetaClassCPtr &metaClass,
+ bool includePackageName)
{
return getClassTargetFullName_(metaClass, includePackageName);
}
-QString getClassTargetFullName(const AbstractMetaEnum &metaEnum, bool includePackageName)
+QString getClassTargetFullName(const AbstractMetaEnum &metaEnum,
+ bool includePackageName)
{
return getClassTargetFullName_(&metaEnum, includePackageName);
}
diff --git a/sources/shiboken6/generator/generator.h b/sources/shiboken6/generator/generator.h
index 131ad427d..5b051b599 100644
--- a/sources/shiboken6/generator/generator.h
+++ b/sources/shiboken6/generator/generator.h
@@ -6,18 +6,23 @@
#include <abstractmetalang_typedefs.h>
#include <typedatabase_typedefs.h>
-#include <QtCore/QSharedPointer>
#include <QtCore/QList>
+#include <memory>
#include <optional>
+
class ApiExtractorResult;
class GeneratorContext;
class DefaultValue;
+struct OptionDescription;
+class OptionsParser;
class TextStream;
-QString getClassTargetFullName(const AbstractMetaClass *metaClass, bool includePackageName = true);
-QString getClassTargetFullName(const AbstractMetaEnum &metaEnum, bool includePackageName = true);
+QString getClassTargetFullName(const AbstractMetaClassCPtr &metaClass,
+ bool includePackageName = true);
+QString getClassTargetFullName(const AbstractMetaEnum &metaEnum,
+ bool includePackageName = true);
QString getFilteredCppSignatureString(QString signature);
/**
@@ -25,12 +30,11 @@ QString getFilteredCppSignatureString(QString signature);
* you must subclass this to create your own generators.
*/
class Generator
-{
+{;
public:
- using OptionDescription = QPair<QString, QString>;
- using OptionDescriptions = QList<OptionDescription>;
+ Q_DISABLE_COPY_MOVE(Generator)
- /// Optiosn used around the generator code
+ /// Options used around the generator code
enum Option {
NoOption = 0x00000000,
ExcludeConst = 0x00000001,
@@ -56,8 +60,8 @@ public:
bool setup(const ApiExtractorResult &api);
- virtual OptionDescriptions options() const;
- virtual bool handleOption(const QString &key, const QString &value);
+ static QList<OptionDescription> options();
+ static std::shared_ptr<OptionsParser> createOptionsParser();
/// Returns the top namespace made invisible
const AbstractMetaClassCList &invisibleTopNamespaces() const;
@@ -91,10 +95,10 @@ public:
bool hasPrivateClasses() const;
/// Returns true if the user enabled PySide extensions (command line option)
- bool usePySideExtensions() const;
+ static bool usePySideExtensions();
/// Returns true if the generated code should not use the
/// "#define protected public" hack.
- bool avoidProtectedHack() const;
+ static bool avoidProtectedHack();
/**
* Retrieves the name of the currently processed module.
@@ -107,6 +111,7 @@ public:
static QString moduleName();
static QString pythonOperatorFunctionName(const QString &cppOpFuncName);
+ static bool isPythonOperatorFunctionName(const QString &cppOpFuncName);
protected:
/// Helper for determining the file name
@@ -120,10 +125,10 @@ protected:
/// Returns all container types found by APIExtractor
static ContainerTypeEntryCList containerTypes();
- virtual GeneratorContext contextForClass(const AbstractMetaClass *c) const;
- static GeneratorContext contextForSmartPointer(const AbstractMetaClass *c,
- const AbstractMetaType &t,
- const AbstractMetaClass *pointeeClass = nullptr);
+ virtual GeneratorContext contextForClass(const AbstractMetaClassCPtr &c) const;
+ static GeneratorContext
+ contextForSmartPointer(const AbstractMetaClassCPtr &c, const AbstractMetaType &t,
+ const AbstractMetaClassCPtr &pointeeClass = {});
/// Generates a file for given AbstractMetaClass or AbstractMetaType (smart pointer case).
bool generateFileForContext(const GeneratorContext &context);
@@ -142,7 +147,7 @@ protected:
* \return the metatype translated to binding source format
*/
QString translateType(AbstractMetaType metatype,
- const AbstractMetaClass *context,
+ const AbstractMetaClassCPtr &context,
Options options = NoOption) const;
/**
@@ -153,7 +158,7 @@ protected:
// Returns the full name of the type.
static QString getFullTypeName(TypeEntryCPtr type);
static QString getFullTypeName(const AbstractMetaType &type);
- static QString getFullTypeName(const AbstractMetaClass *metaClass);
+ static QString getFullTypeName(const AbstractMetaClassCPtr &metaClass);
/**
* Returns the full qualified C++ name for an AbstractMetaType, but removing modifiers
@@ -175,7 +180,7 @@ protected:
QString *errorString = nullptr);
static std::optional<DefaultValue>
minimalConstructor(const ApiExtractorResult &api,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
QString *errorString = nullptr);
/**
@@ -209,6 +214,11 @@ protected:
*/
virtual QString subDirectoryForPackage(QString packageName = QString()) const;
+ static QString addGlobalScopePrefix(const QString &t);
+ static QString globalScopePrefix(const GeneratorContext &classContext);
+
+ static QString m_gsp;
+
private:
struct GeneratorPrivate;
GeneratorPrivate *m_d;
@@ -217,7 +227,7 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(Generator::Options)
Q_DECLARE_OPERATORS_FOR_FLAGS(Generator::FileNameFlags)
-using GeneratorPtr = QSharedPointer<Generator>;
+using GeneratorPtr = std::shared_ptr<Generator>;
using Generators = QList<GeneratorPtr>;
#endif // GENERATOR_H
diff --git a/sources/shiboken6/generator/generatorcontext.h b/sources/shiboken6/generator/generatorcontext.h
index 573f98758..2e58d4346 100644
--- a/sources/shiboken6/generator/generatorcontext.h
+++ b/sources/shiboken6/generator/generatorcontext.h
@@ -31,9 +31,9 @@ public:
GeneratorContext() = default;
- const AbstractMetaClass *metaClass() const { return m_metaClass; }
+ AbstractMetaClassCPtr metaClass() const { return m_metaClass; }
const AbstractMetaType &preciseType() const { return m_preciseClassType; }
- const AbstractMetaClass *pointeeClass() const { return m_pointeeClass; }
+ AbstractMetaClassCPtr pointeeClass() const { return m_pointeeClass; }
bool forSmartPointer() const { return m_type == SmartPointer; }
bool useWrapper() const { return m_type == WrappedClass; }
@@ -44,8 +44,8 @@ public:
QString effectiveClassName() const;
private:
- const AbstractMetaClass *m_metaClass = nullptr;
- const AbstractMetaClass *m_pointeeClass = nullptr;
+ AbstractMetaClassCPtr m_metaClass;
+ AbstractMetaClassCPtr m_pointeeClass;
AbstractMetaType m_preciseClassType;
QString m_wrappername;
Type m_type = Class;
diff --git a/sources/shiboken6/generator/main.cpp b/sources/shiboken6/generator/main.cpp
index 5c9d9320c..9871df206 100644
--- a/sources/shiboken6/generator/main.cpp
+++ b/sources/shiboken6/generator/main.cpp
@@ -9,12 +9,13 @@
#include <apiextractor.h>
#include <apiextractorresult.h>
+#include <exception.h>
#include <fileout.h>
#include <messages.h>
+#include <optionsparser.h>
#include <reporthandler.h>
#include <typedatabase.h>
-#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QLibrary>
@@ -27,280 +28,8 @@
using namespace Qt::StringLiterals;
-static const QChar clangOptionsSplitter = u',';
-static const QChar keywordsSplitter = u',';
-static const QChar dropTypeEntriesSplitter = u';';
-static const QChar apiVersionSplitter = u'|';
-
-static inline QString keywordsOption() { return QStringLiteral("keywords"); }
-static inline QString clangOptionOption() { return QStringLiteral("clang-option"); }
-static inline QString clangOptionsOption() { return QStringLiteral("clang-options"); }
-static inline QString compilerOption() { return QStringLiteral("compiler"); }
-static inline QString compilerPathOption() { return QStringLiteral("compiler-path"); }
-static inline QString platformOption() { return QStringLiteral("platform"); }
-static inline QString apiVersionOption() { return QStringLiteral("api-version"); }
-static inline QString dropTypeEntriesOption() { return QStringLiteral("drop-type-entries"); }
-static inline QString languageLevelOption() { return QStringLiteral("language-level"); }
-static inline QString includePathOption() { return QStringLiteral("include-paths"); }
-static inline QString frameworkIncludePathOption() { return QStringLiteral("framework-include-paths"); }
-static inline QString systemIncludePathOption() { return QStringLiteral("system-include-paths"); }
-static inline QString typesystemPathOption() { return QStringLiteral("typesystem-paths"); }
-static inline QString helpOption() { return QStringLiteral("help"); }
-static inline QString diffOption() { return QStringLiteral("diff"); }
-static inline QString useGlobalHeaderOption() { return QStringLiteral("use-global-header"); }
-static inline QString dryrunOption() { return QStringLiteral("dry-run"); }
-static inline QString skipDeprecatedOption() { return QStringLiteral("skip-deprecated"); }
-static inline QString printBuiltinTypesOption() { return QStringLiteral("print-builtin-types"); }
-
static const char helpHint[] = "Note: use --help or -h for more information.\n";
-
-using OptionDescriptions = Generator::OptionDescriptions;
-
-struct CommandLineArguments
-{
- void addToOptionsList(const QString &option,
- const QString &value);
- void addToOptionsList(const QString &option,
- const QStringList &value);
- void addToOptionsList(const QString &option,
- const QString &listValue,
- QChar separator);
- void addToOptionsPathList(const QString &option,
- const QString &pathListValue)
- {
- addToOptionsList(option, pathListValue, QDir::listSeparator());
- }
-
- bool addCommonOption(const QString &option, const QString &value);
-
- QVariantMap options; // string,stringlist for path lists, etc.
- QStringList positionalArguments;
-};
-
-void CommandLineArguments::addToOptionsList(const QString &option,
- const QString &value)
-{
- auto it = options.find(option);
- if (it == options.end()) {
- options.insert(option, QVariant(QStringList(value)));
- } else {
- auto list = it.value().toStringList();
- list += value;
- options[option] = QVariant(list);
- }
-}
-
-void CommandLineArguments::addToOptionsList(const QString &option,
- const QStringList &value)
-{
- auto it = options.find(option);
- if (it == options.end()) {
- options.insert(option, QVariant(value));
- } else {
- auto list = it.value().toStringList();
- list += value;
- options[option] = QVariant(list);
- }
-}
-
-void CommandLineArguments::addToOptionsList(const QString &option,
- const QString &listValue,
- QChar separator)
-{
- const auto newValues = listValue.split(separator, Qt::SkipEmptyParts);
- addToOptionsList(option, newValues);
-}
-
-// Add options common to project file and command line
-bool CommandLineArguments::addCommonOption(const QString &option,
- const QString &value)
-{
- bool result = true;
- if (option == compilerOption() || option == compilerPathOption()
- || option == platformOption()) {
- options.insert(option, value);
- } else if (option == clangOptionOption()) {
- options.insert(option, QStringList(value));
- } else if (option == clangOptionsOption()) {
- addToOptionsList(option, value, clangOptionsSplitter);
- } else if (option == apiVersionOption()) {
- addToOptionsList(option, value, apiVersionSplitter);
- } else if (option == keywordsOption()) {
- addToOptionsList(option, value, keywordsSplitter);
- } else if (option == dropTypeEntriesOption()) {
- addToOptionsList(option, value, dropTypeEntriesSplitter);
- } else {
- result = false;
- }
- return result;
-}
-
-static void printOptions(QTextStream &s, const OptionDescriptions &options)
-{
- s.setFieldAlignment(QTextStream::AlignLeft);
- for (const auto &od : options) {
- if (!od.first.startsWith(u'-'))
- s << "--";
- s << od.first;
- if (od.second.isEmpty()) {
- s << ", ";
- } else {
- s << Qt::endl;
- const auto lines = QStringView{od.second}.split(u'\n');
- for (const auto &line : lines)
- s << " " << line << Qt::endl;
- s << Qt::endl;
- }
- }
-}
-
-// Return the file command line option matching a project file keyword
-static QString projectFileKeywordToCommandLineOption(const QString &p)
-{
- if (p == u"include-path")
- return includePathOption(); // "include-paths", ...
- if (p == u"framework-include-path")
- return frameworkIncludePathOption();
- if (p == u"typesystem-path")
- return typesystemPathOption();
- if (p == u"system-include-paths")
- return systemIncludePathOption();
- return {};
-}
-
-static void processProjectFileLine(const QByteArray &line, CommandLineArguments &args)
-{
- if (line.isEmpty())
- return;
- const QString lineS = QString::fromUtf8(line);
- const auto split = line.indexOf(u'=');
- if (split < 0) {
- args.options.insert(lineS, QString{});
- return;
- }
-
- const QString key = lineS.left(split).trimmed();
- const QString value = lineS.mid(split + 1).trimmed();
- const QString fileOption = projectFileKeywordToCommandLineOption(key);
- if (fileOption.isEmpty()) {
- if (key == u"header-file") {
- args.positionalArguments.prepend(value);
- } else if (key == u"typesystem-file") {
- args.positionalArguments.append(value);
- } else {
- args.options.insert(key, value);
- }
- } else {
- // Add single line value to the path list
- args.addToOptionsList(fileOption, QDir::toNativeSeparators(value));
- }
-}
-
-static std::optional<CommandLineArguments>
- processProjectFile(const QString &appName, QFile &projectFile)
-{
- QByteArray line = projectFile.readLine().trimmed();
- if (line.isEmpty() || line != "[generator-project]") {
- std::cerr << qPrintable(appName) << ": first line of project file \""
- << qPrintable(projectFile.fileName())
- << "\" must be the string \"[generator-project]\"\n";
- return {};
- }
-
- CommandLineArguments args;
- while (!projectFile.atEnd())
- processProjectFileLine(projectFile.readLine().trimmed(), args);
- return args;
-}
-
-static std::optional<CommandLineArguments> getProjectFileArguments()
-{
- QStringList arguments = QCoreApplication::arguments();
- QString appName = arguments.constFirst();
- arguments.removeFirst();
-
- QString projectFileName;
- for (const QString &arg : std::as_const(arguments)) {
- if (arg.startsWith(u"--project-file")) {
- int split = arg.indexOf(u'=');
- if (split > 0)
- projectFileName = arg.mid(split + 1).trimmed();
- break;
- }
- }
-
- if (projectFileName.isEmpty())
- return CommandLineArguments{};
-
- if (!QFile::exists(projectFileName)) {
- std::cerr << qPrintable(appName) << ": Project file \""
- << qPrintable(projectFileName) << "\" not found.\n";
- return {};
- }
-
- QFile projectFile(projectFileName);
- if (!projectFile.open(QIODevice::ReadOnly)) {
- std::cerr << qPrintable(appName) << ": Cannot open project file \""
- << qPrintable(projectFileName) << "\" : " << qPrintable(projectFile.errorString())
- << '\n';
- return {};
- }
- return processProjectFile(appName, projectFile);
-}
-
-static void getCommandLineArg(QString arg, int &argNum, CommandLineArguments &args)
-{
- if (arg.startsWith(u"--")) {
- arg.remove(0, 2);
- const auto split = arg.indexOf(u'=');
- if (split < 0) {
- args.options.insert(arg, QString());
- return;
- }
- const QString option = arg.left(split);
- const QString value = arg.mid(split + 1).trimmed();
- if (args.addCommonOption(option, value)) {
- } else if (option == includePathOption() || option == frameworkIncludePathOption()
- || option == systemIncludePathOption() || option == typesystemPathOption()) {
- // Add platform path-separator separated list value to path list
- args.addToOptionsPathList(option, value);
- } else {
- args.options.insert(option, value);
- }
- return;
- }
- if (arg.startsWith(u'-')) {
- arg.remove(0, 1);
- if (arg.startsWith(u'I')) // Shorthand path arguments -I/usr/include...
- args.addToOptionsPathList(includePathOption(), arg.mid(1));
- else if (arg.startsWith(u'F'))
- args.addToOptionsPathList(frameworkIncludePathOption(), arg.mid(1));
- else if (arg.startsWith(u"isystem"))
- args.addToOptionsPathList(systemIncludePathOption(), arg.mid(7));
- else if (arg.startsWith(u'T'))
- args.addToOptionsPathList(typesystemPathOption(), arg.mid(1));
- else if (arg == u"h")
- args.options.insert(helpOption(), QString());
- else if (arg.startsWith(u"std="))
- args.options.insert(languageLevelOption(), arg.mid(4));
- else
- args.options.insert(arg, QString());
- return;
- }
- if (argNum < args.positionalArguments.size())
- args.positionalArguments[argNum] = arg;
- else
- args.positionalArguments.append(arg);
- ++argNum;
-}
-
-static void getCommandLineArgs(CommandLineArguments &args)
-{
- const QStringList arguments = QCoreApplication::arguments();
- int argNum = 0;
- for (qsizetype i = 1, size = arguments.size(); i < size; ++i)
- getCommandLineArg(arguments.at(i).trimmed(), argNum, args);
-}
+static const char appName[] = "shiboken";
static inline Generators docGenerators()
{
@@ -318,66 +47,57 @@ static inline Generators shibokenGenerators()
return result;
}
-static inline QString languageLevelDescription()
+struct CommonOptions
{
- return u"C++ Language level (c++11..c++17, default="_s
- + QLatin1StringView(clang::languageLevelOption(clang::emulatedCompilerLanguageLevel()))
- + u')';
-}
+ QString generatorSet;
+ QString licenseComment;
+ QString outputDirectory = u"out"_s;
+ QStringList headers;
+ QString typeSystemFileName;
+ bool help = false;
+ bool version = false;
+ bool diff = false;
+ bool dryRun = false;
+ bool logUnmatched = false;
+ bool printBuiltinTypes = false;
+};
-void printUsage()
+class CommonOptionsParser : public OptionsParser
{
- const QChar pathSplitter = QDir::listSeparator();
- QTextStream s(stdout);
- s << "Usage:\n "
- << "shiboken [options] header-file(s) typesystem-file\n\n"
- << "General options:\n";
- QString pathSyntax;
- QTextStream(&pathSyntax) << "<path>[" << pathSplitter << "<path>"
- << pathSplitter << "...]";
- OptionDescriptions generalOptions = {
- {u"api-version=<\"package mask\">,<\"version\">"_s,
- u"Specify the supported api version used to generate the bindings"_s},
+public:
+ explicit CommonOptionsParser(CommonOptions *o) : m_options(o) {}
+
+ bool handleBoolOption(const QString &key, OptionSource source) override;
+ bool handleOption(const QString &key, const QString &value, OptionSource source) override;
+
+ static OptionDescriptions optionDescriptions();
+
+private:
+ CommonOptions *m_options;
+};
+
+OptionDescriptions CommonOptionsParser::optionDescriptions()
+{
+ return {
{u"debug-level=[sparse|medium|full]"_s,
u"Set the debug level"_s},
{u"documentation-only"_s,
u"Do not generates any code, just the documentation"_s},
- {u"drop-type-entries=\"<TypeEntry0>[;TypeEntry1;...]\""_s,
- u"Semicolon separated list of type system entries (classes, namespaces,\n"
- "global functions and enums) to be dropped from generation."_s},
- {keywordsOption() + QStringLiteral("=keyword1[,keyword2,...]"),
- u"A comma-separated list of keywords for conditional typesystem parsing"_s},
- {clangOptionOption(),
- u"Option to be passed to clang"_s},
- {clangOptionsOption(),
- u"A comma-separated list of options to be passed to clang"_s},
- {compilerOption() + u"=<type>"_s,
+ {u"compiler=<type>"_s,
u"Emulated compiler type (g++, msvc, clang)"_s},
- {platformOption() + u"=<name>"_s,
+ {u"platform=<name>"_s,
u"Emulated platform (windows, darwin, unix)"_s},
- {compilerPathOption() + u"=<file>"_s,
+ {u"compiler-path=<file>"_s,
u"Path to the compiler for determining builtin include paths"_s},
- {u"-F<path>"_s, {} },
- {u"framework-include-paths="_s + pathSyntax,
- u"Framework include paths used by the C++ parser"_s},
- {u"-isystem<path>"_s, {} },
- {u"system-include-paths="_s + pathSyntax,
- u"System include paths used by the C++ parser"_s},
- {useGlobalHeaderOption(),
- u"Use the global headers in generated code."_s},
{u"generator-set=<\"generator module\">"_s,
u"generator-set to be used. e.g. qtdoc"_s},
- {skipDeprecatedOption(),
- u"Skip deprecated functions"_s},
- {diffOption(), u"Print a diff of wrapper files"_s},
- {dryrunOption(), u"Dry run, do not generate wrapper files"_s},
+ {u"diff"_s, u"Print a diff of wrapper files"_s},
+ {u"dry-run"_s, u"Dry run, do not generate wrapper files"_s},
{u"-h"_s, {} },
- {helpOption(), u"Display this help and exit"_s},
+ {u"help"_s, u"Display this help and exit"_s},
{u"-I<path>"_s, {} },
- {u"include-paths="_s + pathSyntax,
+ {u"include-paths="_s + OptionsParser::pathSyntax(),
u"Include paths used by the C++ parser"_s},
- {languageLevelOption() + u"=, -std=<level>"_s,
- languageLevelDescription()},
{u"license-file=<license-file>"_s,
u"File used for copyright headers of generated files"_s},
{u"no-suppress-warnings"_s,
@@ -388,339 +108,252 @@ void printUsage()
u"text file containing a description of the binding project.\n"
"Replaces and overrides command line arguments"_s},
{u"silent"_s, u"Avoid printing any message"_s},
- {u"-T<path>"_s, {} },
- {u"typesystem-paths="_s + pathSyntax,
- u"Paths used when searching for typesystems"_s},
- {printBuiltinTypesOption(),
+ {u"print-builtin-types"_s,
u"Print information about builtin types"_s},
{u"version"_s,
u"Output version information and exit"_s}
};
- printOptions(s, generalOptions);
-
- const Generators generators = shibokenGenerators() + docGenerators();
- for (const GeneratorPtr &generator : generators) {
- const OptionDescriptions options = generator->options();
- if (!options.isEmpty()) {
- s << Qt::endl << generator->name() << " options:\n\n";
- printOptions(s, generator->options());
+}
+
+bool CommonOptionsParser::handleBoolOption(const QString &key, OptionSource source)
+{
+ if (source == OptionSource::CommandLineSingleDash) {
+ if (key == u"h") {
+ m_options->help = true;
+ return true;
+ }
+ return false;
+ }
+
+ if (key == u"version") {
+ m_options->version = true;
+ return true;
+ }
+ if (key == u"help") {
+ m_options->help = true;
+ return true;
+ }
+ if (key == u"diff") {
+ FileOut::setDiff(true);
+ return true;
+ }
+ if (key == u"dry-run") {
+ FileOut::setDryRun(true);
+ return true;
+ }
+ if (key == u"silent") {
+ ReportHandler::setSilent(true);
+ return true;
+ }
+ if (key == u"log-unmatched") {
+ m_options->logUnmatched = true;
+ return true;
+ }
+ if (key == u"print-builtin-types") {
+ m_options->printBuiltinTypes = true;
+ return true;
+ }
+
+ return false;
+}
+
+bool CommonOptionsParser::handleOption(const QString &key, const QString &value,
+ OptionSource source)
+{
+ if (source == OptionSource::CommandLineSingleDash)
+ return false;
+
+ if (key == u"generator-set" || key == u"generatorSet" /* legacy */) {
+ m_options->generatorSet = value;
+ return true;
+ }
+ if (key == u"license-file") {
+ QFile licenseFile(value);
+ if (!licenseFile.open(QIODevice::ReadOnly))
+ throw Exception(msgCannotOpenForReading(licenseFile));
+ m_options->licenseComment = QString::fromUtf8(licenseFile.readAll());
+ return true;
+ }
+ if (key == u"debug-level") {
+ if (!ReportHandler::setDebugLevelFromArg(value))
+ throw Exception(u"Invalid debug level: "_s + value);
+ return true;
+ }
+ if (key == u"output-directory") {
+ m_options->outputDirectory = value;
+ return true;
+ }
+ if (key == u"compiler") {
+ if (!clang::setCompiler(value))
+ throw Exception(u"Invalid value \""_s + value + u"\" passed to --compiler"_s);
+ return true;
+ }
+ if (key == u"compiler-path") {
+ clang::setCompilerPath(value);
+ return true;
+ }
+ if (key == u"platform") {
+ if (!clang::setPlatform(value))
+ throw Exception(u"Invalid value \""_s + value + u"\" passed to --platform"_s);
+ return true;
+ }
+
+ if (source == OptionSource::ProjectFile) {
+ if (key == u"header-file") {
+ m_options->headers.append(value);
+ return true;
+ }
+ if (key == u"typesystem-file") {
+ m_options->typeSystemFileName = value;
+ return true;
}
}
+
+ return false;
+}
+
+void printUsage()
+{
+ const auto generatorOptions = Generator::options();
+
+ QTextStream s(stdout);
+ s << "Usage:\n "
+ << "shiboken [options] header-file(s) typesystem-file\n\n"
+ << "General options:\n"
+ << CommonOptionsParser::optionDescriptions()
+ << ApiExtractor::options()
+ << TypeDatabase::options()
+ << "\nSource generator options:\n\n" << generatorOptions
+ << ShibokenGenerator::options();
+
+#ifdef DOCSTRINGS_ENABLED
+ s << "\nDocumentation Generator options:\n\n"
+ << generatorOptions << QtDocGenerator::options();
+#endif
}
static inline void printVerAndBanner()
{
- std::cout << "shiboken v" SHIBOKEN_VERSION << std::endl;
+ std::cout << appName << " v" << SHIBOKEN_VERSION << std::endl;
std::cout << "Copyright (C) 2016 The Qt Company Ltd." << std::endl;
}
-static inline void errorPrint(const QString &s)
+static inline void errorPrint(const QString &s, const QStringList &arguments)
{
- QStringList arguments = QCoreApplication::arguments();
- arguments.pop_front();
- std::cerr << "shiboken: " << qPrintable(s) << "\nCommand line:\n";
+ std::cerr << appName << ": " << qPrintable(s) << "\nCommand line:\n";
for (const auto &argument : arguments)
std::cerr << " \"" << qPrintable(argument) << "\"\n";
}
-static void parseIncludePathOption(const QString &option, HeaderType headerType,
- CommandLineArguments &args,
- ApiExtractor &extractor)
-{
- const auto it = args.options.find(option);
- if (it != args.options.end()) {
- const auto includePathListList = it.value().toStringList();
- args.options.erase(it);
- for (const QString &s : includePathListList) {
- auto path = QFile::encodeName(QDir::cleanPath(s));
- extractor.addIncludePath(HeaderPath{path, headerType});
- }
- }
-}
-
-int shibokenMain(int argc, char *argv[])
+int shibokenMain(const QStringList &argV)
{
// PYSIDE-757: Request a deterministic ordering of QHash in the code model
// and type system.
- qSetGlobalQHashSeed(0);
- // needed by qxmlpatterns
- QCoreApplication app(argc, argv);
+ QHashSeed::setDeterministicGlobalSeed();
+
ReportHandler::install();
if (ReportHandler::isDebug(ReportHandler::SparseDebug))
- qCInfo(lcShiboken()).noquote().nospace() << QCoreApplication::arguments().join(u' ');
+ qCInfo(lcShiboken()).noquote().nospace() << appName << ' ' << argV.join(u' ');
- // Store command arguments in a map
- const auto projectFileArgumentsOptional = getProjectFileArguments();
- if (!projectFileArgumentsOptional.has_value())
- return EXIT_FAILURE;
-
- const CommandLineArguments projectFileArguments = projectFileArgumentsOptional.value();
- CommandLineArguments args = projectFileArguments;
- getCommandLineArgs(args);
- Generators generators;
+ Options options;
+ options.setOptions(argV);
- auto ait = args.options.find(u"version"_s);
- if (ait != args.options.end()) {
- args.options.erase(ait);
+ CommonOptions commonOptions;
+ {
+ CommonOptionsParser parser(&commonOptions);
+ parser.process(&options);
+ }
+ if (commonOptions.version) {
printVerAndBanner();
return EXIT_SUCCESS;
}
-
- QString generatorSet;
- ait = args.options.find(u"generator-set"_s);
- if (ait == args.options.end()) // Also check "generatorSet" command line argument for backward compatibility.
- ait = args.options.find(u"generatorSet"_s);
- if (ait != args.options.end()) {
- generatorSet = ait.value().toString();
- args.options.erase(ait);
+ if (commonOptions.help) {
+ printUsage();
+ return EXIT_SUCCESS;
}
+ Generators generators;
+
+ OptionsParserList optionParser;
+ optionParser.append(Generator::createOptionsParser());
+ optionParser.append(TypeDatabase::instance()->createOptionsParser());
+ ApiExtractor extractor;
+ optionParser.append(extractor.createOptionsParser());
+
// Pre-defined generator sets.
- if (generatorSet == u"qtdoc") {
+ if (commonOptions.generatorSet == u"qtdoc") {
generators = docGenerators();
if (generators.isEmpty()) {
- errorPrint(u"Doc strings extractions was not enabled in this shiboken build."_s);
+ errorPrint(u"Doc strings extractions was not enabled in this shiboken build."_s, argV);
return EXIT_FAILURE;
}
- } else if (generatorSet.isEmpty() || generatorSet == u"shiboken") {
+#ifdef DOCSTRINGS_ENABLED
+ optionParser.append(QtDocGenerator::createOptionsParser());
+#endif
+ } else if (commonOptions.generatorSet.isEmpty() || commonOptions.generatorSet == u"shiboken") {
generators = shibokenGenerators();
+ optionParser.append(ShibokenGenerator::createOptionsParser());
} else {
- errorPrint(u"Unknown generator set, try \"shiboken\" or \"qtdoc\"."_s);
+ errorPrint(u"Unknown generator set, try \"shiboken\" or \"qtdoc\"."_s, argV);
return EXIT_FAILURE;
}
- ait = args.options.find(u"help"_s);
- if (ait != args.options.end()) {
- args.options.erase(ait);
- printUsage();
- return EXIT_SUCCESS;
- }
-
- ait = args.options.find(diffOption());
- if (ait != args.options.end()) {
- args.options.erase(ait);
- FileOut::setDiff(true);
- }
-
- ait = args.options.find(useGlobalHeaderOption());
- if (ait != args.options.end()) {
- args.options.erase(ait);
- ApiExtractor::setUseGlobalHeader(true);
- }
-
- ait = args.options.find(dryrunOption());
- if (ait != args.options.end()) {
- args.options.erase(ait);
- FileOut::setDryRun(true);
- }
-
- QString licenseComment;
- ait = args.options.find(u"license-file"_s);
- if (ait != args.options.end()) {
- QFile licenseFile(ait.value().toString());
- args.options.erase(ait);
- if (licenseFile.open(QIODevice::ReadOnly)) {
- licenseComment = QString::fromUtf8(licenseFile.readAll());
- } else {
- errorPrint(QStringLiteral("Could not open the file \"%1\" containing the license heading: %2").
- arg(QDir::toNativeSeparators(licenseFile.fileName()), licenseFile.errorString()));
- return EXIT_FAILURE;
- }
- }
-
- QString outputDirectory = u"out"_s;
- ait = args.options.find(u"output-directory"_s);
- if (ait != args.options.end()) {
- outputDirectory = ait.value().toString();
- args.options.erase(ait);
- }
-
- if (!QDir(outputDirectory).exists()) {
- if (!QDir().mkpath(outputDirectory)) {
+ if (!QDir(commonOptions.outputDirectory).exists()) {
+ if (!QDir().mkpath(commonOptions.outputDirectory)) {
qCWarning(lcShiboken).noquote().nospace()
- << "Can't create output directory: " << QDir::toNativeSeparators(outputDirectory);
+ << "Can't create output directory: "
+ << QDir::toNativeSeparators(commonOptions.outputDirectory);
return EXIT_FAILURE;
}
}
// Create and set-up API Extractor
- ApiExtractor extractor;
- extractor.setLogDirectory(outputDirectory);
- ait = args.options.find(skipDeprecatedOption());
- if (ait != args.options.end()) {
- extractor.setSkipDeprecated(true);
- args.options.erase(ait);
- }
-
- ait = args.options.find(u"silent"_s);
- if (ait != args.options.end()) {
- extractor.setSilent(true);
- args.options.erase(ait);
- } else {
- ait = args.options.find(u"debug-level"_s);
- if (ait != args.options.end()) {
- const QString value = ait.value().toString();
- if (!ReportHandler::setDebugLevelFromArg(value)) {
- errorPrint(u"Invalid debug level: "_s + value);
- return EXIT_FAILURE;
- }
- args.options.erase(ait);
- }
- }
- ait = args.options.find(u"no-suppress-warnings"_s);
- if (ait != args.options.end()) {
- args.options.erase(ait);
- extractor.setSuppressWarnings(false);
- }
- ait = args.options.find(apiVersionOption());
- if (ait != args.options.end()) {
- const QStringList &versions = ait.value().toStringList();
- args.options.erase(ait);
- for (const QString &fullVersion : versions) {
- QStringList parts = fullVersion.split(u',');
- QString package;
- QString version;
- package = parts.size() == 1 ? u"*"_s : parts.constFirst();
- version = parts.constLast();
- if (!extractor.setApiVersion(package, version)) {
- errorPrint(msgInvalidVersion(package, version));
- return EXIT_FAILURE;
- }
- }
- }
-
- ait = args.options.find(dropTypeEntriesOption());
- if (ait != args.options.end()) {
- extractor.setDropTypeEntries(ait.value().toStringList());
- args.options.erase(ait);
- }
-
- ait = args.options.find(keywordsOption());
- if (ait != args.options.end()) {
- extractor.setTypesystemKeywords(ait.value().toStringList());
- args.options.erase(ait);
- }
-
- ait = args.options.find(typesystemPathOption());
- if (ait != args.options.end()) {
- extractor.addTypesystemSearchPath(ait.value().toStringList());
- args.options.erase(ait);
- }
-
- ait = args.options.find(clangOptionsOption());
- if (ait != args.options.end()) {
- extractor.setClangOptions(ait.value().toStringList());
- args.options.erase(ait);
- }
-
- ait = args.options.find(compilerOption());
- if (ait != args.options.end()) {
- const QString name = ait.value().toString();
- if (!clang::setCompiler(name)) {
- errorPrint(u"Invalid value \""_s + name + u"\" passed to --compiler"_s);
+ extractor.setLogDirectory(commonOptions.outputDirectory);
+
+ if (commonOptions.typeSystemFileName.isEmpty() && commonOptions.headers.isEmpty()) {
+ if (options.positionalArguments.size() < 2) {
+ errorPrint(u"Insufficient positional arguments, specify header-file and typesystem-file."_s,
+ argV);
+ std::cout << '\n';
+ printUsage();
return EXIT_FAILURE;
}
- args.options.erase(ait);
- }
- ait = args.options.find(printBuiltinTypesOption());
- const bool printBuiltinTypes = ait != args.options.end();
- if (printBuiltinTypes)
- args.options.erase(ait);
-
- ait = args.options.find(compilerPathOption());
- if (ait != args.options.end()) {
- clang::setCompilerPath(ait.value().toString());
- args.options.erase(ait);
+ commonOptions.typeSystemFileName = options.positionalArguments.takeLast();
+ commonOptions.headers = options.positionalArguments;
}
- ait = args.options.find(platformOption());
- if (ait != args.options.end()) {
- const QString name = ait.value().toString();
- if (!clang::setPlatform(name)) {
- errorPrint(u"Invalid value \""_s + name + u"\" passed to --platform"_s);
- return EXIT_FAILURE;
- }
- args.options.erase(ait);
- }
-
- parseIncludePathOption(includePathOption(), HeaderType::Standard,
- args, extractor);
- parseIncludePathOption(frameworkIncludePathOption(), HeaderType::Framework,
- args, extractor);
- parseIncludePathOption(systemIncludePathOption(), HeaderType::System,
- args, extractor);
-
- if (args.positionalArguments.size() < 2) {
- errorPrint(u"Insufficient positional arguments, specify header-file and typesystem-file."_s);
- std::cout << '\n';
- printUsage();
- return EXIT_FAILURE;
- }
-
- const QString typeSystemFileName = args.positionalArguments.takeLast();
- QString messagePrefix = QFileInfo(typeSystemFileName).baseName();
+ QString messagePrefix = QFileInfo(commonOptions.typeSystemFileName).baseName();
if (messagePrefix.startsWith(u"typesystem_"))
messagePrefix.remove(0, 11);
ReportHandler::setPrefix(u'(' + messagePrefix + u')');
QFileInfoList cppFileNames;
- for (const QString &cppFileName : std::as_const(args.positionalArguments)) {
+ for (const QString &cppFileName : std::as_const(commonOptions.headers)) {
const QFileInfo cppFileNameFi(cppFileName);
if (!cppFileNameFi.isFile() && !cppFileNameFi.isSymLink()) {
- errorPrint(u'"' + cppFileName + u"\" does not exist."_s);
+ errorPrint(u'"' + cppFileName + u"\" does not exist."_s, argV);
return EXIT_FAILURE;
}
cppFileNames.append(cppFileNameFi);
}
- // Pass option to all generators (Cpp/Header generator have the same options)
- for (ait = args.options.begin(); ait != args.options.end(); ) {
- bool found = false;
- for (const GeneratorPtr &generator : std::as_const(generators))
- found |= generator->handleOption(ait.key(), ait.value().toString());
- if (found)
- ait = args.options.erase(ait);
- else
- ++ait;
- }
-
- ait = args.options.find(languageLevelOption());
- if (ait != args.options.end()) {
- const QByteArray languageLevelBA = ait.value().toString().toLatin1();
- args.options.erase(ait);
- const LanguageLevel level = clang::languageLevelFromOption(languageLevelBA.constData());
- if (level == LanguageLevel::Default) {
- std::cout << "Invalid argument for language level: \""
- << languageLevelBA.constData() << "\"\n" << helpHint;
- return EXIT_FAILURE;
- }
- extractor.setLanguageLevel(level);
- }
-
- /* Make sure to remove the project file's arguments (if any) and
- * --project-file, also the arguments of each generator before
- * checking if there isn't any existing arguments in argsHandler.
- */
- args.options.remove(u"project-file"_s);
- for (auto it = projectFileArguments.options.cbegin(), end = projectFileArguments.options.cend();
- it != end; ++it) {
- args.options.remove(it.key());
- }
+ optionParser.process(&options);
+ optionParser.clear();
- if (!args.options.isEmpty()) {
- errorPrint(msgLeftOverArguments(args.options));
+ if (!options.boolOptions.isEmpty() || !options.valueOptions.isEmpty()) {
+ errorPrint(msgLeftOverArguments(options.msgUnprocessedOptions(), argV), argV);
std::cout << helpHint;
return EXIT_FAILURE;
}
- if (typeSystemFileName.isEmpty()) {
+ if (commonOptions.typeSystemFileName.isEmpty()) {
std::cout << "You must specify a Type System file." << std::endl << helpHint;
return EXIT_FAILURE;
}
extractor.setCppFileNames(cppFileNames);
- extractor.setTypeSystem(typeSystemFileName);
+ extractor.setTypeSystem(commonOptions.typeSystemFileName);
ApiExtractorFlags apiExtractorFlags;
if (generators.constFirst()->usePySideExtensions())
@@ -730,7 +363,7 @@ int shibokenMain(int argc, char *argv[])
const std::optional<ApiExtractorResult> apiOpt = extractor.run(apiExtractorFlags);
if (!apiOpt.has_value()) {
- errorPrint(u"Error running ApiExtractor."_s);
+ errorPrint(u"Error running ApiExtractor."_s, argV);
return EXIT_FAILURE;
}
@@ -743,35 +376,59 @@ int shibokenMain(int argc, char *argv[])
<< "\n\nType datase:\n" << *TypeDatabase::instance();
}
- if (printBuiltinTypes)
+ if (commonOptions.printBuiltinTypes)
TypeDatabase::instance()->formatBuiltinTypes(qInfo());
for (const GeneratorPtr &g : std::as_const(generators)) {
- g->setOutputDirectory(outputDirectory);
- g->setLicenseComment(licenseComment);
- ReportHandler::startProgress(QByteArray("Running ") + g->name() + "...");
+ g->setOutputDirectory(commonOptions.outputDirectory);
+ g->setLicenseComment(commonOptions.licenseComment);
+ ReportHandler::startProgress("Ran "_ba + g->name() + '.');
const bool ok = g->setup(apiOpt.value()) && g->generate();
ReportHandler::endProgress();
if (!ok) {
errorPrint(u"Error running generator: "_s
- + QLatin1StringView(g->name()) + u'.');
+ + QLatin1StringView(g->name()) + u'.', argV);
return EXIT_FAILURE;
}
}
+ if (commonOptions.logUnmatched)
+ TypeDatabase::instance()->logUnmatched();
+
const QByteArray doneMessage = ReportHandler::doneMessage();
std::cout << doneMessage.constData() << std::endl;
return EXIT_SUCCESS;
}
+#ifndef Q_OS_WIN
+
+static inline QString argvToString(const char *arg)
+{
+ return QString::fromLocal8Bit(arg);
+}
+
int main(int argc, char *argv[])
+#else
+
+static inline QString argvToString(const wchar_t *arg)
+{
+ return QString::fromWCharArray(arg);
+}
+
+int wmain(int argc, wchar_t *argv[])
+#endif
{
int ex = EXIT_SUCCESS;
+
+ QStringList argV;
+ argV.reserve(argc - 1);
+ std::transform(argv + 1, argv + argc, std::back_inserter(argV), argvToString);
+
try {
- ex = shibokenMain(argc, argv);
+ ex = shibokenMain(argV);
} catch (const std::exception &e) {
- std::cerr << e.what() << std::endl;
+ std::cerr << appName << " error: " << e.what() << std::endl;
ex = EXIT_FAILURE;
}
return ex;
diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
index cf16efaa0..2797ff254 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
@@ -15,6 +15,7 @@
#include <abstractmetafield.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
+#include "abstractmetalang_helpers.h"
#include <fileout.h>
#include <messages.h>
#include <modifications.h>
@@ -25,6 +26,8 @@
#include <functiontypeentry.h>
#include <enumtypeentry.h>
#include <complextypeentry.h>
+#include <flagstypeentry.h>
+#include <primitivetypeentry.h>
#include <qtdocparser.h>
#include <doxygenparser.h>
@@ -36,12 +39,36 @@
#include <QtCore/QJsonArray>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
+#include <QtCore/QSet>
#include <algorithm>
#include <limits>
using namespace Qt::StringLiterals;
+static inline QString classScope(const AbstractMetaClassCPtr &metaClass)
+{
+ return metaClass->fullName();
+}
+
+struct DocPackage
+{
+ QStringList classPages;
+ QStringList decoratorPages;
+ AbstractMetaFunctionCList globalFunctions;
+ AbstractMetaEnumList globalEnums;
+};
+
+struct DocGeneratorOptions
+{
+ QtXmlToSphinxParameters parameters;
+ QString extraSectionDir;
+ QString additionalDocumentationList;
+ QString inheritanceFile;
+ bool doxygen = false;
+ bool inheritanceDiagram = true;
+};
+
struct GeneratorDocumentation
{
struct Property
@@ -55,8 +82,7 @@ struct GeneratorDocumentation
AbstractMetaFunctionCPtr notify;
};
- AbstractMetaFunctionCList constructors;
- AbstractMetaFunctionCList allFunctions; // Except constructors
+ AbstractMetaFunctionCList allFunctions;
AbstractMetaFunctionCList tocNormalFunctions; // Index lists
AbstractMetaFunctionCList tocVirtuals;
AbstractMetaFunctionCList tocSignalFunctions;
@@ -72,19 +98,18 @@ static bool operator<(const GeneratorDocumentation::Property &lhs,
return lhs.name < rhs.name;
}
-static QString propertyRefTarget(const AbstractMetaClass *cppClass, const QString &name)
+static QString propertyRefTarget(const QString &name)
{
- QString result = cppClass->fullName() + u'.' + name;
- result.replace(u"::"_s, u"."_s);
+ QString result = name;
// For sphinx referencing, disambiguate the target from the getter name
- // by inserting an invisible "Hangul choseong filler" character.
- result.insert(1, QChar(0x115F));
+ // by appending an invisible "Hangul choseong filler" character.
+ result.append(QChar(0x115F));
return result;
}
-static inline QString additionalDocumentationOption() { return QStringLiteral("additional-documentation"); }
+constexpr auto additionalDocumentationOption = "additional-documentation"_L1;
-static inline QString none() { return QStringLiteral("None"); }
+constexpr auto none = "None"_L1;
static bool shouldSkip(const AbstractMetaFunctionCPtr &func)
{
@@ -121,7 +146,14 @@ static bool shouldSkip(const AbstractMetaFunctionCPtr &func)
static bool functionSort(const AbstractMetaFunctionCPtr &func1, const AbstractMetaFunctionCPtr &func2)
{
- return func1->name() < func2->name();
+ const bool ctor1 = func1->isConstructor();
+ if (ctor1 != func2->isConstructor())
+ return ctor1;
+ const QString &name1 = func1->name();
+ const QString &name2 = func2->name();
+ if (name1 != name2)
+ return name1 < name2;
+ return func1->arguments().size() < func2->arguments().size();
}
static inline QVersionNumber versionOf(const TypeEntryCPtr &te)
@@ -131,82 +163,144 @@ static inline QVersionNumber versionOf(const TypeEntryCPtr &te)
if (!version.isNull() && version > QVersionNumber(0, 0))
return version;
}
- return QVersionNumber();
+ return {};
}
-// Format a documentation reference (meth/attr): ":meth:`name<target>`"
-// We do not use the short form ":meth:`~target`" since that adds parentheses ()
-// for functions where we list the parameters instead.
struct docRef
{
- explicit docRef(const char *kind, const QString &name, const AbstractMetaClass *cppClass) :
- m_kind(kind), m_name(name), m_cppClass(cppClass) {}
+ explicit docRef(const char *kind, QAnyStringView name) :
+ m_kind(kind), m_name(name) {}
const char *m_kind;
- const QString &m_name;
- const AbstractMetaClass *m_cppClass;
+ QAnyStringView m_name;
};
static TextStream &operator<<(TextStream &s, const docRef &dr)
{
- QString className = dr.m_cppClass->fullName();
- className.replace(u"::"_s, u"."_s);
- s << ':' << dr.m_kind << ":`" << dr.m_name << '<';
- if (!dr.m_name.startsWith(className))
- s << className << '.';
- s << dr.m_name << ">`";
+ s << ':' << dr.m_kind << ":`" << dr.m_name << '`';
return s;
}
+static QString fileNameToTocEntry(const QString &fileName)
+{
+ constexpr auto rstSuffix = ".rst"_L1;
+
+ QString result = fileName;
+ if (result.endsWith(rstSuffix))
+ result.chop(rstSuffix.size()); // Remove the .rst extension
+ // skip namespace if necessary
+ auto lastDot = result.lastIndexOf(u'.');
+ if (lastDot != -1)
+ result.remove(0, lastDot + 1);
+ return result;
+}
+
+static void readExtraDoc(const QFileInfo &fi,
+ const QString &moduleName,
+ const QString &outputDir,
+ DocPackage *docPackage, QStringList *extraTocEntries)
+{
+ // Strip to "Property.rst" in output directory
+ const QString newFileName = fi.fileName().mid(moduleName.size() + 1);
+ QFile sourceFile(fi.absoluteFilePath());
+ if (!sourceFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
+ qCWarning(lcShibokenDoc, "%s", qPrintable(msgCannotOpenForReading(sourceFile)));
+ return;
+ }
+ const QByteArray contents = sourceFile.readAll();
+ sourceFile.close();
+ QFile targetFile(outputDir + u'/' + newFileName);
+ if (!targetFile.open(QIODevice::WriteOnly|QIODevice::Text)) {
+ qCWarning(lcShibokenDoc, "%s", qPrintable(msgCannotOpenForWriting(targetFile)));
+ return;
+ }
+ targetFile.write(contents);
+ if (contents.contains("decorator::"))
+ docPackage->decoratorPages.append(newFileName);
+ else
+ docPackage->classPages.append(newFileName);
+ extraTocEntries->append(fileNameToTocEntry(newFileName));
+}
+
// Format a short documentation reference (automatically dropping the prefix
// by using '~'), usable for property/attributes ("attr").
struct shortDocRef
{
- explicit shortDocRef(const char *kind, const QString &target) :
- m_kind(kind), m_target(target) {}
+ explicit shortDocRef(const char *kind, QAnyStringView name) :
+ m_kind(kind), m_name(name) {}
const char *m_kind;
- const QString &m_target;
+ QAnyStringView m_name;
};
static TextStream &operator<<(TextStream &s, const shortDocRef &sdr)
{
- s << ':' << sdr.m_kind << ":`~" << sdr.m_target << '`';
+ s << ':' << sdr.m_kind << ":`~" << sdr.m_name << '`';
return s;
}
struct functionRef : public docRef
{
- explicit functionRef(const QString &name, const AbstractMetaClass *cppClass) :
- docRef("meth", name, cppClass) {}
+ explicit functionRef(QAnyStringView name) : docRef("meth", name) {}
+};
+
+struct classRef : public shortDocRef
+{
+ explicit classRef(QAnyStringView name) : shortDocRef("class", name) {}
+};
+
+struct propRef : public shortDocRef // Attribute/property (short) reference
+{
+ explicit propRef(const QString &target) :
+ shortDocRef("attr", target) {}
};
-struct functionTocEntry // Format a TOC entry for a function
+struct headline
{
- explicit functionTocEntry(const AbstractMetaFunctionCPtr& func,
- const AbstractMetaClass *cppClass) :
- m_func(func), m_cppClass(cppClass) {}
+ explicit headline(QAnyStringView title, char underLineChar = '-') :
+ m_title(title), m_underLineChar(underLineChar) {}
- AbstractMetaFunctionCPtr m_func;
- const AbstractMetaClass *m_cppClass;
+ QAnyStringView m_title;
+ char m_underLineChar;
};
-static TextStream &operator<<(TextStream &s, const functionTocEntry &ft)
+static TextStream &operator<<(TextStream &s, const headline &h)
{
- s << functionRef(QtDocGenerator::getFuncName(ft.m_func), ft.m_cppClass)
- << ' ' << QtDocGenerator::formatArgs(ft.m_func);
+ s << h.m_title << '\n' << Pad(h.m_underLineChar, h.m_title.size()) << "\n\n";
return s;
}
-struct propRef : public shortDocRef // Attribute/property (short) reference
+struct pyClass
{
- explicit propRef(const QString &target) :
- shortDocRef("attr", target) {}
+ explicit pyClass(QAnyStringView name) : m_name(name) {}
+
+ QAnyStringView m_name;
+};
+
+static TextStream &operator<<(TextStream &s, pyClass c)
+{
+ s << ".. py:class:: " << c.m_name << "\n\n";
+ return s;
+}
+
+struct currentModule
+{
+ explicit currentModule(QAnyStringView module) : m_module(module) {}
+
+ QAnyStringView m_module;
};
+static TextStream &operator<<(TextStream &s, const currentModule &m)
+{
+ s << ".. currentmodule:: " << m.m_module << "\n\n\n";
+ return s;
+}
+
+DocGeneratorOptions QtDocGenerator::m_options;
+
QtDocGenerator::QtDocGenerator()
{
- m_parameters.snippetComparison =
+ m_options.parameters.snippetComparison =
ReportHandler::debugLevel() >= ReportHandler::FullDebug;
}
@@ -231,28 +325,23 @@ QString QtDocGenerator::fileNameForContext(const GeneratorContext &context) cons
}
void QtDocGenerator::writeFormattedBriefText(TextStream &s, const Documentation &doc,
- const AbstractMetaClass *metaclass) const
+ const QString &scope) const
{
- writeFormattedText(s, doc.brief(), doc.format(), metaclass);
+ writeFormattedText(s, doc.brief(), doc.format(), scope);
}
void QtDocGenerator::writeFormattedDetailedText(TextStream &s, const Documentation &doc,
- const AbstractMetaClass *metaclass) const
+ const QString &scope) const
{
- writeFormattedText(s, doc.detailed(), doc.format(), metaclass);
+ writeFormattedText(s, doc.detailed(), doc.format(), scope);
}
void QtDocGenerator::writeFormattedText(TextStream &s, const QString &doc,
Documentation::Format format,
- const AbstractMetaClass *metaClass) const
+ const QString &scope) const
{
- QString metaClassName;
-
- if (metaClass)
- metaClassName = metaClass->fullName();
-
if (format == Documentation::Native) {
- QtXmlToSphinx x(this, m_parameters, doc, metaClassName);
+ QtXmlToSphinx x(this, m_options.parameters, doc, scope);
s << x;
} else {
const auto lines = QStringView{doc}.split(u'\n');
@@ -276,50 +365,71 @@ void QtDocGenerator::writeFormattedText(TextStream &s, const QString &doc,
s << '\n';
}
-static void writeInheritedByList(TextStream &s, const AbstractMetaClass *metaClass,
+static void writeInheritanceList(TextStream &s, const AbstractMetaClassCList& classes,
+ const char *label)
+{
+ s << "**" << label << ":** ";
+ for (qsizetype i = 0, size = classes.size(); i < size; ++i) {
+ if (i > 0)
+ s << ", ";
+ s << classRef(classes.at(i)->fullName());
+ }
+ s << "\n\n";
+}
+
+static void writeInheritedByList(TextStream &s, const AbstractMetaClassCPtr &metaClass,
const AbstractMetaClassCList& allClasses)
{
AbstractMetaClassCList res;
- for (auto c : allClasses) {
- if (c != metaClass && c->inheritsFrom(metaClass))
+ for (const auto &c : allClasses) {
+ if (c != metaClass && inheritsFrom(c, metaClass))
res << c;
}
- if (res.isEmpty())
- return;
+ if (!res.isEmpty())
+ writeInheritanceList(s, res, "Inherited by");
+}
+
+static void writeInheritedFromList(TextStream &s, const AbstractMetaClassCPtr &metaClass)
+{
+ AbstractMetaClassCList res;
+
+ recurseClassHierarchy(metaClass, [&res, metaClass](const AbstractMetaClassCPtr &c) {
+ if (c.get() != metaClass.get())
+ res.append(c);
+ return false;
+ });
- s << "**Inherited by:** ";
- QStringList classes;
- for (auto c : std::as_const(res))
- classes << u":ref:`"_s + c->name() + u'`';
- s << classes.join(u", "_s) << "\n\n";
+ if (!res.isEmpty())
+ writeInheritanceList(s, res, "Inherits from");
}
void QtDocGenerator::generateClass(TextStream &s, const GeneratorContext &classContext)
{
- const AbstractMetaClass *metaClass = classContext.metaClass();
+ AbstractMetaClassCPtr metaClass = classContext.metaClass();
qCDebug(lcShibokenDoc).noquote().nospace() << "Generating Documentation for " << metaClass->fullName();
- m_packages[metaClass->package()] << fileNameForContext(classContext);
+ m_packages[metaClass->package()].classPages << fileNameForContext(classContext);
m_docParser->setPackageName(metaClass->package());
- m_docParser->fillDocumentation(const_cast<AbstractMetaClass*>(metaClass));
-
- QString className = metaClass->name();
- s << ".. _" << className << ":" << "\n\n";
- s << ".. currentmodule:: " << metaClass->package() << "\n\n\n";
+ m_docParser->fillDocumentation(std::const_pointer_cast<AbstractMetaClass>(metaClass));
- s << className << '\n';
- s << Pad('*', className.size()) << "\n\n";
+ s << currentModule(metaClass->package()) << pyClass(metaClass->name());
+ Indentation indent(s);
auto documentation = metaClass->documentation();
+ const QString scope = classScope(metaClass);
if (documentation.hasBrief())
- writeFormattedBriefText(s, documentation, metaClass);
-
- s << ".. inheritance-diagram:: " << metaClass->fullName()<< '\n'
- << " :parts: 2\n\n";
- // TODO: This would be a parameter in the future...
+ writeFormattedBriefText(s, documentation, scope);
+ if (!metaClass->baseClasses().isEmpty()) {
+ if (m_options.inheritanceDiagram) {
+ s << ".. inheritance-diagram:: " << metaClass->fullName()<< '\n'
+ << " :parts: 2\n\n";
+ } else {
+ writeInheritedFromList(s, metaClass);
+ }
+ }
writeInheritedByList(s, metaClass, api().classes());
@@ -332,73 +442,68 @@ void QtDocGenerator::generateClass(TextStream &s, const GeneratorContext &classC
const GeneratorDocumentation doc = generatorDocumentation(metaClass);
if (!doc.allFunctions.isEmpty() || !doc.properties.isEmpty()) {
- s << "\nSynopsis\n--------\n\n";
- writePropertyToc(s, doc, metaClass);
- writeFunctionToc(s, u"Functions"_s, metaClass, doc.tocNormalFunctions);
- writeFunctionToc(s, u"Virtual functions"_s, metaClass, doc.tocVirtuals);
- writeFunctionToc(s, u"Slots"_s, metaClass, doc.tocSlotFunctions);
- writeFunctionToc(s, u"Signals"_s, metaClass, doc.tocSignalFunctions);
- writeFunctionToc(s, u"Static functions"_s, metaClass, doc.tocStaticFunctions);
+ s << '\n' << headline("Synopsis");
+ writePropertyToc(s, doc);
+ writeFunctionToc(s, u"Methods"_s, doc.tocNormalFunctions);
+ writeFunctionToc(s, u"Virtual methods"_s, doc.tocVirtuals);
+ writeFunctionToc(s, u"Slots"_s, doc.tocSlotFunctions);
+ writeFunctionToc(s, u"Signals"_s, doc.tocSignalFunctions);
+ writeFunctionToc(s, u"Static functions"_s, doc.tocStaticFunctions);
}
- s << "\nDetailed Description\n"
- "--------------------\n\n"
- << ".. _More:\n";
+ s << "\n.. note::\n"
+ " This documentation may contain snippets that were automatically\n"
+ " translated from C++ to Python. We always welcome contributions\n"
+ " to the snippet translation. If you see an issue with the\n"
+ " translation, you can also let us know by creating a ticket on\n"
+ " https:/bugreports.qt.io/projects/PYSIDE\n\n";
- writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, metaClass, nullptr);
- if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, metaClass, nullptr))
- writeFormattedDetailedText(s, documentation, metaClass);
+ s << '\n' << headline("Detailed Description") << ".. _More:\n";
- if (!metaClass->isNamespace())
- writeConstructors(s, metaClass, doc.constructors);
+ writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, metaClass);
+ if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, metaClass))
+ writeFormattedDetailedText(s, documentation, scope);
+ writeInjectDocumentation(s, TypeSystem::DocModificationAppend, metaClass);
+
+ writeEnums(s, metaClass->enums(), scope);
if (!doc.properties.isEmpty())
writeProperties(s, doc, metaClass);
- writeEnums(s, metaClass);
if (!metaClass->isNamespace())
writeFields(s, metaClass);
- QString lastName;
- for (const auto &func : std::as_const(doc.allFunctions)) {
- const bool indexed = func->name() != lastName;
- lastName = func->name();
- s << (func->isStatic() ? ".. py:staticmethod:: " : ".. py:method:: ");
- writeFunction(s, metaClass, func, indexed);
- }
-
- writeInjectDocumentation(s, TypeSystem::DocModificationAppend, metaClass, nullptr);
+ writeFunctions(s, doc.allFunctions, metaClass, scope);
}
void QtDocGenerator::writeFunctionToc(TextStream &s, const QString &title,
- const AbstractMetaClass *cppClass,
const AbstractMetaFunctionCList &functions)
{
if (!functions.isEmpty()) {
- s << title << '\n'
- << Pad('^', title.size()) << '\n';
-
- s << ".. container:: function_list\n\n" << indent;
- for (const auto &func : functions)
- s << "* def " << functionTocEntry(func, cppClass) << '\n';
+ s << headline(title, '^')
+ << ".. container:: function_list\n\n" << indent;
+ // Functions are sorted by the Metabuilder; erase overloads
+ QStringList toc;
+ toc.reserve(functions.size());
+ std::transform(functions.cbegin(), functions.end(),
+ std::back_inserter(toc), getFuncName);
+ toc.erase(std::unique(toc.begin(), toc.end()), toc.end());
+ for (const auto &func : toc)
+ s << "* def " << functionRef(func) << '\n';
s << outdent << "\n\n";
}
}
void QtDocGenerator::writePropertyToc(TextStream &s,
- const GeneratorDocumentation &doc,
- const AbstractMetaClass *cppClass)
+ const GeneratorDocumentation &doc)
{
if (doc.properties.isEmpty())
return;
- const QString title = u"Properties"_s;
- s << title << '\n'
- << Pad('^', title.size()) << '\n';
-
- s << ".. container:: function_list\n\n" << indent;
+ s << headline("Properties", '^')
+ << ".. container:: function_list\n\n" << indent;
for (const auto &prop : doc.properties) {
- s << "* " << propRef(propertyRefTarget(cppClass, prop.name));
+ s << "* " << propRef(propertyRefTarget(prop.name));
if (prop.documentation.hasBrief())
s << " - " << prop.documentation.brief();
s << '\n';
@@ -408,38 +513,39 @@ void QtDocGenerator::writePropertyToc(TextStream &s,
void QtDocGenerator::writeProperties(TextStream &s,
const GeneratorDocumentation &doc,
- const AbstractMetaClass *cppClass) const
+ const AbstractMetaClassCPtr &cppClass) const
{
s << "\n.. note:: Properties can be used directly when "
<< "``from __feature__ import true_property`` is used or via accessor "
<< "functions otherwise.\n\n";
+ const QString scope = classScope(cppClass);
for (const auto &prop : doc.properties) {
const QString type = translateToPythonType(prop.type, cppClass, /* createRef */ false);
- s << ".. py:property:: " << propertyRefTarget(cppClass, prop.name)
+ s << ".. py:property:: " << propertyRefTarget(prop.name)
<< "\n :type: " << type << "\n\n\n";
if (!prop.documentation.isEmpty())
- writeFormattedText(s, prop.documentation.detailed(), Documentation::Native, cppClass);
+ writeFormattedText(s, prop.documentation.detailed(), Documentation::Native, scope);
s << "**Access functions:**\n";
- if (!prop.getter.isNull())
- s << " * " << functionTocEntry(prop.getter, cppClass) << '\n';
- if (!prop.setter.isNull())
- s << " * " << functionTocEntry(prop.setter, cppClass) << '\n';
- if (!prop.reset.isNull())
- s << " * " << functionTocEntry(prop.reset, cppClass) << '\n';
- if (!prop.notify.isNull())
- s << " * Signal " << functionTocEntry(prop.notify, cppClass) << '\n';
+ if (prop.getter)
+ s << " * " << functionRef(prop.getter->name()) << '\n';
+ if (prop.setter)
+ s << " * " << functionRef(prop.setter->name()) << '\n';
+ if (prop.reset)
+ s << " * " << functionRef(prop.reset->name()) << '\n';
+ if (prop.notify)
+ s << " * Signal " << functionRef(prop.notify->name()) << '\n';
s << '\n';
}
}
-void QtDocGenerator::writeEnums(TextStream &s, const AbstractMetaClass *cppClass) const
+void QtDocGenerator::writeEnums(TextStream &s, const AbstractMetaEnumList &enums,
+ const QString &scope) const
{
- static const QString section_title = u".. attribute:: "_s;
-
- for (const AbstractMetaEnum &en : cppClass->enums()) {
- s << section_title << cppClass->fullName() << '.' << en.name() << "\n\n";
- writeFormattedDetailedText(s, en.documentation(), cppClass);
+ for (const AbstractMetaEnum &en : enums) {
+ s << pyClass(en.name());
+ Indentation indent(s);
+ writeFormattedDetailedText(s, en.documentation(), scope);
const auto version = versionOf(en.typeEntry());
if (!version.isNull())
s << rstVersionAdded(version);
@@ -447,64 +553,15 @@ void QtDocGenerator::writeEnums(TextStream &s, const AbstractMetaClass *cppClass
}
-void QtDocGenerator::writeFields(TextStream &s, const AbstractMetaClass *cppClass) const
+void QtDocGenerator::writeFields(TextStream &s, const AbstractMetaClassCPtr &cppClass) const
{
- static const QString section_title = u".. attribute:: "_s;
+ constexpr auto section_title = ".. attribute:: "_L1;
+ const QString scope = classScope(cppClass);
for (const AbstractMetaField &field : cppClass->fields()) {
s << section_title << cppClass->fullName() << "." << field.name() << "\n\n";
- writeFormattedDetailedText(s, field.documentation(), cppClass);
- }
-}
-
-void QtDocGenerator::writeConstructors(TextStream &s, const AbstractMetaClass *cppClass,
- const AbstractMetaFunctionCList &constructors) const
-{
- static const QString sectionTitle = u".. class:: "_s;
-
- bool first = true;
- QHash<QString, AbstractMetaArgument> arg_map;
-
- if (constructors.isEmpty()) {
- s << sectionTitle << cppClass->fullName();
- } else {
- QByteArray pad;
- for (const auto &func : constructors) {
- s << pad;
- if (first) {
- first = false;
- s << sectionTitle;
- pad = QByteArray(sectionTitle.size(), ' ');
- }
- s << functionSignature(cppClass, func) << "\n\n";
-
- const auto version = versionOf(func->typeEntry());
- if (!version.isNull())
- s << pad << rstVersionAdded(version);
- if (func->isDeprecated())
- s << pad << rstDeprecationNote("constructor");
-
- const AbstractMetaArgumentList &arguments = func->arguments();
- for (const AbstractMetaArgument &arg : arguments) {
- if (!arg_map.contains(arg.name())) {
- arg_map.insert(arg.name(), arg);
- }
- }
- }
- }
-
- s << '\n';
-
- for (auto it = arg_map.cbegin(), end = arg_map.cend(); it != end; ++it) {
- s.indent(2);
- writeParameterType(s, cppClass, it.value());
- s.outdent(2);
+ writeFormattedDetailedText(s, field.documentation(), scope);
}
-
- s << '\n';
-
- for (const auto &func : constructors)
- writeFormattedDetailedText(s, func->documentation(), cppClass);
}
QString QtDocGenerator::formatArgs(const AbstractMetaFunctionCPtr &func)
@@ -538,13 +595,13 @@ QString QtDocGenerator::formatArgs(const AbstractMetaFunctionCPtr &func)
|| defValue.startsWith(u"QList")) {
defValue = u"list()"_s;
} else if (defValue == u"QVariant()") {
- defValue = none();
+ defValue = none;
} else {
defValue.replace(u"::"_s, u"."_s);
if (defValue == u"nullptr")
- defValue = none();
+ defValue = none;
else if (defValue == u"0" && arg.type().isObject())
- defValue = none();
+ defValue = none;
}
ret += u'=' + defValue;
}
@@ -612,25 +669,21 @@ void QtDocGenerator::writeDocSnips(TextStream &s,
}
}
-bool QtDocGenerator::writeInjectDocumentation(TextStream &s,
- TypeSystem::DocModificationMode mode,
- const AbstractMetaClass *cppClass,
- const AbstractMetaFunctionCPtr &func)
+bool QtDocGenerator::writeDocModifications(TextStream &s,
+ const DocModificationList &mods,
+ TypeSystem::DocModificationMode mode,
+ const QString &scope) const
{
- Indentation indentation(s);
bool didSomething = false;
-
- const DocModificationList mods = DocParser::getDocModifications(cppClass, func);
-
for (const DocModification &mod : mods) {
if (mod.mode() == mode) {
switch (mod.format()) {
case TypeSystem::NativeCode:
- writeFormattedText(s, mod.code(), Documentation::Native, cppClass);
+ writeFormattedText(s, mod.code(), Documentation::Native, scope);
didSomething = true;
break;
case TypeSystem::TargetLangCode:
- writeFormattedText(s, mod.code(), Documentation::Target, cppClass);
+ writeFormattedText(s, mod.code(), Documentation::Target, scope);
didSomething = true;
break;
default:
@@ -638,67 +691,105 @@ bool QtDocGenerator::writeInjectDocumentation(TextStream &s,
}
}
}
+ return didSomething;
+}
+bool QtDocGenerator::writeInjectDocumentation(TextStream &s,
+ TypeSystem::DocModificationMode mode,
+ const AbstractMetaClassCPtr &cppClass) const
+{
+ const bool didSomething =
+ writeDocModifications(s, DocParser::getDocModifications(cppClass),
+ mode, classScope(cppClass));
s << '\n';
// FIXME PYSIDE-7: Deprecate the use of doc string on glue code.
// This is pre "add-function" and "inject-documentation" tags.
const TypeSystem::CodeSnipPosition pos = mode == TypeSystem::DocModificationPrepend
? TypeSystem::CodeSnipPositionBeginning : TypeSystem::CodeSnipPositionEnd;
- if (func)
- writeDocSnips(s, func->injectedCodeSnips(), pos, TypeSystem::TargetLangCode);
- else
- writeDocSnips(s, cppClass->typeEntry()->codeSnips(), pos, TypeSystem::TargetLangCode);
+ writeDocSnips(s, cppClass->typeEntry()->codeSnips(), pos, TypeSystem::TargetLangCode);
return didSomething;
}
-QString QtDocGenerator::functionSignature(const AbstractMetaClass *cppClass,
- const AbstractMetaFunctionCPtr &func)
+bool QtDocGenerator::writeInjectDocumentation(TextStream &s,
+ TypeSystem::DocModificationMode mode,
+ const DocModificationList &modifications,
+ const AbstractMetaFunctionCPtr &func,
+ const QString &scope) const
{
- QString funcName = cppClass->fullName();
- if (!func->isConstructor())
- funcName += u'.' + getFuncName(func);
+ const bool didSomething = writeDocModifications(s, modifications, mode, scope);
+ s << '\n';
- return funcName + formatArgs(func);
+ // FIXME PYSIDE-7: Deprecate the use of doc string on glue code.
+ // This is pre "add-function" and "inject-documentation" tags.
+ const TypeSystem::CodeSnipPosition pos = mode == TypeSystem::DocModificationPrepend
+ ? TypeSystem::CodeSnipPositionBeginning : TypeSystem::CodeSnipPositionEnd;
+ writeDocSnips(s, func->injectedCodeSnips(), pos, TypeSystem::TargetLangCode);
+ return didSomething;
+}
+
+static QString inline toRef(const QString &t)
+{
+ return ":class:`~"_L1 + t + u'`';
}
QString QtDocGenerator::translateToPythonType(const AbstractMetaType &type,
- const AbstractMetaClass *cppClass,
+ const AbstractMetaClassCPtr &cppClass,
bool createRef) const
{
static const QStringList nativeTypes =
- {boolT(), floatT(), intT(), pyObjectT(), pyStrT()};
+ {boolT, floatT, intT, pyObjectT, pyStrT};
- const QString name = type.name();
+ QString name = type.name();
if (nativeTypes.contains(name))
return name;
- static const QMap<QString, QString> typeMap = {
- { cPyObjectT(), pyObjectT() },
- { qStringT(), pyStrT() },
- { u"uchar"_s, pyStrT() },
+ if (type.typeUsagePattern() == AbstractMetaType::PrimitivePattern) {
+ const auto &basicName = basicReferencedTypeEntry(type.typeEntry())->name();
+ if (AbstractMetaType::cppSignedIntTypes().contains(basicName)
+ || AbstractMetaType::cppUnsignedIntTypes().contains(basicName)) {
+ return intT;
+ }
+ if (AbstractMetaType::cppFloatTypes().contains(basicName))
+ return floatT;
+ }
+
+ static const QSet<QString> stringTypes = {
+ u"uchar"_s, u"std::string"_s, u"std::wstring"_s,
+ u"std::stringview"_s, u"std::wstringview"_s,
+ qStringT, u"QStringView"_s, u"QAnyStringView"_s, u"QUtf8StringView"_s
+ };
+ if (stringTypes.contains(name))
+ return pyStrT;
+
+ static const QHash<QString, QString> typeMap = {
+ { cPyObjectT, pyObjectT },
{ u"QStringList"_s, u"list of strings"_s },
- { qVariantT(), pyObjectT() },
- { u"quint32"_s, intT() },
- { u"uint32_t"_s, intT() },
- { u"quint64"_s, intT() },
- { u"qint64"_s, intT() },
- { u"size_t"_s, intT() },
- { u"int64_t"_s, intT() },
- { u"qreal"_s, floatT() }
+ { qVariantT, pyObjectT }
};
- const auto found = typeMap.find(name);
- if (found != typeMap.end())
+ const auto found = typeMap.constFind(name);
+ if (found != typeMap.cend())
return found.value();
- QString strType;
- if (type.isConstant() && name == u"char" && type.indirections() == 1) {
- strType = u"str"_s;
- } else if (name.startsWith(unsignedShortT())) {
- strType = intT();
- } else if (name.startsWith(unsignedT())) { // uint and ulong
- strType = intT();
- } else if (type.isContainer()) {
+ if (type.isFlags()) {
+ const auto fte = std::static_pointer_cast<const FlagsTypeEntry>(type.typeEntry());
+ auto enumTypeEntry = fte->originator();
+ auto enumName = enumTypeEntry->targetLangName();
+ if (createRef)
+ enumName.prepend(enumTypeEntry->targetLangPackage() + u'.');
+ return "Combination of "_L1 + (createRef ? toRef(enumName) : enumName);
+ } else if (type.isEnum()) {
+ auto enumTypeEntry = std::static_pointer_cast<const EnumTypeEntry>(type.typeEntry());
+ auto enumName = enumTypeEntry->targetLangName();
+ if (createRef)
+ enumName.prepend(enumTypeEntry->targetLangPackage() + u'.');
+ return createRef ? toRef(enumName) : enumName;
+ }
+
+ if (type.isConstant() && name == "char"_L1 && type.indirections() == 1)
+ return "str"_L1;
+
+ if (type.isContainer()) {
QString strType = translateType(type, cppClass, Options(ExcludeConst) | ExcludeReference);
strType.remove(u'*');
strType.remove(u'>');
@@ -714,19 +805,19 @@ QString QtDocGenerator::translateToPythonType(const AbstractMetaType &type,
strType = QString::fromLatin1("Dictionary with keys of type %1 and values of type %2.")
.arg(types[0], types[1]);
}
- } else {
- auto k = AbstractMetaClass::findClass(api().classes(), type.typeEntry());
- strType = k ? k->fullName() : type.name();
- if (createRef) {
- strType.prepend(u":any:`"_s);
- strType.append(u'`');
- }
+ return strType;
}
- return strType;
+
+ if (auto k = AbstractMetaClass::findClass(api().classes(), type.typeEntry()))
+ return createRef ? toRef(k->fullName()) : k->name();
+
+ return createRef ? toRef(name) : name;
}
QString QtDocGenerator::getFuncName(const AbstractMetaFunctionCPtr &cppFunc)
{
+ if (cppFunc->isConstructor())
+ return "__init__"_L1;
QString result = cppFunc->name();
if (cppFunc->isOperatorOverload()) {
const QString pythonOperator = Generator::pythonOperatorFunctionName(result);
@@ -737,14 +828,16 @@ QString QtDocGenerator::getFuncName(const AbstractMetaFunctionCPtr &cppFunc)
return result;
}
-void QtDocGenerator::writeParameterType(TextStream &s, const AbstractMetaClass *cppClass,
+void QtDocGenerator::writeParameterType(TextStream &s,
+ const AbstractMetaClassCPtr &cppClass,
const AbstractMetaArgument &arg) const
{
s << ":param " << arg.name() << ": "
<< translateToPythonType(arg.type(), cppClass) << '\n';
}
-void QtDocGenerator::writeFunctionParametersType(TextStream &s, const AbstractMetaClass *cppClass,
+void QtDocGenerator::writeFunctionParametersType(TextStream &s,
+ const AbstractMetaClassCPtr &cppClass,
const AbstractMetaFunctionCPtr &func) const
{
s << '\n';
@@ -754,36 +847,54 @@ void QtDocGenerator::writeFunctionParametersType(TextStream &s, const AbstractMe
writeParameterType(s, cppClass, arg);
}
- if (!func->isConstructor() && !func->isVoid()) {
-
- QString retType;
+ QString retType;
+ if (!func->isConstructor()) {
// check if the return type was modified
- for (const auto &mod : func->modifications()) {
- for (const ArgumentModification &argMod : mod.argument_mods()) {
- if (argMod.index() == 0) {
- retType = argMod.modifiedType();
- break;
- }
- }
- }
-
- if (retType.isEmpty())
+ retType = func->modifiedTypeName();
+ if (retType.isEmpty() && !func->isVoid())
retType = translateToPythonType(func->type(), cppClass);
- s << ":rtype: " << retType << '\n';
}
+
+ if (!retType.isEmpty())
+ s << ":rtype: " << retType << '\n';
+
s << '\n';
}
-void QtDocGenerator::writeFunction(TextStream &s, const AbstractMetaClass *cppClass,
- const AbstractMetaFunctionCPtr &func, bool indexed)
+static bool containsFunctionDirective(const DocModification &dm)
{
- s << functionSignature(cppClass, func);
+ return dm.mode() != TypeSystem::DocModificationXPathReplace
+ && dm.code().contains(".. py:"_L1);
+}
- {
+void QtDocGenerator::writeFunctions(TextStream &s, const AbstractMetaFunctionCList &funcs,
+ const AbstractMetaClassCPtr &cppClass, const QString &scope)
+{
+ QString lastName;
+ for (const auto &func : funcs) {
+ const bool indexed = func->name() != lastName;
+ lastName = func->name();
+ writeFunction(s, func, cppClass, scope, indexed);
+ }
+}
+
+void QtDocGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaClassCPtr &cppClass,
+ const QString &scope, bool indexed)
+{
+ const auto modifications = DocParser::getDocModifications(func, cppClass);
+
+ // Enable injecting parameter documentation by adding a complete function directive.
+ if (std::none_of(modifications.cbegin(), modifications.cend(), containsFunctionDirective)) {
+ if (func->ownerClass() == nullptr)
+ s << ".. py:function:: ";
+ else
+ s << (func->isStatic() ? ".. py:staticmethod:: " : ".. py:method:: ");
+ s << getFuncName(func) << formatArgs(func);
Indentation indentation(s);
if (!indexed)
s << "\n:noindex:";
- if (func->attributes().testFlag(AbstractMetaFunction::Attribute::FinalCppMethod))
+ if (func->cppAttributes().testFlag(FunctionAttribute::Final))
s << "\n:final:";
else if (func->isAbstract())
s << "\n:abstractmethod:";
@@ -795,16 +906,12 @@ void QtDocGenerator::writeFunction(TextStream &s, const AbstractMetaClass *cppCl
if (func->isDeprecated())
s << rstDeprecationNote("function");
}
- writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, cppClass, func);
- if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, cppClass, func)) {
- writeFormattedBriefText(s, func->documentation(), cppClass);
- writeFormattedDetailedText(s, func->documentation(), cppClass);
- }
- writeInjectDocumentation(s, TypeSystem::DocModificationAppend, cppClass, func);
+
+ writeFunctionDocumentation(s, func, modifications, scope);
if (auto propIndex = func->propertySpecIndex(); propIndex >= 0) {
const QString name = cppClass->propertySpecs().at(propIndex).name();
- const QString target = propertyRefTarget(cppClass, name);
+ const QString target = propertyRefTarget(name);
if (func->isPropertyReader())
s << "\nGetter of property " << propRef(target) << " .\n\n";
else if (func->isPropertyWriter())
@@ -816,23 +923,77 @@ void QtDocGenerator::writeFunction(TextStream &s, const AbstractMetaClass *cppCl
}
}
-static void writeFancyToc(TextStream& s, const QStringList& items)
+void QtDocGenerator::writeFunctionDocumentation(TextStream &s, const AbstractMetaFunctionCPtr &func,
+ const DocModificationList &modifications,
+ const QString &scope) const
+
+{
+ writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, modifications, func, scope);
+ if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, modifications, func, scope)) {
+ writeFormattedBriefText(s, func->documentation(), scope);
+ writeFormattedDetailedText(s, func->documentation(), scope);
+ }
+ writeInjectDocumentation(s, TypeSystem::DocModificationAppend, modifications, func, scope);
+}
+
+static QStringList fileListToToc(const QStringList &items)
+{
+ QStringList result;
+ result.reserve(items.size());
+ std::transform(items.cbegin(), items.cend(), std::back_inserter(result),
+ fileNameToTocEntry);
+ return result;
+}
+
+static QStringList functionListToToc(const AbstractMetaFunctionCList &functions)
+{
+ QStringList result;
+ result.reserve(functions.size());
+ for (const auto &f : functions)
+ result.append(f->name());
+ // Functions are sorted by the Metabuilder; erase overloads
+ result.erase(std::unique(result.begin(), result.end()), result.end());
+ return result;
+}
+
+static QStringList enumListToToc(const AbstractMetaEnumList &enums)
+{
+ QStringList result;
+ result.reserve(enums.size());
+ for (const auto &e : enums)
+ result.append(e.name());
+ return result;
+}
+
+// Sort entries for a TOC by first character, dropping the
+// leading common Qt prefixes like 'Q'.
+static QChar sortKey(const QString &key)
+{
+ const auto size = key.size();
+ if (size >= 2 && (key.at(0) == u'Q' || key.at(0) == u'q') && key.at(1).isUpper())
+ return key.at(1); // "QClass" -> 'C', "qSin()" -> 'S'
+ if (size >= 3 && key.startsWith("Q_"_L1))
+ return key.at(2).toUpper(); // "Q_ARG" -> 'A'
+ if (size >= 4 && key.startsWith("QT_"_L1))
+ return key.at(3).toUpper(); // "QT_TR" -> 'T'
+ auto idx = 0;
+ for (; idx < size && key.at(idx) == u'_'; ++idx) {
+ } // "__init__" -> 'I'
+ return idx < size ? key.at(idx).toUpper() : u'A';
+}
+
+static void writeFancyToc(TextStream& s, QAnyStringView title,
+ const QStringList& items,
+ QLatin1StringView referenceType)
{
using TocMap = QMap<QChar, QStringList>;
+
+ if (items.isEmpty())
+ return;
+
TocMap tocMap;
- QChar idx;
- for (QString item : items) {
- if (item.isEmpty())
- continue;
- item.chop(4); // Remove the .rst extension
- // skip namespace if necessary
- const QString className = item.split(u'.').last();
- if (className.startsWith(u'Q') && className.length() > 1)
- idx = className[1];
- else
- idx = className[0];
- tocMap[idx] << item;
- }
+ for (const QString &item : items)
+ tocMap[sortKey(item)] << item;
static const qsizetype numColumns = 4;
@@ -847,7 +1008,7 @@ static void writeFancyToc(TextStream& s, const QStringList& items)
row.clear();
row << QtXmlToSphinx::TableCell(QString{});
}
- const QString entry = u"* :doc:`"_s + item + u'`';
+ const QString entry = "* :"_L1 + referenceType + ":`"_L1 + item + u'`';
row << QtXmlToSphinx::TableCell(entry);
}
if (row.size() > 1)
@@ -855,33 +1016,44 @@ static void writeFancyToc(TextStream& s, const QStringList& items)
}
table.normalize();
- s << ".. container:: pysidetoc\n\n";
+ s << '\n' << headline(title) << ".. container:: pysidetoc\n\n";
table.format(s);
}
bool QtDocGenerator::finishGeneration()
{
- if (!api().classes().isEmpty())
+ for (const auto &f : api().globalFunctions()) {
+ auto ncf = std::const_pointer_cast<AbstractMetaFunction>(f);
+ m_docParser->fillGlobalFunctionDocumentation(ncf);
+ m_packages[f->targetLangPackage()].globalFunctions.append(f);
+ }
+
+ for (auto e : api().globalEnums()) {
+ m_docParser->fillGlobalEnumDocumentation(e);
+ m_packages[e.typeEntry()->targetLangPackage()].globalEnums.append(e);
+ }
+
+ if (!m_packages.isEmpty())
writeModuleDocumentation();
- if (!m_additionalDocumentationList.isEmpty())
+ if (!m_options.additionalDocumentationList.isEmpty())
writeAdditionalDocumentation();
- if (!m_inheritanceFile.isEmpty() && !writeInheritanceFile())
+ if (!m_options.inheritanceFile.isEmpty() && !writeInheritanceFile())
return false;
return true;
}
bool QtDocGenerator::writeInheritanceFile()
{
- QFile inheritanceFile(m_inheritanceFile);
+ QFile inheritanceFile(m_options.inheritanceFile);
if (!inheritanceFile.open(QIODevice::WriteOnly | QIODevice::Text))
- throw Exception(msgCannotOpenForWriting(m_inheritanceFile));
+ throw Exception(msgCannotOpenForWriting(m_options.inheritanceFile));
QJsonObject dict;
- for (auto *c : api().classes()) {
+ for (const auto &c : api().classes()) {
const auto &bases = c->baseClasses();
if (!bases.isEmpty()) {
QJsonArray list;
- for (auto *base : bases)
+ for (const auto &base : bases)
list.append(QJsonValue(base->fullName()));
dict[c->fullName()] = list;
}
@@ -892,11 +1064,22 @@ bool QtDocGenerator::writeInheritanceFile()
return true;
}
+// Remove function entries that have extra documentation pages
+static inline void removeExtraDocs(const QStringList &extraTocEntries,
+ AbstractMetaFunctionCList *functions)
+{
+ auto predicate = [&extraTocEntries](const AbstractMetaFunctionCPtr &f) {
+ return extraTocEntries.contains(f->name());
+ };
+ functions->erase(std::remove_if(functions->begin(),functions->end(), predicate),
+ functions->end());
+}
+
void QtDocGenerator::writeModuleDocumentation()
{
- QMap<QString, QStringList>::iterator it = m_packages.begin();
- for (; it != m_packages.end(); ++it) {
- std::sort(it.value().begin(), it.value().end());
+ for (auto it = m_packages.begin(), end = m_packages.end(); it != end; ++it) {
+ auto &docPackage = it.value();
+ std::sort(docPackage.classPages.begin(), docPackage.classPages.end());
QString key = it.key();
key.replace(u'.', u'/');
@@ -905,9 +1088,7 @@ void QtDocGenerator::writeModuleDocumentation()
TextStream& s = output.stream;
const QString &title = it.key();
- s << ".. module:: " << title << "\n\n"
- << title << '\n'
- << Pad('*', title.length()) << "\n\n";
+ s << ".. module:: " << title << "\n\n" << headline(title, '*');
// Store the it.key() in a QString so that it can be stripped off unwanted
// information when neeeded. For example, the RST files in the extras directory
@@ -918,11 +1099,12 @@ void QtDocGenerator::writeModuleDocumentation()
moduleName.remove(0, lastIndex + 1);
// Search for extra-sections
- if (!m_extraSectionDir.isEmpty()) {
- QDir extraSectionDir(m_extraSectionDir);
+ QStringList extraTocEntries;
+ if (!m_options.extraSectionDir.isEmpty()) {
+ QDir extraSectionDir(m_options.extraSectionDir);
if (!extraSectionDir.exists()) {
- const QString m = QStringLiteral("Extra sections directory ") +
- m_extraSectionDir + QStringLiteral(" doesn't exist");
+ const QString m = u"Extra sections directory "_s +
+ m_options.extraSectionDir + u" doesn't exist"_s;
throw Exception(m);
}
@@ -930,31 +1112,26 @@ void QtDocGenerator::writeModuleDocumentation()
const QString filter = moduleName + u".?*.rst"_s;
const auto fileList =
extraSectionDir.entryInfoList({filter}, QDir::Files, QDir::Name);
- for (const auto &fi : fileList) {
- // Strip to "Property.rst" in output directory
- const QString newFileName = fi.fileName().mid(moduleName.size() + 1);
- it.value().append(newFileName);
- const QString newFilePath = outputDir + u'/' + newFileName;
- if (QFile::exists(newFilePath))
- QFile::remove(newFilePath);
- if (!QFile::copy(fi.absoluteFilePath(), newFilePath)) {
- qCDebug(lcShibokenDoc).noquote().nospace() << "Error copying extra doc "
- << QDir::toNativeSeparators(fi.absoluteFilePath())
- << " to " << QDir::toNativeSeparators(newFilePath);
- }
- }
+ for (const auto &fi : fileList)
+ readExtraDoc(fi, moduleName, outputDir, &docPackage, &extraTocEntries);
}
+ removeExtraDocs(extraTocEntries, &docPackage.globalFunctions);
+ const bool hasGlobals = !docPackage.globalFunctions.isEmpty()
+ || !docPackage.globalEnums.isEmpty();
+ const QString globalsPage = moduleName + "_globals.rst"_L1;
+
s << ".. container:: hide\n\n" << indent
<< ".. toctree::\n" << indent
<< ":maxdepth: 1\n\n";
- for (const QString &className : std::as_const(it.value()))
+ if (hasGlobals)
+ s << globalsPage << '\n';
+ for (const QString &className : std::as_const(docPackage.classPages))
s << className << '\n';
- s << "\n\n" << outdent << outdent
- << "Detailed Description\n--------------------\n\n";
+ s << "\n\n" << outdent << outdent << headline("Detailed Description");
// module doc is always wrong and C++istic, so go straight to the extra directory!
- QFile moduleDoc(m_extraSectionDir + u'/' + moduleName
+ QFile moduleDoc(m_options.extraSectionDir + u'/' + moduleName
+ u".rst"_s);
if (moduleDoc.open(QIODevice::ReadOnly | QIODevice::Text)) {
s << moduleDoc.readAll();
@@ -965,21 +1142,50 @@ void QtDocGenerator::writeModuleDocumentation()
if (moduleDoc.format() == Documentation::Native) {
QString context = it.key();
QtXmlToSphinx::stripPythonQualifiers(&context);
- QtXmlToSphinx x(this, m_parameters, moduleDoc.detailed(), context);
+ QtXmlToSphinx x(this, m_options.parameters, moduleDoc.detailed(), context);
s << x;
} else {
s << moduleDoc.detailed();
}
}
- s << "\nList of Classes\n"
- << "---------------\n\n";
- writeFancyToc(s, it.value());
+ writeFancyToc(s, "List of Classes", fileListToToc(docPackage.classPages),
+ "class"_L1);
+ writeFancyToc(s, "List of Decorators", fileListToToc(docPackage.decoratorPages),
+ "deco"_L1);
+ writeFancyToc(s, "List of Functions", functionListToToc(docPackage.globalFunctions),
+ "py:func"_L1);
+ writeFancyToc(s, "List of Enumerations", enumListToToc(docPackage.globalEnums),
+ "any"_L1);
output.done();
+
+ if (hasGlobals)
+ writeGlobals(it.key(), outputDir + u'/' + globalsPage, docPackage);
}
}
+void QtDocGenerator::writeGlobals(const QString &package,
+ const QString &fileName,
+ const DocPackage &docPackage)
+{
+ FileOut output(fileName);
+ TextStream &s = output.stream;
+
+ // Write out functions with injected documentation
+ if (!docPackage.globalFunctions.isEmpty()) {
+ s << currentModule(package) << headline("Functions");
+ writeFunctions(s, docPackage.globalFunctions, {}, {});
+ }
+
+ if (!docPackage.globalEnums.isEmpty()) {
+ s << headline("Enumerations");
+ writeEnums(s, docPackage.globalEnums, package);
+ }
+
+ output.done();
+}
+
static inline QString msgNonExistentAdditionalDocFile(const QString &dir,
const QString &fileName)
{
@@ -992,7 +1198,7 @@ static inline QString msgNonExistentAdditionalDocFile(const QString &dir,
void QtDocGenerator::writeAdditionalDocumentation() const
{
- QFile additionalDocumentationFile(m_additionalDocumentationList);
+ QFile additionalDocumentationFile(m_options.additionalDocumentationList);
if (!additionalDocumentationFile.open(QIODevice::ReadOnly | QIODevice::Text))
throw Exception(msgCannotOpenForReading(additionalDocumentationFile));
@@ -1017,8 +1223,8 @@ void QtDocGenerator::writeAdditionalDocumentation() const
targetDir = outDir.absolutePath();
} else {
if (!outDir.exists(dir) && !outDir.mkdir(dir)) {
- const QString m = QStringLiteral("Cannot create directory ")
- + dir + QStringLiteral(" under ")
+ const QString m = "Cannot create directory "_L1
+ + dir + " under "_L1
+ QDir::toNativeSeparators(outputDirectory());
throw Exception(m);
}
@@ -1026,7 +1232,7 @@ void QtDocGenerator::writeAdditionalDocumentation() const
}
} else {
// Normal file entry
- QFileInfo fi(m_parameters.docDataDir + u'/' + line);
+ QFileInfo fi(m_options.parameters.docDataDir + u'/' + line);
if (fi.isFile()) {
const QString rstFileName = fi.baseName() + rstSuffix;
const QString rstFile = targetDir + u'/' + rstFileName;
@@ -1044,7 +1250,7 @@ void QtDocGenerator::writeAdditionalDocumentation() const
// FIXME: This should be an exception, in principle, but it
// requires building all modules.
qCWarning(lcShibokenDoc, "%s",
- qPrintable(msgNonExistentAdditionalDocFile(m_parameters.docDataDir, line)));
+ qPrintable(msgNonExistentAdditionalDocFile(m_options.parameters.docDataDir, line)));
}
++count;
}
@@ -1063,32 +1269,34 @@ void QtDocGenerator::writeAdditionalDocumentation() const
bool QtDocGenerator::doSetup()
{
- if (m_parameters.codeSnippetDirs.isEmpty()) {
- m_parameters.codeSnippetDirs =
- m_parameters.libSourceDir.split(QLatin1Char(PATH_SEP));
+ if (m_options.parameters.codeSnippetDirs.isEmpty()) {
+ m_options.parameters.codeSnippetDirs =
+ m_options.parameters.libSourceDir.split(QLatin1Char(PATH_SEP));
}
- if (m_docParser.isNull())
- m_docParser.reset(new QtDocParser);
+ if (m_docParser.isNull()) {
+ if (m_options.doxygen)
+ m_docParser.reset(new DoxygenParser);
+ else
+ m_docParser.reset(new QtDocParser);
+ }
- if (m_parameters.libSourceDir.isEmpty()
- || m_parameters.docDataDir.isEmpty()) {
+ if (m_options.parameters.libSourceDir.isEmpty()
+ || m_options.parameters.docDataDir.isEmpty()) {
qCWarning(lcShibokenDoc) << "Documentation data dir and/or Qt source dir not informed, "
"documentation will not be extracted from Qt sources.";
return false;
}
- m_docParser->setDocumentationDataDirectory(m_parameters.docDataDir);
- m_docParser->setLibrarySourceDirectory(m_parameters.libSourceDir);
- m_parameters.outputDirectory = outputDirectory();
+ m_docParser->setDocumentationDataDirectory(m_options.parameters.docDataDir);
+ m_docParser->setLibrarySourceDirectory(m_options.parameters.libSourceDir);
+ m_options.parameters.outputDirectory = outputDirectory();
return true;
}
-
-Generator::OptionDescriptions QtDocGenerator::options() const
+QList<OptionDescription> QtDocGenerator::options()
{
- auto result = Generator::options();
- result.append({
+ return {
{u"doc-parser=<parser>"_s,
u"The documentation parser used to interpret the documentation\n"
"input files (qdoc|doxygen)"_s},
@@ -1102,30 +1310,52 @@ Generator::OptionDescriptions QtDocGenerator::options() const
u"Directory used to search for extra documentation sections"_s},
{u"library-source-dir=<dir>"_s,
u"Directory where library source code is located"_s},
- {additionalDocumentationOption() + u"=<file>"_s,
+ {additionalDocumentationOption + u"=<file>"_s,
u"List of additional XML files to be converted to .rst files\n"
"(for example, tutorials)."_s},
{u"inheritance-file=<file>"_s,
- u"Generate a JSON file containing the class inheritance."_s}
-
- });
- return result;
+ u"Generate a JSON file containing the class inheritance."_s},
+ {u"disable-inheritance-diagram"_s,
+ u"Disable the generation of the inheritance diagram."_s}
+ };
}
-bool QtDocGenerator::handleOption(const QString &key, const QString &value)
+class QtDocGeneratorOptionsParser : public OptionsParser
{
- if (Generator::handleOption(key, value))
+public:
+ explicit QtDocGeneratorOptionsParser(DocGeneratorOptions *o) : m_options(o) {}
+
+ bool handleBoolOption(const QString &key, OptionSource source) override;
+ bool handleOption(const QString &key, const QString &value, OptionSource source) override;
+
+private:
+ DocGeneratorOptions *m_options;
+};
+
+bool QtDocGeneratorOptionsParser::handleBoolOption(const QString &key, OptionSource)
+{
+ if (key == "disable-inheritance-diagram"_L1) {
+ m_options->inheritanceDiagram = false;
return true;
+ }
+ return false;
+}
+
+bool QtDocGeneratorOptionsParser::handleOption(const QString &key, const QString &value,
+ OptionSource source)
+{
+ if (source == OptionSource::CommandLineSingleDash)
+ return false;
if (key == u"library-source-dir") {
- m_parameters.libSourceDir = value;
+ m_options->parameters.libSourceDir = value;
return true;
}
if (key == u"documentation-data-dir") {
- m_parameters.docDataDir = value;
+ m_options->parameters.docDataDir = value;
return true;
}
if (key == u"documentation-code-snippets-dir") {
- m_parameters.codeSnippetDirs = value.split(QLatin1Char(PATH_SEP));
+ m_options->parameters.codeSnippetDirs = value.split(QLatin1Char(PATH_SEP));
return true;
}
@@ -1133,34 +1363,39 @@ bool QtDocGenerator::handleOption(const QString &key, const QString &value)
const auto pos = value.indexOf(u':');
if (pos == -1)
return false;
- m_parameters.codeSnippetRewriteOld= value.left(pos);
- m_parameters.codeSnippetRewriteNew = value.mid(pos + 1);
+ m_options->parameters.codeSnippetRewriteOld= value.left(pos);
+ m_options->parameters.codeSnippetRewriteNew = value.mid(pos + 1);
return true;
}
if (key == u"documentation-extra-sections-dir") {
- m_extraSectionDir = value;
+ m_options->extraSectionDir = value;
return true;
}
if (key == u"doc-parser") {
qCDebug(lcShibokenDoc).noquote().nospace() << "doc-parser: " << value;
if (value == u"doxygen")
- m_docParser.reset(new DoxygenParser);
+ m_options->doxygen = true;
return true;
}
- if (key == additionalDocumentationOption()) {
- m_additionalDocumentationList = value;
+ if (key == additionalDocumentationOption) {
+ m_options->additionalDocumentationList = value;
return true;
}
if (key == u"inheritance-file") {
- m_inheritanceFile = value;
+ m_options->inheritanceFile = value;
return true;
}
return false;
}
+std::shared_ptr<OptionsParser> QtDocGenerator::createOptionsParser()
+{
+ return std::make_shared<QtDocGeneratorOptionsParser>(&m_options);
+}
+
bool QtDocGenerator::convertToRst(const QString &sourceFileName,
const QString &targetFileName,
const QString &context,
@@ -1176,28 +1411,22 @@ bool QtDocGenerator::convertToRst(const QString &sourceFileName,
sourceFile.close();
FileOut targetFile(targetFileName);
- QtXmlToSphinx x(this, m_parameters, doc, context);
+ QtXmlToSphinx x(this, m_options.parameters, doc, context);
targetFile.stream << x;
targetFile.done();
return true;
}
GeneratorDocumentation
- QtDocGenerator::generatorDocumentation(const AbstractMetaClass *cppClass) const
+ QtDocGenerator::generatorDocumentation(const AbstractMetaClassCPtr &cppClass)
{
GeneratorDocumentation result;
const auto allFunctions = cppClass->functions();
result.allFunctions.reserve(allFunctions.size());
- for (const auto &func : allFunctions) {
- if (!shouldSkip(func)) {
- if (func->isConstructor())
- result.constructors.append(func);
- else
- result.allFunctions.append(func);
- }
- }
+ std::remove_copy_if(allFunctions.cbegin(), allFunctions.cend(),
+ std::back_inserter(result.allFunctions), shouldSkip);
- std::sort(result.allFunctions.begin(), result.allFunctions.end(), functionSort);
+ std::stable_sort(result.allFunctions.begin(), result.allFunctions.end(), functionSort);
for (const auto &func : std::as_const(result.allFunctions)) {
if (func->isStatic())
@@ -1236,11 +1465,11 @@ GeneratorDocumentation
// QtXmlToSphinxDocGeneratorInterface
QString QtDocGenerator::expandFunction(const QString &function) const
{
- const int firstDot = function.indexOf(u'.');
- const AbstractMetaClass *metaClass = nullptr;
+ const auto firstDot = function.indexOf(u'.');
+ AbstractMetaClassCPtr metaClass;
if (firstDot != -1) {
const auto className = QStringView{function}.left(firstDot);
- for (auto cls : api().classes()) {
+ for (const auto &cls : api().classes()) {
if (cls->name() == className) {
metaClass = cls;
break;
@@ -1275,8 +1504,8 @@ QString QtDocGenerator::resolveContextForMethod(const QString &context,
{
const auto currentClass = QStringView{context}.split(u'.').constLast();
- const AbstractMetaClass *metaClass = nullptr;
- for (auto cls : api().classes()) {
+ AbstractMetaClassCPtr metaClass;
+ for (const auto &cls : api().classes()) {
if (cls->name() == currentClass) {
metaClass = cls;
break;
@@ -1291,7 +1520,7 @@ QString QtDocGenerator::resolveContextForMethod(const QString &context,
funcList.append(func);
}
- const AbstractMetaClass *implementingClass = nullptr;
+ AbstractMetaClassCPtr implementingClass;
for (const auto &func : std::as_const(funcList)) {
implementingClass = func->implementingClass();
if (implementingClass->name() == currentClass)
@@ -1322,7 +1551,7 @@ QtXmlToSphinxLink QtDocGenerator::resolveLink(const QtXmlToSphinxLink &link) con
{
if (link.type != QtXmlToSphinxLink::Reference || !isRelativeHtmlFile(link.linkRef))
return link;
- static const QString prefix = QStringLiteral("https://doc.qt.io/qt-")
+ static const QString prefix = "https://doc.qt.io/qt-"_L1
+ QString::number(QT_VERSION_MAJOR) + u'/';
QtXmlToSphinxLink resolved = link;
resolved.type = QtXmlToSphinxLink::External;
@@ -1333,6 +1562,5 @@ QtXmlToSphinxLink QtDocGenerator::resolveLink(const QtXmlToSphinxLink &link) con
if (anchor != -1)
resolved.linkText.truncate(anchor);
}
- qDebug() << __FUNCTION__ << link << "->" << resolved;
return resolved;
}
diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
index af4b60d2e..3b1c82e74 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
@@ -9,13 +9,15 @@
#include "generator.h"
#include "documentation.h"
+#include <optionsparser.h>
#include "typesystem_enums.h"
#include "modifications_typedefs.h"
#include "qtxmltosphinxinterface.h"
class DocParser;
-
+struct DocGeneratorOptions;
struct GeneratorDocumentation;
+struct DocPackage;
/**
* The DocGenerator generates documentation from library being binded.
@@ -23,6 +25,8 @@ struct GeneratorDocumentation;
class QtDocGenerator : public Generator, public QtXmlToSphinxDocGeneratorInterface
{
public:
+ Q_DISABLE_COPY_MOVE(QtDocGenerator)
+
QtDocGenerator();
~QtDocGenerator();
@@ -33,8 +37,8 @@ public:
return "QtDocGenerator";
}
- OptionDescriptions options() const override;
- bool handleOption(const QString &key, const QString &value) override;
+ static QList<OptionDescription> options();
+ static std::shared_ptr<OptionsParser> createOptionsParser();
// QtXmlToSphinxDocGeneratorInterface
QString expandFunction(const QString &function) const override;
@@ -56,50 +60,57 @@ protected:
bool finishGeneration() override;
private:
- void writeEnums(TextStream &s, const AbstractMetaClass *cppClass) const;
-
- void writeFields(TextStream &s, const AbstractMetaClass *cppClass) const;
- static QString functionSignature(const AbstractMetaClass *cppClass,
- const AbstractMetaFunctionCPtr &func);
- void writeFunction(TextStream &s, const AbstractMetaClass *cppClass,
- const AbstractMetaFunctionCPtr &func, bool indexed = true);
- void writeFunctionParametersType(TextStream &s, const AbstractMetaClass *cppClass,
+ void writeEnums(TextStream &s, const AbstractMetaEnumList &enums,
+ const QString &scope) const;
+
+ void writeFields(TextStream &s, const AbstractMetaClassCPtr &cppClass) const;
+ void writeFunctions(TextStream &s, const AbstractMetaFunctionCList &funcs,
+ const AbstractMetaClassCPtr &cppClass, const QString &scope);
+ void writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaClassCPtr &cppClass = {},
+ const QString &scope = {}, bool indexed = true);
+ void writeFunctionDocumentation(TextStream &s, const AbstractMetaFunctionCPtr &func,
+ const DocModificationList &modifications,
+ const QString &scope) const;
+ void writeFunctionParametersType(TextStream &s, const AbstractMetaClassCPtr &cppClass,
const AbstractMetaFunctionCPtr &func) const;
static void writeFunctionToc(TextStream &s, const QString &title,
- const AbstractMetaClass *cppClass,
const AbstractMetaFunctionCList &functions);
- void writePropertyToc(TextStream &s,
- const GeneratorDocumentation &doc,
- const AbstractMetaClass *cppClass);
+ static void writePropertyToc(TextStream &s,
+ const GeneratorDocumentation &doc);
void writeProperties(TextStream &s,
const GeneratorDocumentation &doc,
- const AbstractMetaClass *cppClass) const;
- void writeParameterType(TextStream &s, const AbstractMetaClass *cppClass,
+ const AbstractMetaClassCPtr &cppClass) const;
+ void writeParameterType(TextStream &s, const AbstractMetaClassCPtr &cppClass,
const AbstractMetaArgument &arg) const;
-
- void writeConstructors(TextStream &s,
- const AbstractMetaClass *cppClass,
- const AbstractMetaFunctionCList &constructors) const;
-
void writeFormattedText(TextStream &s, const QString &doc,
Documentation::Format format,
- const AbstractMetaClass *metaClass = nullptr) const;
+ const QString &scope = {}) const;
void writeFormattedBriefText(TextStream &s, const Documentation &doc,
- const AbstractMetaClass *metaclass = nullptr) const;
+ const QString &scope = {}) const;
void writeFormattedDetailedText(TextStream &s, const Documentation &doc,
- const AbstractMetaClass *metaclass = nullptr) const;
+ const QString &scope = {}) const;
bool writeInjectDocumentation(TextStream &s, TypeSystem::DocModificationMode mode,
- const AbstractMetaClass *cppClass,
- const AbstractMetaFunctionCPtr &func);
+ const AbstractMetaClassCPtr &cppClass) const;
+ bool writeInjectDocumentation(TextStream &s, TypeSystem::DocModificationMode mode,
+ const DocModificationList &modifications,
+ const AbstractMetaFunctionCPtr &func,
+ const QString &scope = {}) const;
+ bool writeDocModifications(TextStream &s, const DocModificationList &mods,
+ TypeSystem::DocModificationMode mode,
+ const QString &scope = {}) const;
static void writeDocSnips(TextStream &s, const CodeSnipList &codeSnips,
TypeSystem::CodeSnipPosition position, TypeSystem::Language language);
void writeModuleDocumentation();
+ void writeGlobals(const QString &package, const QString &fileName,
+ const DocPackage &docPackage);
void writeAdditionalDocumentation() const;
bool writeInheritanceFile();
- QString translateToPythonType(const AbstractMetaType &type, const AbstractMetaClass *cppClass,
+ QString translateToPythonType(const AbstractMetaType &type,
+ const AbstractMetaClassCPtr &cppClass,
bool createRef = true) const;
bool convertToRst(const QString &sourceFileName,
@@ -107,15 +118,12 @@ private:
const QString &context = QString(),
QString *errorMessage = nullptr) const;
- GeneratorDocumentation generatorDocumentation(const AbstractMetaClass *cppClass) const;
+ static GeneratorDocumentation generatorDocumentation(const AbstractMetaClassCPtr &cppClass);
- QString m_extraSectionDir;
QStringList m_functionList;
- QMap<QString, QStringList> m_packages;
+ QMap<QString, DocPackage> m_packages;
QScopedPointer<DocParser> m_docParser;
- QtXmlToSphinxParameters m_parameters;
- QString m_additionalDocumentationList;
- QString m_inheritanceFile;
+ static DocGeneratorOptions m_options;
};
#endif // DOCGENERATOR_H
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
index 222320d38..55c1d2090 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
@@ -19,10 +19,6 @@
using namespace Qt::StringLiterals;
-static inline QString nameAttribute() { return QStringLiteral("name"); }
-static inline QString titleAttribute() { return QStringLiteral("title"); }
-static inline QString fullTitleAttribute() { return QStringLiteral("fulltitle"); }
-
QString msgTagWarning(const QXmlStreamReader &reader, const QString &context,
const QString &tag, const QString &message)
{
@@ -63,6 +59,20 @@ static bool isHttpLink(const QString &ref)
return ref.startsWith(u"http://") || ref.startsWith(u"https://");
}
+static QString trimRight(QString s)
+{
+ while (!s.isEmpty() && s.crbegin()->isSpace())
+ s.chop(1);
+ return s;
+}
+
+static QString trimLeadingNewlines(QString s)
+{
+ while (!s.isEmpty() && s.at(0) == u'\n')
+ s.remove(0, 1);
+ return s;
+}
+
QDebug operator<<(QDebug d, const QtXmlToSphinxLink &l)
{
static const QHash<QtXmlToSphinxLink::Type, const char *> typeName = {
@@ -407,32 +417,49 @@ void QtXmlToSphinx::callHandler(WebXmlTag t, QXmlStreamReader &r)
void QtXmlToSphinx::formatCurrentTable()
{
- if (m_currentTable.isEmpty())
+ Q_ASSERT(!m_tables.isEmpty());
+ auto &table = m_tables.back();
+ if (table.isEmpty())
return;
- m_currentTable.normalize();
+ table.normalize();
m_output << '\n';
- m_currentTable.format(m_output);
+ table.format(m_output);
}
void QtXmlToSphinx::pushOutputBuffer()
{
- m_buffers.append(StringSharedPtr(new QString{}));
- m_output.setString(m_buffers.top().data());
+ m_buffers.append(std::make_shared<QString>());
+ m_output.setString(m_buffers.top().get());
}
QString QtXmlToSphinx::popOutputBuffer()
{
Q_ASSERT(!m_buffers.isEmpty());
- QString result(*m_buffers.top().data());
+ QString result(*m_buffers.top());
m_buffers.pop();
- m_output.setString(m_buffers.isEmpty() ? nullptr : m_buffers.top().data());
+ m_output.setString(m_buffers.isEmpty() ? nullptr : m_buffers.top().get());
return result;
}
+constexpr auto autoTranslatedPlaceholder = "AUTO_GENERATED\n"_L1;
+constexpr auto autoTranslatedNote =
+R"(.. warning::
+ This section contains snippets that were automatically
+ translated from C++ to Python and may contain errors.
+
+)"_L1;
+
+void QtXmlToSphinx::setAutoTranslatedNote(QString *str) const
+{
+ if (m_containsAutoTranslations)
+ str->replace(autoTranslatedPlaceholder, autoTranslatedNote);
+ else
+ str->remove(autoTranslatedPlaceholder);
+}
+
QString QtXmlToSphinx::transform(const QString& doc)
{
Q_ASSERT(m_buffers.isEmpty());
- Indentation indentation(m_output);
if (doc.trimmed().isEmpty())
return doc;
@@ -440,6 +467,9 @@ QString QtXmlToSphinx::transform(const QString& doc)
QXmlStreamReader reader(doc);
+ m_output << autoTranslatedPlaceholder;
+ Indentation indentation(m_output);
+
while (!reader.atEnd()) {
QXmlStreamReader::TokenType token = reader.readNext();
if (reader.hasError()) {
@@ -480,6 +510,7 @@ QString QtXmlToSphinx::transform(const QString& doc)
m_output.flush();
QString retval = popOutputBuffer();
Q_ASSERT(m_buffers.isEmpty());
+ setAutoTranslatedNote(&retval);
return retval;
}
@@ -528,7 +559,7 @@ static QString pySnippetName(const QString &path, SnippetType type)
QtXmlToSphinx::Snippet QtXmlToSphinx::readSnippetFromLocations(const QString &path,
const QString &identifier,
const QString &fallbackPath,
- QString *errorMessage) const
+ QString *errorMessage)
{
// For anything else but C++ header/sources (no conversion to Python),
// use existing fallback paths first.
@@ -550,6 +581,7 @@ QtXmlToSphinx::Snippet QtXmlToSphinx::readSnippetFromLocations(const QString &pa
rewrittenPath.replace(m_parameters.codeSnippetRewriteOld,
m_parameters.codeSnippetRewriteNew);
const QString code = readFromLocation(rewrittenPath, identifier, errorMessage);
+ m_containsAutoTranslations = true;
return {code, code.isNull() ? Snippet::Error : Snippet::Converted};
}
}
@@ -561,7 +593,7 @@ QtXmlToSphinx::Snippet QtXmlToSphinx::readSnippetFromLocations(const QString &pa
}
}
- resolvedPath =resolveFile(locations, path);
+ resolvedPath = resolveFile(locations, path);
if (!resolvedPath.isEmpty()) {
const QString code = readFromLocation(resolvedPath, identifier, errorMessage);
return {code, code.isNull() ? Snippet::Error : Snippet::Resolved};
@@ -577,6 +609,88 @@ QtXmlToSphinx::Snippet QtXmlToSphinx::readSnippetFromLocations(const QString &pa
return {{}, Snippet::Error};
}
+// Helpers for extracting qdoc snippets "#/// [id]"
+static QString fileNameOfDevice(const QIODevice *inputFile)
+{
+ const auto *file = qobject_cast<const QFile *>(inputFile);
+ return file ? QDir::toNativeSeparators(file->fileName()) : u"<stdin>"_s;
+}
+
+static QString msgSnippetNotFound(const QIODevice &inputFile,
+ const QString &identifier)
+{
+ return u"Code snippet file found ("_s + fileNameOfDevice(&inputFile)
+ + u"), but snippet ["_s + identifier + u"] not found."_s;
+}
+
+static QString msgEmptySnippet(const QIODevice &inputFile, int lineNo,
+ const QString &identifier)
+{
+ return u"Empty code snippet ["_s + identifier + u"] at "_s
+ + fileNameOfDevice(&inputFile) + u':' + QString::number(lineNo);
+}
+
+// Pattern to match qdoc snippet IDs with "#/// [id]" comments and helper to find ID
+static const QRegularExpression &snippetIdPattern()
+{
+ static const QRegularExpression result(uR"RX((//|#) *! *\[([^]]+)\])RX"_s);
+ Q_ASSERT(result.isValid());
+ return result;
+}
+
+static bool matchesSnippetId(QRegularExpressionMatchIterator it,
+ const QString &identifier)
+{
+ while (it.hasNext()) {
+ if (it.next().captured(2) == identifier)
+ return true;
+ }
+ return false;
+}
+
+QString QtXmlToSphinx::readSnippet(QIODevice &inputFile, const QString &identifier,
+ QString *errorMessage)
+{
+ const QByteArray identifierBA = identifier.toUtf8();
+ // Lambda that matches the snippet id
+ const auto snippetIdPred = [&identifierBA, &identifier](const QByteArray &lineBA)
+ {
+ const bool isComment = lineBA.contains('/') || lineBA.contains('#');
+ if (!isComment || !lineBA.contains(identifierBA))
+ return false;
+ const QString line = QString::fromUtf8(lineBA);
+ return matchesSnippetId(snippetIdPattern().globalMatch(line), identifier);
+ };
+
+ // Find beginning, skip over
+ int lineNo = 1;
+ for (; !inputFile.atEnd() && !snippetIdPred(inputFile.readLine());
+ ++lineNo) {
+ }
+
+ if (inputFile.atEnd()) {
+ *errorMessage = msgSnippetNotFound(inputFile, identifier);
+ return {};
+ }
+
+ QString code;
+ for (; !inputFile.atEnd(); ++lineNo) {
+ const QString line = QString::fromUtf8(inputFile.readLine());
+ auto it = snippetIdPattern().globalMatch(line);
+ if (it.hasNext()) { // Skip snippet id lines
+ if (matchesSnippetId(it, identifier))
+ break;
+ } else {
+ code += line;
+ }
+ }
+
+ if (code.isEmpty())
+ *errorMessage = msgEmptySnippet(inputFile, lineNo, identifier);
+
+ return code;
+}
+
QString QtXmlToSphinx::readFromLocation(const QString &location, const QString &identifier,
QString *errorMessage)
{
@@ -586,7 +700,7 @@ QString QtXmlToSphinx::readFromLocation(const QString &location, const QString &
QTextStream(errorMessage) << "Could not read code snippet file: "
<< QDir::toNativeSeparators(inputFile.fileName())
<< ": " << inputFile.errorString();
- return QString(); // null
+ return {}; // null
}
QString code = u""_s; // non-null
@@ -596,37 +710,8 @@ QString QtXmlToSphinx::readFromLocation(const QString &location, const QString &
return CodeSnipHelpers::fixSpaces(code);
}
- const QRegularExpression searchString(u"//!\\s*\\["_s
- + identifier + u"\\]"_s);
- Q_ASSERT(searchString.isValid());
- static const QRegularExpression cppCodeSnippetCode(u"//!\\s*\\[[\\w\\d\\s]+\\]"_s);
- Q_ASSERT(cppCodeSnippetCode.isValid());
- static const QRegularExpression pythonCodeSnippetCode(u"#!\\s*\\[[\\w\\d\\s]+\\]"_s);
- Q_ASSERT(pythonCodeSnippetCode.isValid());
-
- bool getCode = false;
-
- while (!inputFile.atEnd()) {
- QString line = QString::fromUtf8(inputFile.readLine());
- if (getCode && !line.contains(searchString)) {
- line.remove(cppCodeSnippetCode);
- line.remove(pythonCodeSnippetCode);
- code += line;
- } else if (line.contains(searchString)) {
- if (getCode)
- break;
- getCode = true;
- }
- }
-
- if (!getCode) {
- QTextStream(errorMessage) << "Code snippet file found ("
- << QDir::toNativeSeparators(location) << "), but snippet ["
- << identifier << "] not found.";
- return QString(); // null
- }
-
- return CodeSnipHelpers::fixSpaces(code);
+ code = readSnippet(inputFile, identifier, errorMessage);
+ return code.isEmpty() ? QString{} : CodeSnipHelpers::fixSpaces(code); // maintain isNull()
}
void QtXmlToSphinx::handleHeadingTag(QXmlStreamReader& reader)
@@ -689,9 +774,9 @@ void QtXmlToSphinx::handleParaTagEnd()
{
QString result = popOutputBuffer().simplified();
if (result.startsWith(u"**Warning:**"))
- result.replace(0, 12, QStringLiteral(".. warning:: "));
+ result.replace(0, 12, ".. warning:: "_L1);
else if (result.startsWith(u"**Note:**"))
- result.replace(0, 9, QStringLiteral(".. note:: "));
+ result.replace(0, 9, ".. note:: "_L1);
m_output << result << "\n\n";
}
@@ -760,23 +845,23 @@ void QtXmlToSphinx::handleArgumentTag(QXmlStreamReader& reader)
}
}
-static inline QString functionLinkType() { return QStringLiteral("function"); }
-static inline QString classLinkType() { return QStringLiteral("class"); }
+constexpr auto functionLinkType = "function"_L1;
+constexpr auto classLinkType = "class"_L1;
static inline QString fixLinkType(QStringView type)
{
// TODO: create a flag PROPERTY-AS-FUNCTION to ask if the properties
// are recognized as such or not in the binding
if (type == u"property")
- return functionLinkType();
+ return functionLinkType;
if (type == u"typedef")
- return classLinkType();
+ return classLinkType;
return type.toString();
}
static inline QString linkSourceAttribute(const QString &type)
{
- if (type == functionLinkType() || type == classLinkType())
+ if (type == functionLinkType || type == classLinkType)
return u"raw"_s;
return type == u"enum" || type == u"page"
? type : u"href"_s;
@@ -802,7 +887,7 @@ void QtXmlToSphinx::handleSeeAlsoTag(QXmlStreamReader& reader)
const QString text = textR.toString();
if (m_seeAlsoContext.isNull()) {
const QString type = text.endsWith(u"()")
- ? functionLinkType() : classLinkType();
+ ? functionLinkType : classLinkType;
m_seeAlsoContext.reset(handleLinkStart(type, text));
}
handleLinkText(m_seeAlsoContext.data(), text);
@@ -821,7 +906,7 @@ void QtXmlToSphinx::handleSeeAlsoTag(QXmlStreamReader& reader)
}
}
-static inline QString fallbackPathAttribute() { return QStringLiteral("path"); }
+constexpr auto fallbackPathAttribute = "path"_L1;
template <class Indent> // const char*/class Indentor
void formatSnippet(TextStream &str, Indent indent, const QString &snippet)
@@ -856,14 +941,15 @@ void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
|| m_lastTagName == u"dots" || m_lastTagName == u"codeline";
if (consecutiveSnippet) {
m_output.flush();
- m_output.string()->chop(2);
+ m_output.string()->chop(1); // Strip newline from previous snippet
}
QString location = reader.attributes().value(u"location"_s).toString();
QString identifier = reader.attributes().value(u"identifier"_s).toString();
QString fallbackPath;
- if (reader.attributes().hasAttribute(fallbackPathAttribute()))
- fallbackPath = reader.attributes().value(fallbackPathAttribute()).toString();
+ if (reader.attributes().hasAttribute(fallbackPathAttribute))
+ fallbackPath = reader.attributes().value(fallbackPathAttribute).toString();
QString errorMessage;
+
const Snippet snippet = readSnippetFromLocations(location, identifier,
fallbackPath, &errorMessage);
if (!errorMessage.isEmpty())
@@ -886,6 +972,7 @@ void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
m_output << '\n';
}
}
+
void QtXmlToSphinx::handleDotsTag(QXmlStreamReader& reader)
{
QXmlStreamReader::TokenType token = reader.tokenType();
@@ -916,11 +1003,11 @@ void QtXmlToSphinx::handleTableTag(QXmlStreamReader& reader)
if (token == QXmlStreamReader::StartElement) {
if (parentTag() == WebXmlTag::para)
handleParaTagEnd(); // End <para> to prevent the table from being rst-escaped
- m_currentTable.clear();
+ m_tables.push({});
} else if (token == QXmlStreamReader::EndElement) {
// write the table on m_output
formatCurrentTable();
- m_currentTable.clear();
+ m_tables.pop();
if (parentTag() == WebXmlTag::para)
handleParaTagStart();
}
@@ -936,7 +1023,7 @@ void QtXmlToSphinx::handleTermTag(QXmlStreamReader& reader)
} else if (token == QXmlStreamReader::EndElement) {
TableCell cell;
cell.data = popOutputBuffer().trimmed();
- m_currentTable.appendRow(TableRow(1, cell));
+ m_tables.back().appendRow(TableRow(1, cell));
}
}
@@ -945,18 +1032,20 @@ void QtXmlToSphinx::handleItemTag(QXmlStreamReader& reader)
{
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
- if (m_currentTable.isEmpty())
- m_currentTable.appendRow({});
- TableRow& row = m_currentTable.last();
+ auto &table = m_tables.back();
+ if (table.isEmpty())
+ table.appendRow({});
+ TableRow& row = table.last();
TableCell cell;
cell.colSpan = reader.attributes().value(u"colspan"_s).toShort();
cell.rowSpan = reader.attributes().value(u"rowspan"_s).toShort();
row << cell;
pushOutputBuffer();
} else if (token == QXmlStreamReader::EndElement) {
- QString data = popOutputBuffer().trimmed();
- if (!m_currentTable.isEmpty()) {
- TableRow& row = m_currentTable.last();
+ QString data = trimLeadingNewlines(trimRight(popOutputBuffer()));
+ auto &table = m_tables.back();
+ if (!table.isEmpty()) {
+ TableRow& row = table.last();
if (!row.isEmpty())
row.last().data = data;
}
@@ -969,15 +1058,16 @@ void QtXmlToSphinx::handleHeaderTag(QXmlStreamReader &reader)
// C++ header with "name"/"href" attributes.
if (reader.tokenType() == QXmlStreamReader::StartElement
&& !reader.attributes().hasAttribute(u"name"_s)) {
- m_currentTable.setHeaderEnabled(true);
- m_currentTable.appendRow({});
+ auto &table = m_tables.back();
+ table.setHeaderEnabled(true);
+ table.appendRow({});
}
}
void QtXmlToSphinx::handleRowTag(QXmlStreamReader& reader)
{
if (reader.tokenType() == QXmlStreamReader::StartElement)
- m_currentTable.appendRow({});
+ m_tables.back().appendRow({});
}
enum ListType { BulletList, OrderedList, EnumeratedList };
@@ -993,27 +1083,29 @@ static inline ListType webXmlListType(QStringView t)
void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
{
- // BUG We do not support a list inside a table cell
static ListType listType = BulletList;
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
+ m_tables.push({});
+ auto &table = m_tables.back();
listType = webXmlListType(reader.attributes().value(u"type"_s));
if (listType == EnumeratedList) {
- m_currentTable.appendRow(TableRow{TableCell(u"Constant"_s),
- TableCell(u"Description"_s)});
- m_currentTable.setHeaderEnabled(true);
+ table.appendRow(TableRow{TableCell(u"Constant"_s),
+ TableCell(u"Description"_s)});
+ table.setHeaderEnabled(true);
}
m_output.indent();
} else if (token == QXmlStreamReader::EndElement) {
m_output.outdent();
- if (!m_currentTable.isEmpty()) {
+ const auto &table = m_tables.back();
+ if (!table.isEmpty()) {
switch (listType) {
case BulletList:
case OrderedList: {
m_output << '\n';
const char *separator = listType == BulletList ? "* " : "#. ";
const char *indentLine = listType == BulletList ? " " : " ";
- for (const TableCell &cell : m_currentTable.constFirst()) {
+ for (const TableCell &cell : table.constFirst()) {
const auto itemLines = QStringView{cell.data}.split(u'\n');
m_output << separator << itemLines.constFirst() << '\n';
for (qsizetype i = 1, max = itemLines.size(); i < max; ++i)
@@ -1027,7 +1119,7 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
break;
}
}
- m_currentTable.clear();
+ m_tables.pop();
}
}
@@ -1069,7 +1161,7 @@ QtXmlToSphinxLink *QtXmlToSphinx::handleLinkStart(const QString &type, QString r
if (type == u"external" || isHttpLink(ref)) {
result->type = QtXmlToSphinxLink::External;
- } else if (type == functionLinkType() && !m_context.isEmpty()) {
+ } else if (type == functionLinkType && !m_context.isEmpty()) {
result->type = QtXmlToSphinxLink::Method;
const auto rawlinklist = QStringView{result->linkRef}.split(u'.');
if (rawlinklist.size() == 1 || rawlinklist.constFirst() == m_context) {
@@ -1080,9 +1172,9 @@ QtXmlToSphinxLink *QtXmlToSphinx::handleLinkStart(const QString &type, QString r
} else {
result->linkRef = m_generator->expandFunction(result->linkRef);
}
- } else if (type == functionLinkType() && m_context.isEmpty()) {
+ } else if (type == functionLinkType && m_context.isEmpty()) {
result->type = QtXmlToSphinxLink::Function;
- } else if (type == classLinkType()) {
+ } else if (type == classLinkType) {
result->type = QtXmlToSphinxLink::Class;
result->linkRef = m_generator->expandClass(m_context, result->linkRef);
} else if (type == u"enum") {
@@ -1122,10 +1214,10 @@ static QString fixLinkText(const QtXmlToSphinxLink *linkContext,
else
QtXmlToSphinx::stripPythonQualifiers(&linktext);
if (linkContext->linkRef == linktext)
- return QString();
+ return {};
if ((linkContext->type & QtXmlToSphinxLink::FunctionMask) != 0
&& (linkContext->linkRef + u"()"_s) == linktext) {
- return QString();
+ return {};
}
return linktext;
}
@@ -1153,7 +1245,7 @@ static bool copyImage(const QString &href, const QString &docDataDir,
const QLoggingCategory &lc, QString *errorMessage)
{
const QChar slash = u'/';
- const int lastSlash = href.lastIndexOf(slash);
+ const auto lastSlash = href.lastIndexOf(slash);
const QString imagePath = lastSlash != -1 ? href.left(lastSlash) : QString();
const QString imageFileName = lastSlash != -1 ? href.right(href.size() - lastSlash - 1) : href;
QFileInfo imageSource(docDataDir + slash + href);
@@ -1166,7 +1258,7 @@ static bool copyImage(const QString &href, const QString &docDataDir,
// FIXME: Not perfect yet, should have knowledge about namespaces (DataVis3D) or
// nested classes "Pyside2.QtGui.QTouchEvent.QTouchPoint".
QString relativeTargetDir = context;
- const int lastDot = relativeTargetDir.lastIndexOf(u'.');
+ const auto lastDot = relativeTargetDir.lastIndexOf(u'.');
if (lastDot != -1)
relativeTargetDir.truncate(lastDot);
relativeTargetDir.replace(u'.', slash);
@@ -1233,7 +1325,7 @@ void QtXmlToSphinx::handleInlineImageTag(QXmlStreamReader& reader)
// enclosed by '|' and define it further down. Determine tag from the base
//file name with number.
QString tag = href;
- int pos = tag.lastIndexOf(u'/');
+ auto pos = tag.lastIndexOf(u'/');
if (pos != -1)
tag.remove(0, pos + 1);
pos = tag.indexOf(u'.');
@@ -1301,11 +1393,11 @@ void QtXmlToSphinx::handlePageTag(QXmlStreamReader &reader)
m_output << disableIndent;
- const auto title = reader.attributes().value(titleAttribute());
+ const auto title = reader.attributes().value("title");
if (!title.isEmpty())
m_output << rstLabel(title.toString());
- const auto fullTitle = reader.attributes().value(fullTitleAttribute());
+ const auto fullTitle = reader.attributes().value("fulltitle");
const int size = fullTitle.isEmpty()
? writeEscapedRstText(m_output, title)
: writeEscapedRstText(m_output, fullTitle);
@@ -1318,7 +1410,7 @@ void QtXmlToSphinx::handleTargetTag(QXmlStreamReader &reader)
{
if (reader.tokenType() != QXmlStreamReader::StartElement)
return;
- const auto name = reader.attributes().value(nameAttribute());
+ const auto name = reader.attributes().value("name");
if (!name.isEmpty())
m_output << rstLabel(name.toString());
}
@@ -1493,13 +1585,11 @@ void QtXmlToSphinx::Table::format(TextStream& s) const
// print line
s << '+';
for (qsizetype col = 0; col < headerColumnCount; ++col) {
- char c;
+ char c = '-';
if (col >= row.size() || row[col].rowSpan == -1)
c = ' ';
else if (i == 1 && hasHeader())
c = '=';
- else
- c = '-';
s << Pad(c, colWidths.at(col)) << '+';
}
s << '\n';
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
index e3efde412..398c5bc97 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
@@ -8,9 +8,10 @@
#include <QtCore/QList>
#include <QtCore/QScopedPointer>
-#include <QtCore/QSharedPointer>
#include <QtCore/QStack>
+#include <memory>
+
QT_BEGIN_NAMESPACE
class QDebug;
class QXmlStreamReader;
@@ -69,14 +70,9 @@ public:
return m_normalized;
}
- void clear() {
- m_normalized = false;
- m_rows.clear();
- }
-
void appendRow(const TableRow &row) { m_rows.append(row); }
- const TableRow &constFirst() { return m_rows.constFirst(); }
+ const TableRow &constFirst() const { return m_rows.constFirst(); }
TableRow &first() { return m_rows.first(); }
TableRow &last() { return m_rows.last(); }
@@ -105,8 +101,12 @@ public:
static void stripPythonQualifiers(QString *s);
+ // For testing
+ static QString readSnippet(QIODevice &inputFile, const QString &identifier,
+ QString *errorMessage);
+
private:
- using StringSharedPtr = QSharedPointer<QString>;
+ using StringSharedPtr = std::shared_ptr<QString>;
QString transform(const QString& doc);
@@ -160,7 +160,7 @@ private:
QStack<StringSharedPtr> m_buffers; // Maintain address stability since it used in TextStream
- Table m_currentTable;
+ QStack<Table> m_tables; // Stack of tables, used for <table><list> with nested <item>
QScopedPointer<QtXmlToSphinxLink> m_linkContext; // for <link>
QScopedPointer<QtXmlToSphinxLink> m_seeAlsoContext; // for <see-also>foo()</see-also>
QString m_context;
@@ -173,6 +173,8 @@ private:
QString m_opened_anchor;
QList<InlineImage> m_inlineImages;
+ bool m_containsAutoTranslations = false;
+
struct Snippet
{
enum Result {
@@ -186,10 +188,12 @@ private:
Result result;
};
+ void setAutoTranslatedNote(QString *str) const;
+
Snippet readSnippetFromLocations(const QString &path,
const QString &identifier,
const QString &fallbackPath,
- QString *errorMessage) const;
+ QString *errorMessage);
static QString readFromLocation(const QString &location, const QString &identifier,
QString *errorMessage);
void pushOutputBuffer();
diff --git a/sources/shiboken6/generator/qtdoc/rstformat.h b/sources/shiboken6/generator/qtdoc/rstformat.h
index 6e97c5fcd..8af7671fb 100644
--- a/sources/shiboken6/generator/qtdoc/rstformat.h
+++ b/sources/shiboken6/generator/qtdoc/rstformat.h
@@ -30,28 +30,6 @@ inline QByteArray rstDeprecationNote(const char *what)
+ what + QByteArrayLiteral(" is deprecated.\n\n");
}
-class Pad
-{
-public:
- explicit Pad(char c, int count) : m_char(c), m_count(count) {}
-
- void write(TextStream &str) const
- {
- for (int i = 0; i < m_count; ++i)
- str << m_char;
- }
-
-private:
- const char m_char;
- const int m_count;
-};
-
-inline TextStream &operator<<(TextStream &str, const Pad &pad)
-{
- pad.write(str);
- return str;
-}
-
template <class String>
inline int writeEscapedRstText(TextStream &str, const String &s)
{
diff --git a/sources/shiboken6/generator/shiboken/configurablescope.h b/sources/shiboken6/generator/shiboken/configurablescope.h
new file mode 100644
index 000000000..9040c7ad9
--- /dev/null
+++ b/sources/shiboken6/generator/shiboken/configurablescope.h
@@ -0,0 +1,33 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef CONFIGURABLESCOPE_H
+#define CONFIGURABLESCOPE_H
+
+#include <textstream.h>
+#include <configurabletypeentry.h>
+
+/// Enclose a scope within preprocessor conditions for configurable entries
+class ConfigurableScope
+{
+public:
+ explicit ConfigurableScope(TextStream &s, const ConfigurableTypeEntryCPtr &t) :
+ m_stream(s),
+ m_hasConfigCondition(t->hasConfigCondition())
+ {
+ if (m_hasConfigCondition)
+ m_stream << t->configCondition() << '\n';
+ }
+
+ ~ConfigurableScope()
+ {
+ if (m_hasConfigCondition)
+ m_stream << "#endif\n";
+ }
+
+private:
+ TextStream &m_stream;
+ const bool m_hasConfigCondition;
+};
+
+#endif // CONFIGURABLESCOPE_H
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.cpp b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
index c59cfbc11..a109cd17a 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -2,7 +2,9 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "cppgenerator.h"
+#include "configurablescope.h"
#include "generatorargument.h"
+#include "generatorstrings.h"
#include "defaultvalue.h"
#include "generatorcontext.h"
#include "codesnip.h"
@@ -50,14 +52,29 @@
#include <algorithm>
#include <cstring>
#include <memory>
+#include <set>
using namespace Qt::StringLiterals;
+static const char shibokenErrorsOccurred[] = "Shiboken::Errors::occurred() != nullptr";
+
+static constexpr auto virtualMethodStaticReturnVar = "result"_L1;
+
+static constexpr auto sbkObjectTypeF = "SbkObject_TypeF()"_L1;
+static const char initInheritanceFunction[] = "initInheritance";
+
+static QString mangleName(QString name)
+{
+ if (name == u"None" || name == u"False" || name == u"True" || name == u"from")
+ name += u'_';
+ return name;
+}
+
struct sbkUnusedVariableCast
{
- explicit sbkUnusedVariableCast(QString name) : m_name(name) {}
+ explicit sbkUnusedVariableCast(QAnyStringView name) : m_name(name) {}
- const QString m_name;
+ const QAnyStringView m_name;
};
TextStream &operator<<(TextStream &str, const sbkUnusedVariableCast &c)
@@ -66,36 +83,23 @@ TextStream &operator<<(TextStream &str, const sbkUnusedVariableCast &c)
return str;
}
-static const QString CPP_ARG0 = u"cppArg0"_s;
-static const char methodDefSentinel[] = "{nullptr, nullptr, 0, nullptr} // Sentinel\n";
-const char *CppGenerator::PYTHON_TO_CPPCONVERSION_STRUCT = "Shiboken::Conversions::PythonToCppConversion";
+struct pyTypeGetSlot
+{
+ explicit pyTypeGetSlot(QAnyStringView funcType, QAnyStringView typeObject,
+ QAnyStringView aSlot) :
+ m_funcType(funcType), m_typeObject(typeObject), m_slot(aSlot) {}
-static inline QString reprFunction() { return QStringLiteral("__repr__"); }
+ const QAnyStringView m_funcType;
+ const QAnyStringView m_typeObject;
+ const QAnyStringView m_slot;
+};
-static const char typeNameFunc[] = R"CPP(template <class T>
-static const char *typeNameOf(const T &t)
+TextStream &operator<<(TextStream &str, const pyTypeGetSlot &p)
{
- const char *typeName = typeid(t).name();
- auto size = std::strlen(typeName);
-#if defined(Q_CC_MSVC) // MSVC: "class QPaintDevice * __ptr64"
- if (auto lastStar = strchr(typeName, '*')) {
- // MSVC: "class QPaintDevice * __ptr64"
- while (*--lastStar == ' ') {
- }
- size = lastStar - typeName + 1;
- }
-#else // g++, Clang: "QPaintDevice *" -> "P12QPaintDevice"
- if (size > 2 && typeName[0] == 'P' && std::isdigit(typeName[1])) {
- ++typeName;
- --size;
- }
-#endif
- char *result = new char[size + 1];
- result[size] = '\0';
- memcpy(result, typeName, size);
- return result;
+ str << "reinterpret_cast<" << p.m_funcType << ">(PepType_GetSlot("
+ << p.m_typeObject << ", " << p.m_slot << "));\n";
+ return str;
}
-)CPP";
TextStream &operator<<(TextStream &s, CppGenerator::ErrorReturn r)
{
@@ -117,6 +121,25 @@ TextStream &operator<<(TextStream &s, CppGenerator::ErrorReturn r)
return s;
}
+static constexpr auto converterVar = "converter"_L1;
+
+struct registerConverterName
+{
+ explicit registerConverterName(QAnyStringView typeName,
+ QAnyStringView varName = converterVar) :
+ m_typeName(typeName), m_varName(varName) {}
+
+ QAnyStringView m_typeName;
+ QAnyStringView m_varName;
+};
+
+TextStream &operator<<(TextStream &s, const registerConverterName &r)
+{
+ s << "Shiboken::Conversions::registerConverterName(" << r.m_varName
+ << ", \"" << r.m_typeName << "\");\n";
+ return s;
+}
+
// Protocol function name / function parameters / return type
struct ProtocolEntry
{
@@ -149,7 +172,7 @@ const ProtocolEntries &mappingProtocols()
u"PyObject*"_s},
{u"__msetitem__"_s,
u"PyObject *self, PyObject *_key, PyObject *_value"_s,
- intT()}};
+ intT}};
return result;
}
@@ -166,16 +189,16 @@ const ProtocolEntries &sequenceProtocols()
u"PyObject*"_s},
{u"__setitem__"_s,
u"PyObject *self, Py_ssize_t _i, PyObject *_value"_s,
- intT()},
+ intT},
{u"__getslice__"_s,
u"PyObject *self, Py_ssize_t _i1, Py_ssize_t _i2"_s,
u"PyObject*"_s},
{u"__setslice__"_s,
u"PyObject *self, Py_ssize_t _i1, Py_ssize_t _i2, PyObject *_value"_s,
- intT()},
+ intT},
{u"__contains__"_s,
u"PyObject *self, PyObject *_value"_s,
- intT()},
+ intT},
{u"__concat__"_s,
u"PyObject *self, PyObject *_other"_s,
u"PyObject*"_s}
@@ -187,13 +210,13 @@ const ProtocolEntries &sequenceProtocols()
static QString opaqueContainerCreationFunc(const AbstractMetaType &type)
{
const auto containerTypeEntry =
- qSharedPointerCast<const ContainerTypeEntry>(type.typeEntry());
+ std::static_pointer_cast<const ContainerTypeEntry>(type.typeEntry());
const auto instantiationTypeEntry =
type.instantiations().constFirst().typeEntry();
QString result = u"create"_s;
if (type.isConstant())
result += u"Const"_s;
- result += containerTypeEntry->opaqueContainerName(instantiationTypeEntry->name());
+ result += containerTypeEntry->opaqueContainerName(type.instantiationCppSignatures());
return result;
}
@@ -213,135 +236,16 @@ QString CppGenerator::fileNameForContext(const GeneratorContext &context) const
return fileNameForContextHelper(context, u"_wrapper.cpp"_s);
}
-static bool isInplaceAdd(const AbstractMetaFunctionCPtr &func)
-{
- return func->name() == u"operator+=";
-}
-
-static bool isIncrementOperator(const AbstractMetaFunctionCPtr &func)
-{
- return func->functionType() == AbstractMetaFunction::IncrementOperator;
-}
-
-static bool isDecrementOperator(const AbstractMetaFunctionCPtr &func)
-{
- return func->functionType() == AbstractMetaFunction::DecrementOperator;
-}
-
-// Filter predicate for operator functions
-static bool skipOperatorFunc(const AbstractMetaFunctionCPtr &func)
-{
- if (func->isModifiedRemoved() || func->usesRValueReferences())
- return true;
- const auto &name = func->name();
- return name == u"operator[]" || name == u"operator->" || name == u"operator!";
-}
-
-QList<AbstractMetaFunctionCList>
- CppGenerator::filterGroupedOperatorFunctions(const AbstractMetaClass *metaClass,
- OperatorQueryOptions query)
-{
- // ( func_name, num_args ) => func_list
- QMap<QPair<QString, int>, AbstractMetaFunctionCList> results;
-
- auto funcs = metaClass->operatorOverloads(query);
- auto end = std::remove_if(funcs.begin(), funcs.end(), skipOperatorFunc);
- funcs.erase(end, funcs.end());
-
- // If we have operator+=, we remove the operator++/-- which would
- // otherwise be used for emulating __iadd__, __isub__.
- if (std::any_of(funcs.cbegin(), funcs.cend(), isInplaceAdd)) {
- end = std::remove_if(funcs.begin(), funcs.end(),
- [] (const AbstractMetaFunctionCPtr &func) {
- return func->isIncDecrementOperator();
- });
- funcs.erase(end, funcs.end());
- } else {
- // If both prefix/postfix ++/-- are present, remove one
- if (std::count_if(funcs.begin(), funcs.end(), isIncrementOperator) > 1)
- funcs.erase(std::find_if(funcs.begin(), funcs.end(), isIncrementOperator));
- if (std::count_if(funcs.begin(), funcs.end(), isDecrementOperator) > 1)
- funcs.erase(std::find_if(funcs.begin(), funcs.end(), isDecrementOperator));
- }
-
- for (const auto &func : funcs) {
- int args;
- if (func->isComparisonOperator()) {
- args = -1;
- } else {
- args = func->arguments().size();
- }
- QPair<QString, int > op(func->name(), args);
- results[op].append(func);
- }
- QList<AbstractMetaFunctionCList> result;
- result.reserve(results.size());
- for (auto it = results.cbegin(), end = results.cend(); it != end; ++it)
- result.append(it.value());
- return result;
-}
-
-CppGenerator::BoolCastFunctionOptional
- CppGenerator::boolCast(const AbstractMetaClass *metaClass) const
-{
- const auto te = metaClass->typeEntry();
- if (te->isSmartPointer()) {
- auto ste = qSharedPointerCast<const SmartPointerTypeEntry>(te);
-
- auto valueCheckMethod = ste->valueCheckMethod();
- if (!valueCheckMethod.isEmpty()) {
- const auto func = metaClass->findFunction(valueCheckMethod);
- if (func.isNull())
- throw Exception(msgMethodNotFound(metaClass, valueCheckMethod));
- return BoolCastFunction{func, false};
- }
-
- auto nullCheckMethod = ste->nullCheckMethod();
- if (!nullCheckMethod.isEmpty()) {
- const auto func = metaClass->findFunction(nullCheckMethod);
- if (func.isNull())
- throw Exception(msgMethodNotFound(metaClass, nullCheckMethod));
- return BoolCastFunction{func, true};
- }
- }
-
- auto mode = te->operatorBoolMode();
- if (useOperatorBoolAsNbNonZero()
- ? mode != TypeSystem::BoolCast::Disabled : mode == TypeSystem::BoolCast::Enabled) {
- const auto func = metaClass->findOperatorBool();
- if (!func.isNull())
- return BoolCastFunction{func, false};
- }
-
- mode = te->isNullMode();
- if (useIsNullAsNbNonZero()
- ? mode != TypeSystem::BoolCast::Disabled : mode == TypeSystem::BoolCast::Enabled) {
- const auto func = metaClass->findQtIsNullMethod();
- if (!func.isNull())
- return BoolCastFunction{func, true};
- }
- return std::nullopt;
-}
-
-std::optional<AbstractMetaType>
- CppGenerator::findSmartPointerInstantiation(const SmartPointerTypeEntryCPtr &pointer,
- const TypeEntryCPtr &pointee) const
-{
- for (const auto &smp : api().instantiatedSmartPointers()) {
- const auto &i = smp.type;
- if (i.typeEntry() == pointer && i.instantiations().at(0).typeEntry() == pointee)
- return i;
- }
- return {};
-}
-
void CppGenerator::clearTpFuncs()
{
+ // Functions that should not be registered under a name in PyMethodDef,
+ // but under a special constant under slots.
m_tpFuncs = {
{u"__str__"_s, {}}, {u"__str__"_s, {}},
- {reprFunction(), {}}, {u"__iter__"_s, {}},
+ {REPR_FUNCTION, {}}, {u"__iter__"_s, {}},
{u"__next__"_s, {}}
};
+ m_nbFuncs = { {u"__abs__"_s, {}}, {u"__pow__"_s, {} }};
}
// Prevent ELF symbol qt_version_tag from being generated into the source
@@ -351,7 +255,7 @@ static const char includeQDebug[] =
"#endif\n"
"#include <QtCore/QDebug>\n";
-static QString chopType(QString s)
+QString CppGenerator::chopType(QString s)
{
if (s.endsWith(u"_Type"))
s.chop(5);
@@ -463,11 +367,7 @@ static QSet<QString> useIntSet()
static bool _shouldInheritInt(const AbstractMetaEnum &cppEnum)
{
- if (!cppEnum.fullName().startsWith(u"PySide6."_s))
- return true;
- // static auto intSet = useIntSet();
- // return intSet.contains(cppEnum.fullName());
- return false;
+ return !cppEnum.fullName().startsWith(u"PySide6."_s);
}
static QString BuildEnumFlagInfo(const AbstractMetaEnum &cppEnum)
@@ -495,15 +395,15 @@ static QString BuildEnumFlagInfo(const AbstractMetaEnum &cppEnum)
static void writePyGetSetDefEntry(TextStream &s, const QString &name,
const QString &getFunc, const QString &setFunc)
{
- s << "{const_cast<char *>(\"" << name << "\"), " << getFunc << ", "
+ s << "{const_cast<char *>(\"" << mangleName(name) << "\"), " << getFunc << ", "
<< (setFunc.isEmpty() ? NULL_PTR : setFunc) << ", nullptr, nullptr},\n";
}
static bool generateRichComparison(const GeneratorContext &c)
{
- auto *metaClass = c.metaClass();
+ const auto metaClass = c.metaClass();
if (c.forSmartPointer()) {
- auto te = qSharedPointerCast<const SmartPointerTypeEntry>(metaClass->typeEntry());
+ auto te = std::static_pointer_cast<const SmartPointerTypeEntry>(metaClass->typeEntry());
return te->smartPointerType() == TypeSystem::SmartPointerType::Shared;
}
@@ -514,17 +414,16 @@ void CppGenerator::generateIncludes(TextStream &s, const GeneratorContext &class
const IncludeGroupList &includes,
const AbstractMetaClassCList &innerClasses) const
{
- const AbstractMetaClass *metaClass = classContext.metaClass();
+ const auto metaClass = classContext.metaClass();
// write license comment
s << licenseComment() << '\n';
const bool normalClass = !classContext.forSmartPointer();
- if (normalClass && !avoidProtectedHack() && !metaClass->isNamespace()
- && !metaClass->hasPrivateDestructor()) {
- s << "//workaround to access protected functions\n";
- s << "#define protected public\n\n";
- }
+ // Normally only required for classes for which we want to generate protected API,
+ // but it needs to be generated into all files to ensure ODR for Unity builds.
+ if (!avoidProtectedHack())
+ s << HeaderGenerator::protectedHackDefine;
QByteArrayList cppIncludes{"typeinfo", "iterator", // for containers
"cctype", "cstring"};
@@ -540,7 +439,7 @@ void CppGenerator::generateIncludes(TextStream &s, const GeneratorContext &class
s << includeQDebug;
if (metaClass->hasToStringCapability())
s << "#include <QtCore/QBuffer>\n";
- if (metaClass->isQObject()) {
+ if (isQObject(metaClass)) {
s << "#include <pysideqobject.h>\n"
<< "#include <pysidesignal.h>\n"
<< "#include <pysideproperty.h>\n"
@@ -548,7 +447,6 @@ void CppGenerator::generateIncludes(TextStream &s, const GeneratorContext &class
<< "#include <pysidemetafunction.h>\n";
}
s << "#include <pysideqenum.h>\n"
- << "#include <pysideqflags.h>\n"
<< "#include <pysideqmetatype.h>\n"
<< "#include <pysideutils.h>\n"
<< "#include <feature_select.h>\n"
@@ -571,13 +469,16 @@ void CppGenerator::generateIncludes(TextStream &s, const GeneratorContext &class
if (!innerClasses.isEmpty()) {
s << "\n// inner classes\n";
- for (const AbstractMetaClass *innerClass : innerClasses) {
+ for (const auto &innerClass : innerClasses) {
GeneratorContext innerClassContext = contextForClass(innerClass);
s << "#include \""
<< HeaderGenerator::headerFileNameForContext(innerClassContext) << "\"\n";
}
}
+ if (avoidProtectedHack())
+ s << baseWrapperIncludes(classContext);
+
for (const auto &g : includes)
s << g;
@@ -588,35 +489,34 @@ void CppGenerator::generateIncludes(TextStream &s, const GeneratorContext &class
s << "#include <" << i << ">\n";
}
-static const char openTargetExternC[] = R"(
-// Target ---------------------------------------------------------
-
-extern "C" {
-)";
-
-static const char closeExternC[] = "} // extern \"C\"\n\n";
-
// Write methods definition
-static void writePyMethodDefs(TextStream &s, const QString &className,
- const QString &methodsDefinitions, bool generateCopy)
+void CppGenerator::writePyMethodDefs(TextStream &s, const QString &className,
+ const QString &methodsDefinitions)
{
s << "static PyMethodDef " << className << "_methods[] = {\n" << indent
- << methodsDefinitions << '\n';
- if (generateCopy) {
- s << "{\"__copy__\", reinterpret_cast<PyCFunction>(" << className << "___copy__)"
- << ", METH_NOARGS, nullptr},\n";
+ << methodsDefinitions << METHOD_DEF_SENTINEL << outdent << "};\n\n";
+}
+
+void CppGenerator::writeModuleCodeSnips(TextStream &s, const CodeSnipList &codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language) const
+{
+ if (!codeSnips.isEmpty()) {
+ try {
+ writeCodeSnips(s, codeSnips, position, language);
+ } catch (const std::exception &e) {
+ throw Exception(msgSnippetError("module source of "_L1 + moduleName(), e.what()));
+ }
}
- s << methodDefSentinel << outdent
- << "};\n\n";
}
-static bool hasHashFunction(const AbstractMetaClass *c)
+bool CppGenerator::hasHashFunction(const AbstractMetaClassCPtr &c)
{
return !c->typeEntry()->hashFunction().isEmpty()
|| c->hasHashFunction();
}
-static bool needsTypeDiscoveryFunction(const AbstractMetaClass *c)
+static bool needsTypeDiscoveryFunction(const AbstractMetaClassCPtr &c)
{
return c->baseClass() != nullptr
&& (c->isPolymorphic() || !c->typeEntry()->polymorphicIdValue().isEmpty());
@@ -646,7 +546,7 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
}
s.setLanguage(TextStream::Language::Cpp);
- const AbstractMetaClass *metaClass = classContext.metaClass();
+ AbstractMetaClassCPtr metaClass = classContext.metaClass();
const auto typeEntry = metaClass->typeEntry();
auto innerClasses = metaClass->innerClasses();
@@ -671,10 +571,10 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
// Use class base namespace
{
- const AbstractMetaClass *context = metaClass->enclosingClass();
+ AbstractMetaClassCPtr context = metaClass->enclosingClass();
while (context) {
if (context->isNamespace() && !context->enclosingClass()
- && qSharedPointerCast<const NamespaceTypeEntry>(context->typeEntry())->generateUsing()) {
+ && std::static_pointer_cast<const NamespaceTypeEntry>(context->typeEntry())->generateUsing()) {
s << "\nusing namespace " << context->qualifiedCppName() << ";\n";
break;
}
@@ -682,7 +582,7 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
}
}
- s << '\n' << typeNameFunc << '\n';
+ s << '\n';
// class inject-code native/beginning
if (!typeEntry->codeSnips().isEmpty()) {
@@ -694,7 +594,7 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
// python conversion rules
if (typeEntry->isValue()) {
- auto vte = qSharedPointerCast<const ValueTypeEntry>(typeEntry);
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(typeEntry);
if (vte->hasTargetConversionRule()) {
s << "// Python Conversion\n";
s << vte->targetConversionRule() << '\n';
@@ -721,13 +621,15 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
writeVirtualMethodNative(s, func, maxOverrides++);
}
- if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor()) {
- if (usePySideExtensions() && metaClass->isQObject())
- writeMetaObjectMethod(s, classContext);
+ if (shouldGenerateMetaObjectFunctions(metaClass))
+ writeMetaObjectMethod(s, classContext);
+ if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
writeDestructorNative(s, classContext);
- }
}
+ for (const auto &f : metaClass->userAddedPythonOverrides())
+ writeUserAddedPythonOverride(s, f);
+
StringStream smd(TextStream::Language::Cpp);
StringStream md(TextStream::Language::Cpp);
StringStream signatureStream(TextStream::Language::Cpp);
@@ -767,22 +669,22 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
smd << "static PyMethodDef " << methDefName << " = " << indent
<< defEntries.constFirst() << outdent << ";\n\n";
}
- if (!m_tpFuncs.contains(rfunc->name()))
+ const auto &fname = rfunc->name();
+ if (!m_tpFuncs.contains(fname) && !m_nbFuncs.contains(fname))
md << defEntries;
}
}
for (const auto &pyMethodDef : typeEntry->addedPyMethodDefEntrys())
md << pyMethodDef << ",\n";
+
+ if (typeEntry->isValue())
+ writeCopyFunction(s, md, signatureStream, classContext);
+
const QString methodsDefinitions = md.toString();
const QString singleMethodDefinitions = smd.toString();
const QString className = chopType(cpythonTypeName(metaClass));
- if (typeEntry->isValue()) {
- writeCopyFunction(s, classContext);
- signatureStream << fullPythonClassName(metaClass) << ".__copy__()\n";
- }
-
// Write single method definitions
s << singleMethodDefinitions;
@@ -818,7 +720,7 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
}
// Write methods definition
- writePyMethodDefs(s, className, methodsDefinitions, typeEntry->isValue());
+ writePyMethodDefs(s, className, methodsDefinitions);
// Write tp_s/getattro function
const AttroCheck attroCheck = checkAttroFunctionNeeds(metaClass);
@@ -831,25 +733,8 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
writeNbBoolFunction(classContext, f.value(), s);
if (supportsNumberProtocol(metaClass)) {
- const QList<AbstractMetaFunctionCList> opOverloads = filterGroupedOperatorFunctions(
- metaClass,
- OperatorQueryOption::ArithmeticOp
- | OperatorQueryOption::IncDecrementOp
- | OperatorQueryOption::LogicalOp
- | OperatorQueryOption::BitwiseOp);
-
- for (const AbstractMetaFunctionCList &allOverloads : opOverloads) {
- AbstractMetaFunctionCList overloads;
- for (const auto &func : allOverloads) {
- if (!func->isModifiedRemoved()
- && !func->isPrivate()
- && (func->ownerClass() == func->implementingClass() || func->isAbstract()))
- overloads.append(func);
- }
-
- if (overloads.isEmpty())
- continue;
-
+ const auto numberProtocolOps = numberProtocolOperators(metaClass);
+ for (const auto &overloads : numberProtocolOps) {
OverloadData overloadData(overloads, api());
writeMethodWrapper(s, overloadData, classContext);
writeSignatureInfo(signatureStream, overloadData);
@@ -928,11 +813,10 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
writeClassDefinition(s, metaClass, classContext);
s << '\n';
- if (needsTypeDiscoveryFunction(metaClass))
+ if (needsTypeDiscoveryFunction(metaClass)) {
writeTypeDiscoveryFunction(s, metaClass);
-
- writeFlagsNumberMethodsDefinitions(s, classEnums);
- s << '\n';
+ s << '\n';
+ }
writeConverterFunctions(s, metaClass, classContext);
writeAddedTypeSignatures(signatureStream, typeEntry);
@@ -950,147 +834,6 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
}
}
-static bool hasParameterPredicate(const AbstractMetaFunctionCPtr &f)
-{
- return !f->arguments().isEmpty();
-}
-
-void CppGenerator::generateSmartPointerClass(TextStream &s, const GeneratorContext &classContext)
-{
- s.setLanguage(TextStream::Language::Cpp);
- const AbstractMetaClass *metaClass = classContext.metaClass();
- const auto typeEntry = qSharedPointerCast<const SmartPointerTypeEntry>(metaClass->typeEntry());
- const bool hasPointeeClass = classContext.pointeeClass() != nullptr;
- const auto smartPointerType = typeEntry->smartPointerType();
- const bool isValueHandle = smartPointerType ==TypeSystem::SmartPointerType::ValueHandle;
-
- IncludeGroup includes{u"Extra includes"_s, typeEntry->extraIncludes()};
- if (hasPointeeClass)
- includes.append(classContext.pointeeClass()->typeEntry()->include());
- generateIncludes(s, classContext, {includes});
-
- s << '\n' << typeNameFunc << '\n';
-
- // Create string literal for smart pointer getter method.
- QString rawGetter = typeEntry->getter();
- s << "static const char " << SMART_POINTER_GETTER << "[] = \"" << rawGetter << "\";";
-
- // class inject-code native/beginning
- if (!typeEntry->codeSnips().isEmpty()) {
- writeClassCodeSnips(s, typeEntry->codeSnips(),
- TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode,
- classContext);
- s << '\n';
- }
-
- StringStream smd(TextStream::Language::Cpp);
- StringStream md(TextStream::Language::Cpp);
- StringStream signatureStream(TextStream::Language::Cpp);
-
- s << openTargetExternC;
-
- const auto &functionGroups = getFunctionGroups(metaClass);
-
- // Skip all public methods of the smart pointer except for the special
- // methods declared in the type entry.
-
- auto ctors = metaClass->queryFunctions(FunctionQueryOption::Constructors);
- if (!hasPointeeClass && !isValueHandle) { // Cannot generate "int*"
- auto end = std::remove_if(ctors.begin(), ctors.end(), hasParameterPredicate);
- ctors.erase(end, ctors.end());
- }
-
- if (!ctors.isEmpty()) {
- OverloadData overloadData(ctors, api());
- writeConstructorWrapper(s, overloadData, classContext);
- writeSignatureInfo(signatureStream, overloadData);
- }
-
- if (!typeEntry->resetMethod().isEmpty()) {
- auto it = functionGroups.constFind(typeEntry->resetMethod());
- if (it == functionGroups.cend())
- throw Exception(msgCannotFindSmartPointerMethod(typeEntry, typeEntry->resetMethod()));
- AbstractMetaFunctionCList resets = it.value();
- if (!hasPointeeClass && !isValueHandle) { // Cannot generate "int*"
- auto end = std::remove_if(resets.begin(), resets.end(), hasParameterPredicate);
- resets.erase(end, resets.end());
- }
- if (!resets.isEmpty())
- writeMethodWrapper(s, md, signatureStream, resets, classContext);
- }
-
- auto it = functionGroups.constFind(rawGetter);
- if (it == functionGroups.cend() || it.value().size() != 1)
- throw Exception(msgCannotFindSmartPointerGetter(typeEntry));
-
- writeMethodWrapper(s, md, signatureStream, it.value(), classContext);
-
- QStringList optionalMethods;
- if (!typeEntry->refCountMethodName().isEmpty())
- optionalMethods.append(typeEntry->refCountMethodName());
- const QString valueCheckMethod = typeEntry->valueCheckMethod();
- if (!valueCheckMethod.isEmpty() && !valueCheckMethod.startsWith(u"operator"))
- optionalMethods.append(valueCheckMethod);
- if (!typeEntry->nullCheckMethod().isEmpty())
- optionalMethods.append(typeEntry->nullCheckMethod());
-
- for (const QString &optionalMethod : optionalMethods) {
- auto it = functionGroups.constFind(optionalMethod);
- if (it == functionGroups.cend() || it.value().size() != 1)
- throw Exception(msgCannotFindSmartPointerMethod(typeEntry, optionalMethod));
- writeMethodWrapper(s, md, signatureStream, it.value(), classContext);
- }
-
- const QString methodsDefinitions = md.toString();
- const QString singleMethodDefinitions = smd.toString();
-
- const QString className = chopType(cpythonTypeName(typeEntry));
-
- writeCopyFunction(s, classContext);
- signatureStream << fullPythonClassName(metaClass) << ".__copy__()\n";
-
- // Write single method definitions
- s << singleMethodDefinitions;
-
- // Write methods definition
- writePyMethodDefs(s, className, methodsDefinitions, true /* ___copy__ */);
-
- // Write tp_s/getattro function
- const auto boolCastOpt = boolCast(metaClass);
- writeSmartPointerGetattroFunction(s, classContext, boolCastOpt);
- writeSmartPointerSetattroFunction(s, classContext);
-
- if (boolCastOpt.has_value())
- writeNbBoolFunction(classContext, boolCastOpt.value(), s);
-
- if (smartPointerType == TypeSystem::SmartPointerType::Shared)
- writeSmartPointerRichCompareFunction(s, classContext);
-
- s << closeExternC;
-
- if (hasHashFunction(metaClass))
- writeHashFunction(s, classContext);
-
- // Write tp_traverse and tp_clear functions.
- writeTpTraverseFunction(s, metaClass);
- writeTpClearFunction(s, metaClass);
-
- writeClassDefinition(s, metaClass, classContext);
-
- s << '\n';
-
- writeConverterFunctions(s, metaClass, classContext);
- writeClassRegister(s, metaClass, classContext, signatureStream);
-
- // class inject-code native/end
- if (!typeEntry->codeSnips().isEmpty()) {
- writeClassCodeSnips(s, typeEntry->codeSnips(),
- TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode,
- classContext);
- s << '\n';
- }
-}
-
void CppGenerator::writeMethodWrapper(TextStream &s, TextStream &definitionStream,
TextStream &signatureStream,
const AbstractMetaFunctionCList &overloads,
@@ -1132,7 +875,7 @@ void CppGenerator::writeConstructorNative(TextStream &s, const GeneratorContext
}
void CppGenerator::writeDestructorNative(TextStream &s,
- const GeneratorContext &classContext) const
+ const GeneratorContext &classContext)
{
s << classContext.wrapperName() << "::~"
<< classContext.wrapperName() << "()\n{\n" << indent;
@@ -1157,9 +900,10 @@ QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunctio
// SbkType would return null when the type is a container.
auto typeEntry = func->type().typeEntry();
if (typeEntry->isContainer()) {
- const auto cte = qSharedPointerCast<const ContainerTypeEntry>(typeEntry);
+ const auto cte = std::static_pointer_cast<const ContainerTypeEntry>(typeEntry);
switch (cte->containerKind()) {
case ContainerTypeEntry::ListContainer:
+ case ContainerTypeEntry::SpanContainer:
break;
case ContainerTypeEntry::SetContainer:
return uR"("set")"_s;
@@ -1186,8 +930,8 @@ QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunctio
if (func->type().isPrimitive())
return u'"' + func->type().name() + u'"';
- return u"reinterpret_cast<PyTypeObject *>(Shiboken::SbkType< "_s
- + typeEntry->qualifiedCppName() + u" >())->tp_name"_s;
+ return u"Shiboken::SbkType< "_s
+ + typeEntry->qualifiedCppName() + u" >()->tp_name"_s;
}
// When writing an overridden method of a wrapper class, write the part
@@ -1232,17 +976,24 @@ void CppGenerator::writeVirtualMethodCppCall(TextStream &s,
}
// Determine the return statement (void or a result value).
-QString CppGenerator::virtualMethodReturn(TextStream &s, const ApiExtractorResult &api,
- const AbstractMetaFunctionCPtr &func,
- const FunctionModificationList &functionModifications)
+
+CppGenerator::VirtualMethodReturn
+ CppGenerator::virtualMethodReturn(const ApiExtractorResult &api,
+ const AbstractMetaFunctionCPtr &func,
+ const FunctionModificationList &functionModifications)
{
- if (func->isVoid())
- return u"return;"_s;
+ VirtualMethodReturn result;
+ if (func->isVoid()) {
+ result.statement = "return;"_L1;
+ return result;
+ }
+
+ result.statement = "return "_L1;
const AbstractMetaType &returnType = func->type();
for (const FunctionModification &mod : functionModifications) {
for (const ArgumentModification &argMod : mod.argument_mods()) {
if (argMod.index() == 0 && !argMod.replacedDefaultExpression().isEmpty()) {
- static const QRegularExpression regex(QStringLiteral("%(\\d+)"));
+ static const QRegularExpression regex("%(\\d+)"_L1);
Q_ASSERT(regex.isValid());
QString expr = argMod.replacedDefaultExpression();
for (int offset = 0; ; ) {
@@ -1258,8 +1009,8 @@ QString CppGenerator::virtualMethodReturn(TextStream &s, const ApiExtractorResul
offset = match.capturedStart(1);
}
DefaultValue defaultReturnExpr(DefaultValue::Custom, expr);
- return u"return "_s + defaultReturnExpr.returnValue()
- + u';';
+ result.statement += defaultReturnExpr.returnValue() + u';';
+ return result;
}
}
}
@@ -1271,22 +1022,19 @@ QString CppGenerator::virtualMethodReturn(TextStream &s, const ApiExtractorResul
errorMsg = msgCouldNotFindMinimalConstructor(errorMsg,
func->type().cppSignature(),
errorMessage);
- qCWarning(lcShiboken).noquote().nospace() << errorMsg;
- s << "\n#error " << errorMsg << '\n';
- }
- if (returnType.referenceType() == LValueReference) {
- s << "static " << returnType.typeEntry()->qualifiedCppName()
- << " result;\n";
- return u"return result;"_s;
+ throw Exception(errorMsg);
}
- return u"return "_s + defaultReturnExpr->returnValue()
- + u';';
+
+ result.needsReference = returnType.referenceType() == LValueReference;
+ result.statement += (result.needsReference
+ ? virtualMethodStaticReturnVar : defaultReturnExpr->returnValue()) + u';';
+ return result;
}
// Create an argument for Py_BuildValue() when writing virtual methods.
// Return a pair of (argument, format-char).
-QPair<QString, QChar> CppGenerator::virtualMethodNativeArg(const AbstractMetaFunctionCPtr &func,
- const AbstractMetaArgument &arg)
+std::pair<QString, QChar> CppGenerator::virtualMethodNativeArg(const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaArgument &arg)
{
if (func->hasConversionRule(TypeSystem::TargetLangCode, arg.argumentIndex() + 1))
return {arg.name() + CONV_RULE_OUT_VAR_SUFFIX, u'N'};
@@ -1312,7 +1060,7 @@ static const char PYTHON_ARGS_ARRAY[] = "pyArgArray";
void CppGenerator::writeVirtualMethodNativeVectorCallArgs(TextStream &s,
const AbstractMetaFunctionCPtr &func,
const AbstractMetaArgumentList &arguments,
- const QList<int> &invalidateArgs) const
+ const QList<int> &invalidateArgs)
{
Q_ASSERT(!arguments.isEmpty());
s << "PyObject *" << PYTHON_ARGS_ARRAY <<'[' << arguments.size() << "] = {\n" << indent;
@@ -1333,15 +1081,15 @@ void CppGenerator::writeVirtualMethodNativeVectorCallArgs(TextStream &s,
if (!invalidateArgs.isEmpty())
s << '\n';
for (int index : invalidateArgs) {
- s << "const bool invalidateArg" << index << " = " << PYTHON_ARGS_ARRAY <<
- '[' << index - 1 << "]->ob_refcnt == 1;\n";
+ s << "const bool invalidateArg" << index << " = Py_REFCNT(" << PYTHON_ARGS_ARRAY <<
+ '[' << index - 1 << "]) == 1;\n";
}
}
void CppGenerator::writeVirtualMethodNativeArgs(TextStream &s,
const AbstractMetaFunctionCPtr &func,
const AbstractMetaArgumentList &arguments,
- const QList<int> &invalidateArgs) const
+ const QList<int> &invalidateArgs)
{
s << "Shiboken::AutoDecRef " << PYTHON_ARGS << '(';
if (arguments.isEmpty()) {
@@ -1361,8 +1109,8 @@ void CppGenerator::writeVirtualMethodNativeArgs(TextStream &s,
<< indent << argConversions.join(u",\n"_s) << outdent << "\n));\n";
for (int index : std::as_const(invalidateArgs)) {
- s << "bool invalidateArg" << index << " = PyTuple_GET_ITEM(" << PYTHON_ARGS
- << ", " << index - 1 << ")->ob_refcnt == 1;\n";
+ s << "bool invalidateArg" << index << " = Py_REFCNT(PyTuple_GET_ITEM(" << PYTHON_ARGS
+ << ", " << index - 1 << ")) == 1;\n";
}
}
@@ -1373,13 +1121,42 @@ static bool isArgumentNotRemoved(const AbstractMetaArgument &a)
// PyObject_Vectorcall(): since 3.9
static const char vectorCallCondition[] =
- "#if !defined(Py_LIMITED_API) && PY_VERSION_HEX >= 0x03090000\n";
+ "#if !defined(PYPY_VERSION) && !defined(Py_LIMITED_API)\n";
// PyObject_CallNoArgs(): since 3.9, stable API since 3.10
static const char noArgsCallCondition[] =
- "#if (defined(Py_LIMITED_API) && Py_LIMITED_API >= 0x030A0000) || (!defined(Py_LIMITED_API) && PY_VERSION_HEX >= 0x03090000)\n";
+ "#if !defined(PYPY_VERSION) && ((defined(Py_LIMITED_API) && Py_LIMITED_API >= 0x030A0000) || !defined(Py_LIMITED_API))\n";
static const char inverseNoArgsCallCondition[] =
- "#if (defined(Py_LIMITED_API) && Py_LIMITED_API < 0x030A0000) || (!defined(Py_LIMITED_API) && PY_VERSION_HEX < 0x03090000)\n";
+ "#if defined(PYPY_VERSION) || (defined(Py_LIMITED_API) && Py_LIMITED_API < 0x030A0000)\n";
+
+static inline void writeVirtualMethodStaticReturnVar(TextStream &s, const AbstractMetaFunctionCPtr &func)
+{
+ s << "static " << func->type().typeEntry()->qualifiedCppName() << ' '
+ << virtualMethodStaticReturnVar << ";\n";
+}
+
+static void writeFuncNameVar(TextStream &s, const AbstractMetaFunctionCPtr &func,
+ const QString &funcName)
+{
+ // PYSIDE-1019: Add info about properties
+ int propFlag = 0;
+ if (func->isPropertyReader())
+ propFlag |= 1;
+ if (func->isPropertyWriter())
+ propFlag |= 2;
+ if (propFlag && func->isStatic())
+ propFlag |= 4;
+ QString propStr;
+ if (propFlag != 90)
+ propStr = QString::number(propFlag) + u':';
+
+ if (propFlag != 0)
+ s << "// This method belongs to a property.\n";
+ s << "static const char *funcName = \"";
+ if (propFlag != 0)
+ s << propFlag << ':';
+ s << funcName << "\";\n";
+}
void CppGenerator::writeVirtualMethodNative(TextStream &s,
const AbstractMetaFunctionCPtr &func,
@@ -1394,13 +1171,16 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
Generator::OriginalTypeDescription)
<< "\n{\n" << indent;
- const QString returnStatement = virtualMethodReturn(s, api(), func,
- func->modifications());
+ const auto returnStatement = virtualMethodReturn(api(), func,
+ func->modifications());
+
+ if (returnStatement.needsReference)
+ writeVirtualMethodStaticReturnVar(s, func);
const bool isAbstract = func->isAbstract();
if (isAbstract && func->isModifiedRemoved()) {
- qCWarning(lcShiboken, "%s", qPrintable(msgPureVirtualFunctionRemoved(func.data())));
- s << returnStatement << '\n' << outdent << "}\n\n";
+ qCWarning(lcShiboken, "%s", qPrintable(msgPureVirtualFunctionRemoved(func.get())));
+ s << returnStatement.statement << '\n' << outdent << "}\n\n";
return;
}
@@ -1429,7 +1209,7 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
s << "if (m_PyMethodCache[" << cacheIndex << "])" << (multi_line ? " {\n" : "\n")
<< indent;
writeVirtualMethodCppCall(s, func, funcName, snips, lastArg, retType,
- returnStatement, false);
+ returnStatement.statement, false);
s << outdent;
if (multi_line)
s << "}\n";
@@ -1437,34 +1217,33 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
s << "Shiboken::GilState gil;\n";
// Get out of virtual method call if someone already threw an error.
- s << "if (PyErr_Occurred())\n" << indent
- << returnStatement << '\n' << outdent;
-
- // PYSIDE-1019: Add info about properties
- int propFlag = 0;
- if (func->isPropertyReader())
- propFlag |= 1;
- if (func->isPropertyWriter())
- propFlag |= 2;
- if (propFlag && func->isStatic())
- propFlag |= 4;
- QString propStr;
- if (propFlag)
- propStr = QString::number(propFlag) + u':';
+ s << "if (" << shibokenErrorsOccurred << ")\n" << indent
+ << returnStatement.statement << '\n' << outdent;
s << "static PyObject *nameCache[2] = {};\n";
- if (propFlag)
- s << "// This method belongs to a property.\n";
- s << "static const char *funcName = \"" << propStr << funcName << "\";\n"
- << "Shiboken::AutoDecRef " << PYTHON_OVERRIDE_VAR
+ writeFuncNameVar(s, func, funcName);
+ s << "Shiboken::AutoDecRef " << PYTHON_OVERRIDE_VAR
<< "(Shiboken::BindingManager::instance().getOverride(this, nameCache, funcName));\n"
<< "if (" << PYTHON_OVERRIDE_VAR << ".isNull()) {\n" << indent;
if (useOverrideCaching(func->ownerClass()))
s << "m_PyMethodCache[" << cacheIndex << "] = true;\n";
writeVirtualMethodCppCall(s, func, funcName, snips, lastArg, retType,
- returnStatement, true);
+ returnStatement.statement, true);
s << outdent << "}\n\n"; //WS
+ if (!snips.isEmpty()) {
+ writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionPyOverride,
+ TypeSystem::ShellCode, func, false, lastArg);
+ }
+
+ writeVirtualMethodPythonOverride(s, func, snips, returnStatement);
+}
+
+void CppGenerator::writeVirtualMethodPythonOverride(TextStream &s,
+ const AbstractMetaFunctionCPtr &func,
+ const CodeSnipList &snips,
+ const VirtualMethodReturn &returnStatement) const
+{
writeConversionRule(s, func, TypeSystem::TargetLangCode, false);
bool invalidateReturn = false;
@@ -1487,7 +1266,7 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
auto arguments = func->arguments();
auto removedEnd = std::stable_partition(arguments.begin(), arguments.end(),
isArgumentNotRemoved);
- if (isAbstract) { // Base function is not called, indicate unused arguments.
+ if (func->isAbstract()) { // Base function is not called, indicate unused arguments.
for (auto it = removedEnd; it != arguments.end(); ++it)
s << sbkUnusedVariableCast(it->name());
}
@@ -1533,7 +1312,7 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
if (argCount > 0) {
s << "PyObject_Vectorcall(" << PYTHON_OVERRIDE_VAR << ", "
<< PYTHON_ARGS_ARRAY << ", " << argCount << ", nullptr));\n";
- for (int argIndex : qAsConst(invalidateArgs)) {
+ for (int argIndex : std::as_const(invalidateArgs)) {
s << "if (invalidateArg" << argIndex << ")\n" << indent
<< "Shiboken::Object::invalidate(" << PYTHON_ARGS_ARRAY
<< '[' << (argIndex - 1) << "]);\n" << outdent;
@@ -1558,12 +1337,13 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
s << "if (" << PYTHON_RETURN_VAR << ".isNull()) {\n" << indent
<< "// An error happened in python code!\n"
- << "PyErr_Print();\n"
- << returnStatement << "\n" << outdent
+ << "Shiboken::Errors::storePythonOverrideErrorOrPrint(\""
+ << func->ownerClass()->name() << "\", funcName);\n"
+ << returnStatement.statement << "\n" << outdent
<< "}\n";
if (invalidateReturn) {
- s << "bool invalidateArg0 = " << PYTHON_RETURN_VAR << "->ob_refcnt == 1;\n"
+ s << "bool invalidateArg0 = Py_REFCNT(" << PYTHON_RETURN_VAR << ") == 1;\n"
<< "if (invalidateArg0)\n" << indent
<< "Shiboken::Object::releaseOwnership(" << PYTHON_RETURN_VAR
<< ".object());\n" << outdent;
@@ -1571,7 +1351,7 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
if (!func->isVoid()) {
- if (func->modifiedTypeName() != cPyObjectT()) {
+ if (func->modifiedTypeName() != cPyObjectT) {
s << "// Check return type\n";
@@ -1583,10 +1363,10 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
<< PYTHON_RETURN_VAR << ");\n" << outdent
<< "if (!" << PYTHON_TO_CPP_VAR << ") {\n" << indent
<< "Shiboken::Warnings::warnInvalidReturnValue(\""
- << func->ownerClass()->name() << "\", \"" << funcName << "\", "
+ << func->ownerClass()->name() << "\", funcName, "
<< getVirtualFunctionReturnTypeName(func) << ", "
<< "Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);\n"
- << returnStatement << '\n' << outdent
+ << returnStatement.statement << '\n' << outdent
<< "}\n";
} else {
@@ -1605,10 +1385,10 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
s << " && " << PYTHON_RETURN_VAR << " != Py_None";
s << ") {\n" << indent
<< "Shiboken::Warnings::warnInvalidReturnValue(\""
- << func->ownerClass()->name() << "\", \"" << funcName << "\", "
+ << func->ownerClass()->name() << "\", funcName, "
<< getVirtualFunctionReturnTypeName(func) << ", "
<< "Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);\n"
- << returnStatement << '\n' << outdent
+ << returnStatement.statement << '\n' << outdent
<< "}\n";
}
@@ -1645,13 +1425,14 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
if (!func->isVoid()) {
s << "return ";
+ TypeEntryCPtr retType = func->type().typeEntry();
if (avoidProtectedHack() && retType->isEnum()) {
auto metaEnum = api().findAbstractMetaEnum(retType);
bool isProtectedEnum = metaEnum.has_value() && metaEnum->isProtected();
if (isProtectedEnum) {
QString typeCast;
if (metaEnum->enclosingClass())
- typeCast += u"::"_s + metaEnum->enclosingClass()->qualifiedCppName();
+ typeCast += getFullTypeName(metaEnum->enclosingClass());
typeCast += u"::"_s + metaEnum->name();
s << '(' << typeCast << ')';
}
@@ -1665,6 +1446,28 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
s << outdent << "}\n\n";
}
+void CppGenerator::writeUserAddedPythonOverride(TextStream &s,
+ const AbstractMetaFunctionCPtr &func) const
+{
+ TypeEntryCPtr retType = func->type().typeEntry();
+ const QString funcName = func->isOperatorOverload()
+ ? pythonOperatorFunctionName(func) : func->definitionNames().constFirst();
+
+ const CodeSnipList snips = func->hasInjectedCode()
+ ? func->injectedCodeSnips() : CodeSnipList();
+
+ QString prefix = wrapperName(func->ownerClass()) + u"::"_s;
+ s << '\n' << functionSignature(func, prefix, QString(), Generator::SkipDefaultValues |
+ Generator::OriginalTypeDescription)
+ << "\n{\n" << indent << sbkUnusedVariableCast("gil");
+
+ writeFuncNameVar(s, func, funcName);
+
+ const auto returnStatement = virtualMethodReturn(api(), func,
+ func->modifications());
+ writeVirtualMethodPythonOverride(s, func, snips, returnStatement);
+}
+
void CppGenerator::writeMetaObjectMethod(TextStream &s,
const GeneratorContext &classContext) const
{
@@ -1672,7 +1475,7 @@ void CppGenerator::writeMetaObjectMethod(TextStream &s,
const QString wrapperClassName = classContext.wrapperName();
const QString qualifiedCppName = classContext.metaClass()->qualifiedCppName();
s << "const QMetaObject *" << wrapperClassName << "::metaObject() const\n{\n";
- s << indent << "if (QObject::d_ptr->metaObject)\n"
+ s << indent << "if (QObject::d_ptr->metaObject != nullptr)\n"
<< indent << "return QObject::d_ptr->dynamicMetaObject();\n" << outdent
<< "SbkObject *pySelf = Shiboken::BindingManager::instance().retrieveWrapper(this);\n"
<< "if (pySelf == nullptr)\n"
@@ -1715,68 +1518,15 @@ void CppGenerator::writeMetaCast(TextStream &s,
const QString wrapperClassName = classContext.wrapperName();
const QString qualifiedCppName = classContext.metaClass()->qualifiedCppName();
s << "void *" << wrapperClassName << "::qt_metacast(const char *_clname)\n{\n"
- << indent << "if (!_clname)\n" << indent << "return {};\n" << outdent
+ << indent << "if (_clname == nullptr)\n" << indent << "return {};\n" << outdent
<< "SbkObject *pySelf = Shiboken::BindingManager::instance().retrieveWrapper(this);\n"
- << "if (pySelf && PySide::inherits(Py_TYPE(pySelf), _clname))\n"
+ << "if (pySelf != nullptr && PySide::inherits(Py_TYPE(pySelf), _clname))\n"
<< indent << "return static_cast<void *>(const_cast< "
<< wrapperClassName << " *>(this));\n" << outdent
<< "return " << qualifiedCppName << "::qt_metacast(_clname);\n"
<< outdent << "}\n\n";
}
-void CppGenerator::writeFlagsConverterFunctions(TextStream &s,
- const FlagsTypeEntryCPtr &flagsType,
- const QString &enumTypeName,
- const QString &flagsCppTypeName,
- const QString &enumTypeCheck) const
-{
- Q_ASSERT(flagsType);
- const QString flagsTypeName = fixedCppTypeName(flagsType);
- const QString flagsPythonType = cpythonTypeNameExt(flagsType);
-
- StringStream c(TextStream::Language::Cpp);
- c << "*reinterpret_cast<" << flagsCppTypeName << " *>(cppOut) =\n"
- << " " << flagsCppTypeName
- << "(QFlag(int(PySide::QFlags::getValue(reinterpret_cast<PySideQFlagsObject *>(pyIn)))))"
- << ";\n";
- writePythonToCppFunction(s, c.toString(), flagsTypeName, flagsTypeName);
-
- QString pyTypeCheck = u"PyObject_TypeCheck(pyIn, "_s + flagsPythonType + u')';
- writeIsPythonConvertibleToCppFunction(s, flagsTypeName, flagsTypeName, pyTypeCheck);
-
- c.clear();
-
- c << "const int castCppIn = int(*reinterpret_cast<const "
- << flagsCppTypeName << " *>(cppIn));\n" << "return "
- << "reinterpret_cast<PyObject *>(PySide::QFlags::newObject(castCppIn, "
- << flagsPythonType << "));\n";
- writeCppToPythonFunction(s, c.toString(), flagsTypeName, flagsTypeName);
- s << '\n';
-
- c.clear();
- c << "*reinterpret_cast<" << flagsCppTypeName << " *>(cppOut) =\n"
- << " " << flagsCppTypeName
- << "(QFlag(int(Shiboken::Enum::getValue(pyIn))));\n";
-
- writePythonToCppFunction(s, c.toString(), enumTypeName, flagsTypeName);
- writeIsPythonConvertibleToCppFunction(s, enumTypeName, flagsTypeName, enumTypeCheck);
-
- c.clear();
- c << "Shiboken::AutoDecRef pyLong(PyNumber_Long(pyIn));\n"
- << "*reinterpret_cast<" << flagsCppTypeName << " *>(cppOut) =\n"
- << " " << flagsCppTypeName
- << "(QFlag(int(PyLong_AsLong(pyLong.object()))));\n";
- // PYSIDE-898: Include an additional condition to detect if the type of the
- // enum corresponds to the object that is being evaluated.
- // Using only `PyNumber_Check(...)` is too permissive,
- // then we would have been unable to detect the difference between
- // a PolarOrientation and Qt::AlignmentFlag, which was the main
- // issue of the bug.
- const QString numberCondition = u"PyNumber_Check(pyIn) && "_s + enumTypeCheck;
- writePythonToCppFunction(s, c.toString(), u"number"_s, flagsTypeName);
- writeIsPythonConvertibleToCppFunction(s, u"number"_s, flagsTypeName, numberCondition);
-}
-
static void generateDeprecatedValueWarnings(TextStream &c,
const AbstractMetaEnum &metaEnum,
bool useSurrogateName)
@@ -1796,14 +1546,15 @@ static void generateDeprecatedValueWarnings(TextStream &c,
<< "\", \"" << v.name() << "\");\nbreak;\n" << outdent;
}
if (deprecatedValues.size() < metaEnum.values().size())
- c << "default:\n" << indent << "break;\n" << outdent << "}\n";
+ c << "default:\n" << indent << "break;\n" << outdent;
+ c << "}\n";
}
void CppGenerator::writeEnumConverterFunctions(TextStream &s, const AbstractMetaEnum &metaEnum) const
{
if (metaEnum.isPrivate() || metaEnum.isAnonymous())
return;
- EnumTypeEntryPtr enumType = metaEnum.typeEntry();
+ EnumTypeEntryCPtr enumType = metaEnum.typeEntry();
Q_ASSERT(enumType);
QString typeName = fixedCppTypeName(enumType);
QString enumPythonType = cpythonTypeNameExt(enumType);
@@ -1824,6 +1575,8 @@ void CppGenerator::writeEnumConverterFunctions(TextStream &s, const AbstractMeta
generateDeprecatedValueWarnings(c, metaEnum, useSurrogateName);
c << "*reinterpret_cast<" << cppTypeName << " *>(cppOut) = value;\n";
+
+ ConfigurableScope configScope(s, enumType);
writePythonToCppFunction(s, c.toString(), typeName, typeName);
QString pyTypeCheck = u"PyObject_TypeCheck(pyIn, "_s + enumPythonType + u')';
@@ -1836,16 +1589,36 @@ void CppGenerator::writeEnumConverterFunctions(TextStream &s, const AbstractMeta
<< "Shiboken::Enum::newItem(" << enumPythonType << ", castCppIn);\n";
writeCppToPythonFunction(s, c.toString(), typeName, typeName);
s << '\n';
+}
- // QFlags part.
- if (auto flags = enumType->flags(); !flags.isNull()) {
- const QString flagsCppTypeName = useSurrogateName
- ? cppTypeName : getFullTypeName(flags).trimmed();
- writeFlagsConverterFunctions(s, flags, typeName, flagsCppTypeName, pyTypeCheck);
+static void writePointerToPythonConverter(TextStream &c,
+ const AbstractMetaClassCPtr &metaClass,
+ const QString &typeName,
+ const QString &cpythonType)
+{
+ c << "auto *pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(cppIn));\n"
+ << "if (pyOut) {\n" << indent
+ << "Py_INCREF(pyOut);\nreturn pyOut;\n" << outdent
+ << "}\n";
+
+ const QString nameFunc = metaClass->typeEntry()->polymorphicNameFunction();
+ if (nameFunc.isEmpty() && !metaClass->hasVirtualDestructor()) {
+ c << "return Shiboken::Object::newObjectWithHeuristics("
+ << cpythonType << ", const_cast<void *>(cppIn), false);\n";
+ return;
}
+
+ c << "auto *tCppIn = reinterpret_cast<const " << typeName << R"( *>(cppIn);
+const char *typeName = )";
+ if (nameFunc.isEmpty())
+ c << "typeid(*tCppIn).name();\n";
+ else
+ c << nameFunc << "(tCppIn);\n";
+ c << "return Shiboken::Object::newObjectForPointer("
+ << cpythonType << ", const_cast<void *>(cppIn), false, typeName);\n";
}
-void CppGenerator::writeConverterFunctions(TextStream &s, const AbstractMetaClass *metaClass,
+void CppGenerator::writeConverterFunctions(TextStream &s, const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext) const
{
s << "// Type conversion functions.\n\n";
@@ -1886,34 +1659,11 @@ void CppGenerator::writeConverterFunctions(TextStream &s, const AbstractMetaClas
// C++ pointer to a Python wrapper, keeping identity.
s << "// C++ to Python pointer conversion - tries to find the Python wrapper for the C++ object (keeps object identity).\n";
c.clear();
- if (usePySideExtensions() && metaClass->isQObject()) {
+ if (usePySideExtensions() && isQObject(metaClass)) {
c << "return PySide::getWrapperForQObject(reinterpret_cast<"
<< typeName << " *>(const_cast<void *>(cppIn)), " << cpythonType << ");\n";
} else {
- c << "auto pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper(cppIn));\n"
- << "if (pyOut) {\n" << indent
- << "Py_INCREF(pyOut);\nreturn pyOut;\n" << outdent
- << "}\n"
- << "bool changedTypeName = false;\n"
- << "auto tCppIn = reinterpret_cast<const " << typeName << R"( *>(cppIn);
-const char *typeName = )";
-
- const QString nameFunc = metaClass->typeEntry()->polymorphicNameFunction();
- if (nameFunc.isEmpty())
- c << "typeid(*tCppIn).name();\n";
- else
- c << nameFunc << "(tCppIn);\n";
- c << R"(auto sbkType = Shiboken::ObjectType::typeForTypeName(typeName);
-if (sbkType && Shiboken::ObjectType::hasSpecialCastFunction(sbkType)) {
- typeName = typeNameOf(tCppIn);
- changedTypeName = true;
-}
-)"
- << "PyObject *result = Shiboken::Object::newObject(" << cpythonType
- << R"(, const_cast<void *>(cppIn), false, /* exactType */ changedTypeName, typeName);
-if (changedTypeName)
- delete [] typeName;
-return result;)";
+ writePointerToPythonConverter(c, metaClass, typeName, cpythonType);
}
std::swap(targetTypeName, sourceTypeName);
writeCppToPythonFunction(s, c.toString(), sourceTypeName, targetTypeName);
@@ -1942,7 +1692,7 @@ return result;)";
c << "auto *source = reinterpret_cast<const " << typeName << " *>(cppIn);\n";
}
c << "return Shiboken::Object::newObject(" << cpythonType
- << ", new ::" << classContext.effectiveClassName() << '('
+ << ", new " << globalScopePrefix(classContext) << classContext.effectiveClassName() << '('
<< (isUniquePointer ? "std::move(*source)" : "*source")
<< "), true, true);";
writeCppToPythonFunction(s, c.toString(), sourceTypeName, targetTypeName);
@@ -1952,7 +1702,7 @@ return result;)";
s << "// Python to C++ copy conversion.\n";
sourceTypeName = metaClass->name();
- targetTypeName = sourceTypeName + QStringLiteral("_COPY");
+ targetTypeName = sourceTypeName + "_COPY"_L1;
c.clear();
QString pyInVariable = u"pyIn"_s;
@@ -1961,7 +1711,7 @@ return result;)";
c << '*' << outPtr << " = *"
<< cpythonWrapperCPtr(typeEntry, pyInVariable) << ';';
} else {
- auto ste = qSharedPointerCast<const SmartPointerTypeEntry>(typeEntry);
+ auto ste = std::static_pointer_cast<const SmartPointerTypeEntry>(typeEntry);
const QString resetMethod = ste->resetMethod();
c << "auto *ptr = " << outPtr << ";\n";
c << "if (" << pyInVariable << " == Py_None)\n" << indent;
@@ -1999,7 +1749,7 @@ return result;)";
QString toCppConv;
QString toCppPreConv;
if (conv->isConversionOperator()) {
- const AbstractMetaClass *sourceClass = conv->ownerClass();
+ const auto sourceClass = conv->ownerClass();
typeCheck = u"PyObject_TypeCheck(pyIn, "_s
+ cpythonTypeNameExt(sourceClass->typeEntry()) + u')';
toCppConv = u'*' + cpythonWrapperCPtr(sourceClass->typeEntry(),
@@ -2033,14 +1783,14 @@ return result;)";
StringStream pc(TextStream::Language::Cpp);
pc << getFullTypeNameWithoutModifiers(sourceType) << " cppIn"
<< minimalConstructorExpression(api(), sourceType) << ";\n";
- writeToCppConversion(pc, sourceType, nullptr, pyInVariable,
+ writeToCppConversion(pc, sourceType, pyInVariable,
u"cppIn"_s);
pc << ';';
toCppPreConv = pc.toString();
toCppConv.append(u"cppIn"_s);
} else if (!sourceType.isWrapperType()) {
StringStream tcc(TextStream::Language::Cpp);
- writeToCppConversion(tcc, sourceType, metaClass, pyInVariable,
+ writeToCppConversion(tcc, sourceType, pyInVariable,
u"/*BOZO-1061*/"_s);
toCppConv = tcc.toString();
}
@@ -2052,7 +1802,7 @@ return result;)";
}
if (typeEntry->isValue()) {
- auto vte = qSharedPointerCast<const ValueTypeEntry>(typeEntry);
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(typeEntry);
writeCustomConverterFunctions(s, vte->customConversion());
}
}
@@ -2060,7 +1810,7 @@ return result;)";
void CppGenerator::writeCustomConverterFunctions(TextStream &s,
const CustomConversionPtr &customConversion) const
{
- if (customConversion.isNull())
+ if (!customConversion)
return;
const TargetToNativeConversions &toCppConversions = customConversion->targetToNativeConversions();
if (toCppConversions.isEmpty())
@@ -2072,7 +1822,7 @@ void CppGenerator::writeCustomConverterFunctions(TextStream &s,
s << '\n';
}
-void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass *metaClass,
+void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext) const
{
const auto typeEntry = metaClass->typeEntry();
@@ -2096,9 +1846,8 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass
auto writeConversions = [&s](const QString &signature)
{
- s << "Shiboken::Conversions::registerConverterName(converter, \"" << signature << "\");\n"
- << "Shiboken::Conversions::registerConverterName(converter, \"" << signature << "*\");\n"
- << "Shiboken::Conversions::registerConverterName(converter, \"" << signature << "&\");\n";
+ s << registerConverterName(signature) << registerConverterName(signature + u'*')
+ << registerConverterName(signature + u'&');
};
auto writeConversionsForType = [writeConversions](const QString &fullTypeName)
@@ -2123,14 +1872,14 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass
Qt::SkipEmptyParts);
while (!lst.isEmpty()) {
QString signature = lst.join(u"::"_s);
- writeConversions(smartPointerName + u'<' + signature + u" >"_s);
+ writeConversions(smartPointerName + u'<' + signature + u'>');
lst.removeFirst();
}
writeConversionsForType(smartPointerType);
}
- s << "Shiboken::Conversions::registerConverterName(converter, typeid(::";
+ s << "Shiboken::Conversions::registerConverterName(converter, typeid(" << m_gsp;
QString qualifiedCppNameInvocation;
if (!classContext.forSmartPointer())
qualifiedCppNameInvocation = metaClass->qualifiedCppName();
@@ -2140,17 +1889,15 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass
s << qualifiedCppNameInvocation << ").name());\n";
if (classContext.useWrapper()) {
- s << "Shiboken::Conversions::registerConverterName(converter, typeid(::"
+ s << "Shiboken::Conversions::registerConverterName(converter, typeid("
<< classContext.wrapperName() << ").name());\n";
}
- s << '\n';
-
if (!typeEntry->isValue() && !typeEntry->isSmartPointer())
return;
// Python to C++ copy (value, not pointer neither reference) conversion.
- s << "// Add Python to C++ copy (value, not pointer neither reference) conversion to type converter.\n";
+ s << "\n// Add Python to C++ copy (value, not pointer neither reference) conversion to type converter.\n";
sourceTypeName = metaClass->name();
targetTypeName = sourceTypeName + u"_COPY"_s;
QString toCpp = pythonToCppFunctionName(sourceTypeName, targetTypeName);
@@ -2185,7 +1932,7 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass
}
if (typeEntry->isValue()) {
- auto vte = qSharedPointerCast<const ValueTypeEntry>(typeEntry);
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(typeEntry);
writeCustomConverterRegister(s, vte->customConversion(), u"converter"_s);
}
}
@@ -2194,7 +1941,7 @@ void CppGenerator::writeCustomConverterRegister(TextStream &s,
const CustomConversionPtr &customConversion,
const QString &converterVar)
{
- if (customConversion.isNull())
+ if (!customConversion)
return;
const TargetToNativeConversions &toCppConversions =
customConversion->targetToNativeConversions();
@@ -2215,46 +1962,7 @@ void CppGenerator::writeContainerConverterFunctions(TextStream &s,
writePythonToCppConversionFunctions(s, containerType);
}
-// Helpers to collect all smart pointer pointee base classes
-static AbstractMetaClassCList findSmartPointeeBaseClasses(const ApiExtractorResult &api,
- const AbstractMetaType &smartPointerType)
-{
- AbstractMetaClassCList result;
- auto instantiationsTe = smartPointerType.instantiations().at(0).typeEntry();
- auto targetClass = AbstractMetaClass::findClass(api.classes(), instantiationsTe);
- if (targetClass != nullptr)
- result = targetClass->allTypeSystemAncestors();
- return result;
-}
-
-void CppGenerator::writeSmartPointerConverterFunctions(TextStream &s,
- const AbstractMetaType &smartPointerType) const
-{
- const auto baseClasses = findSmartPointeeBaseClasses(api(), smartPointerType);
- if (baseClasses.isEmpty())
- return;
-
- auto smartPointerTypeEntry =
- qSharedPointerCast<const SmartPointerTypeEntry>(smartPointerType.typeEntry());
-
- // TODO: Missing conversion to smart pointer pointer type:
-
- s << "// Register smartpointer conversion for all derived classes\n";
- for (auto *base : baseClasses) {
- auto baseTe = base->typeEntry();
- if (smartPointerTypeEntry->matchesInstantiation(baseTe)) {
- if (auto opt = findSmartPointerInstantiation(smartPointerTypeEntry, baseTe)) {
- const auto smartTargetType = opt.value();
- s << "// SmartPointer derived class: "
- << smartTargetType.cppSignature() << "\n";
- writePythonToCppConversionFunctions(s, smartPointerType,
- smartTargetType, {}, {}, {});
- }
- }
- }
-}
-
-bool CppGenerator::needsArgumentErrorHandling(const OverloadData &overloadData) const
+bool CppGenerator::needsArgumentErrorHandling(const OverloadData &overloadData)
{
if (overloadData.maxArgs() > 0)
return true;
@@ -2263,15 +1971,16 @@ bool CppGenerator::needsArgumentErrorHandling(const OverloadData &overloadData)
return false;
auto rfunc = overloadData.referenceFunction();
return rfunc->functionType() == AbstractMetaFunction::ConstructorFunction
- && rfunc->ownerClass()->isQObject();
+ && isQObject(rfunc->ownerClass());
}
-void CppGenerator::writeMethodWrapperPreamble(TextStream &s,const OverloadData &overloadData,
+void CppGenerator::writeMethodWrapperPreamble(TextStream &s,
+ const OverloadData &overloadData,
const GeneratorContext &context,
- ErrorReturn errorReturn) const
+ ErrorReturn errorReturn)
{
const auto rfunc = overloadData.referenceFunction();
- const AbstractMetaClass *ownerClass = rfunc->targetLangOwner();
+ const auto ownerClass = rfunc->targetLangOwner();
Q_ASSERT(ownerClass == context.metaClass());
int minArgs = overloadData.minArgs();
int maxArgs = overloadData.maxArgs();
@@ -2281,7 +1990,9 @@ void CppGenerator::writeMethodWrapperPreamble(TextStream &s,const OverloadData &
if (rfunc->isConstructor()) {
// Check if the right constructor was called.
if (!ownerClass->hasPrivateDestructor()) {
- s << "if (Shiboken::Object::isUserType(self) && !Shiboken::ObjectType::canCallConstructor(self->ob_type, Shiboken::SbkType< ::";
+ s << "if (Shiboken::Object::isUserType(self) && "
+ << "!Shiboken::ObjectType::canCallConstructor(self->ob_type, Shiboken::SbkType< "
+ << m_gsp;
QString qualifiedCppName;
if (!context.forSmartPointer())
qualifiedCppName = ownerClass->qualifiedCppName();
@@ -2291,7 +2002,7 @@ void CppGenerator::writeMethodWrapperPreamble(TextStream &s,const OverloadData &
s << qualifiedCppName << " >()))\n" << indent << errorReturn << outdent << '\n';
}
// Declare pointer for the underlying C++ object.
- s << "::" << context.effectiveClassName() << " *cptr{};\n";
+ s << globalScopePrefix(context) << context.effectiveClassName() << " *cptr{};\n";
initPythonArguments = maxArgs > 0;
@@ -2311,11 +2022,18 @@ void CppGenerator::writeMethodWrapperPreamble(TextStream &s,const OverloadData &
initPythonArguments = minArgs != maxArgs || maxArgs > 1;
}
- if (needsArgumentErrorHandling(overloadData)) {
- s << R"(Shiboken::AutoDecRef errInfo{};
-static const char fullName[] = ")" << fullPythonFunctionName(rfunc, true)
- << "\";\nSBK_UNUSED(fullName)\n";
- }
+ if (needsArgumentErrorHandling(overloadData))
+ s << "Shiboken::AutoDecRef errInfo{};\n";
+
+ s << "static const char fullName[] = \"" << fullPythonFunctionName(rfunc, true)
+ << "\";\nSBK_UNUSED(fullName)\n"
+ << "Shiboken::PythonContextMarker pcm;\n";
+ // PYSIDE-2335: Mark blocking calls like `exec` or `run` as such.
+ bool isBlockingFunction = rfunc->name() == u"exec"_s || rfunc->name() == u"exec_"_s
+ || rfunc->name() == u"run"_s;
+ if (isBlockingFunction)
+ s << "pcm.setBlocking();\n";
+
if (maxArgs > 0) {
s << "int overloadId = -1;\n"
<< PYTHON_TO_CPPCONVERSION_STRUCT << ' ' << PYTHON_TO_CPP_VAR;
@@ -2341,20 +2059,20 @@ void CppGenerator::writeConstructorWrapper(TextStream &s, const OverloadData &ov
const ErrorReturn errorReturn = ErrorReturn::MinusOne;
const auto rfunc = overloadData.referenceFunction();
- const AbstractMetaClass *metaClass = rfunc->ownerClass();
+ const auto metaClass = rfunc->ownerClass();
s << "static int\n";
s << cpythonFunctionName(rfunc)
<< "(PyObject *self, PyObject *args, PyObject *kwds)\n{\n" << indent;
if (overloadData.maxArgs() == 0 || metaClass->isAbstract())
- s << sbkUnusedVariableCast(u"args"_s);
- s << sbkUnusedVariableCast(u"kwds"_s);
+ s << sbkUnusedVariableCast("args");
+ s << sbkUnusedVariableCast("kwds");
- const bool needsMetaObject = usePySideExtensions() && metaClass->isQObject();
+ const bool needsMetaObject = usePySideExtensions() && isQObject(metaClass);
if (needsMetaObject)
s << "const QMetaObject *metaObject;\n";
- s << "SbkObject *sbkSelf = reinterpret_cast<SbkObject *>(self);\n";
+ s << "auto *sbkSelf = reinterpret_cast<SbkObject *>(self);\n";
if (metaClass->isAbstract() || metaClass->baseClassNames().size() > 1) {
s << "PyTypeObject *type = self->ob_type;\n"
@@ -2365,11 +2083,11 @@ void CppGenerator::writeConstructorWrapper(TextStream &s, const OverloadData &ov
if (metaClass->isAbstract()) {
// C++ Wrapper disabled: Abstract C++ class cannot be instantiated.
if (metaClass->typeEntry()->typeFlags().testFlag(ComplexTypeEntry::DisableWrapper)) {
- s << sbkUnusedVariableCast(u"sbkSelf"_s)
- << sbkUnusedVariableCast(u"type"_s)
- << sbkUnusedVariableCast(u"myType"_s);
+ s << sbkUnusedVariableCast("sbkSelf")
+ << sbkUnusedVariableCast("type")
+ << sbkUnusedVariableCast("myType");
if (needsMetaObject)
- s << sbkUnusedVariableCast(u"metaObject"_s);
+ s << sbkUnusedVariableCast("metaObject");
s << "Shiboken::Errors::setInstantiateAbstractClassDisabledWrapper(\""
<< metaClass->qualifiedCppName() << "\");\n" << errorReturn << outdent
<< "}\n\n";
@@ -2401,19 +2119,29 @@ void CppGenerator::writeConstructorWrapper(TextStream &s, const OverloadData &ov
s << '\n';
if (overloadData.maxArgs() > 0)
- writeOverloadedFunctionDecisor(s, overloadData);
+ writeOverloadedFunctionDecisor(s, overloadData, errorReturn);
+
+ // Handles Python Multiple Inheritance
+ QString pre = needsMetaObject ? u"bool usesPyMI = "_s : u""_s;
+ s << "\n// PyMI support\n"
+ << pre << "Shiboken::callInheritedInit(self, args, kwds, fullName);\n"
+ << "if (" << shibokenErrorsOccurred << ")\n"
+ << indent << errorReturn << outdent << "\n";
writeFunctionCalls(s, overloadData, classContext, errorReturn);
s << '\n';
const QString typeName = classContext.forSmartPointer()
? classContext.preciseType().cppSignature() : metaClass->qualifiedCppName();
- s << "if (PyErr_Occurred() || !Shiboken::Object::setCppPointer(sbkSelf, Shiboken::SbkType< ::"
- << typeName << " >(), cptr)) {\n"
+ s << "if (" << shibokenErrorsOccurred
+ << " || !Shiboken::Object::setCppPointer(sbkSelf, Shiboken::SbkType< "
+ << globalScopePrefix(classContext) << typeName << " >(), cptr)) {\n"
<< indent << "delete cptr;\n" << errorReturn << outdent
<< "}\n";
if (overloadData.maxArgs() > 0)
- s << "if (!cptr) goto " << cpythonFunctionName(rfunc) << "_TypeError;\n\n";
+ s << "if (cptr == nullptr)\n" << indent
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n\n"
+ << outdent;
s << "Shiboken::Object::setValidCpp(sbkSelf, true);\n";
// If the created C++ object has a C++ wrapper the ownership is assigned to Python
@@ -2435,8 +2163,9 @@ void CppGenerator::writeConstructorWrapper(TextStream &s, const OverloadData &ov
<< "PySide::Signal::updateSourceObject(self);\n"
<< "metaObject = cptr->metaObject(); // <- init python qt properties\n"
<< "if (!errInfo.isNull() && PyDict_Check(errInfo.object())) {\n" << indent
- << "if (!PySide::fillQtProperties(self, metaObject, errInfo))\n" << indent
- << "goto " << cpythonFunctionName(rfunc) << "_TypeError;\n" << outdent << outdent
+ << "if (!PySide::fillQtProperties(self, metaObject, errInfo, usesPyMI))\n" << indent
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n"
+ << outdent << outdent
<< "};\n";
}
@@ -2474,8 +2203,6 @@ void CppGenerator::writeConstructorWrapper(TextStream &s, const OverloadData &ov
}
s << "\n\nreturn 1;\n";
- if (needsArgumentErrorHandling(overloadData))
- writeErrorSection(s, overloadData, errorReturn);
s<< outdent << "}\n\n";
}
@@ -2498,9 +2225,9 @@ void CppGenerator::writeMethodWrapper(TextStream &s, const OverloadData &overloa
}
s << ")\n{\n" << indent;
if (rfunc->ownerClass() == nullptr || overloadData.hasStaticFunction())
- s << sbkUnusedVariableCast(u"self"_s);
+ s << sbkUnusedVariableCast(PYTHON_SELF_VAR);
if (hasKwdArgs)
- s << sbkUnusedVariableCast(u"kwds"_s);
+ s << sbkUnusedVariableCast("kwds");
writeMethodWrapperPreamble(s, overloadData, classContext);
@@ -2527,7 +2254,8 @@ void CppGenerator::writeMethodWrapper(TextStream &s, const OverloadData &overloa
<< "PyObject *revOpMethod = PyObject_GetAttr(" << PYTHON_ARG << ", attrName);\n"
<< "if (revOpMethod && PyCallable_Check(revOpMethod)) {\n" << indent
<< PYTHON_RETURN_VAR << " = PyObject_CallFunction(revOpMethod, \"O\", self);\n"
- << "if (PyErr_Occurred() && (PyErr_ExceptionMatches(PyExc_NotImplementedError)"
+ << "if (" << shibokenErrorsOccurred
+ << " && (PyErr_ExceptionMatches(PyExc_NotImplementedError)"
<< " || PyErr_ExceptionMatches(PyExc_AttributeError))) {\n" << indent
<< "PyErr_Clear();\n"
<< "Py_XDECREF(" << PYTHON_RETURN_VAR << ");\n"
@@ -2537,14 +2265,14 @@ void CppGenerator::writeMethodWrapper(TextStream &s, const OverloadData &overloa
<< "Py_XDECREF(revOpMethod);\n\n"
<< outdent << "}\n\n"
<< "// Do not enter here if other object has implemented a reverse operator.\n"
- << "if (!" << PYTHON_RETURN_VAR << ") {\n" << indent;
+ << "if (" << PYTHON_RETURN_VAR << " == nullptr) {\n" << indent;
if (maxArgs > 0)
- writeOverloadedFunctionDecisor(s, overloadData);
+ writeOverloadedFunctionDecisor(s, overloadData, ErrorReturn::Default);
writeFunctionCalls(s, overloadData, classContext, ErrorReturn::Default);
s << outdent << '\n' << "} // End of \"if (!" << PYTHON_RETURN_VAR << ")\"\n";
} else { // binary shift operator
if (maxArgs > 0)
- writeOverloadedFunctionDecisor(s, overloadData);
+ writeOverloadedFunctionDecisor(s, overloadData, ErrorReturn::Default);
writeFunctionCalls(s, overloadData, classContext, ErrorReturn::Default);
}
@@ -2563,9 +2291,6 @@ void CppGenerator::writeMethodWrapper(TextStream &s, const OverloadData &overloa
s << "Py_RETURN_NONE;\n";
}
- if (needsArgumentErrorHandling(overloadData))
- writeErrorSection(s, overloadData, ErrorReturn::Default);
-
s<< outdent << "}\n\n";
}
@@ -2573,7 +2298,7 @@ void CppGenerator::writeArgumentsInitializer(TextStream &s, const OverloadData &
ErrorReturn errorReturn)
{
const auto rfunc = overloadData.referenceFunction();
- s << "PyTuple_GET_SIZE(args);\n" << sbkUnusedVariableCast(u"numArgs"_s);
+ s << "PyTuple_GET_SIZE(args);\n" << sbkUnusedVariableCast("numArgs");
int minArgs = overloadData.minArgs();
int maxArgs = overloadData.maxArgs();
@@ -2602,15 +2327,16 @@ void CppGenerator::writeArgumentsInitializer(TextStream &s, const OverloadData &
// Disable argument count checks for QObject constructors to allow for
// passing properties as KW args.
- auto *owner = rfunc->ownerClass();
- bool isQObjectConstructor = owner != nullptr && owner->isQObject()
+ const auto owner = rfunc->ownerClass();
+ bool isQObjectConstructor = owner && isQObject(owner)
&& rfunc->functionType() == AbstractMetaFunction::ConstructorFunction;
if (usesNamedArguments && !isQObjectConstructor) {
s << "errInfo.reset(Shiboken::checkInvalidArgumentCount(numArgs, "
<< minArgs << ", " << maxArgs << "));\n"
<< "if (!errInfo.isNull())\n" << indent
- << "goto " << cpythonFunctionName(rfunc) << "_TypeError;\n" << outdent;
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n"
+ << outdent;
}
const QList<int> invalidArgsLength = overloadData.invalidArgumentLengths();
@@ -2622,7 +2348,8 @@ void CppGenerator::writeArgumentsInitializer(TextStream &s, const OverloadData &
s << "numArgs == " << invalidArgsLength.at(i);
}
s << ")\n" << indent
- << "goto " << cpythonFunctionName(rfunc) << "_TypeError;\n" << outdent;
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n"
+ << outdent;
}
s << '\n';
@@ -2633,7 +2360,7 @@ void CppGenerator::writeArgumentsInitializer(TextStream &s, const OverloadData &
funcName = rfunc->name();
QString argsVar = overloadData.hasVarargs() ? u"nonvarargs"_s : u"args"_s;
- s << "if (!";
+ s << "if (";
if (usesNamedArguments) {
s << "PyArg_ParseTuple(" << argsVar << ", \"|" << QByteArray(maxArgs, 'O')
<< ':' << funcName << '"';
@@ -2643,7 +2370,7 @@ void CppGenerator::writeArgumentsInitializer(TextStream &s, const OverloadData &
}
for (int i = 0; i < maxArgs; i++)
s << ", &(" << PYTHON_ARGS << '[' << i << "])";
- s << "))\n" << indent << errorReturn << outdent << '\n';
+ s << ") == 0)\n" << indent << errorReturn << outdent << '\n';
}
void CppGenerator::writeCppSelfConversion(TextStream &s, const GeneratorContext &context,
@@ -2654,23 +2381,15 @@ void CppGenerator::writeCppSelfConversion(TextStream &s, const GeneratorContext
return;
}
- static const QString pythonSelfVar = u"self"_s;
if (useWrapperClass)
s << "static_cast<" << className << " *>(";
- s << cpythonWrapperCPtr(context.metaClass(), pythonSelfVar);
+ s << cpythonWrapperCPtr(context.metaClass(), PYTHON_SELF_VAR);
if (useWrapperClass)
s << ')';
}
-void CppGenerator::writeSmartPointerCppSelfConversion(TextStream &s,
- const GeneratorContext &context)
-{
- Q_ASSERT(context.forSmartPointer());
- s << cpythonWrapperCPtr(context.preciseType(), u"self"_s);
-}
-
-static inline void writeCppSelfVarDef(TextStream &s,
- CppGenerator::CppSelfDefinitionFlags flags = {})
+void CppGenerator::writeCppSelfVarDef(TextStream &s,
+ CppSelfDefinitionFlags flags)
{
if (flags.testFlag(CppGenerator::CppSelfAsReference))
s << "auto &" << CPP_SELF_VAR << " = *";
@@ -2678,22 +2397,10 @@ static inline void writeCppSelfVarDef(TextStream &s,
s << "auto *" << CPP_SELF_VAR << " = ";
}
-void CppGenerator::writeSmartPointerCppSelfDefinition(TextStream &s,
- const GeneratorContext &context,
- ErrorReturn errorReturn,
- CppSelfDefinitionFlags flags)
-{
- Q_ASSERT(context.forSmartPointer());
- writeInvalidPyObjectCheck(s, u"self"_s, errorReturn);
- writeCppSelfVarDef(s, flags);
- writeSmartPointerCppSelfConversion(s, context);
- s << ";\n";
-}
-
void CppGenerator::writeCppSelfDefinition(TextStream &s,
const GeneratorContext &context,
ErrorReturn errorReturn,
- CppSelfDefinitionFlags flags) const
+ CppSelfDefinitionFlags flags)
{
Q_ASSERT(!(flags.testFlag(CppSelfAsReference) && flags.testFlag(HasStaticOverload)));
if (context.forSmartPointer()) {
@@ -2701,7 +2408,7 @@ void CppGenerator::writeCppSelfDefinition(TextStream &s,
return;
}
- const AbstractMetaClass *metaClass = context.metaClass();
+ AbstractMetaClassCPtr metaClass = context.metaClass();
const auto cppWrapper = context.metaClass()->cppWrapper();
// In the Python method, use the wrapper to access the protected
// functions.
@@ -2709,10 +2416,9 @@ void CppGenerator::writeCppSelfDefinition(TextStream &s,
&& cppWrapper.testFlag(AbstractMetaClass::CppProtectedHackWrapper);
Q_ASSERT(!useWrapperClass || context.useWrapper());
const QString className = useWrapperClass
- ? context.wrapperName()
- : (u"::"_s + metaClass->qualifiedCppName());
+ ? context.wrapperName() : getFullTypeName(metaClass);
- writeInvalidPyObjectCheck(s, u"self"_s, errorReturn);
+ writeInvalidPyObjectCheck(s, PYTHON_SELF_VAR, errorReturn);
if (flags.testFlag(CppSelfAsReference)) {
writeCppSelfVarDef(s, flags);
@@ -2745,7 +2451,7 @@ void CppGenerator::writeCppSelfDefinition(TextStream &s,
const AbstractMetaFunctionCPtr &func,
const GeneratorContext &context,
ErrorReturn errorReturn,
- CppSelfDefinitionFlags flags) const
+ CppSelfDefinitionFlags flags)
{
if (!func->ownerClass() || func->isConstructor())
return;
@@ -2761,24 +2467,32 @@ void CppGenerator::writeCppSelfDefinition(TextStream &s,
writeCppSelfDefinition(s, context, errorReturn, flags);
}
-void CppGenerator::writeErrorSection(TextStream &s, const OverloadData &overloadData,
- ErrorReturn errorReturn)
+QString CppGenerator::returnErrorWrongArguments(const OverloadData &overloadData,
+ ErrorReturn errorReturn)
{
const auto rfunc = overloadData.referenceFunction();
QString argsVar = overloadData.pythonFunctionWrapperUsesListOfArguments()
? u"args"_s : PYTHON_ARG;
- s << '\n' << cpythonFunctionName(rfunc) << "_TypeError:\n" << indent
- << "Shiboken::setErrorAboutWrongArguments(" << argsVar << ", fullName, errInfo);\n"
- << errorReturn << outdent;
+ switch (errorReturn) {
+ case ErrorReturn::Default:
+ return u"Shiboken::returnWrongArguments("_s + argsVar + u", fullName, errInfo)"_s;
+ case ErrorReturn::Zero:
+ return u"Shiboken::returnWrongArguments_Zero("_s + argsVar + u", fullName, errInfo)"_s;
+ case ErrorReturn::MinusOne:
+ return u"Shiboken::returnWrongArguments_MinusOne("_s + argsVar + u", fullName, errInfo)"_s;
+ case ErrorReturn::Void:
+ Q_ASSERT(false);
+ }
+ return {};
}
void CppGenerator::writeFunctionReturnErrorCheckSection(TextStream &s,
ErrorReturn errorReturn,
bool hasReturnValue)
{
- s << "if (PyErr_Occurred()";
+ s << "if (" << shibokenErrorsOccurred;
if (hasReturnValue)
- s << " || !" << PYTHON_RETURN_VAR;
+ s << " || " << PYTHON_RETURN_VAR << " == nullptr";
s << ") {\n" << indent;
if (hasReturnValue)
s << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");\n";
@@ -2886,7 +2600,7 @@ static void checkTypeViability(const AbstractMetaFunctionCPtr &func)
}
void CppGenerator::writeTypeCheck(TextStream &s,
- const QSharedPointer<OverloadDataNode> &overloadData,
+ const std::shared_ptr<OverloadDataNode> &overloadData,
const QString &argumentName)
{
QSet<TypeEntryCPtr> numericTypes;
@@ -2918,7 +2632,7 @@ qsizetype CppGenerator::writeArgumentConversion(TextStream &s,
const QString &argName,
const QString &pyArgName,
ErrorReturn errorReturn,
- const AbstractMetaClass *context,
+ const AbstractMetaClassCPtr &context,
const QString &defaultValue,
bool castArgumentAsUnused) const
{
@@ -2950,12 +2664,12 @@ static inline QString arrayHandleType(const AbstractMetaTypeList &nestedArrayTyp
{
switch (nestedArrayTypes.size()) {
case 1:
- return QStringLiteral("Shiboken::Conversions::ArrayHandle<")
+ return "Shiboken::Conversions::ArrayHandle<"_L1
+ nestedArrayTypes.constLast().minimalSignature() + u'>';
case 2:
- return QStringLiteral("Shiboken::Conversions::Array2Handle<")
+ return "Shiboken::Conversions::Array2Handle<"_L1
+ nestedArrayTypes.constLast().minimalSignature()
- + QStringLiteral(", ")
+ + ", "_L1
+ QString::number(nestedArrayTypes.constFirst().arrayElementCount())
+ u'>';
}
@@ -2994,7 +2708,7 @@ qsizetype CppGenerator::writePythonToCppTypeConversion(TextStream &s,
const AbstractMetaType &type,
const QString &pyIn,
const QString &cppOut,
- const AbstractMetaClass *context,
+ const AbstractMetaClassCPtr &context,
const QString &defaultValue) const
{
TypeEntryCPtr typeEntry = type.typeEntry();
@@ -3030,7 +2744,7 @@ qsizetype CppGenerator::writePythonToCppTypeConversion(TextStream &s,
// conversion for &cppOut
s << ' ' << cppOutAux;
// No default value for containers which can also be passed by pointer.
- if (arg.type != GeneratorArgument::Type::Container)
+ if (arg.type != GeneratorArgument::Type::Container || type.indirections() == 0)
writeMinimalConstructorExpression(s, api(), type, isPrimitive, defaultValue);
s << ";\n" << typeName << " *" << cppOut << " = &" << cppOutAux;
}
@@ -3062,7 +2776,7 @@ qsizetype CppGenerator::writePythonToCppTypeConversion(TextStream &s,
|| arg.type == GeneratorArgument::Type::Enum
|| arg.type == GeneratorArgument::Type::Flags) {
writeMinimalConstructorExpression(s, api(), typeEntry, isPrimitive, defaultValue);
- } else if (!type.isContainer() && !type.isSmartPointer()) {
+ } else if ((!type.isContainer() || type.indirections() == 0) && !type.isSmartPointer()) {
writeMinimalConstructorExpression(s, api(), type, isPrimitive, defaultValue);
}
break;
@@ -3157,7 +2871,9 @@ void CppGenerator::writeNoneReturn(TextStream &s, const AbstractMetaFunctionCPtr
}
}
-void CppGenerator::writeOverloadedFunctionDecisor(TextStream &s, const OverloadData &overloadData) const
+void CppGenerator::writeOverloadedFunctionDecisor(TextStream &s,
+ const OverloadData &overloadData,
+ ErrorReturn errorReturn) const
{
s << "// Overloaded function decisor\n";
const auto rfunc = overloadData.referenceFunction();
@@ -3167,7 +2883,7 @@ void CppGenerator::writeOverloadedFunctionDecisor(TextStream &s, const OverloadD
s << "// " << i << ": ";
if (func->isStatic())
s << "static ";
- if (const auto *decl = func->declaringClass())
+ if (const auto &decl = func->declaringClass())
s << decl->name() << "::";
s << func->signatureComment() << '\n';
}
@@ -3184,8 +2900,9 @@ void CppGenerator::writeOverloadedFunctionDecisor(TextStream &s, const OverloadD
}
s << "// Function signature not found.\n"
- << "if (overloadId == -1) goto "
- << cpythonFunctionName(overloadData.referenceFunction()) << "_TypeError;\n\n";
+ << "if (overloadId == -1)\n" << indent
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n\n"
+ << outdent;
}
void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
@@ -3251,7 +2968,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
auto func = referenceFunction;
for (const auto &child : children) {
const auto defValFunc = child->getFunctionWithDefaultValue();
- if (!defValFunc.isNull()) {
+ if (defValFunc) {
func = defValFunc;
break;
}
@@ -3277,7 +2994,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
int sequenceArgCount = 0;
while (od && !od->argType().isVarargs()) {
const bool typeReplacedByPyObject = od->isTypeModified()
- && od->modifiedArgType().name() == cPyObjectT();
+ && od->modifiedArgType().name() == cPyObjectT;
if (!typeReplacedByPyObject) {
if (usePyArgs)
pyArgName = pythonArgsAt(od->argPos());
@@ -3285,7 +3002,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
auto func = od->referenceFunction();
if (func->isConstructor() && func->arguments().size() == 1) {
- const AbstractMetaClass *ownerClass = func->ownerClass();
+ AbstractMetaClassCPtr ownerClass = func->ownerClass();
ComplexTypeEntryCPtr baseContainerType = ownerClass->typeEntry()->baseContainerType();
if (baseContainerType && baseContainerType == func->arguments().constFirst().type().typeEntry()
&& ownerClass->isCopyable()) {
@@ -3341,7 +3058,7 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
s << indent << typeChecks.join(u"\n&& "_s) << outdent;
}
s << ") {\n" << indent;
- writeOverloadedFunctionDecisorEngine(s, overloadData, child.data());
+ writeOverloadedFunctionDecisorEngine(s, overloadData, child.get());
s << outdent << '}';
}
s << '\n';
@@ -3374,11 +3091,12 @@ static void writeDeprecationWarning(TextStream &s,
CppGenerator::ErrorReturn errorReturn)
{
s << "Shiboken::Warnings::warnDeprecated(\"";
- if (auto *cls = context.metaClass())
+ if (const auto cls = context.metaClass())
s << cls->name() << "\", ";
// Check error in case "warning-as-error" is set.
s << '"' << func->signature().replace(u"::"_s, u"."_s) << "\");\n"
- << "if (PyErr_Occurred())\n" << indent << errorReturn << outdent;
+ << "if (" << shibokenErrorsOccurred << ")\n"
+ << indent << errorReturn << outdent;
}
void CppGenerator::writeSingleFunctionCall(TextStream &s,
@@ -3400,7 +3118,7 @@ void CppGenerator::writeSingleFunctionCall(TextStream &s,
const bool usePyArgs = overloadData.pythonFunctionWrapperUsesListOfArguments();
// Handle named arguments.
- writeNamedArgumentResolution(s, func, usePyArgs, overloadData);
+ writeNamedArgumentResolution(s, func, usePyArgs, overloadData, errorReturn);
bool injectCodeCallsFunc = injectedCodeCallsCppFunction(context, func);
bool mayHaveUnunsedArguments = !func->isUserAdded() && func->hasInjectedCode() && injectCodeCallsFunc;
@@ -3414,8 +3132,7 @@ void CppGenerator::writeSingleFunctionCall(TextStream &s,
const AbstractMetaArgument &arg = func->arguments().at(argIdx);
if (arg.isModifiedRemoved()) {
if (!arg.defaultValueExpression().isEmpty()) {
- const QString cppArgRemoved = CPP_ARG_REMOVED
- + QString::number(argIdx);
+ const QString cppArgRemoved = CPP_ARG_REMOVED(argIdx);
s << getFullTypeName(arg.type()) << ' ' << cppArgRemoved;
s << " = " << arg.defaultValueExpression() << ";\n"
<< sbkUnusedVariableCast(cppArgRemoved);
@@ -3437,10 +3154,9 @@ void CppGenerator::writeSingleFunctionCall(TextStream &s,
continue;
auto argType = getArgumentType(func, argIdx);
int argPos = argIdx - removedArgs;
- QString argName = CPP_ARG + QString::number(argPos);
QString pyArgName = usePyArgs ? pythonArgsAt(argPos) : PYTHON_ARG;
indirections[argIdx] =
- writeArgumentConversion(s, argType, argName, pyArgName, errorReturn,
+ writeArgumentConversion(s, argType, CPP_ARG_N(argPos), pyArgName, errorReturn,
func->implementingClass(), arg.defaultValueExpression(),
func->isUserAdded());
}
@@ -3449,7 +3165,7 @@ void CppGenerator::writeSingleFunctionCall(TextStream &s,
int numRemovedArgs = OverloadData::numberOfRemovedArguments(func);
- s << "if (!PyErr_Occurred()) {\n" << indent;
+ s << "if (Shiboken::Errors::occurred() == nullptr) {\n" << indent;
writeMethodCall(s, func, context,
overloadData.pythonFunctionWrapperUsesListOfArguments(),
func->arguments().size() - numRemovedArgs, indirections, errorReturn);
@@ -3500,9 +3216,10 @@ void CppGenerator::writeCppToPythonFunction(TextStream &s, const QString &code,
{
QString prettyCode = code;
- processCodeSnip(prettyCode);
+ const QString funcName = cppToPythonFunctionName(sourceTypeName, targetTypeName);
+ processCodeSnip(prettyCode, funcName);
- s << "static PyObject *" << cppToPythonFunctionName(sourceTypeName, targetTypeName)
+ s << "static PyObject *" << funcName
<< "(const void *cppIn)\n{\n" << indent << prettyCode
<< ensureEndl << outdent << "}\n";
}
@@ -3540,10 +3257,22 @@ void CppGenerator::writeCppToPythonFunction(TextStream &s,
replaceCppToPythonVariables(code, getFullTypeName(ownerType), constRef);
writeCppToPythonFunction(s, code, fixedCppTypeName(customConversion->ownerType()));
}
+
+QString CppGenerator::containerNativeToTargetTypeName(const ContainerTypeEntryCPtr &type)
+{
+ QString result = type->targetLangApiName();
+ if (result != cPyObjectT) {
+ result = containerCpythonBaseName(type);
+ if (result == cPySequenceT)
+ result = cPyListT;
+ }
+ return result;
+}
+
void CppGenerator::writeCppToPythonFunction(TextStream &s, const AbstractMetaType &containerType) const
{
Q_ASSERT(containerType.typeEntry()->isContainer());
- auto cte = qSharedPointerCast<const ContainerTypeEntry>(containerType.typeEntry());
+ auto cte = std::static_pointer_cast<const ContainerTypeEntry>(containerType.typeEntry());
if (!cte->hasCustomConversion()) {
QString m;
QTextStream(&m) << "Can't write the C++ to Python conversion function for container type '"
@@ -3561,16 +3290,18 @@ void CppGenerator::writeCppToPythonFunction(TextStream &s, const AbstractMetaTyp
code.replace(u"%INTYPE_"_s + QString::number(i), typeName);
}
replaceCppToPythonVariables(code, getFullTypeNameWithoutModifiers(containerType), true);
- processCodeSnip(code);
- writeCppToPythonFunction(s, code, fixedCppTypeName(containerType));
+ processCodeSnip(code, containerType.typeEntry()->qualifiedCppName());
+ writeCppToPythonFunction(s, code, fixedCppTypeName(containerType),
+ containerNativeToTargetTypeName(cte));
}
void CppGenerator::writePythonToCppFunction(TextStream &s, const QString &code, const QString &sourceTypeName,
const QString &targetTypeName) const
{
QString prettyCode = code;
- processCodeSnip(prettyCode);
- s << "static void " << pythonToCppFunctionName(sourceTypeName, targetTypeName)
+ const QString funcName = pythonToCppFunctionName(sourceTypeName, targetTypeName);
+ processCodeSnip(prettyCode, funcName);
+ s << "static void " << funcName
<< "(PyObject *pyIn, void *cppOut)\n{\n" << indent << prettyCode
<< ensureEndl << outdent << "}\n";
}
@@ -3592,7 +3323,7 @@ void CppGenerator::writeIsPythonConvertibleToCppFunction(TextStream &s,
<< "return Shiboken::Conversions::nonePythonToCppNullPtr;\n" << outdent;
} else {
if (!condition.contains(u"pyIn"))
- s << sbkUnusedVariableCast(u"pyIn"_s);
+ s << sbkUnusedVariableCast("pyIn");
}
s << "if (" << condition << ")\n" << indent
<< "return " << pythonToCppFuncName << ";\n" << outdent
@@ -3659,8 +3390,6 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s,
QString pyTypeName = toNative.sourceTypeName();
if (pyTypeName == u"Py_None" || pyTypeName == u"PyNone")
typeCheck = u"%in == Py_None"_s;
- else if (pyTypeName == u"SbkEnumType")
- typeCheck = u"Shiboken::isShibokenEnum(%in)"_s;
else if (pyTypeName == u"SbkObject")
typeCheck = u"Shiboken::Object::checkType(%in)"_s;
}
@@ -3675,29 +3404,26 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s,
+ cpythonTypeNameExt(toNative.sourceType()) + u')';
}
typeCheck.replace(u"%in"_s, u"pyIn"_s);
- processCodeSnip(typeCheck);
+ processCodeSnip(typeCheck, targetType->qualifiedCppName());
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, typeCheck);
}
void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, const AbstractMetaType &containerType) const
{
Q_ASSERT(containerType.typeEntry()->isContainer());
- auto cte = qSharedPointerCast<const ContainerTypeEntry>(containerType.typeEntry());
- if (!cte->hasCustomConversion()) {
- //qFatal
- return;
- }
-
+ const auto cte = std::static_pointer_cast<const ContainerTypeEntry>(containerType.typeEntry());
const auto customConversion = cte->customConversion();
- const TargetToNativeConversions &toCppConversions =
- customConversion->targetToNativeConversions();
- if (toCppConversions.isEmpty()) {
- //qFatal
- return;
- }
+ for (const auto &conv : customConversion->targetToNativeConversions())
+ writePythonToCppConversionFunction(s, containerType, conv);
+}
+
+void CppGenerator::writePythonToCppConversionFunction(TextStream &s,
+ const AbstractMetaType &containerType,
+ const TargetToNativeConversion &conv) const
+{
// Python to C++ conversion function.
QString cppTypeName = getFullTypeNameWithoutModifiers(containerType);
- QString code = toCppConversions.constFirst().conversion();
+ QString code = conv.conversion();
const QString line = u"auto &cppOutRef = *reinterpret_cast<"_s
+ cppTypeName + u" *>(cppOut);"_s;
CodeSnipAbstract::prependCode(&code, line);
@@ -3725,7 +3451,8 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, const Abst
code.replace(u"%in"_s, u"pyIn"_s);
code.replace(u"%out"_s, u"cppOutRef"_s);
QString typeName = fixedCppTypeName(containerType);
- writePythonToCppFunction(s, code, typeName, typeName);
+ const QString &sourceTypeName = conv.sourceTypeName();
+ writePythonToCppFunction(s, code, sourceTypeName, typeName);
// Python to C++ convertible check function.
QString typeCheck = cpythonCheckFunction(containerType);
@@ -3733,7 +3460,7 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, const Abst
typeCheck = u"false"_s;
else
typeCheck = typeCheck + u"pyIn)"_s;
- writeIsPythonConvertibleToCppFunction(s, typeName, typeName, typeCheck);
+ writeIsPythonConvertibleToCppFunction(s, sourceTypeName, typeName, typeCheck);
s << '\n';
}
@@ -3774,17 +3501,20 @@ static bool forceQObjectNamedArguments(const AbstractMetaFunctionCPtr &func)
{
if (func->functionType() != AbstractMetaFunction::ConstructorFunction)
return false;
- auto *owner = func->ownerClass();
+ const auto owner = func->ownerClass();
Q_ASSERT(owner);
- if (!owner->isQObject())
+ if (!isQObject(owner))
return false;
const QString &name = owner->name();
return name == u"QVBoxLayout" || name == u"QHBoxLayout"
|| name == u"QSplitterHandle" || name == u"QSizeGrip";
}
-void CppGenerator::writeNamedArgumentResolution(TextStream &s, const AbstractMetaFunctionCPtr &func,
- bool usePyArgs, const OverloadData &overloadData) const
+void CppGenerator::writeNamedArgumentResolution(TextStream &s,
+ const AbstractMetaFunctionCPtr &func,
+ bool usePyArgs,
+ const OverloadData &overloadData,
+ ErrorReturn errorReturn)
{
const AbstractMetaArgumentList &args = OverloadData::getArgumentsWithDefaultValues(func);
const bool hasDefaultArguments = !args.isEmpty();
@@ -3793,10 +3523,10 @@ void CppGenerator::writeNamedArgumentResolution(TextStream &s, const AbstractMet
if (!hasDefaultArguments && !force) {
if (overloadData.hasArgumentWithDefaultValue()) {
// PySide-535: Allow for empty dict instead of nullptr in PyPy
- s << "if (kwds && PyDict_Size(kwds) > 0) {\n" << indent
+ s << "if (kwds != nullptr && PyDict_Size(kwds) > 0) {\n" << indent
<< "errInfo.reset(kwds);\n"
<< "Py_INCREF(errInfo.object());\n"
- << "goto " << cpythonFunctionName(func) << "_TypeError;\n"
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n"
<< outdent << "}\n";
}
return;
@@ -3815,19 +3545,19 @@ void CppGenerator::writeNamedArgumentResolution(TextStream &s, const AbstractMet
QString pyKeyName = u"key_"_s + arg.name();
s << "static PyObject *const " << pyKeyName
<< " = Shiboken::String::createStaticString(\"" << arg.name() << "\");\n"
- << "if (PyDict_Contains(kwds, " << pyKeyName << ")) {\n" << indent
+ << "if (PyDict_Contains(kwds, " << pyKeyName << ") != 0) {\n" << indent
<< "value = PyDict_GetItem(kwds, " << pyKeyName << ");\n"
- << "if (value && " << pyArgName << ") {\n" << indent
- << "errInfo.reset(" << pyKeyName << ");\n"
+ << "if (value != nullptr && " << pyArgName << " != nullptr ) {\n"
+ << indent << "errInfo.reset(" << pyKeyName << ");\n"
<< "Py_INCREF(errInfo.object());\n"
- << "goto " << cpythonFunctionName(func) << "_TypeError;\n"
- << outdent << "}\nif (value) {\n" << indent
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n"
+ << outdent << "}\nif (value != nullptr) {\n" << indent
<< pyArgName << " = value;\nif (!";
const auto &type = arg.modifiedType();
writeTypeCheck(s, type, pyArgName, isNumber(type.typeEntry()), {});
s << ")\n" << indent
- << "goto " << cpythonFunctionName(func) << "_TypeError;\n" << outdent
- << outdent
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n"
+ << outdent << outdent
<< "}\nPyDict_DelItem(kwds_dup, " << pyKeyName << ");\n"
<< outdent << "}\n";
}
@@ -3837,8 +3567,8 @@ void CppGenerator::writeNamedArgumentResolution(TextStream &s, const AbstractMet
// until extra keyword signals and properties are handled.
s << "if (PyDict_Size(kwds_dup) > 0) {\n" << indent
<< "errInfo.reset(kwds_dup.release());\n";
- if (!(func->isConstructor() && func->ownerClass()->isQObject()))
- s << "goto " << cpythonFunctionName(func) << "_TypeError;\n";
+ if (!(func->isConstructor() && isQObject(func->ownerClass())))
+ s << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n";
else
s << "// fall through to handle extra keyword signals and properties\n";
s << outdent << "}\n"
@@ -3850,7 +3580,7 @@ QString CppGenerator::argumentNameFromIndex(const ApiExtractorResult &api,
{
switch (argIndex) {
case -1:
- return u"self"_s;
+ return PYTHON_SELF_VAR;
case 0:
return PYTHON_RETURN_VAR;
case 1: { // Single argument?
@@ -3863,7 +3593,7 @@ QString CppGenerator::argumentNameFromIndex(const ApiExtractorResult &api,
return pythonArgsAt(argIndex - 1);
}
-const AbstractMetaClass *
+AbstractMetaClassCPtr
CppGenerator::argumentClassFromIndex(const ApiExtractorResult &api,
const AbstractMetaFunctionCPtr &func, int argIndex)
{
@@ -3888,7 +3618,7 @@ CppGenerator::argumentClassFromIndex(const ApiExtractorResult &api,
auto te = type.typeEntry();
if (type.isVoid() || !te->isComplex())
throw Exception(msgInvalidArgumentModification(func, argIndex));
- auto *result = AbstractMetaClass::findClass(api.classes(), te);
+ const auto result = AbstractMetaClass::findClass(api.classes(), te);
if (!result)
throw Exception(msgClassNotFound(te));
return result;
@@ -3914,6 +3644,11 @@ if (errorType != nullptr)
PyErr_SetObject(errorType, errorString);
)";
+static QString explicitConversion(const QString &v, const AbstractMetaType &t)
+{
+ return t.plainType().cppSignature() + u'(' + v + u')';
+}
+
void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr &func,
const GeneratorContext &context, bool usesPyArgs,
int maxArgs,
@@ -3987,7 +3722,7 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
if (hasConversionRule)
userArgs << arg.name() + CONV_RULE_OUT_VAR_SUFFIX;
else if (!arg.defaultValueExpression().isEmpty())
- userArgs.append(CPP_ARG_REMOVED + QString::number(i));
+ userArgs.append(CPP_ARG_REMOVED(i));
} else {
if (hasConversionRule) {
userArgs.append(arg.name() + CONV_RULE_OUT_VAR_SUFFIX);
@@ -3995,14 +3730,16 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
const int idx = arg.argumentIndex() - removedArgs;
const auto deRef = argumentIndirections.at(i);
QString argName = AbstractMetaType::dereferencePrefix(deRef)
- + CPP_ARG + QString::number(idx);
+ + CPP_ARG_N(idx);
userArgs.append(argName);
}
}
// "Pass unique ptr by value" pattern: Apply std::move()
auto type = arg.type();
- if (type.isUniquePointer() && type.passByValue())
+ if (type.useStdMove())
userArgs.last() = stdMove(userArgs.constLast());
+ else if (type.viewOn() != nullptr)
+ userArgs.last() = explicitConversion(userArgs.constLast(), type);
}
// If any argument's default value was modified the method must be called
@@ -4024,7 +3761,7 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
if (hasConversionRule)
otherArgs.prepend(arg.name() + CONV_RULE_OUT_VAR_SUFFIX);
else
- otherArgs.prepend(CPP_ARG_REMOVED + QString::number(i));
+ otherArgs.prepend(CPP_ARG_REMOVED(i));
}
if (otherArgsModified)
userArgs << otherArgs;
@@ -4072,21 +3809,21 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
Q_ASSERT(owner == context.metaClass());
if (func->functionType() == AbstractMetaFunction::CopyConstructorFunction
&& maxArgs == 1) {
- mc << "new ::" << context.effectiveClassName()
+ mc << "new " << globalScopePrefix(context) << context.effectiveClassName()
<< "(*" << CPP_ARG0 << ')';
} else {
const QString ctorCall = context.effectiveClassName() + u'('
+ userArgs.join(u", "_s) + u')';
- if (usePySideExtensions() && owner->isQObject()) {
+ if (usePySideExtensions() && isQObject(owner)) {
s << "void *addr = PySide::nextQObjectMemoryAddr();\n";
- uva << "if (addr) {\n" << indent
- << "cptr = new (addr) ::" << ctorCall << ";\n"
- << "PySide::setNextQObjectMemoryAddr(nullptr);\n" << outdent
+ uva << "if (addr != nullptr) {\n" << indent
+ << "cptr = new (addr) " << globalScopePrefix(context) << ctorCall
+ << ";\nPySide::setNextQObjectMemoryAddr(nullptr);\n" << outdent
<< "} else {\n" << indent
- << "cptr = new ::" << ctorCall << ";\n"
+ << "cptr = new " << globalScopePrefix(context) << ctorCall << ";\n"
<< outdent << "}\n";
} else {
- mc << "new ::" << ctorCall;
+ mc << "new " << globalScopePrefix(context) << ctorCall;
}
}
} else {
@@ -4100,7 +3837,7 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
const bool hasWrapper = shouldGenerateCppWrapper(ownerClass);
if (!avoidProtectedHack() || !func->isProtected() || !hasWrapper) {
if (func->isStatic()) {
- mc << "::" << methodCallClassName << "::";
+ mc << m_gsp << methodCallClassName << "::";
} else {
const QString cppSelfVar = CPP_SELF_VAR;
const QString selfVarCast = func->ownerClass() == func->implementingClass()
@@ -4109,7 +3846,7 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
+ u" *>("_s + cppSelfVar + u')';
if (func->isConstant()) {
if (avoidProtectedHack()) {
- mc << "const_cast<const ::";
+ mc << "const_cast<const " << globalScopePrefix(context);
if (ownerClass->cppWrapper().testFlag(AbstractMetaClass::CppProtectedHackWrapper)) {
// PYSIDE-500: Need a special wrapper cast when inherited
const QString selfWrapCast = ownerClass == func->implementingClass()
@@ -4124,7 +3861,7 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
mc << " *>(" << selfVarCast << ")->";
}
} else {
- mc << "const_cast<const ::" << methodCallClassName;
+ mc << "const_cast<const " << m_gsp << methodCallClassName;
mc << " *>(" << selfVarCast << ")->";
}
} else {
@@ -4140,13 +3877,13 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
if (!func->isStatic()) {
const bool directInheritance = context.metaClass() == ownerClass;
mc << (directInheritance ? "static_cast" : "reinterpret_cast")
- << "<::" << wrapperName(ownerClass) << " *>(" << CPP_SELF_VAR << ")->";
+ << '<' << wrapperName(ownerClass) << " *>("
+ << CPP_SELF_VAR << ")->";
}
if (!func->isAbstract())
mc << (func->isProtected() ? wrapperName(func->ownerClass()) :
- u"::"_s
- + methodCallClassName) << "::";
+ m_gsp + methodCallClassName) << "::";
mc << func->originalName() << "_protected";
}
} else {
@@ -4297,8 +4034,8 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
s << "Shiboken::Object::";
if (ownership == TypeSystem::TargetLangOwnership) {
s << "getOwnership(" << pyArgName << ");";
- } else if (auto *ac = argumentClassFromIndex(api(), func, argIndex);
- ac->hasVirtualDestructor()) {
+ } else if (auto ac = argumentClassFromIndex(api(), func, argIndex);
+ ac && ac->hasVirtualDestructor()) {
s << "releaseOwnership(" << pyArgName << ");";
} else {
s << "invalidate(" << pyArgName << ");";
@@ -4343,12 +4080,12 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
s << propagateException;
}
-QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass *metaClass)
+QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClassCPtr &metaClass)
{
QStringList result;
const auto &baseClases = metaClass->typeSystemBaseClasses();
if (!baseClases.isEmpty()) {
- for (const AbstractMetaClass *baseClass : baseClases) {
+ for (const auto &baseClass : baseClases) {
QString offset;
QTextStream(&offset) << "reinterpret_cast<uintptr_t>(static_cast<const "
<< baseClass->qualifiedCppName() << " *>(class_ptr)) - base";
@@ -4361,50 +4098,55 @@ QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass
result.append(offset);
}
- for (const AbstractMetaClass *baseClass : baseClases)
+ for (const auto &baseClass : baseClases)
result.append(getAncestorMultipleInheritance(baseClass));
}
return result;
}
-void CppGenerator::writeMultipleInheritanceInitializerFunction(TextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeMultipleInheritanceInitializerFunction(TextStream &s,
+ const AbstractMetaClassCPtr &metaClass)
{
QString className = metaClass->qualifiedCppName();
const QStringList ancestors = getAncestorMultipleInheritance(metaClass);
- s << "static int mi_offsets[] = { ";
- for (qsizetype i = 0; i < ancestors.size(); i++)
- s << "-1, ";
- s << "-1 };\n"
- << "int *\n"
+ s << "int *\n"
<< multipleInheritanceInitializerFunctionName(metaClass) << "(const void *cptr)\n"
- << "{\n" << indent
- << "if (mi_offsets[0] == -1) {\n" << indent
- << "std::set<int> offsets;\n"
- << "const auto *class_ptr = reinterpret_cast<const " << className << " *>(cptr);\n"
- << "const auto base = reinterpret_cast<uintptr_t>(class_ptr);\n";
+ << "{\n" << indent;
+ s << "static int mi_offsets[] = {-2";
+ for (qsizetype i = 0; i < ancestors.size(); i++)
+ s << ", 0";
+ s << "};\n"
+ << "if (mi_offsets[0] == -2) {\n" << indent
+ << "const auto *class_ptr = reinterpret_cast<const " << className << " *>(cptr);\n"
+ << "const auto base = reinterpret_cast<uintptr_t>(class_ptr);\n"
+ << "int *p = mi_offsets;\n";
for (const QString &ancestor : ancestors)
- s << "offsets.insert(int(" << ancestor << "));\n";
-
- s << "\noffsets.erase(0);\n\n"
- << "std::copy(offsets.cbegin(), offsets.cend(), mi_offsets);\n" << outdent
+ s << "*p++ = int(" << ancestor << ");\n";
+ s << "std::sort(mi_offsets, p);\n"
+ << "auto *end = std::unique(mi_offsets, p);\n"
+ << "*end++ = -1;\n"
+ << "if (mi_offsets[0] == 0)\n"
+ << indent
+ << "std::memmove(&mi_offsets[0], &mi_offsets[1], (end - mi_offsets - 1) * sizeof(int));\n"
+ << outdent << outdent
<< "}\nreturn mi_offsets;\n" << outdent << "}\n";
}
-void CppGenerator::writeSpecialCastFunction(TextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeSpecialCastFunction(TextStream &s, const AbstractMetaClassCPtr &metaClass)
{
QString className = metaClass->qualifiedCppName();
s << "static void * " << cpythonSpecialCastFunctionName(metaClass)
<< "(void *obj, PyTypeObject *desiredType)\n{\n" << indent
- << "auto me = reinterpret_cast< ::" << className << " *>(obj);\n";
+ << "auto me = reinterpret_cast< " << m_gsp << className << " *>(obj);\n";
bool firstClass = true;
const auto &allAncestors = metaClass->allTypeSystemAncestors();
- for (const AbstractMetaClass *baseClass : allAncestors) {
+ for (const auto &baseClass : allAncestors) {
if (!firstClass)
s << "else ";
s << "if (desiredType == " << cpythonTypeNameExt(baseClass->typeEntry())
<< ")\n" << indent
- << "return static_cast< ::" << baseClass->qualifiedCppName() << " *>(me);\n"
+ << "return static_cast< " << getFullTypeName(baseClass) << " *>(me);\n"
<< outdent;
firstClass = false;
}
@@ -4420,79 +4162,28 @@ void CppGenerator::writePrimitiveConverterInitialization(TextStream &s,
<< converter << " = Shiboken::Conversions::createConverter(";
if (!type->hasTargetLangApiType())
s << "nullptr";
- else if (type->targetLangApiName() == cPyObjectT())
+ else if (type->targetLangApiName() == cPyObjectT)
s << "&PyBaseObject_Type";
else
s << '&' << type->targetLangApiName() << "_Type";
QString typeName = fixedCppTypeName(type);
s << ", " << cppToPythonFunctionName(typeName, typeName) << ");\n"
- << "Shiboken::Conversions::registerConverterName(" << converter << ", \""
- << type->qualifiedCppName() << "\");\n";
+ << registerConverterName(type->qualifiedCppName(), converter);
writeCustomConverterRegister(s, customConversion, converter);
}
-static void registerEnumConverterScopes(TextStream &s, QString signature)
+static void registerConverterInScopes(TextStream &s, QStringView signature,
+ QAnyStringView varName = converterVar)
{
while (true) {
- s << "Shiboken::Conversions::registerConverterName(converter, \""
- << signature << "\");\n";
- const int qualifierPos = signature.indexOf(u"::");
- if (qualifierPos != -1)
- signature.remove(0, qualifierPos + 2);
- else
+ s << registerConverterName(signature, varName);
+ const auto qualifierPos = signature.indexOf("::"_L1);
+ if (qualifierPos == -1)
break;
+ signature = signature.sliced(qualifierPos + 2);
}
}
-void CppGenerator::writeFlagsConverterInitialization(TextStream &s,
- const FlagsTypeEntryCPtr &flags)
-{
- static const char enumPythonVar[] = "FType";
-
- const QString qualifiedCppName = flags->qualifiedCppName();
- s << "// Register converter for flag '" << qualifiedCppName << "'.\n{\n"
- << indent;
- QString typeName = fixedCppTypeName(flags);
- s << "SbkConverter *converter = Shiboken::Conversions::createConverter("
- << enumPythonVar << ',' << '\n' << indent
- << cppToPythonFunctionName(typeName, typeName) << ");\n" << outdent;
-
- const QString enumTypeName = fixedCppTypeName(flags->originator());
- QString toCpp = pythonToCppFunctionName(enumTypeName, typeName);
- QString isConv = convertibleToCppFunctionName(enumTypeName, typeName);
- writeAddPythonToCppConversion(s, u"converter"_s, toCpp, isConv);
- toCpp = pythonToCppFunctionName(typeName, typeName);
- isConv = convertibleToCppFunctionName(typeName, typeName);
- writeAddPythonToCppConversion(s, u"converter"_s, toCpp, isConv);
- toCpp = pythonToCppFunctionName(u"number"_s, typeName);
- isConv = convertibleToCppFunctionName(u"number"_s, typeName);
- writeAddPythonToCppConversion(s, u"converter"_s, toCpp, isConv);
- s << "Shiboken::Enum::setTypeConverter(" << enumPythonVar
- << ", converter, true);\n";
- // Replace "QFlags<Class::Option>" by "Class::Options"
- QString signature = qualifiedCppName;
- if (qualifiedCppName.startsWith(u"QFlags<") && qualifiedCppName.endsWith(u'>')) {
- signature.chop(1);
- signature.remove(0, 7);
- const int lastQualifierPos = signature.lastIndexOf(u"::");
- if (lastQualifierPos != -1) {
- signature.replace(lastQualifierPos + 2, signature.size() - lastQualifierPos - 2,
- flags->flagsName());
- } else {
- signature = flags->flagsName();
- }
- }
-
- registerEnumConverterScopes(s, signature);
-
- // PYSIDE-1673: Also register "QFlags<Class::Option>" purely for
- // the purpose of finding the converter by QVariant::typeName()
- // in the QVariant conversion code.
- s << "Shiboken::Conversions::registerConverterName(converter, \""
- << flags->name() << "\");\n"
- << outdent << "}\n";
-}
-
void CppGenerator::writeEnumConverterInitialization(TextStream &s, const AbstractMetaEnum &metaEnum)
{
if (metaEnum.isPrivate() || metaEnum.isAnonymous())
@@ -4514,81 +4205,71 @@ void CppGenerator::writeEnumConverterInitialization(TextStream &s, const Abstrac
const QString isConv = convertibleToCppFunctionName(typeName, typeName);
writeAddPythonToCppConversion(s, u"converter"_s, toCpp, isConv);
s << "Shiboken::Enum::setTypeConverter(" << enumPythonVar
- << ", converter, false);\n";
+ << ", converter);\n";
- registerEnumConverterScopes(s, enumType->qualifiedCppName());
+ registerConverterInScopes(s, enumType->qualifiedCppName());
+ if (auto flags = enumType->flags())
+ s << "// Register converter for flag '" << flags->qualifiedCppName() << "'.\n"
+ << registerConverterName(flags->name()) // QMetaType
+ << registerConverterName(flags->originalName()); // Signals with flags
s << outdent << "}\n";
-
- if (auto flags = enumType->flags(); !flags.isNull())
- writeFlagsConverterInitialization(s, flags);
}
-QString CppGenerator::writeContainerConverterInitialization(TextStream &s, const AbstractMetaType &type) const
+QString CppGenerator::writeContainerConverterInitialization(TextStream &s,
+ const AbstractMetaType &type,
+ const ApiExtractorResult &api)
{
- QByteArray cppSignature = QMetaObject::normalizedSignature(type.cppSignature().toUtf8());
+ const auto cppSignature =
+ QString::fromUtf8(QMetaObject::normalizedSignature(type.cppSignature().toUtf8()));
s << "// Register converter for type '" << cppSignature << "'.\n";
- QString converter = converterObject(type);
+ const QString converter = converterObject(type);
s << converter << " = Shiboken::Conversions::createConverter(";
- if (type.typeEntry()->targetLangApiName() == cPyObjectT()) {
+
+ Q_ASSERT(type.typeEntry()->isContainer());
+ const auto typeEntry = std::static_pointer_cast<const ContainerTypeEntry>(type.typeEntry());
+
+ const QString targetTypeName = containerNativeToTargetTypeName(typeEntry);
+ if (targetTypeName == cPyObjectT) {
s << "&PyBaseObject_Type";
} else {
- QString baseName = cpythonBaseName(type.typeEntry());
- if (baseName == cPySequenceT())
- baseName = cPyListT();
- s << '&' << baseName << "_Type";
- }
- QString typeName = fixedCppTypeName(type);
- s << ", " << cppToPythonFunctionName(typeName, typeName) << ");\n";
- QString toCpp = pythonToCppFunctionName(typeName, typeName);
- QString isConv = convertibleToCppFunctionName(typeName, typeName);
- s << "Shiboken::Conversions::registerConverterName(" << converter << ", \"" << cppSignature << "\");\n";
- if (usePySideExtensions() && cppSignature.startsWith("const ") && cppSignature.endsWith("&")) {
- cppSignature.chop(1);
- cppSignature.remove(0, sizeof("const ") / sizeof(char) - 1);
- s << "Shiboken::Conversions::registerConverterName(" << converter << ", \"" << cppSignature << "\");\n";
+ s << '&' << targetTypeName << "_Type";
}
- const QString converterObj = converterObject(type);
- writeAddPythonToCppConversion(s, converterObj, toCpp, isConv);
- return converterObj;
-}
-
-void CppGenerator::writeSmartPointerConverterInitialization(TextStream &s, const AbstractMetaType &type) const
-{
- const QByteArray cppSignature = type.cppSignature().toUtf8();
- auto writeConversionRegister = [&s](const AbstractMetaType &sourceType, const QString &targetTypeName, const QString &targetConverter)
- {
- const QString sourceTypeName = fixedCppTypeName(sourceType);
- const QString toCpp = pythonToCppFunctionName(sourceTypeName, targetTypeName);
- const QString isConv = convertibleToCppFunctionName(sourceTypeName, targetTypeName);
- writeAddPythonToCppConversion(s, targetConverter, toCpp, isConv);
- };
-
- const auto classes = findSmartPointeeBaseClasses(api(), type);
- if (classes.isEmpty())
- return;
+ const QString typeName = fixedCppTypeName(type);
+ s << ", " << cppToPythonFunctionName(typeName, targetTypeName) << ");\n";
- auto smartPointerTypeEntry = qSharedPointerCast<const SmartPointerTypeEntry>(type.typeEntry());
+ s << registerConverterName(cppSignature, converter);
+ if (usePySideExtensions() && cppSignature.startsWith("const "_L1)
+ && cppSignature.endsWith(u'&')) {
+ auto underlyingType = QStringView{cppSignature}.sliced(6, cppSignature.size() - 7);
+ s << registerConverterName(underlyingType, converter);
+ }
- s << "// Register SmartPointer converter for type '" << cppSignature << "'." << '\n'
- << "///////////////////////////////////////////////////////////////////////////////////////\n\n";
+ for (const auto &conv : typeEntry->customConversion()->targetToNativeConversions()) {
+ const QString &sourceTypeName = conv.sourceTypeName();
+ QString toCpp = pythonToCppFunctionName(sourceTypeName, typeName);
+ QString isConv = convertibleToCppFunctionName(sourceTypeName, typeName);
+ writeAddPythonToCppConversion(s, converter, toCpp, isConv);
+ }
- for (auto *base : classes) {
- auto baseTe = base->typeEntry();
- if (auto opt = findSmartPointerInstantiation(smartPointerTypeEntry, baseTe)) {
- const auto smartTargetType = opt.value();
- s << "// Convert to SmartPointer derived class: ["
- << smartTargetType.cppSignature() << "]\n";
- const QString converter = u"Shiboken::Conversions::getConverter(\""_s
- + smartTargetType.cppSignature() + u"\")"_s;
- writeConversionRegister(type, fixedCppTypeName(smartTargetType), converter);
- } else {
- s << "// Class not found:" << type.instantiations().at(0).cppSignature();
+ auto typedefItPair = api.typedefTargetToName().equal_range(type.cppSignature());
+ if (typedefItPair.first != typedefItPair.second) {
+ auto *typeDb = TypeDatabase::instance();
+ s << "// Register converters for type aliases of " << cppSignature << "'.\n";
+ for (auto it = typedefItPair.first; it != typedefItPair.second; ++it) {
+ if (!typeDb->findType(it.value()))
+ s << registerConverterName(it.value(), converter);
}
}
- s << "///////////////////////////////////////////////////////////////////////////////////////" << '\n' << '\n';
+ return converter;
+}
+
+QString CppGenerator::typeInitStruct(const TypeEntryCPtr &te)
+{
+ return cppApiVariableName(te->targetLangPackage()) + u'['
+ + getTypeIndexVariableName(te) + u']';
}
void CppGenerator::writeExtendedConverterInitialization(TextStream &s,
@@ -4597,23 +4278,23 @@ void CppGenerator::writeExtendedConverterInitialization(TextStream &s,
{
s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName()
<< ".\n";
- for (const AbstractMetaClass *sourceClass : conversions) {
- const QString converterVar = cppApiVariableName(externalType->targetLangPackage()) + u'['
- + getTypeIndexVariableName(externalType) + u']';
+ for (const auto &sourceClass : conversions) {
QString sourceTypeName = fixedCppTypeName(sourceClass->typeEntry());
QString targetTypeName = fixedCppTypeName(externalType);
QString toCpp = pythonToCppFunctionName(sourceTypeName, targetTypeName);
QString isConv = convertibleToCppFunctionName(sourceTypeName, targetTypeName);
- writeAddPythonToCppConversion(s, converterVar, toCpp, isConv);
+ if (!externalType->isPrimitive())
+ s << cpythonTypeNameExt(externalType) << ";\n";
+ writeAddPythonToCppConversion(s, typeInitStruct(externalType), toCpp, isConv);
}
}
-QString CppGenerator::multipleInheritanceInitializerFunctionName(const AbstractMetaClass *metaClass)
+QString CppGenerator::multipleInheritanceInitializerFunctionName(const AbstractMetaClassCPtr &metaClass)
{
return cpythonBaseName(metaClass->typeEntry()) + u"_mi_init"_s;
}
-bool CppGenerator::supportsMappingProtocol(const AbstractMetaClass *metaClass)
+bool CppGenerator::supportsMappingProtocol(const AbstractMetaClassCPtr &metaClass)
{
for (const auto &m : mappingProtocols()) {
if (metaClass->hasFunction(m.name))
@@ -4623,7 +4304,7 @@ bool CppGenerator::supportsMappingProtocol(const AbstractMetaClass *metaClass)
return false;
}
-bool CppGenerator::supportsNumberProtocol(const AbstractMetaClass *metaClass) const
+bool CppGenerator::supportsNumberProtocol(const AbstractMetaClassCPtr &metaClass)
{
return metaClass->hasArithmeticOperatorOverload()
|| metaClass->hasIncDecrementOperatorOverload()
@@ -4632,7 +4313,7 @@ bool CppGenerator::supportsNumberProtocol(const AbstractMetaClass *metaClass) co
|| hasBoolCast(metaClass);
}
-bool CppGenerator::supportsSequenceProtocol(const AbstractMetaClass *metaClass)
+bool CppGenerator::supportsSequenceProtocol(const AbstractMetaClassCPtr &metaClass)
{
for (const auto &seq : sequenceProtocols()) {
if (metaClass->hasFunction(seq.name))
@@ -4643,7 +4324,7 @@ bool CppGenerator::supportsSequenceProtocol(const AbstractMetaClass *metaClass)
return baseType && baseType->isContainer();
}
-bool CppGenerator::shouldGenerateGetSetList(const AbstractMetaClass *metaClass) const
+bool CppGenerator::shouldGenerateGetSetList(const AbstractMetaClassCPtr &metaClass)
{
for (const AbstractMetaField &f : metaClass->fields()) {
if (!f.isStatic())
@@ -4661,29 +4342,24 @@ bool CppGenerator::shouldGenerateGetSetList(const AbstractMetaClass *metaClass)
struct pyTypeSlotEntry
{
- explicit pyTypeSlotEntry(const char *name, const QString &function) :
+ explicit pyTypeSlotEntry(QAnyStringView name, QAnyStringView function) :
m_name(name), m_function(function) {}
- const char *m_name;
- const QString &m_function;
+ QAnyStringView m_name;
+ QAnyStringView m_function;
};
TextStream &operator<<(TextStream &str, const pyTypeSlotEntry &e)
{
- str << '{' << e.m_name << ',';
- const int padding = qMax(0, 18 - int(strlen(e.m_name)));
- for (int p = 0; p < padding; ++p)
- str << ' ';
- if (e.m_function.isEmpty())
- str << NULL_PTR;
- else
- str << "reinterpret_cast<void *>(" << e.m_function << ')';
- str << "},\n";
+ if (!e.m_function.isEmpty()) {
+ str << '{' << e.m_name << ',' << Pad(' ', qMax(0, 18 - e.m_name.size()))
+ << "reinterpret_cast<void *>(" << e.m_function << ")},\n";
+ }
return str;
}
void CppGenerator::writeClassDefinition(TextStream &s,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext)
{
QString tp_init;
@@ -4692,7 +4368,6 @@ void CppGenerator::writeClassDefinition(TextStream &s,
QString tp_hash;
QString tp_call;
const QString className = chopType(cpythonTypeName(metaClass));
- QString baseClassName;
AbstractMetaFunctionCList ctors;
const auto &allCtors = metaClass->queryFunctions(FunctionQueryOption::AnyConstructor);
for (const auto &f : allCtors) {
@@ -4702,13 +4377,10 @@ void CppGenerator::writeClassDefinition(TextStream &s,
}
}
- if (!metaClass->baseClass())
- baseClassName = u"SbkObject_TypeF()"_s;
-
bool onlyPrivCtor = !metaClass->hasNonPrivateConstructor();
const bool isQApp = usePySideExtensions()
- && metaClass->inheritsFrom(u"QCoreApplication"_s);
+ && inheritsFrom(metaClass, u"QCoreApplication"_s);
QString tp_flags = u"Py_TPFLAGS_DEFAULT"_s;
if (!metaClass->attributes().testFlag(AbstractMetaClass::FinalCppClass))
@@ -4760,25 +4432,31 @@ void CppGenerator::writeClassDefinition(TextStream &s,
if (generateRichComparison(classContext))
tp_richcompare = cpythonBaseName(metaClass) + u"_richcompare"_s;
+ const bool isSmartPointer = classContext.forSmartPointer();
QString tp_getset;
- if (shouldGenerateGetSetList(metaClass) && !classContext.forSmartPointer())
+ if (shouldGenerateGetSetList(metaClass) && !isSmartPointer)
tp_getset = cpythonGettersSettersDefinitionName(metaClass);
// search for special functions
clearTpFuncs();
for (const auto &func : metaClass->functions()) {
- if (m_tpFuncs.contains(func->name()))
- m_tpFuncs[func->name()] = cpythonFunctionName(func);
+ // Special non-operator functions identified by name
+ auto it = m_tpFuncs.find(func->name());
+ if (it != m_tpFuncs.end())
+ it.value() = cpythonFunctionName(func);
+ else if ( it = m_nbFuncs.find(func->name()); it != m_nbFuncs.end() )
+ it.value() = cpythonFunctionName(func);
}
- if (m_tpFuncs.value(reprFunction()).isEmpty()
- && metaClass->hasToStringCapability()) {
- m_tpFuncs[reprFunction()] = writeReprFunction(s,
- classContext,
- metaClass->toStringCapabilityIndirections());
+ if (m_tpFuncs.value(REPR_FUNCTION).isEmpty()
+ && (isSmartPointer || metaClass->hasToStringCapability())) {
+ const QString name = isSmartPointer
+ ? writeSmartPointerReprFunction(s, classContext)
+ : writeReprFunction(s, classContext, metaClass->toStringCapabilityIndirections());
+ m_tpFuncs[REPR_FUNCTION] = name;
}
// class or some ancestor has multiple inheritance
- const AbstractMetaClass *miClass = getMultipleInheritingClass(metaClass);
+ const auto miClass = getMultipleInheritingClass(metaClass);
if (miClass) {
if (metaClass == miClass)
writeMultipleInheritanceInitializerFunction(s, metaClass);
@@ -4792,8 +4470,8 @@ void CppGenerator::writeClassDefinition(TextStream &s,
if (hasHashFunction(metaClass))
tp_hash = u'&' + cpythonBaseName(metaClass) + u"_HashFunc"_s;
- const auto callOp = metaClass->findFunction(u"operator()");
- if (!callOp.isNull() && !callOp->isModifiedRemoved())
+ const auto callOp = metaClass->findFunction("operator()");
+ if (callOp && !callOp->isModifiedRemoved())
tp_call = u'&' + cpythonFunctionName(callOp);
const QString typePtr = u"_"_s + className
@@ -4804,7 +4482,7 @@ void CppGenerator::writeClassDefinition(TextStream &s,
<< "}\n\nstatic PyType_Slot " << className << "_slots[] = {\n" << indent
<< "{Py_tp_base, nullptr}, // inserted by introduceWrapperType\n"
<< pyTypeSlotEntry("Py_tp_dealloc", tp_dealloc)
- << pyTypeSlotEntry("Py_tp_repr", m_tpFuncs.value(reprFunction()))
+ << pyTypeSlotEntry("Py_tp_repr", m_tpFuncs.value(REPR_FUNCTION))
<< pyTypeSlotEntry("Py_tp_hash", tp_hash)
<< pyTypeSlotEntry("Py_tp_call", tp_call)
<< pyTypeSlotEntry("Py_tp_str", m_tpFuncs.value(u"__str__"_s))
@@ -4828,7 +4506,6 @@ void CppGenerator::writeClassDefinition(TextStream &s,
writeTypeAsMappingDefinition(s, metaClass);
}
if (supportsNumberProtocol(metaClass)) {
- // This one must come last. See the function itself.
s << "// type supports number protocol\n";
writeTypeAsNumberDefinition(s, metaClass);
}
@@ -4843,12 +4520,12 @@ void CppGenerator::writeClassDefinition(TextStream &s,
}
void CppGenerator::writeMappingMethods(TextStream &s,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &context) const
{
for (const auto & m : mappingProtocols()) {
const auto func = metaClass->findFunction(m.name);
- if (func.isNull())
+ if (!func)
continue;
QString funcName = cpythonFunctionName(func);
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode);
@@ -4865,14 +4542,14 @@ void CppGenerator::writeMappingMethods(TextStream &s,
}
void CppGenerator::writeSequenceMethods(TextStream &s,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &context) const
{
bool injectedCode = false;
for (const auto &seq : sequenceProtocols()) {
const auto func = metaClass->findFunction(seq.name);
- if (func.isNull())
+ if (!func)
continue;
injectedCode = true;
QString funcName = cpythonFunctionName(func);
@@ -4896,25 +4573,25 @@ void CppGenerator::writeSequenceMethods(TextStream &s,
static const QHash<QString, QString> &sqFuncs()
{
static const QHash<QString, QString> result = {
- {u"__concat__"_s, u"sq_concat"_s},
- {u"__contains__"_s, u"sq_contains"_s},
- {u"__getitem__"_s, u"sq_item"_s},
- {u"__getslice__"_s, u"sq_slice"_s},
- {u"__len__"_s, u"sq_length"_s},
- {u"__setitem__"_s, u"sq_ass_item"_s},
- {u"__setslice__"_s, u"sq_ass_slice"_s}
+ {u"__concat__"_s, u"Py_sq_concat"_s},
+ {u"__contains__"_s, u"Py_sq_contains"_s},
+ {u"__getitem__"_s, u"Py_sq_item"_s},
+ {u"__getslice__"_s, u"Py_sq_slice"_s},
+ {u"__len__"_s, u"Py_sq_length"_s},
+ {u"__setitem__"_s, u"Py_sq_ass_item"_s},
+ {u"__setslice__"_s, u"Py_sq_ass_slice"_s}
};
return result;
}
void CppGenerator::writeTypeAsSequenceDefinition(TextStream &s,
- const AbstractMetaClass *metaClass)
+ const AbstractMetaClassCPtr &metaClass)
{
bool hasFunctions = false;
QMap<QString, QString> funcs;
for (const auto &seq : sequenceProtocols()) {
const auto func = metaClass->findFunction(seq.name);
- if (!func.isNull()) {
+ if (func) {
funcs.insert(seq.name, u'&' + cpythonFunctionName(func));
hasFunctions = true;
}
@@ -4932,38 +4609,34 @@ void CppGenerator::writeTypeAsSequenceDefinition(TextStream &s,
for (auto it = sqFuncs().cbegin(), end = sqFuncs().cend(); it != end; ++it) {
const QString &sqName = it.key();
auto fit = funcs.constFind(sqName);
- if (fit != funcs.constEnd()) {
- s << "{Py_" << it.value() << ", reinterpret_cast<void *>("
- << fit.value() << ")},\n";
- }
+ if (fit != funcs.constEnd())
+ s << pyTypeSlotEntry(it.value(), fit.value());
}
}
void CppGenerator::writeTypeAsMappingDefinition(TextStream &s,
- const AbstractMetaClass *metaClass)
+ const AbstractMetaClassCPtr &metaClass)
{
// Sequence protocol structure members names
static const QHash<QString, QString> mpFuncs{
- {u"__mlen__"_s, u"mp_length"_s},
- {u"__mgetitem__"_s, u"mp_subscript"_s},
- {u"__msetitem__"_s, u"mp_ass_subscript"_s},
+ {u"__mlen__"_s, u"Py_mp_length"_s},
+ {u"__mgetitem__"_s, u"Py_mp_subscript"_s},
+ {u"__msetitem__"_s, u"Py_mp_ass_subscript"_s},
};
QMap<QString, QString> funcs;
for (const auto &m : mappingProtocols()) {
const auto func = metaClass->findFunction(m.name);
- if (!func.isNull()) {
+ if (func) {
const QString entry = u"reinterpret_cast<void *>(&"_s
+ cpythonFunctionName(func) + u')';
funcs.insert(m.name, entry);
- } else {
- funcs.insert(m.name, NULL_PTR);
}
}
for (auto it = mpFuncs.cbegin(), end = mpFuncs.cend(); it != end; ++it) {
const auto fit = funcs.constFind(it.key());
if (fit != funcs.constEnd())
- s << "{Py_" << it.value() << ", " << fit.value() << "},\n";
+ s << pyTypeSlotEntry(it.value(), fit.value());
}
}
@@ -4971,105 +4644,102 @@ void CppGenerator::writeTypeAsMappingDefinition(TextStream &s,
static const QHash<QString, QString> &nbFuncs()
{
static const QHash<QString, QString> result = {
- {u"__add__"_s, u"nb_add"_s},
- {u"__sub__"_s, u"nb_subtract"_s},
- {u"__mul__"_s, u"nb_multiply"_s},
- {u"__div__"_s, u"nb_divide"_s},
- {u"__mod__"_s, u"nb_remainder"_s},
- {u"__neg__"_s, u"nb_negative"_s},
- {u"__pos__"_s, u"nb_positive"_s},
- {u"__invert__"_s, u"nb_invert"_s},
- {u"__lshift__"_s, u"nb_lshift"_s},
- {u"__rshift__"_s, u"nb_rshift"_s},
- {u"__and__"_s, u"nb_and"_s},
- {u"__xor__"_s, u"nb_xor"_s},
- {u"__or__"_s, u"nb_or"_s},
- {u"__iadd__"_s, u"nb_inplace_add"_s},
- {u"__isub__"_s, u"nb_inplace_subtract"_s},
- {u"__imul__"_s, u"nb_inplace_multiply"_s},
- {u"__idiv__"_s, u"nb_inplace_divide"_s},
- {u"__imod__"_s, u"nb_inplace_remainder"_s},
- {u"__ilshift__"_s, u"nb_inplace_lshift"_s},
- {u"__irshift__"_s, u"nb_inplace_rshift"_s},
- {u"__iand__"_s, u"nb_inplace_and"_s},
- {u"__ixor__"_s, u"nb_inplace_xor"_s},
- {u"__ior__"_s, u"nb_inplace_or"_s},
- {boolT(), u"nb_nonzero"_s}
+ {u"__abs__"_s, u"Py_nb_absolute"_s},
+ {u"__add__"_s, u"Py_nb_add"_s},
+ {u"__sub__"_s, u"Py_nb_subtract"_s},
+ {u"__mul__"_s, u"Py_nb_multiply"_s},
+ {u"__div__"_s, u"Py_nb_true_divide"_s},
+ {u"__mod__"_s, u"Py_nb_remainder"_s},
+ {u"__neg__"_s, u"Py_nb_negative"_s},
+ {u"__pos__"_s, u"Py_nb_positive"_s},
+ {u"__pow__"_s, u"Py_nb_power"_s},
+ {u"__invert__"_s, u"Py_nb_invert"_s},
+ {u"__lshift__"_s, u"Py_nb_lshift"_s},
+ {u"__rshift__"_s, u"Py_nb_rshift"_s},
+ {u"__and__"_s, u"Py_nb_and"_s},
+ {u"__xor__"_s, u"Py_nb_xor"_s},
+ {u"__or__"_s, u"Py_nb_or"_s},
+ {u"__iadd__"_s, u"Py_nb_inplace_add"_s},
+ {u"__isub__"_s, u"Py_nb_inplace_subtract"_s},
+ {u"__imul__"_s, u"Py_nb_inplace_multiply"_s},
+ {u"__imod__"_s, u"Py_nb_inplace_remainder"_s},
+ {u"__ilshift__"_s, u"Py_nb_inplace_lshift"_s},
+ {u"__irshift__"_s, u"Py_nb_inplace_rshift"_s},
+ {u"__iand__"_s, u"Py_nb_inplace_and"_s},
+ {u"__ixor__"_s, u"Py_nb_inplace_xor"_s},
+ {u"__ior__"_s, u"Py_nb_inplace_or"_s},
+ {u"__bool__"_s, u"Py_nb_bool"_s},
+ {u"__int__"_s, u"Py_nb_int"_s},
+ {u"__float__"_s, u"Py_nb_float"_s}
};
return result;
}
-void CppGenerator::writeTypeAsNumberDefinition(TextStream &s, const AbstractMetaClass *metaClass) const
+void CppGenerator::writeTypeAsNumberDefinition(TextStream &s, const AbstractMetaClassCPtr &metaClass) const
{
QMap<QString, QString> nb;
- const QList<AbstractMetaFunctionCList> opOverloads =
- filterGroupedOperatorFunctions(metaClass,
- OperatorQueryOption::ArithmeticOp
- | OperatorQueryOption::IncDecrementOp
- | OperatorQueryOption::LogicalOp
- | OperatorQueryOption::BitwiseOp);
-
- for (const AbstractMetaFunctionCList &opOverload : opOverloads) {
+ const QList<AbstractMetaFunctionCList> opOverloads = numberProtocolOperators(metaClass);
+ for (const auto &opOverload : opOverloads) {
const auto rfunc = opOverload.at(0);
QString opName = ShibokenGenerator::pythonOperatorFunctionName(rfunc);
nb[opName] = cpythonFunctionName(rfunc);
}
+ for (auto it = m_nbFuncs.cbegin(), end = m_nbFuncs.cend(); it != end; ++it) {
+ if (!it.value().isEmpty())
+ nb.insert(it.key(), it.value());
+ }
+
QString baseName = cpythonBaseName(metaClass);
if (hasBoolCast(metaClass))
- nb.insert(boolT(), baseName + u"___nb_bool"_s);
+ nb.insert(u"__bool__"_s, baseName + u"___nb_bool"_s);
for (auto it = nbFuncs().cbegin(), end = nbFuncs().cend(); it != end; ++it) {
const QString &nbName = it.key();
- if (nbName == u"__div__" || nbName == u"__idiv__")
- continue; // excludeFromPy3K
const auto nbIt = nb.constFind(nbName);
- if (nbIt != nb.constEnd()) {
- const QString fixednbName = nbName == boolT()
- ? u"nb_bool"_s : it.value();
- s << "{Py_" << fixednbName << ", reinterpret_cast<void *>("
- << nbIt.value() << ")},\n";
- }
- }
-
- auto nbIt = nb.constFind(u"__div__"_s);
- if (nbIt != nb.constEnd())
- s << "{Py_nb_true_divide, reinterpret_cast<void *>(" << nbIt.value() << ")},\n";
-
- nbIt = nb.constFind(u"__idiv__"_s);
- if (nbIt != nb.constEnd()) {
- s << "// This function is unused in Python 3. We reference it here.\n"
- << "{0, reinterpret_cast<void *>(" << nbIt.value() << ")},\n"
- << "// This list is ending at the first 0 entry.\n"
- << "// Therefore, we need to put the unused functions at the very end.\n";
+ if (nbIt != nb.constEnd())
+ s << pyTypeSlotEntry(it.value(), nbIt.value());
}
}
-void CppGenerator::writeTpTraverseFunction(TextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeTpTraverseFunction(TextStream &s, const AbstractMetaClassCPtr &metaClass)
{
QString baseName = cpythonBaseName(metaClass);
s << "static int " << baseName
<< "_traverse(PyObject *self, visitproc visit, void *arg)\n{\n" << indent
- << "return SbkObject_TypeF()->tp_traverse(self, visit, arg);\n"
+ << "auto traverseProc = "
+ << pyTypeGetSlot("traverseproc", sbkObjectTypeF, "Py_tp_traverse") << ";\n"
+ << "return traverseProc(self, visit, arg);\n"
<< outdent << "}\n";
}
-void CppGenerator::writeTpClearFunction(TextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeTpClearFunction(TextStream &s, const AbstractMetaClassCPtr &metaClass)
{
QString baseName = cpythonBaseName(metaClass);
s << "static int " << baseName << "_clear(PyObject *self)\n{\n" << indent
- << "return reinterpret_cast<PyTypeObject *>(SbkObject_TypeF())->tp_clear(self);\n"
+ << "auto clearProc = "
+ << pyTypeGetSlot("inquiry", sbkObjectTypeF, "Py_tp_clear") << ";\n"
+ << "return clearProc(self);\n"
<< outdent << "}\n";
}
-void CppGenerator::writeCopyFunction(TextStream &s, const GeneratorContext &context) const
+QString CppGenerator::writeCopyFunction(TextStream &s,
+ TextStream &definitionStream,
+ TextStream &signatureStream,
+ const GeneratorContext &context)
{
- const AbstractMetaClass *metaClass = context.metaClass();
+ const auto metaClass = context.metaClass();
const QString className = chopType(cpythonTypeName(metaClass));
- s << "static PyObject *" << className << "___copy__(PyObject *self)\n"
- << "{\n" << indent;
+ const QString funcName = className + u"__copy__"_s;
+
+ signatureStream << fullPythonClassName(metaClass) << ".__copy__()\n";
+ definitionStream << PyMethodDefEntry{u"__copy__"_s, funcName, {"METH_NOARGS"_ba}, {}}
+ << ",\n";
+
+ s << "static PyObject *" << funcName << "(PyObject *self)\n"
+ << "{\n" << indent;
writeCppSelfDefinition(s, context, ErrorReturn::Default, CppSelfDefinitionFlag::CppSelfAsReference);
QString conversionCode;
if (!context.forSmartPointer())
@@ -5082,16 +4752,18 @@ void CppGenerator::writeCopyFunction(TextStream &s, const GeneratorContext &cont
writeFunctionReturnErrorCheckSection(s, ErrorReturn::Default);
s << "return " << PYTHON_RETURN_VAR << ";\n" << outdent
<< "}\n\n";
+
+ return funcName;
}
static inline void writeGetterFunctionStart(TextStream &s, const QString &funcName)
{
- s << "static PyObject *" << funcName << "(PyObject *self, void *)\n"
+ s << "static PyObject *" << funcName << "(PyObject *self, void * /* closure */)\n"
<< "{\n" << indent;
}
QString CppGenerator::cppFieldAccess(const AbstractMetaField &metaField,
- const GeneratorContext &context) const
+ const GeneratorContext &context)
{
QString result;
QTextStream str(&result);
@@ -5105,7 +4777,7 @@ QString CppGenerator::cppFieldAccess(const AbstractMetaField &metaField,
void CppGenerator::writeGetterFunction(TextStream &s,
const AbstractMetaField &metaField,
- const GeneratorContext &context) const
+ const GeneratorContext &context)
{
writeGetterFunctionStart(s, cpythonGetterFunctionName(metaField));
@@ -5147,7 +4819,7 @@ void CppGenerator::writeGetterFunction(TextStream &s,
<< "pyOut = reinterpret_cast<PyObject *>(Shiboken::Object::findColocatedChild("
<< "reinterpret_cast<SbkObject *>(self), "
<< cpythonTypeNameExt(fieldType) << "));\n"
- << "if (pyOut) {\n" << indent
+ << "if (pyOut != nullptr) {\n" << indent
<< "Py_IncRef(pyOut);\n"
<< "return pyOut;\n"
<< outdent << "}\n";
@@ -5159,7 +4831,14 @@ void CppGenerator::writeGetterFunction(TextStream &s,
<< "Py_IncRef(pyOut);" << "\n"
<< "return pyOut;" << "\n"
<< outdent << "}\n";
- // Create and register new wrapper
+ // Create and register new wrapper. We force a pointer conversion also
+ // for wrapped value types so that they refer to the struct member,
+ // avoiding any trouble copying them. Add a parent relationship to
+ // properly notify if the struct is deleted (see protected_test.py,
+ // testProtectedValueTypeProperty()). Note that this has currently
+ // unsolved issues when using temporary Python lists of structs
+ // which can cause elements to be reported deleted in expressions like
+ // "foo.list_of_structs[2].field".
s << "pyOut = "
<< "Shiboken::Object::newObject(" << cpythonTypeNameExt(fieldType)
<< ", " << cppField << ", false, true);\n"
@@ -5172,27 +4851,29 @@ void CppGenerator::writeGetterFunction(TextStream &s,
}
// Write a getter for QPropertySpec
-void CppGenerator::writeGetterFunction(TextStream &s, const QPropertySpec &property,
- const GeneratorContext &context) const
+void CppGenerator::writeGetterFunction(TextStream &s,
+ const QPropertySpec &property,
+ const GeneratorContext &context)
{
writeGetterFunctionStart(s, cpythonGetterFunctionName(property, context.metaClass()));
writeCppSelfDefinition(s, context);
- const QString value = QStringLiteral("value");
+ const QString value = "value"_L1;
s << "auto " << value << " = " << CPP_SELF_VAR << "->" << property.read() << "();\n"
- << "auto pyResult = ";
+ << "auto *pyResult = ";
writeToPythonConversion(s, property.type(), context.metaClass(), value);
- s << ";\nif (PyErr_Occurred() || !pyResult) {\n" << indent
- << "Py_XDECREF(pyResult);\nreturn {};\n" << outdent
+ s << ";\nif (" << shibokenErrorsOccurred << " || pyResult == nullptr) {\n"
+ << indent << "Py_XDECREF(pyResult);\nreturn {};\n" << outdent
<< "}\nreturn pyResult;\n" << outdent << "}\n\n";
}
// Write setter function preamble (type checks on "pyIn")
-void CppGenerator::writeSetterFunctionPreamble(TextStream &s, const QString &name,
+void CppGenerator::writeSetterFunctionPreamble(TextStream &s,
+ const QString &name,
const QString &funcName,
const AbstractMetaType &type,
- const GeneratorContext &context) const
+ const GeneratorContext &context)
{
- s << "static int " << funcName << "(PyObject *self, PyObject *pyIn, void *)\n"
+ s << "static int " << funcName << "(PyObject *self, PyObject *pyIn, void * /* closure */)\n"
<< "{\n" << indent;
writeCppSelfDefinition(s, context, ErrorReturn::Zero);
@@ -5214,7 +4895,7 @@ void CppGenerator::writeSetterFunctionPreamble(TextStream &s, const QString &nam
void CppGenerator::writeSetterFunction(TextStream &s,
const AbstractMetaField &metaField,
- const GeneratorContext &context) const
+ const GeneratorContext &context)
{
const AbstractMetaType &fieldType = metaField.type();
writeSetterFunctionPreamble(s, metaField.name(), cpythonSetterFunctionName(metaField),
@@ -5246,16 +4927,18 @@ void CppGenerator::writeSetterFunction(TextStream &s,
}
// Write a setter for QPropertySpec
-void CppGenerator::writeSetterFunction(TextStream &s, const QPropertySpec &property,
- const GeneratorContext &context) const
+void CppGenerator::writeSetterFunction(TextStream &s,
+ const QPropertySpec &property,
+ const GeneratorContext &context)
{
- writeSetterFunctionPreamble(s, property.name(),
+ writeSetterFunctionPreamble(s,
+ property.name(),
cpythonSetterFunctionName(property, context.metaClass()),
property.type(), context);
s << "auto cppOut = " << CPP_SELF_VAR << "->" << property.read() << "();\n"
<< PYTHON_TO_CPP_VAR << "(pyIn, &cppOut);\n"
- << "if (PyErr_Occurred())\n" << indent
+ << "if (" << shibokenErrorsOccurred << ")\n" << indent
<< "return -1;\n" << outdent
<< CPP_SELF_VAR << "->" << property.write() << "(cppOut);\n"
<< "return 0;\n" << outdent << "}\n\n";
@@ -5263,7 +4946,7 @@ void CppGenerator::writeSetterFunction(TextStream &s, const QPropertySpec &prope
void CppGenerator::writeRichCompareFunctionHeader(TextStream &s,
const QString &baseName,
- const GeneratorContext &context) const
+ const GeneratorContext &context)
{
s << "static PyObject * ";
s << baseName << "_richcompare(PyObject *self, PyObject *" << PYTHON_ARG
@@ -5275,25 +4958,16 @@ void CppGenerator::writeRichCompareFunctionHeader(TextStream &s,
<< sbkUnusedVariableCast(PYTHON_TO_CPP_VAR) << '\n';
}
-static bool containsGoto(const CodeSnip &s)
-{
- return s.code().contains(u"goto");
-}
-
-static const char richCompareComment[] =
- "// PYSIDE-74: By default, we redirect to object's tp_richcompare (which is `==`, `!=`).\n";
-
void CppGenerator::writeRichCompareFunction(TextStream &s,
const GeneratorContext &context) const
{
- const AbstractMetaClass *metaClass = context.metaClass();
+ const auto metaClass = context.metaClass();
QString baseName = cpythonBaseName(metaClass);
writeRichCompareFunctionHeader(s, baseName, context);
s << "switch (op) {\n" << indent;
const QList<AbstractMetaFunctionCList> &groupedFuncs =
filterGroupedOperatorFunctions(metaClass, OperatorQueryOption::ComparisonOp);
- bool needErrorLabel = false;
for (const AbstractMetaFunctionCList &overloads : groupedFuncs) {
const auto rfunc = overloads[0];
@@ -5339,7 +5013,6 @@ void CppGenerator::writeRichCompareFunction(TextStream &s,
TypeSystem::TargetLangCode, func,
false /* uses PyArgs */, &func->arguments().constLast());
generateOperatorCode = false;
- needErrorLabel |= std::any_of(snips.cbegin(), snips.cend(), containsGoto);
}
}
if (generateOperatorCode) {
@@ -5373,8 +5046,8 @@ void CppGenerator::writeRichCompareFunction(TextStream &s,
<< (op == AbstractMetaFunction::OperatorEqual ? "Py_False" : "Py_True") << ";\n"
<< "Py_INCREF(" << PYTHON_RETURN_VAR << ");\n" << outdent;
} else {
- s << indent << "goto " << baseName << "_RichComparison_TypeError;\n" << outdent;
- needErrorLabel = true;
+ s << indent << "return Shiboken::returnFromRichCompare("
+ << PYTHON_RETURN_VAR << ");\n" << outdent;
}
s << "}\n\n";
@@ -5383,131 +5056,9 @@ void CppGenerator::writeRichCompareFunction(TextStream &s,
s << "default:\n" << indent
<< richCompareComment
<< "return FallbackRichCompare(self, " << PYTHON_ARG << ", op);\n"
- << outdent << outdent << "}\n\n";
-
- writeRichCompareFunctionFooter(s, baseName, needErrorLabel);
-}
-
-void CppGenerator::writeRichCompareFunctionFooter(TextStream &s,
- const QString &baseName,
- bool writeErrorLabel)
-{
- s << "if (" << PYTHON_RETURN_VAR << " && !PyErr_Occurred())\n" << indent
- << "return " << PYTHON_RETURN_VAR << ";\n" << outdent;
- if (writeErrorLabel)
- s << baseName << "_RichComparison_TypeError:\n";
- s << "Shiboken::Errors::setOperatorNotImplemented();\n"
- << ErrorReturn::Default << '\n' << outdent << "}\n\n";
-}
-
-using ComparisonOperatorList = QList<AbstractMetaFunction::ComparisonOperatorType>;
-
-// Return the available comparison operators for smart pointers
-static ComparisonOperatorList smartPointeeComparisons(const GeneratorContext &context)
-{
- Q_ASSERT(context.forSmartPointer());
- auto te = context.preciseType().instantiations().constFirst().typeEntry();
- if (isExtendedCppPrimitive(te)) { // Primitive pointee types have all
- return {AbstractMetaFunction::OperatorEqual,
- AbstractMetaFunction::OperatorNotEqual,
- AbstractMetaFunction::OperatorLess,
- AbstractMetaFunction::OperatorLessEqual,
- AbstractMetaFunction::OperatorGreater,
- AbstractMetaFunction::OperatorGreaterEqual};
- }
-
- auto *pointeeClass = context.pointeeClass();
- if (!pointeeClass)
- return {};
-
- ComparisonOperatorList result;
- const auto &comparisons =
- pointeeClass->operatorOverloads(OperatorQueryOption::SymmetricalComparisonOp);
- for (const auto &f : comparisons) {
- const auto ct = f->comparisonOperatorType().value();
- if (!result.contains(ct))
- result.append(ct);
- }
- return result;
-}
-
-void CppGenerator::writeSmartPointerRichCompareFunction(TextStream &s,
- const GeneratorContext &context) const
-{
- static const char selfPointeeVar[] = "cppSelfPointee";
- static const char cppArg0PointeeVar[] = "cppArg0Pointee";
-
- const AbstractMetaClass *metaClass = context.metaClass();
- QString baseName = cpythonBaseName(metaClass);
- writeRichCompareFunctionHeader(s, baseName, context);
-
- s << "if (";
- writeTypeCheck(s, context.preciseType(), PYTHON_ARG);
- s << ") {\n" << indent;
- writeArgumentConversion(s, context.preciseType(), CPP_ARG0,
- PYTHON_ARG, ErrorReturn::Default, metaClass);
-
- const auto te = context.preciseType().typeEntry();
- Q_ASSERT(te->isSmartPointer());
- const auto ste = qSharedPointerCast<const SmartPointerTypeEntry>(te);
-
- s << "const auto *" << selfPointeeVar << " = " << CPP_SELF_VAR
- << '.' << ste->getter() << "();\n";
- s << "const auto *" << cppArg0PointeeVar << " = " << CPP_ARG0
- << '.' << ste->getter() << "();\n";
-
- // If we have an object without any comparisons, only generate a simple
- // equality check by pointee address
- auto availableOps = smartPointeeComparisons(context);
- const bool comparePointeeAddressOnly = availableOps.isEmpty();
- if (comparePointeeAddressOnly) {
- availableOps << AbstractMetaFunction::OperatorEqual
- << AbstractMetaFunction::OperatorNotEqual;
- } else {
- // For value types with operators, we complain about nullptr
- s << "if (" << selfPointeeVar << " == nullptr || " << cppArg0PointeeVar
- << " == nullptr) {\n" << indent
- << "PyErr_SetString(PyExc_NotImplementedError, \"nullptr passed to comparison.\");\n"
- << ErrorReturn::Default << '\n' << outdent << "}\n";
- }
-
- s << "bool " << CPP_RETURN_VAR << "= false;\n"
- << "switch (op) {\n";
- for (auto op : availableOps) {
- s << "case " << AbstractMetaFunction::pythonRichCompareOpCode(op) << ":\n"
- << indent << CPP_RETURN_VAR << " = ";
- if (comparePointeeAddressOnly) {
- s << selfPointeeVar << ' ' << AbstractMetaFunction::cppComparisonOperator(op)
- << ' ' << cppArg0PointeeVar << ";\n";
- } else {
- // Shortcut for equality: Check pointee address
- if (op == AbstractMetaFunction::OperatorEqual
- || op == AbstractMetaFunction::OperatorLessEqual
- || op == AbstractMetaFunction::OperatorGreaterEqual) {
- s << selfPointeeVar << " == " << cppArg0PointeeVar << " || ";
- }
- // Generate object's comparison
- s << "*" << selfPointeeVar << ' '
- << AbstractMetaFunction::cppComparisonOperator(op) << " *"
- << cppArg0PointeeVar << ";\n";
- }
- s << "break;\n" << outdent;
-
- }
- if (availableOps.size() < 6) {
- s << "default:\n" << indent
- << richCompareComment
- << "return FallbackRichCompare(self, " << PYTHON_ARG << ", op);\n" << outdent;
- }
- s << "}\n" << PYTHON_RETURN_VAR << " = " << CPP_RETURN_VAR
- << " ? Py_True : Py_False;\n"
- << "Py_INCREF(" << PYTHON_RETURN_VAR << ");\n";
-
- s << outdent << "} else {\n" << indent
- << "goto " << baseName << "_RichComparison_TypeError;\n"
- << outdent << "}\n";
-
- writeRichCompareFunctionFooter(s, baseName, true);
+ << outdent << outdent << "}\n\n"
+ << "return Shiboken::returnFromRichCompare(" << PYTHON_RETURN_VAR << ");\n" << outdent
+ << "}\n\n";
}
// Return a flag combination for PyMethodDef
@@ -5528,9 +5079,9 @@ QByteArrayList CppGenerator::methodDefinitionParameters(const OverloadData &over
}
// METH_STATIC causes a crash when used for global functions (also from
// invisible namespaces).
- auto *ownerClass = overloadData.referenceFunction()->ownerClass();
+ const auto ownerClass = overloadData.referenceFunction()->ownerClass();
if (ownerClass
- && !invisibleTopNamespaces().contains(const_cast<AbstractMetaClass *>(ownerClass))) {
+ && !invisibleTopNamespaces().contains(std::const_pointer_cast<AbstractMetaClass>(ownerClass))) {
if (overloadData.hasStaticFunction())
result.append(QByteArrayLiteral("METH_STATIC"));
if (overloadData.hasClassMethod())
@@ -5554,6 +5105,17 @@ QList<PyMethodDefEntry>
return result;
}
+QString CppGenerator::pythonSignature(const AbstractMetaType &type) const
+{
+ if (type.isSmartPointer() && !type.instantiations().isEmpty()) {
+ const auto ste = std::static_pointer_cast<const SmartPointerTypeEntry>(type.typeEntry());
+ const auto instantiationTe = type.instantiations().constFirst().typeEntry();
+ if (auto opt = api().findSmartPointerInstantiation(ste, instantiationTe))
+ return opt->specialized->typeEntry()->qualifiedTargetLangName();
+ }
+ return type.pythonSignature();
+}
+
// Format the type signature of a function parameter
QString CppGenerator::signatureParameter(const AbstractMetaArgument &arg) const
{
@@ -5565,17 +5127,22 @@ QString CppGenerator::signatureParameter(const AbstractMetaArgument &arg) const
metaType = *viewOn;
s << arg.name() << ':';
- QStringList signatures(metaType.pythonSignature());
+ QStringList signatures(pythonSignature(metaType));
// Implicit conversions (C++): Check for converting constructors
// "QColor(Qt::GlobalColor)" or conversion operators
const AbstractMetaFunctionCList conversions =
api().implicitConversions(metaType);
for (const auto &f : conversions) {
- if (f->isConstructor() && !f->arguments().isEmpty())
- signatures << f->arguments().constFirst().type().pythonSignature();
- else if (f->isConversionOperator())
+ if (f->isConstructor() && !f->arguments().isEmpty()) {
+ // PYSIDE-2712: modified types from converting constructors are not always correct
+ // candidates if they are modified by the type system reference
+ if (!f->arguments().constFirst().isTypeModified()) {
+ signatures << pythonSignature(f->arguments().constFirst().type());
+ }
+ } else if (f->isConversionOperator()) {
signatures << f->ownerClass()->fullName();
+ }
}
const qsizetype size = signatures.size();
@@ -5589,12 +5156,6 @@ QString CppGenerator::signatureParameter(const AbstractMetaArgument &arg) const
if (size > 1)
s << ']';
- if (!arg.defaultValueExpression().isEmpty()) {
- s << '=';
- QString e = arg.defaultValueExpression();
- e.replace(u"::"_s, u"."_s);
- s << e;
- }
return result;
}
@@ -5611,18 +5172,22 @@ void CppGenerator::writeSignatureInfo(TextStream &s, const OverloadData &overloa
// PYSIDE-1328: `self`-ness cannot be computed in Python because there are mixed cases.
// Toplevel functions like `PySide6.QtCore.QEnum` are always self-less.
if (!(f->isStatic()) && f->ownerClass())
- args << u"self"_s;
+ args << PYTHON_SELF_VAR;
const auto &arguments = f->arguments();
for (qsizetype i = 0, size = arguments.size(); i < size; ++i) {
const auto n = i + 1;
+ const auto &arg = arguments.at(i);
if (!f->argumentRemoved(n)) {
QString t = f->pyiTypeReplaced(n);
if (t.isEmpty()) {
- t = signatureParameter(arguments.at(i));
+ t = signatureParameter(arg);
} else {
t.prepend(u':');
- t.prepend(arguments.at(i).name());
+ t.prepend(arg.name());
}
+ QString defaultValue = arg.defaultValueExpression();
+ if (!defaultValue.isEmpty())
+ t += u'=' + defaultValue.replace(u"::"_s, u"."_s);
args.append(t);
}
}
@@ -5634,7 +5199,7 @@ void CppGenerator::writeSignatureInfo(TextStream &s, const OverloadData &overloa
QString returnType = f->pyiTypeReplaced(0); // pyi or modified type
if (returnType.isEmpty() && !f->isVoid())
- returnType = f->type().pythonSignature();
+ returnType = pythonSignature(f->type());
if (!returnType.isEmpty())
s << "->" << returnType;
@@ -5642,43 +5207,44 @@ void CppGenerator::writeSignatureInfo(TextStream &s, const OverloadData &overloa
}
}
-void CppGenerator::writeEnumsInitialization(TextStream &s, AbstractMetaEnumList &enums,
- ErrorReturn errorReturn) const
+void CppGenerator::writeEnumsInitialization(TextStream &s, AbstractMetaEnumList &enums)
{
if (enums.isEmpty())
return;
- bool preambleWrittenE = false;
- bool preambleWrittenF = false;
+ bool preambleWritten = false;
+ bool etypeUsed = false;
+
for (const AbstractMetaEnum &cppEnum : std::as_const(enums)) {
if (cppEnum.isPrivate())
continue;
- if (!preambleWrittenE) {
+ if (!preambleWritten) {
s << "// Initialization of enums.\n"
+ << "Shiboken::AutoDecRef tpDict{};\n"
<< "PyTypeObject *EType{};\n\n";
- preambleWrittenE = true;
+ preambleWritten = true;
}
- if (!preambleWrittenF && cppEnum.typeEntry()->flags()) {
- s << "// Initialization of enums, flags part.\n"
- << "PyTypeObject *FType{};\n\n";
- preambleWrittenF = true;
- }
- writeEnumInitialization(s, cppEnum, errorReturn);
+ ConfigurableScope configScope(s, cppEnum.typeEntry());
+ etypeUsed |= writeEnumInitialization(s, cppEnum);
}
+ if (preambleWritten && !etypeUsed)
+ s << sbkUnusedVariableCast("EType");
}
-static QString mangleName(QString name)
+static qsizetype maxLineLength(const QStringList &list)
{
- if (name == u"None" || name == u"False" || name == u"True")
- name += u'_';
- return name;
+ qsizetype result = 0;
+ for (const auto &s : list) {
+ if (auto len = s.size(); len > result)
+ result = len;
+ }
+ return result;
}
-void CppGenerator::writeEnumInitialization(TextStream &s, const AbstractMetaEnum &cppEnum,
- ErrorReturn errorReturn) const
+bool CppGenerator::writeEnumInitialization(TextStream &s, const AbstractMetaEnum &cppEnum)
{
- const AbstractMetaClass *enclosingClass = cppEnum.targetLangEnclosingClass();
- bool hasUpperEnclosingClass = enclosingClass
- && enclosingClass->targetLangEnclosingClass() != nullptr;
+ const auto enclosingClass = cppEnum.targetLangEnclosingClass();
+ const bool hasUpperEnclosingClass = enclosingClass
+ && enclosingClass->targetLangEnclosingClass();
EnumTypeEntryCPtr enumTypeEntry = cppEnum.typeEntry();
QString enclosingObjectVariable;
if (enclosingClass)
@@ -5692,96 +5258,115 @@ void CppGenerator::writeEnumInitialization(TextStream &s, const AbstractMetaEnum
s << (cppEnum.isAnonymous() ? "anonymous enum identified by enum value" : "enum");
s << " '" << cppEnum.name() << "'.\n";
- QString enumVarTypeObj = cpythonTypeNameExt(enumTypeEntry);
- if (!cppEnum.isAnonymous()) {
- int packageLevel = packageName().count(u'.') + 1;
- FlagsTypeEntryPtr flags = enumTypeEntry->flags();
- if (!flags.isNull()) {
- // The following could probably be made nicer:
- // We need 'flags->flagsName()' with the full module/class path.
- QString fullPath = getClassTargetFullName(cppEnum);
- fullPath.truncate(fullPath.lastIndexOf(u'.') + 1);
- s << "FType = PySide::QFlags::create(\""
- << packageLevel << ':' << fullPath << flags->flagsName() << "\", \n" << indent
- << cpythonEnumName(cppEnum) << "_number_slots);\n" << outdent
- << cpythonTypeNameExt(flags) << " = FType;\n";
+ const QString userType = cppEnum.typeEntry()->cppType();
+ const bool isSigned = cppEnum.isSigned() && !userType.contains(u"unsigned"_s);
+ const bool isAccessible = !avoidProtectedHack() || !cppEnum.isProtected();
+ const auto enumValues = cppEnum.nonRejectedValues();
+
+ const QString prefix = cppEnum.name();
+
+ const QString intType = userType.isEmpty() ? cppEnum.underlyingType() : userType;
+
+ // Create a list of values
+ const QString initializerValues = prefix + u"_InitializerValues"_s;
+ const QString initializerName = prefix + u"_Initializer"_s;
+
+ // Build maybe array of enum names.
+ if (cppEnum.enumKind() != AnonymousEnum) {
+ s << "const char *" << initializerName << "[] = {\n" << indent;
+ for (const auto &enumValue : enumValues) {
+ QString name = mangleName(enumValue.name());
+ s << '\"' << name << "\",\n";
}
+ s << "nullptr};\n" << outdent;
+ }
- s << "EType = Shiboken::Enum::"
- << ((enclosingClass
- || hasUpperEnclosingClass) ? "createScopedEnum" : "createGlobalEnum")
- << '(' << enclosingObjectVariable << ',' << '\n' << indent
- << '"' << cppEnum.name() << "\",\n"
- << '"' << packageLevel << ':' << getClassTargetFullName(cppEnum) << "\",\n"
- << '"' << cppEnum.qualifiedCppName() << '"';
- if (flags)
- s << ",\nFType";
- s << ");\n" << outdent
- << "if (!EType)\n"
- << indent << errorReturn << outdent << '\n';
- }
-
- for (const AbstractMetaEnumValue &enumValue : cppEnum.values()) {
- if (enumTypeEntry->isEnumValueRejected(enumValue.name()))
- continue;
+ int targetHexLen = 0;
+ QString usedIntType = userType;
+ if (usedIntType.isEmpty()) {
+ const int usedBits = cppEnum.usedBits();
+ targetHexLen = usedBits / 4;
+ usedIntType = AbstractMetaEnum::intTypeForSize(usedBits, cppEnum.isSigned());
+ }
- QString enumValueText;
- if (!avoidProtectedHack() || !cppEnum.isProtected()) {
- enumValueText = cppEnum.typeEntry()->cppType();
- if (enumValueText.isEmpty())
- enumValueText = u"Shiboken::Enum::EnumValueType"_s;
- enumValueText += u'(';
- if (cppEnum.enclosingClass())
- enumValueText += cppEnum.enclosingClass()->qualifiedCppName() + u"::"_s;
- // Fully qualify the value which is required for C++ 11 enum classes.
- if (!cppEnum.isAnonymous())
- enumValueText += cppEnum.name() + u"::"_s;
- enumValueText += enumValue.name();
- enumValueText += u')';
- } else {
- enumValueText += enumValue.value().toString();
+ if (usedIntType != intType)
+ s << "// \"" << usedIntType << "\" used instead of \"" << intType << "\"\n";
+
+ // Calculating formatting columns
+ QString enumValuePrefix;
+ if (isAccessible) {
+ if (cppEnum.enclosingClass())
+ enumValuePrefix += cppEnum.enclosingClass()->qualifiedCppName() + u"::"_s;
+ if (!cppEnum.isAnonymous())
+ enumValuePrefix += cppEnum.name() + u"::"_s;
+ }
+
+ // Build array of enum values
+ if (enumValues.isEmpty()) {
+ s << "const " << usedIntType << " *" << initializerValues << "{};\n";
+ } else {
+ QStringList values;
+ values.reserve(enumValues.size());
+ s << "constexpr " << usedIntType << ' ' << initializerValues << "[] = {\n" << indent;
+ for (qsizetype idx = 0, last = enumValues.size() - 1; idx <= last; ++idx) {
+ const auto &enumValue = enumValues.at(idx);
+ QString line = usedIntType + u'(' + (isAccessible
+ ? enumValuePrefix + enumValue.name()
+ : enumValue.value().toString()) + u')';
+ if (idx != last)
+ line += u',';
+ values.append(line);
}
- const QString mangledName = mangleName(enumValue.name());
- switch (cppEnum.enumKind()) {
- case AnonymousEnum:
+ const auto len = maxLineLength(values) + 1;
+ for (qsizetype idx = 0, size = enumValues.size(); idx < size; ++idx) {
+ const auto &enumValue = enumValues.at(idx).value();
+ const char *numberSpace = enumValue.isNegative() ? " " : " ";
+ s << values.at(idx) << Pad(' ', len - values.at(idx).size())
+ << "//" << numberSpace << enumValue.toHex(targetHexLen)
+ << numberSpace << enumValue.toString() << '\n';
+ }
+ s << "};\n" << outdent;
+ }
+
+ // Build initialization of anonymous enums
+ if (cppEnum.enumKind() == AnonymousEnum) {
+ int idx = 0;
+ for (const auto &enumValue : enumValues) {
+ const QString mangledName = mangleName(enumValue.name());
+ const QString pyValue = initializerValues + u'[' + QString::number(idx++) + u']';
if (enclosingClass || hasUpperEnclosingClass) {
- s << "{\n" << indent
- << "PyObject *anonEnumItem = PyLong_FromLong(" << enumValueText << ");\n"
- << "if (PyDict_SetItemString(reinterpret_cast<PyTypeObject *>("
- << enclosingObjectVariable
- << ")->tp_dict, \"" << mangledName << "\", anonEnumItem) < 0)\n"
- << indent << errorReturn << outdent
- << "Py_DECREF(anonEnumItem);\n" << outdent
- << "}\n";
+ s << "tpDict.reset(PepType_GetDict(reinterpret_cast<PyTypeObject *>("
+ << enclosingObjectVariable << ")));\n"
+ << "PyDict_SetItemString(tpDict.object(), \"" << mangledName << "\",\n"
+ << indent << (isSigned ? "PyLong_FromLongLong" : "PyLong_FromUnsignedLongLong")
+ << "(" << pyValue << "));\n" << outdent;
} else {
- s << "if (PyModule_AddIntConstant(module, \"" << mangledName << "\", ";
- s << enumValueText << ") < 0)\n" << indent << errorReturn << outdent;
+ s << "PyModule_AddObject(module, \"" << mangledName << "\",\n" << indent
+ << (isSigned ? "PyLong_FromLongLong" : "PyLong_FromUnsignedLongLong") << "("
+ << pyValue << "));\n" << outdent;
}
- break;
- case CEnum:
- s << "if (!Shiboken::Enum::";
- s << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnumItem"
- : "createGlobalEnumItem");
- s << '(' << "EType" << ',' << '\n' << indent
- << enclosingObjectVariable << ", \"" << mangledName << "\", "
- << enumValueText << "))\n" << errorReturn << outdent;
- break;
- case EnumClass:
- s << "if (!Shiboken::Enum::createScopedEnumItem("
- << "EType" << ",\n" << indent
- << "EType" << ", \"" << mangledName << "\", "
- << enumValueText << "))\n" << errorReturn << outdent;
- break;
}
}
- s << "// PYSIDE-1735: Resolving the whole enum class at the end for API compatibility.\n"
- << "EType = morphLastEnumToPython();\n"
- << enumVarTypeObj << " = EType;\n";
+
+ bool etypeUsed = false;
+
+ QString enumVarTypeObj = cpythonTypeNameExtSet(enumTypeEntry);
+ if (!cppEnum.isAnonymous()) {
+ int packageLevel = packageName().count(u'.') + 1;
+ s << "EType = Shiboken::Enum::"
+ << "createPythonEnum"
+ << '(' << enclosingObjectVariable << ",\n" << indent
+ << '"' << packageLevel << ':' << getClassTargetFullName(cppEnum) << "\",\n"
+ << initializerName << ", " << initializerValues << ");\n" << outdent
+ << enumVarTypeObj << " = EType;\n";
+ etypeUsed = true;
+ }
+
if (cppEnum.typeEntry()->flags()) {
s << "// PYSIDE-1735: Mapping the flags class to the same enum class.\n"
- << cpythonTypeNameExt(cppEnum.typeEntry()->flags()) << " =\n"
- << indent << "mapFlagsToSameEnum(FType, EType);\n" << outdent;
+ << cpythonTypeNameExtSet(cppEnum.typeEntry()->flags()) << " =\n"
+ << indent << "EType;\n" << outdent;
}
writeEnumConverterInitialization(s, cppEnum);
@@ -5789,9 +5374,11 @@ void CppGenerator::writeEnumInitialization(TextStream &s, const AbstractMetaEnum
if (cppEnum.typeEntry()->flags())
s << "/flags";
s << ".\n\n";
+
+ return etypeUsed;
}
-void CppGenerator::writeSignalInitialization(TextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeSignalInitialization(TextStream &s, const AbstractMetaClassCPtr &metaClass)
{
// Try to check something and print some warnings
const auto &signalFuncs = metaClass->cppSignalFunctions();
@@ -5813,136 +5400,11 @@ void CppGenerator::writeSignalInitialization(TextStream &s, const AbstractMetaCl
}
}
- s << "PySide::Signal::registerSignals(pyType, &::"
+ s << "PySide::Signal::registerSignals(pyType, &" << m_gsp
<< metaClass->qualifiedCppName() << "::staticMetaObject);\n";
}
-void CppGenerator::writeFlagsToLong(TextStream &s, const AbstractMetaEnum &cppEnum)
-{
- FlagsTypeEntryPtr flagsEntry = cppEnum.typeEntry()->flags();
- if (!flagsEntry)
- return;
- s << "static PyObject *" << cpythonEnumName(cppEnum) << "_long(PyObject *self)\n"
- << "{\n" << indent
- << "int val;\n";
- AbstractMetaType flagsType = AbstractMetaType::fromTypeEntry(flagsEntry);
- s << cpythonToCppConversionFunction(flagsType) << "self, &val);\n"
- << "return Shiboken::Conversions::copyToPython(Shiboken::Conversions::PrimitiveTypeConverter<int>(), &val);\n"
- << outdent << "}\n";
-}
-
-void CppGenerator::writeFlagsNonZero(TextStream &s, const AbstractMetaEnum &cppEnum)
-{
- FlagsTypeEntryPtr flagsEntry = cppEnum.typeEntry()->flags();
- if (flagsEntry.isNull())
- return;
- s << "static int " << cpythonEnumName(cppEnum) << "__nonzero(PyObject *self)\n";
- s << "{\n" << indent << "int val;\n";
- AbstractMetaType flagsType = AbstractMetaType::fromTypeEntry(flagsEntry);
- s << cpythonToCppConversionFunction(flagsType) << "self, &val);\n"
- << "return val != 0;\n"
- << outdent << "}\n";
-}
-
-void CppGenerator::writeFlagsMethods(TextStream &s, const AbstractMetaEnum &cppEnum)
-{
- writeFlagsBinaryOperator(s, cppEnum, u"and"_s, u"&"_s);
- writeFlagsBinaryOperator(s, cppEnum, u"or"_s, u"|"_s);
- writeFlagsBinaryOperator(s, cppEnum, u"xor"_s, u"^"_s);
-
- writeFlagsUnaryOperator(s, cppEnum, u"invert"_s, u"~"_s);
- writeFlagsToLong(s, cppEnum);
- writeFlagsNonZero(s, cppEnum);
-
- s << '\n';
-}
-
-void CppGenerator::writeFlagsNumberMethodsDefinition(TextStream &s, const AbstractMetaEnum &cppEnum)
-{
- QString cpythonName = cpythonEnumName(cppEnum);
-
- s << "static PyType_Slot " << cpythonName << "_number_slots[] = {\n" << indent
- << "{Py_nb_bool, reinterpret_cast<void *>(" << cpythonName << "__nonzero)},\n"
- << "{Py_nb_invert, reinterpret_cast<void *>(" << cpythonName << "___invert__)},\n"
- << "{Py_nb_and, reinterpret_cast<void *>(" << cpythonName << "___and__)},\n"
- << "{Py_nb_xor, reinterpret_cast<void *>(" << cpythonName << "___xor__)},\n"
- << "{Py_nb_or, reinterpret_cast<void *>(" << cpythonName << "___or__)},\n"
- << "{Py_nb_int, reinterpret_cast<void *>(" << cpythonName << "_long)},\n"
- << "{Py_nb_index, reinterpret_cast<void *>(" << cpythonName << "_long)},\n"
- << "{0, " << NULL_PTR << "} // sentinel\n" << outdent
- << "};\n\n";
-}
-
-void CppGenerator::writeFlagsNumberMethodsDefinitions(TextStream &s,
- const AbstractMetaEnumList &enums)
-{
- for (const AbstractMetaEnum &e : enums) {
- if (!e.isAnonymous() && !e.isPrivate() && e.typeEntry()->flags()) {
- writeFlagsMethods(s, e);
- writeFlagsNumberMethodsDefinition(s, e);
- s << '\n';
- }
- }
-}
-
-void CppGenerator::writeFlagsBinaryOperator(TextStream &s, const AbstractMetaEnum &cppEnum,
- const QString &pyOpName, const QString &cppOpName)
-{
- FlagsTypeEntryPtr flagsEntry = cppEnum.typeEntry()->flags();
- Q_ASSERT(!flagsEntry.isNull());
-
- s << "PyObject *" << cpythonEnumName(cppEnum) << "___" << pyOpName
- << "__(PyObject *self, PyObject *" << PYTHON_ARG << ")\n{\n" << indent;
-
- AbstractMetaType flagsType = AbstractMetaType::fromTypeEntry(flagsEntry);
- s << "::" << flagsEntry->originalName() << " cppResult, " << CPP_SELF_VAR
- << ", cppArg;\n"
- << CPP_SELF_VAR << " = static_cast<::" << flagsEntry->originalName()
- << ">(int(PyLong_AsLong(self)));\n"
- // PYSIDE-1436: Need to error check self as well because operators are used
- // sometimes with swapped args.
- << "if (PyErr_Occurred())\n" << indent
- << "return nullptr;\n" << outdent
- << "cppArg = static_cast<" << flagsEntry->originalName()
- << ">(int(PyLong_AsLong(" << PYTHON_ARG << ")));\n"
- << "if (PyErr_Occurred())\n" << indent
- << "return nullptr;\n" << outdent
- << "cppResult = " << CPP_SELF_VAR << " " << cppOpName << " cppArg;\n"
- << "return ";
- writeToPythonConversion(s, flagsType, nullptr, u"cppResult"_s);
- s << ";\n" << outdent << "}\n\n";
-}
-
-void CppGenerator::writeFlagsUnaryOperator(TextStream &s, const AbstractMetaEnum &cppEnum,
- const QString &pyOpName,
- const QString &cppOpName, bool boolResult)
-{
- FlagsTypeEntryPtr flagsEntry = cppEnum.typeEntry()->flags();
- Q_ASSERT(flagsEntry);
-
- s << "PyObject *" << cpythonEnumName(cppEnum) << "___" << pyOpName
- << "__(PyObject *self, PyObject *" << PYTHON_ARG << ")\n{\n" << indent;
- if (cppOpName == u"~")
- s << sbkUnusedVariableCast(PYTHON_ARG);
-
- AbstractMetaType flagsType = AbstractMetaType::fromTypeEntry(flagsEntry);
- s << "::" << flagsEntry->originalName() << " " << CPP_SELF_VAR << ";\n"
- << cpythonToCppConversionFunction(flagsType) << "self, &" << CPP_SELF_VAR
- << ");\n";
- if (boolResult)
- s << "bool";
- else
- s << "::" << flagsEntry->originalName();
- s << " cppResult = " << cppOpName << CPP_SELF_VAR << ";\n"
- << "return ";
- if (boolResult)
- s << "PyBool_FromLong(cppResult)";
- else
- writeToPythonConversion(s, flagsType, nullptr, u"cppResult"_s);
- s << ";\n" << outdent << "}\n\n";
-}
-
-QString CppGenerator::getSimpleClassInitFunctionName(const AbstractMetaClass *metaClass)
+QString CppGenerator::getSimpleClassInitFunctionName(const AbstractMetaClassCPtr &metaClass)
{
QString initFunctionName;
// Disambiguate namespaces per module to allow for extending them.
@@ -5953,7 +5415,8 @@ QString CppGenerator::getSimpleClassInitFunctionName(const AbstractMetaClass *me
return initFunctionName;
}
-QString CppGenerator::getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClass *metaClass)
+QString
+ CppGenerator::getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClassCPtr &metaClass)
{
return u"init_"_s + getSimpleClassInitFunctionName(metaClass)
+ u"StaticFields"_s;
@@ -5984,8 +5447,8 @@ void CppGenerator::writeSignatureStrings(TextStream &s,
}
// Return the class name for which to invoke the destructor
-QString CppGenerator::destructorClassName(const AbstractMetaClass *metaClass,
- const GeneratorContext &classContext) const
+QString CppGenerator::destructorClassName(const AbstractMetaClassCPtr &metaClass,
+ const GeneratorContext &classContext)
{
if (metaClass->isNamespace() || metaClass->hasPrivateDestructor())
return {};
@@ -6002,14 +5465,69 @@ QString CppGenerator::destructorClassName(const AbstractMetaClass *metaClass,
return metaClass->qualifiedCppName();
}
+// Return the base type entries for introduceWrapperType()
+static ComplexTypeEntryCList pyBaseTypeEntries(const AbstractMetaClassCPtr &metaClass)
+{
+ ComplexTypeEntryCList result;
+ if (metaClass->isNamespace()) {
+ if (auto extended = metaClass->extendedNamespace())
+ result.append(extended->typeEntry());
+ return result;
+ }
+
+ const auto &baseClasses = metaClass->typeSystemBaseClasses();
+ for (auto base : baseClasses) {
+ for (; base != nullptr; base = base->baseClass()) { // Find a type that is not disabled.
+ const auto ct = base->typeEntry()->codeGeneration();
+ if (ct == TypeEntry::GenerateCode || ct == TypeEntry::GenerateForSubclass)
+ break;
+ }
+ result.append(base->typeEntry());
+ }
+ return result;
+}
+
+// Return the base type strings for introduceWrapperType()
+QStringList CppGenerator::pyBaseTypes(const AbstractMetaClassCPtr &metaClass)
+{
+ const auto &baseEntries = pyBaseTypeEntries(metaClass);
+ QStringList result;
+ for (const auto &baseEntry : baseEntries)
+ result.append("reinterpret_cast<PyObject *>("_L1 + cpythonTypeNameExt(baseEntry) + u')');
+ if (result.isEmpty()) // no base classes -> SbkObjectType.
+ result.append(sbkObjectTypeF);
+ return result;
+}
+
+void CppGenerator::writeInitInheritance(TextStream &s) const
+{
+ s << "static void " << initInheritanceFunction << "()\n{\n" << indent
+ << "auto &bm = Shiboken::BindingManager::instance();\n"
+ << sbkUnusedVariableCast("bm");
+ for (const auto &cls : api().classes()){
+ auto te = cls->typeEntry();
+ if (shouldGenerate(te)) {
+ const auto &baseEntries = pyBaseTypeEntries(cls);
+ if (!baseEntries.isEmpty()) {
+ const QString childTypeInitStruct = typeInitStruct(cls->typeEntry());
+ for (const auto &baseEntry : baseEntries) {
+ s << "bm.addClassInheritance(&" << typeInitStruct(baseEntry) << ",\n"
+ << Pad(' ', 23) << '&' << childTypeInitStruct << ");\n";
+ }
+ }
+ }
+ }
+ s << outdent << "}\n\n";
+}
+
void CppGenerator::writeClassRegister(TextStream &s,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext,
const QString &signatures) const
{
ComplexTypeEntryCPtr classTypeEntry = metaClass->typeEntry();
- const AbstractMetaClass *enc = metaClass->targetLangEnclosingClass();
+ AbstractMetaClassCPtr enc = metaClass->targetLangEnclosingClass();
QString enclosingObjectVariable = enc ? u"enclosingClass"_s : u"module"_s;
QString pyTypeName = cpythonTypeName(metaClass);
@@ -6017,23 +5535,26 @@ void CppGenerator::writeClassRegister(TextStream &s,
// PYSIDE-510: Create a signatures string for the introspection feature.
writeSignatureStrings(s, signatures, initFunctionName, "functions");
- s << "void init_" << initFunctionName;
- s << "(PyObject *" << enclosingObjectVariable << ")\n{\n" << indent;
+ s << "PyTypeObject *init_" << initFunctionName
+ << "(PyObject *" << enclosingObjectVariable << ")\n{\n" << indent;
+
+ const QString globalTypeVarExpr = !classContext.forSmartPointer()
+ ? cpythonTypeNameExtSet(classTypeEntry)
+ : cpythonTypeNameExtSet(classContext.preciseType());
+ s << "if (" << globalTypeVarExpr << " != nullptr)\n" << indent
+ << "return " << globalTypeVarExpr << ";\n\n" << outdent;
// Multiple inheritance
QString pyTypeBasesVariable = chopType(pyTypeName) + u"_Type_bases"_s;
- const auto &baseClasses = metaClass->typeSystemBaseClasses();
- if (metaClass->baseClassNames().size() > 1) {
- s << "PyObject *" << pyTypeBasesVariable
- << " = PyTuple_Pack(" << baseClasses.size() << ',' << '\n' << indent;
- for (qsizetype i = 0, size = baseClasses.size(); i < size; ++i) {
- if (i)
- s << ",\n";
- s << "reinterpret_cast<PyObject *>("
- << cpythonTypeNameExt(baseClasses.at(i)->typeEntry()) << ')';
- }
- s << ");\n\n" << outdent;
+ const QStringList pyBases = pyBaseTypes(metaClass);
+ s << "Shiboken::AutoDecRef " << pyTypeBasesVariable << "(PyTuple_Pack("
+ << pyBases.size() << ",\n" << indent;
+ for (qsizetype i = 0, size = pyBases.size(); i < size; ++i) {
+ if (i)
+ s << ",\n";
+ s << pyBases.at(i);
}
+ s << "));\n\n" << outdent;
// Create type and insert it in the module or enclosing class.
const QString typePtr = u"_"_s + chopType(pyTypeName)
@@ -6065,29 +5586,11 @@ void CppGenerator::writeClassRegister(TextStream &s,
if (dtorClassName.isEmpty())
s << "nullptr,\n";
else
- s << "&Shiboken::callCppDestructor< ::" << dtorClassName << " >,\n";
-
- // 6:baseType: Find a type that is not disabled.
- auto base = metaClass->isNamespace()
- ? metaClass->extendedNamespace() : metaClass->baseClass();
- if (!metaClass->isNamespace()) {
- for (; base != nullptr; base = base->baseClass()) {
- const auto ct = base->typeEntry()->codeGeneration();
- if (ct == TypeEntry::GenerateCode || ct == TypeEntry::GenerateForSubclass)
- break;
- }
- }
- if (base) {
- s << cpythonTypeNameExt(base->typeEntry()) << ",\n";
- } else {
- s << "0,\n";
- }
+ s << "&Shiboken::callCppDestructor< " << globalScopePrefix(classContext)
+ << dtorClassName << " >,\n";
// 7:baseTypes
- if (metaClass->baseClassNames().size() > 1)
- s << pyTypeBasesVariable << ',' << '\n';
- else
- s << "0,\n";
+ s << pyTypeBasesVariable << ".object()," << '\n';
// 8:wrapperflags
QByteArrayList wrapperFlags;
@@ -6095,6 +5598,8 @@ void CppGenerator::writeClassRegister(TextStream &s,
wrapperFlags.append(QByteArrayLiteral("Shiboken::ObjectType::WrapperFlags::InnerClass"));
if (metaClass->deleteInMainThread())
wrapperFlags.append(QByteArrayLiteral("Shiboken::ObjectType::WrapperFlags::DeleteInMainThread"));
+ if (classTypeEntry->isValue())
+ wrapperFlags.append("Shiboken::ObjectType::WrapperFlags::Value"_ba);
if (wrapperFlags.isEmpty())
s << '0';
else
@@ -6107,11 +5612,7 @@ void CppGenerator::writeClassRegister(TextStream &s,
if (usePySideExtensions() && !classContext.forSmartPointer())
s << "SbkObjectType_SetPropertyStrings(pyType, "
<< chopType(pyTypeName) << "_PropertyStrings);\n";
-
- if (!classContext.forSmartPointer())
- s << cpythonTypeNameExt(classTypeEntry) << " = pyType;\n\n";
- else
- s << cpythonTypeNameExt(classContext.preciseType()) << " = pyType;\n\n";
+ s << globalTypeVarExpr << " = pyType;\n\n";
// Register conversions for the type.
writeConverterRegister(s, metaClass, classContext);
@@ -6126,7 +5627,7 @@ void CppGenerator::writeClassRegister(TextStream &s,
}
// Fill multiple inheritance data, if needed.
- const AbstractMetaClass *miClass = getMultipleInheritingClass(metaClass);
+ const auto miClass = getMultipleInheritingClass(metaClass);
if (miClass) {
s << "MultipleInheritanceInitFunction func = ";
if (miClass == metaClass) {
@@ -6143,8 +5644,9 @@ void CppGenerator::writeClassRegister(TextStream &s,
// Set typediscovery struct or fill the struct of another one
if (needsTypeDiscoveryFunction(metaClass)) {
- s << "Shiboken::ObjectType::setTypeDiscoveryFunctionV2(" << cpythonTypeName(metaClass)
- << ", &" << cpythonBaseName(metaClass) << "_typeDiscovery);\n\n";
+ s << "Shiboken::ObjectType::setTypeDiscoveryFunctionV2(\n" << indent
+ << cpythonTypeName(metaClass)
+ << ", &" << cpythonBaseName(metaClass) << "_typeDiscovery);" << outdent << "\n\n";
}
AbstractMetaEnumList classEnums = metaClass->enums();
@@ -6154,7 +5656,7 @@ void CppGenerator::writeClassRegister(TextStream &s,
s << "// Pass the ..._EnumFlagInfo to the class.\n"
<< "SbkObjectType_SetEnumFlagInfo(pyType, " << chopType(pyTypeName)
<< "_EnumFlagInfo);\n\n";
- writeEnumsInitialization(s, classEnums, ErrorReturn::Void);
+ writeEnumsInitialization(s, classEnums);
if (metaClass->hasSignals())
writeSignalInitialization(s, metaClass);
@@ -6174,25 +5676,40 @@ void CppGenerator::writeClassRegister(TextStream &s,
writeInitQtMetaTypeFunctionBody(s, classContext);
}
- if (usePySideExtensions() && metaClass->isQObject()) {
+ if (usePySideExtensions() && isQObject(metaClass)) {
s << "Shiboken::ObjectType::setSubTypeInitHook(pyType, &PySide::initQObjectSubType);\n"
- << "PySide::initDynamicMetaObject(pyType, &::"
- << metaClass->qualifiedCppName() << "::staticMetaObject, sizeof(";
- if (shouldGenerateCppWrapper(metaClass))
- s << wrapperName(metaClass);
- else
- s << "::" << metaClass->qualifiedCppName();
- s << "));\n";
+ << "PySide::initDynamicMetaObject(pyType, &" << m_gsp
+ << metaClass->qualifiedCppName() << "::staticMetaObject, sizeof("
+ << (shouldGenerateCppWrapper(metaClass)
+ ? wrapperName(metaClass) : getFullTypeName(metaClass))
+ << "));\n";
}
- s << outdent << "}\n";
+ s << "\nreturn pyType;\n" << outdent << "}\n";
}
-void CppGenerator::writeStaticFieldInitialization(TextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeStaticFieldInitialization(TextStream &s,
+ const AbstractMetaClassCPtr &metaClass)
{
- s << "\nvoid " << getSimpleClassStaticFieldsInitFunctionName(metaClass)
- << "()\n{\n" << indent << "auto dict = reinterpret_cast<PyTypeObject *>("
- << cpythonTypeName(metaClass) << ")->tp_dict;\n";
+ // cpythonTypeName == "Sbk_QRhiShaderResourceBinding_Data_TypeF"
+ QString name = cpythonTypeName(metaClass);
+ const auto parts = QStringView{name}.split(u'_', Qt::SkipEmptyParts);
+ if (parts.size() < 4) {
+ s << "\nPyTypeObject *" << getSimpleClassStaticFieldsInitFunctionName(metaClass)
+ << "(PyObject *module)\n{\n" << indent
+ << "auto *obType = PyObject_GetAttrString(module, \"" << metaClass->name() << "\");\n"
+ << "auto *type = reinterpret_cast<PyTypeObject *>(obType);\n"
+ << "Shiboken::AutoDecRef dict(PepType_GetDict(type));\n";
+ } else {
+ s << "\nPyTypeObject *" << getSimpleClassStaticFieldsInitFunctionName(metaClass)
+ << "(PyObject *module)\n{\n" << indent
+ << "auto *obContainerType = PyObject_GetAttrString(module, \""
+ << parts.at(1) << "\");\n"
+ << "auto *obType = PyObject_GetAttrString(obContainerType, \""
+ << parts.at(2) << "\");\n"
+ << "auto *type = reinterpret_cast<PyTypeObject *>(obType);\n"
+ << "Shiboken::AutoDecRef dict(PepType_GetDict(type));\n";
+ }
for (const AbstractMetaField &field : metaClass->fields()) {
if (field.isStatic()) {
s << "PyDict_SetItemString(dict, \"" << field.name()
@@ -6201,7 +5718,7 @@ void CppGenerator::writeStaticFieldInitialization(TextStream &s, const AbstractM
s << ");\n";
}
}
- s << '\n' << outdent << "}\n";
+ s << "return type;\n" << outdent << "}\n";
}
enum class QtRegisterMetaType
@@ -6209,7 +5726,7 @@ enum class QtRegisterMetaType
None, Pointer, Value
};
-static bool hasQtMetaTypeRegistrationSpec(const AbstractMetaClass *c)
+static bool hasQtMetaTypeRegistrationSpec(const AbstractMetaClassCPtr &c)
{
return c->typeEntry()->qtMetaTypeRegistration() !=
TypeSystem::QtMetaTypeRegistration::Unspecified;
@@ -6218,7 +5735,7 @@ static bool hasQtMetaTypeRegistrationSpec(const AbstractMetaClass *c)
// Returns if and how to register the Qt meta type. By default, "pointer" for
// non-QObject object types and "value" for non-abstract, default-constructible
// value types.
-QtRegisterMetaType qtMetaTypeRegistration(const AbstractMetaClass *c)
+QtRegisterMetaType qtMetaTypeRegistration(const AbstractMetaClassCPtr &c)
{
if (c->isNamespace())
return QtRegisterMetaType::None;
@@ -6237,7 +5754,7 @@ QtRegisterMetaType qtMetaTypeRegistration(const AbstractMetaClass *c)
// Is there a "base" specification in some base class, meaning only the
// base class is to be registered?
- if (auto *base = recurseClassHierarchy(c, hasQtMetaTypeRegistrationSpec)) {
+ if (auto base = recurseClassHierarchy(c, hasQtMetaTypeRegistrationSpec)) {
const auto baseSpec = base->typeEntry()->qtMetaTypeRegistration();
if (baseSpec == TypeSystem::QtMetaTypeRegistration::BaseEnabled)
return QtRegisterMetaType::None;
@@ -6245,7 +5762,7 @@ QtRegisterMetaType qtMetaTypeRegistration(const AbstractMetaClass *c)
// Default.
if (isObject)
- return c->isQObject() ? QtRegisterMetaType::None : QtRegisterMetaType::Pointer;
+ return isQObject(c) ? QtRegisterMetaType::None : QtRegisterMetaType::Pointer;
return !c->isAbstract() && c->isDefaultConstructible()
? QtRegisterMetaType::Value : QtRegisterMetaType::None;
@@ -6253,7 +5770,7 @@ QtRegisterMetaType qtMetaTypeRegistration(const AbstractMetaClass *c)
void CppGenerator::writeInitQtMetaTypeFunctionBody(TextStream &s, const GeneratorContext &context)
{
- const AbstractMetaClass *metaClass = context.metaClass();
+ const auto metaClass = context.metaClass();
// Gets all class name variants used on different possible scopes
QStringList nameVariants;
if (!context.forSmartPointer())
@@ -6261,7 +5778,7 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(TextStream &s, const Generato
else
nameVariants << context.preciseType().cppSignature();
- const AbstractMetaClass *enclosingClass = metaClass->enclosingClass();
+ AbstractMetaClassCPtr enclosingClass = metaClass->enclosingClass();
while (enclosingClass) {
if (enclosingClass->typeEntry()->generateCode())
nameVariants << (enclosingClass->name() + u"::"_s + nameVariants.constLast());
@@ -6280,55 +5797,67 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(TextStream &s, const Generato
case QtRegisterMetaType::None:
break;
case QtRegisterMetaType::Pointer:
- s << "qRegisterMetaType< ::" << className << " *>();\n";
+ s << "qRegisterMetaType< " << m_gsp << className << " *>();\n";
break;
case QtRegisterMetaType::Value:
for (const QString &name : std::as_const(nameVariants))
- s << "qRegisterMetaType< ::" << className << " >(\"" << name << "\");\n";
+ s << "qRegisterMetaType< " << m_gsp << className << " >(\"" << name << "\");\n";
break;
}
for (const AbstractMetaEnum &metaEnum : metaClass->enums()) {
if (!metaEnum.isPrivate() && !metaEnum.isAnonymous()) {
for (const QString &name : std::as_const(nameVariants)) {
- s << "qRegisterMetaType< ::"
+ s << "qRegisterMetaType< " << m_gsp
<< metaEnum.typeEntry()->qualifiedCppName() << " >(\""
<< name << "::" << metaEnum.name() << "\");\n";
}
- if (metaEnum.typeEntry()->flags()) {
- QString n = metaEnum.typeEntry()->flags()->originalName();
- s << "qRegisterMetaType< ::" << n << " >(\"" << n << "\");\n";
- }
}
}
}
-void CppGenerator::writeTypeDiscoveryFunction(TextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::replacePolymorphicIdPlaceHolders(const AbstractMetaClassCPtr &metaClass,
+ QString *id)
+{
+ if (id->contains("%1"_L1)) {
+ QString replacement = " reinterpret_cast< "_L1 + m_gsp + metaClass->qualifiedCppName()
+ + " *>(cptr)"_L1;
+ id->replace("%1"_L1, replacement);
+ }
+ if (id->contains("%B"_L1)) {
+ auto baseClass = metaClass;
+ while (!baseClass->typeEntry()->isPolymorphicBase() && baseClass->baseClass())
+ baseClass = baseClass->baseClass();
+ QString replacement = " reinterpret_cast< "_L1 + m_gsp + baseClass->qualifiedCppName()
+ + " *>(cptr)"_L1;
+ id->replace("%B"_L1, replacement);
+ }
+}
+
+void CppGenerator::writeTypeDiscoveryFunction(TextStream &s,
+ const AbstractMetaClassCPtr &metaClass)
{
QString polymorphicExpr = metaClass->typeEntry()->polymorphicIdValue();
s << "static void *" << cpythonBaseName(metaClass)
<< "_typeDiscovery(void *cptr, PyTypeObject *instanceType)\n{\n" << indent
- << sbkUnusedVariableCast(u"cptr"_s)
- << sbkUnusedVariableCast(u"instanceType"_s);
+ << sbkUnusedVariableCast("cptr")
+ << sbkUnusedVariableCast("instanceType");
if (!polymorphicExpr.isEmpty()) {
- polymorphicExpr = polymorphicExpr.replace(u"%1"_s,
- u" reinterpret_cast< ::"_s
- + metaClass->qualifiedCppName()
- + u" *>(cptr)"_s);
- s << " if (" << polymorphicExpr << ")\n" << indent
+ replacePolymorphicIdPlaceHolders(metaClass, &polymorphicExpr);
+ s << "if (" << polymorphicExpr << ")\n" << indent
<< "return cptr;\n" << outdent;
} else if (metaClass->isPolymorphic()) {
const auto &ancestors = metaClass->allTypeSystemAncestors();
- for (auto *ancestor : ancestors) {
- if (ancestor->baseClass())
+ for (const auto &ancestor : ancestors) {
+ if (ancestor->baseClass() && !ancestor->typeEntry()->isPolymorphicBase())
continue;
if (ancestor->isPolymorphic()) {
- s << "if (instanceType == Shiboken::SbkType< ::"
+ s << "if (instanceType == Shiboken::SbkType< " << m_gsp
<< ancestor->qualifiedCppName() << " >())\n" << indent
- << "return dynamic_cast< ::" << metaClass->qualifiedCppName()
- << " *>(reinterpret_cast< ::"<< ancestor->qualifiedCppName()
+ << "return dynamic_cast< " << getFullTypeName(metaClass)
+ << " *>(reinterpret_cast< "<< getFullTypeName(ancestor)
<< " *>(cptr));\n" << outdent;
} else {
qCWarning(lcShiboken).noquote().nospace()
@@ -6342,7 +5871,8 @@ void CppGenerator::writeTypeDiscoveryFunction(TextStream &s, const AbstractMetaC
s << "return {};\n" << outdent << "}\n\n";
}
-void CppGenerator::writeSetattroDefinition(TextStream &s, const AbstractMetaClass *metaClass) const
+void CppGenerator::writeSetattroDefinition(TextStream &s,
+ const AbstractMetaClassCPtr &metaClass)
{
s << "static int " << ShibokenGenerator::cpythonSetattroFunctionName(metaClass)
<< "(PyObject *self, PyObject *name, PyObject *value)\n{\n" << indent;
@@ -6352,7 +5882,7 @@ void CppGenerator::writeSetattroDefinition(TextStream &s, const AbstractMetaClas
}
}
-inline void CppGenerator::writeSetattroDefaultReturn(TextStream &s)
+void CppGenerator::writeSetattroDefaultReturn(TextStream &s)
{
s << "return PyObject_GenericSetAttr(self, name, value);\n"
<< outdent << "}\n\n";
@@ -6362,7 +5892,7 @@ void CppGenerator::writeSetattroFunction(TextStream &s, AttroCheck attroCheck,
const GeneratorContext &context) const
{
Q_ASSERT(!context.forSmartPointer());
- const AbstractMetaClass *metaClass = context.metaClass();
+ const auto metaClass = context.metaClass();
writeSetattroDefinition(s, metaClass);
// PYSIDE-1019: Switch tp_dict before doing tp_setattro.
@@ -6372,10 +5902,10 @@ void CppGenerator::writeSetattroFunction(TextStream &s, AttroCheck attroCheck,
// PYSIDE-803: Detect duck-punching; clear cache if a method is set.
if (attroCheck.testFlag(AttroCheckFlag::SetattroMethodOverride)
&& context.useWrapper()) {
- s << "if (value && PyCallable_Check(value)) {\n" << indent
- << "auto plain_inst = " << cpythonWrapperCPtr(metaClass, u"self"_s) << ";\n"
- << "auto inst = dynamic_cast<" << context.wrapperName() << " *>(plain_inst);\n"
- << "if (inst)\n" << indent
+ s << "if (value != nullptr && PyCallable_Check(value) != 0) {\n" << indent
+ << "auto plain_inst = " << cpythonWrapperCPtr(metaClass, PYTHON_SELF_VAR) << ";\n"
+ << "auto *inst = dynamic_cast<" << context.wrapperName() << " *>(plain_inst);\n"
+ << "if (inst != nullptr)\n" << indent
<< "inst->resetPyMethodCache();\n" << outdent << outdent
<< "}\n";
}
@@ -6392,7 +5922,7 @@ void CppGenerator::writeSetattroFunction(TextStream &s, AttroCheck attroCheck,
Q_ASSERT(func);
s << "{\n" << indent
<< "auto " << CPP_SELF_VAR << " = "
- << cpythonWrapperCPtr(metaClass, u"self"_s) << ";\n";
+ << cpythonWrapperCPtr(metaClass, PYTHON_SELF_VAR) << ";\n";
writeClassCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionAny,
TypeSystem::TargetLangCode, context);
s << outdent << "}\n";
@@ -6401,26 +5931,7 @@ void CppGenerator::writeSetattroFunction(TextStream &s, AttroCheck attroCheck,
writeSetattroDefaultReturn(s);
}
-static const char smartPtrComment[] =
- "// Try to find the 'name' attribute, by retrieving the PyObject for "
- "the corresponding C++ object held by the smart pointer.\n";
-
-void CppGenerator::writeSmartPointerSetattroFunction(TextStream &s,
- const GeneratorContext &context) const
-{
- Q_ASSERT(context.forSmartPointer());
- writeSetattroDefinition(s, context.metaClass());
- s << smartPtrComment
- << "if (auto *rawObj = PyObject_CallMethod(self, " << SMART_POINTER_GETTER
- << ", 0)) {\n" << indent
- << "if (PyObject_HasAttr(rawObj, name) != 0)\n" << indent
- << "return PyObject_GenericSetAttr(rawObj, name, value);\n" << outdent
- << "Py_DECREF(rawObj);\n" << outdent
- << "}\n";
- writeSetattroDefaultReturn(s);
-}
-
-void CppGenerator::writeGetattroDefinition(TextStream &s, const AbstractMetaClass *metaClass)
+void CppGenerator::writeGetattroDefinition(TextStream &s, const AbstractMetaClassCPtr &metaClass)
{
s << "static PyObject *" << cpythonGetattroFunctionName(metaClass)
<< "(PyObject *self, PyObject *name)\n{\n" << indent;
@@ -6430,10 +5941,10 @@ QString CppGenerator::qObjectGetAttroFunction() const
{
static QString result;
if (result.isEmpty()) {
- auto qobjectClass = AbstractMetaClass::findClass(api().classes(), qObjectT());
+ auto qobjectClass = AbstractMetaClass::findClass(api().classes(), qObjectT);
Q_ASSERT(qobjectClass);
- result = u"PySide::getMetaDataFromQObject("_s
- + cpythonWrapperCPtr(qobjectClass, u"self"_s)
+ result = u"PySide::getHiddenDataFromQObject("_s
+ + cpythonWrapperCPtr(qobjectClass, PYTHON_SELF_VAR)
+ u", self, name)"_s;
}
return result;
@@ -6443,14 +5954,14 @@ void CppGenerator::writeGetattroFunction(TextStream &s, AttroCheck attroCheck,
const GeneratorContext &context) const
{
Q_ASSERT(!context.forSmartPointer());
- const AbstractMetaClass *metaClass = context.metaClass();
+ const auto metaClass = context.metaClass();
writeGetattroDefinition(s, metaClass);
// PYSIDE-1019: Switch tp_dict before doing tp_getattro.
if (usePySideExtensions())
s << "PySide::Feature::Select(self);\n";
- const QString getattrFunc = usePySideExtensions() && metaClass->isQObject()
+ const QString getattrFunc = usePySideExtensions() && isQObject(metaClass)
? qObjectGetAttroFunction() : u"PyObject_GenericGetAttr(self, name)"_s;
if (attroCheck.testFlag(AttroCheckFlag::GetattroOverloads)) {
@@ -6462,11 +5973,14 @@ void CppGenerator::writeGetattroFunction(TextStream &s, AttroCheck attroCheck,
<< "if (Shiboken::Object::isUserType(self)) {\n" << indent;
// PYSIDE-772: Perform optimized name mangling.
s << "Shiboken::AutoDecRef tmp(_Pep_PrivateMangle(self, name));\n"
- << "if (auto *meth = PyDict_GetItem(Py_TYPE(self)->tp_dict, tmp)) {\n" << indent;
+ << "Shiboken::AutoDecRef tpDict(PepType_GetDict(Py_TYPE(self)));\n"
+ << "if (auto *meth = PyDict_GetItem(tpDict.object(), tmp)) {\n" << indent;
// PYSIDE-1523: PyFunction_Check is not accepting compiled functions.
- s << "if (std::strcmp(Py_TYPE(meth)->tp_name, \"compiled_function\") == 0)\n" << indent
- << "return Py_TYPE(meth)->tp_descr_get(meth, self, nullptr);\n" << outdent
- << "return PyFunction_Check(meth) ? PyMethod_New(meth, self)\n"
+ s << "if (std::strcmp(Py_TYPE(meth)->tp_name, \"compiled_function\") == 0) {\n" << indent
+ << "auto descrGetFunc = "
+ << pyTypeGetSlot("descrgetfunc", "Py_TYPE(meth)", "Py_tp_descr_get") << ";\n"
+ << "return descrGetFunc(meth, self, nullptr);\n" << outdent
+ << "}\nreturn PyFunction_Check(meth) ? PyMethod_New(meth, self)\n"
<< " : " << getattrFunc << ";\n" << outdent
<< "}\n" << outdent << "}\n";
@@ -6492,7 +6006,7 @@ void CppGenerator::writeGetattroFunction(TextStream &s, AttroCheck attroCheck,
Q_ASSERT(func);
s << "{\n" << indent
<< "auto " << CPP_SELF_VAR << " = "
- << cpythonWrapperCPtr(metaClass, u"self"_s) << ";\n";
+ << cpythonWrapperCPtr(metaClass, PYTHON_SELF_VAR) << ";\n";
writeClassCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionAny,
TypeSystem::TargetLangCode, context);
s << outdent << "}\n";
@@ -6501,50 +6015,6 @@ void CppGenerator::writeGetattroFunction(TextStream &s, AttroCheck attroCheck,
s << "return " << getattrFunc << ";\n" << outdent << "}\n\n";
}
-void CppGenerator::writeSmartPointerGetattroFunction(TextStream &s,
- const GeneratorContext &context,
- const BoolCastFunctionOptional &boolCast)
-{
- Q_ASSERT(context.forSmartPointer());
- const AbstractMetaClass *metaClass = context.metaClass();
- writeGetattroDefinition(s, metaClass);
- s << "PyObject *tmp = PyObject_GenericGetAttr(self, name);\n"
- << "if (tmp)\n" << indent << "return tmp;\n" << outdent
- << "if (PyErr_ExceptionMatches(PyExc_AttributeError) == 0)\n"
- << indent << "return nullptr;\n" << outdent
- << "PyErr_Clear();\n";
-
- if (boolCast.has_value()) {
- writeSmartPointerCppSelfDefinition(s, context);
- s << "if (";
- writeNbBoolExpression(s, boolCast.value(), true /* invert */);
- s << ") {\n" << indent
- << R"(PyTypeObject *tp = Py_TYPE(self);
-PyErr_Format(PyExc_AttributeError, "Attempt to retrieve '%s' from null object '%s'.",
- Shiboken::String::toCString(name), tp->tp_name);
-return nullptr;
-)" << outdent << "}\n";
- }
-
- // This generates the code which dispatches access to member functions
- // and fields from the smart pointer to its pointee.
- s << smartPtrComment
- << "if (auto *rawObj = PyObject_CallMethod(self, "
- << SMART_POINTER_GETTER << ", 0)) {\n" << indent
- << "if (auto *attribute = PyObject_GetAttr(rawObj, name))\n"
- << indent << "tmp = attribute;\n" << outdent
- << "Py_DECREF(rawObj);\n" << outdent
- << "}\n"
- << "if (!tmp) {\n" << indent
- << R"(PyTypeObject *tp = Py_TYPE(self);
-PyErr_Format(PyExc_AttributeError,
- "'%.50s' object has no attribute '%.400s'",
- tp->tp_name, Shiboken::String::toCString(name));
-)" << outdent
- << "}\n"
- << "return tmp;\n" << outdent << "}\n\n";
-}
-
void CppGenerator::writeNbBoolExpression(TextStream &s, const BoolCastFunction &f,
bool invert)
{
@@ -6561,7 +6031,7 @@ void CppGenerator::writeNbBoolExpression(TextStream &s, const BoolCastFunction &
void CppGenerator::writeNbBoolFunction(const GeneratorContext &context,
const BoolCastFunction &f,
- TextStream &s) const
+ TextStream &s)
{
s << "static int " << cpythonBaseName(context.metaClass()) << "___nb_bool(PyObject *self)\n"
<< "{\n" << indent;
@@ -6585,28 +6055,53 @@ void CppGenerator::writeNbBoolFunction(const GeneratorContext &context,
// function.
void CppGenerator::writeInitFunc(TextStream &declStr, TextStream &callStr,
const QString &initFunctionName,
- const TypeEntryCPtr &enclosingEntry)
+ const TypeEntryCPtr &enclosingEntry,
+ const QString &pythonName, bool lazy)
{
- const bool hasParent =
- enclosingEntry && enclosingEntry->type() != TypeEntry::TypeSystemType;
- declStr << "void init_" << initFunctionName << "(PyObject *"
+ const QString functionName = "init_"_L1 + initFunctionName;
+ const bool hasParent = enclosingEntry && enclosingEntry->type() != TypeEntry::TypeSystemType;
+ declStr << "PyTypeObject *" << functionName << "(PyObject *"
<< (hasParent ? "enclosingClass" : "module") << ");\n";
- callStr << "init_" << initFunctionName;
- if (hasParent) {
- callStr << "(reinterpret_cast<PyTypeObject *>("
- << cpythonTypeNameExt(enclosingEntry) << ")->tp_dict);\n";
+
+ if (!lazy) {
+ const QString enclosing = hasParent
+ ? "reinterpret_cast<PyObject *>("_L1 + cpythonTypeNameExt(enclosingEntry) + u')'
+ : "module"_L1;
+ callStr << functionName << '(' << enclosing << ");\n";
+ } else if (hasParent) {
+ const QString &enclosingName = enclosingEntry->name();
+ const auto parts = QStringView{enclosingName}.split(u"::", Qt::SkipEmptyParts);
+ const QString namePathPrefix = enclosingEntry->name().replace("::"_L1, "."_L1);
+ callStr << "Shiboken::Module::AddTypeCreationFunction("
+ << "module, \"" << parts[0] << "\", "
+ << functionName << ", \"" << namePathPrefix << '.' << pythonName << "\");\n";
} else {
- callStr << "(module);\n";
+ callStr << "Shiboken::Module::AddTypeCreationFunction("
+ << "module, \"" << pythonName << "\", "
+ << functionName << ");\n";
}
}
+static void writeSubModuleHandling(TextStream &s, const QString &moduleName,
+ const QString &subModuleOf)
+{
+ s << "{\n" << indent
+ << "Shiboken::AutoDecRef parentModule(Shiboken::Module::import(\""
+ << subModuleOf << "\"));\n"
+ << "if (parentModule.isNull())\n" << indent
+ << "return nullptr;\n" << outdent
+ << "if (PyModule_AddObject(parentModule.object(), \"" << moduleName
+ << "\", module) < 0)\n"
+ << indent << "return nullptr;\n" << outdent << outdent << "}\n";
+}
+
bool CppGenerator::finishGeneration()
{
//Generate CPython wrapper file
StringStream s_classInitDecl(TextStream::Language::Cpp);
StringStream s_classPythonDefines(TextStream::Language::Cpp);
- QSet<Include> includes;
+ std::set<Include> includes;
StringStream s_globalFunctionImpl(TextStream::Language::Cpp);
StringStream s_globalFunctionDef(TextStream::Language::Cpp);
StringStream signatureStream(TextStream::Language::Cpp);
@@ -6615,8 +6110,8 @@ bool CppGenerator::finishGeneration()
for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
const AbstractMetaFunctionCList &overloads = it.value();
for (const auto &func : overloads) {
- if (func->typeEntry())
- includes << func->typeEntry()->include();
+ if (auto te = func->typeEntry())
+ includes.insert(te->include());
}
if (overloads.isEmpty())
@@ -6632,50 +6127,59 @@ bool CppGenerator::finishGeneration()
}
AbstractMetaClassCList classesWithStaticFields;
- for (auto cls : api().classes()){
+ for (const auto &cls : api().classes()){
auto te = cls->typeEntry();
if (shouldGenerate(te)) {
+ const bool hasConfigCondition = te->hasConfigCondition();
+ if (hasConfigCondition) {
+ s_classInitDecl << te->configCondition() << '\n';
+ s_classPythonDefines << te->configCondition() << '\n';
+ }
writeInitFunc(s_classInitDecl, s_classPythonDefines,
getSimpleClassInitFunctionName(cls),
- targetLangEnclosingEntry(te));
+ targetLangEnclosingEntry(te), cls->name());
if (cls->hasStaticFields()) {
- s_classInitDecl << "void "
- << getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
+ s_classInitDecl << "PyTypeObject *"
+ << getSimpleClassStaticFieldsInitFunctionName(cls) << "(PyObject *module);\n";
classesWithStaticFields.append(cls);
}
+ if (hasConfigCondition) {
+ s_classInitDecl << "#endif\n";
+ s_classPythonDefines << "#endif\n";
+ }
}
}
// Initialize smart pointer types.
for (const auto &smp : api().instantiatedSmartPointers()) {
GeneratorContext context = contextForSmartPointer(smp.specialized, smp.type);
- auto *enclosingClass = context.metaClass()->enclosingClass();
- auto enclosingTypeEntry = enclosingClass != nullptr
- ? enclosingClass->typeEntry()
- : targetLangEnclosingEntry(smp.type.typeEntry());
+ const auto enclosingClass = context.metaClass()->enclosingClass();
+ auto enclosingTypeEntry = targetLangEnclosingEntry(smp.specialized->typeEntry());
+
writeInitFunc(s_classInitDecl, s_classPythonDefines,
getInitFunctionName(context),
- enclosingTypeEntry);
- includes << smp.type.instantiations().constFirst().typeEntry()->include();
+ enclosingTypeEntry, smp.specialized->name());
+ includes.insert(smp.type.instantiations().constFirst().typeEntry()->include());
}
for (auto &instantiatedContainer : api().instantiatedContainers()) {
+ includes.insert(instantiatedContainer.typeEntry()->include());
for (const auto &inst : instantiatedContainer.instantiations())
- includes << inst.typeEntry()->include();
+ includes.insert(inst.typeEntry()->include());
}
const ExtendedConverterData extendedConverters = getExtendedConverters();
for (auto it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) {
TypeEntryCPtr te = it.key();
- includes << te->include();
+ includes.insert(te->include());
for (const auto &metaClass : it.value())
- includes << metaClass->typeEntry()->include();
+ includes.insert(metaClass->typeEntry()->include());
}
const QList<CustomConversionPtr> &typeConversions = getPrimitiveCustomConversions();
for (const auto &c : typeConversions) {
- if (auto te = c->ownerType(); !te.isNull())
- includes << te->include();
+ if (auto te = c->ownerType())
+ includes.insert(te->include());
}
QString moduleFileName(outputDirectory() + u'/' + subDirectoryForPackage(packageName()));
@@ -6707,13 +6211,13 @@ bool CppGenerator::finishGeneration()
}
s << "#include \"" << getModuleHeaderFileName() << '"' << "\n\n";
- for (const Include &include : std::as_const(includes))
+ for (const Include &include : includes)
s << include;
s << '\n';
// Global enums
AbstractMetaEnumList globalEnums = api().globalEnums();
- for (const AbstractMetaClass *nsp : invisibleTopNamespaces()) {
+ for (const auto &nsp : invisibleTopNamespaces()) {
const auto oldSize = globalEnums.size();
nsp->getEnumsToBeGenerated(&globalEnums);
if (globalEnums.size() > oldSize)
@@ -6722,7 +6226,7 @@ bool CppGenerator::finishGeneration()
TypeDatabase *typeDb = TypeDatabase::instance();
TypeSystemTypeEntryCPtr moduleEntry = typeDb->defaultTypeSystemType();
- Q_ASSERT(!moduleEntry.isNull());
+ Q_ASSERT(moduleEntry);
s << '\n';
// Extra includes
@@ -6737,29 +6241,34 @@ bool CppGenerator::finishGeneration()
s << '\n';
}
+ // FIXME PYSIDE-7: Remove backwards compatible structure
s << "// Current module's type array.\n"
- << "PyTypeObject **" << cppApiVariableName() << " = nullptr;\n"
+ << "Shiboken::Module::TypeInitStruct *" << cppApiVariableName() << " = nullptr;\n"
+ << "// Backwards compatible structure with identical indexing.\n"
+ << "PyTypeObject **" << cppApiVariableNameOld() << " = nullptr;\n"
<< "// Current module's PyObject pointer.\n"
<< "PyObject *" << pythonModuleObjectName() << " = nullptr;\n"
<< "// Current module's converter array.\n"
- << "SbkConverter **" << convertersVariableName() << " = nullptr;\n";
+ << "SbkConverter **" << convertersVariableName() << " = nullptr;\n\n";
const CodeSnipList snips = moduleEntry->codeSnips();
// module inject-code native/beginning
- if (!snips.isEmpty())
- writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode);
+ writeModuleCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode);
// cleanup staticMetaObject attribute
if (usePySideExtensions()) {
+ QString iType = cppApiVariableName() + "[i].type"_L1;
+ QString iName = cppApiVariableName() + "[i].fullName"_L1;
+
s << "void cleanTypesAttributes() {\n" << indent
<< "static PyObject *attrName = Shiboken::PyName::qtStaticMetaObject();\n"
- << "for (int i = 0, imax = SBK_" << moduleName()
- << "_IDX_COUNT; i < imax; i++) {\n" << indent
- << "PyObject *pyType = reinterpret_cast<PyObject *>(" << cppApiVariableName() << "[i]);\n"
- << "if (pyType && PyObject_HasAttr(pyType, attrName))\n" << indent
+ << "const int imax = SBK_" << moduleName() << "_IDX_COUNT;\n"
+ << "for (int i = 0; i < imax && " << iName << " != nullptr; ++i) {\n" << indent
+ << "auto *pyType = reinterpret_cast<PyObject *>(" << iType << ");\n"
+ << "if (pyType != nullptr && PyObject_HasAttr(pyType, attrName))\n" << indent
<< "PyObject_SetAttr(pyType, attrName, Py_None);\n" << outdent
- << outdent << "}\n" << outdent << "}\n";
+ << outdent << "}\n" << outdent << "}\n\n";
}
s << "// Global functions "
@@ -6767,7 +6276,7 @@ bool CppGenerator::finishGeneration()
<< s_globalFunctionImpl.toString() << '\n'
<< "static PyMethodDef " << moduleName() << "_methods[] = {\n" << indent
<< s_globalFunctionDef.toString()
- << methodDefSentinel << outdent << "};\n\n"
+ << METHOD_DEF_SENTINEL << outdent << "};\n\n"
<< "// Classes initialization functions "
<< "------------------------------------------------------------\n"
<< s_classInitDecl.toString() << '\n';
@@ -6788,7 +6297,6 @@ bool CppGenerator::finishGeneration()
<< "} // namespace Shiboken\n\n";
}
- writeFlagsNumberMethodsDefinitions(s, globalEnums);
s << '\n';
}
@@ -6796,7 +6304,7 @@ bool CppGenerator::finishGeneration()
if (!requiredModules.isEmpty())
s << "// Required modules' type and converter arrays.\n";
for (const QString &requiredModule : requiredModules) {
- s << "PyTypeObject **" << cppApiVariableName(requiredModule) << ";\n"
+ s << "Shiboken::Module::TypeInitStruct *" << cppApiVariableName(requiredModule) << ";\n"
<< "SbkConverter **" << convertersVariableName(requiredModule) << ";\n";
}
@@ -6808,7 +6316,7 @@ bool CppGenerator::finishGeneration()
TypeEntryCPtr externalType = it.key();
s << "// Extended implicit conversions for "
<< externalType->qualifiedTargetLangName() << '.' << '\n';
- for (const AbstractMetaClass *sourceClass : it.value()) {
+ for (const auto &sourceClass : it.value()) {
AbstractMetaType sourceType = AbstractMetaType::fromAbstractMetaClass(sourceClass);
AbstractMetaType targetType = AbstractMetaType::fromTypeEntry(externalType);
writePythonToCppConversionFunctions(s, sourceType, targetType);
@@ -6828,14 +6336,17 @@ bool CppGenerator::finishGeneration()
QHash<AbstractMetaType, OpaqueContainerData> opaqueContainers;
const auto &containers = api().instantiatedContainers();
+ QSet<AbstractMetaType> valueConverters;
if (!containers.isEmpty()) {
s << "// Container Type converters.\n\n";
for (const AbstractMetaType &container : containers) {
- s << "// C++ to Python conversion for container type '" << container.cppSignature() << "'.\n";
+ s << "// C++ to Python conversion for container type '"
+ << container.cppSignature() << "'.\n";
writeContainerConverterFunctions(s, container);
if (container.generateOpaqueContainer()) {
- opaqueContainers.insert(container,
- writeOpaqueContainerConverterFunctions(s, container));
+ auto data = writeOpaqueContainerConverterFunctions(s, container,
+ &valueConverters);
+ opaqueContainers.insert(container, data);
}
}
s << '\n';
@@ -6867,6 +6378,8 @@ bool CppGenerator::finishGeneration()
// PYSIDE-510: Create a signatures string for the introspection feature.
writeSignatureStrings(s, signatureStream.toString(), moduleName(), "global functions");
+ writeInitInheritance(s);
+
// Write module init function
const QString globalModuleVar = pythonModuleObjectName();
s << "extern \"C\" LIBSHIBOKEN_EXPORT PyObject *PyInit_"
@@ -6876,8 +6389,8 @@ bool CppGenerator::finishGeneration()
<< indent << "return " << globalModuleVar << ";\n" << outdent;
// module inject-code target/beginning
- if (!snips.isEmpty())
- writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning, TypeSystem::TargetLangCode);
+ writeModuleCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning,
+ TypeSystem::TargetLangCode);
for (const QString &requiredModule : requiredModules) {
s << "{\n" << indent
@@ -6893,9 +6406,30 @@ bool CppGenerator::finishGeneration()
int maxTypeIndex = getMaxTypeIndex() + api().instantiatedSmartPointers().size();
if (maxTypeIndex) {
- s << "// Create an array of wrapper types for the current module.\n"
- << "static PyTypeObject *cppApi[SBK_" << moduleName() << "_IDX_COUNT];\n"
- << cppApiVariableName() << " = cppApi;\n\n";
+ s << "// Create an array of wrapper types/names for the current module.\n"
+ << "static Shiboken::Module::TypeInitStruct cppApi[] = {\n" << indent;
+
+ // Windows did not like an array of QString.
+ QStringList typeNames;
+ for (int idx = 0; idx < maxTypeIndex; ++idx)
+ typeNames.append("+++ unknown entry #"_L1 + QString::number(idx)
+ + " in "_L1 + moduleName());
+
+ collectFullTypeNamesArray(typeNames);
+
+ for (auto typeName : typeNames)
+ s << "{nullptr, \"" << typeName << "\"},\n";
+
+ s << "{nullptr, nullptr}\n" << outdent << "};\n"
+ << "// The new global structure consisting of (type, name) pairs.\n"
+ << cppApiVariableName() << " = cppApi;\n";
+ if (usePySideExtensions())
+ s << "QT_WARNING_PUSH\nQT_WARNING_DISABLE_DEPRECATED\n";
+ s << "// The backward compatible alias with upper case indexes.\n"
+ << cppApiVariableNameOld() << " = reinterpret_cast<PyTypeObject **>(cppApi);\n";
+ if (usePySideExtensions())
+ s << "QT_WARNING_POP\n";
+ s << '\n';
}
s << "// Create an array of primitive type converters for the current module.\n"
@@ -6905,8 +6439,13 @@ bool CppGenerator::finishGeneration()
<< "PyObject *module = Shiboken::Module::create(\"" << moduleName()
<< "\", &moduledef);\n\n"
<< "// Make module available from global scope\n"
- << globalModuleVar << " = module;\n\n"
- << "// Initialize classes in the type system\n"
+ << globalModuleVar << " = module;\n\n";
+
+ const QString subModuleOf = typeDb->defaultTypeSystemType()->subModuleOf();
+ if (!subModuleOf.isEmpty())
+ writeSubModuleHandling(s, moduleName(), subModuleOf);
+
+ s << "// Initialize classes in the type system\n"
<< s_classPythonDefines.toString();
if (!typeConversions.isEmpty()) {
@@ -6920,7 +6459,7 @@ bool CppGenerator::finishGeneration()
if (!containers.isEmpty()) {
s << '\n';
for (const AbstractMetaType &container : containers) {
- const QString converterObj = writeContainerConverterInitialization(s, container);
+ const QString converterObj = writeContainerConverterInitialization(s, container, api());
const auto it = opaqueContainers.constFind(container);
if (it != opaqueContainers.constEnd()) {
writeSetPythonToCppPointerConversion(s, converterObj,
@@ -6955,7 +6494,7 @@ bool CppGenerator::finishGeneration()
}
}
- writeEnumsInitialization(s, globalEnums, ErrorReturn::Default);
+ writeEnumsInitialization(s, globalEnums);
s << "// Register primitive types converters.\n";
const PrimitiveTypeEntryCList &primitiveTypeList = primitiveTypes();
@@ -6965,14 +6504,7 @@ bool CppGenerator::finishGeneration()
if (!pte->referencesType())
continue;
TypeEntryCPtr referencedType = basicReferencedTypeEntry(pte);
- QString converter = converterObject(referencedType);
- QStringList cppSignature = pte->qualifiedCppName().split(u"::"_s, Qt::SkipEmptyParts);
- while (!cppSignature.isEmpty()) {
- QString signature = cppSignature.join(u"::"_s);
- s << "Shiboken::Conversions::registerConverterName("
- << converter << ", \"" << signature << "\");\n";
- cppSignature.removeFirst();
- }
+ registerConverterInScopes(s, pte->qualifiedCppName(), converterObject(referencedType));
}
s << '\n';
@@ -6984,27 +6516,29 @@ bool CppGenerator::finishGeneration()
// of the previously registered types (PYSIDE-1529).
if (!classesWithStaticFields.isEmpty()) {
s << "\n// Static field initialization\n";
- for (auto cls : std::as_const(classesWithStaticFields))
- s << getSimpleClassStaticFieldsInitFunctionName(cls) << "();\n";
+ for (const auto &cls : std::as_const(classesWithStaticFields)) {
+ ConfigurableScope configScope(s, cls->typeEntry());
+ s << getSimpleClassStaticFieldsInitFunctionName(cls) << "(module);\n";
+ }
}
- s << "\nif (PyErr_Occurred()) {\n" << indent
+ s << '\n' << initInheritanceFunction << "();\n"
+ << "\nif (" << shibokenErrorsOccurred << ") {\n" << indent
<< "PyErr_Print();\n"
<< "Py_FatalError(\"can't initialize module " << moduleName() << "\");\n"
<< outdent << "}\n";
// module inject-code target/end
- if (!snips.isEmpty())
- writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode);
+ writeModuleCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::TargetLangCode);
// module inject-code native/end
- if (!snips.isEmpty())
- writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode);
+ writeModuleCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode);
if (usePySideExtensions()) {
for (const AbstractMetaEnum &metaEnum : std::as_const(globalEnums))
if (!metaEnum.isAnonymous()) {
- s << "qRegisterMetaType< ::" << metaEnum.typeEntry()->qualifiedCppName()
+ ConfigurableScope configScope(s, metaEnum.typeEntry());
+ s << "qRegisterMetaType< " << getFullTypeName(metaEnum.typeEntry())
<< " >(\"" << metaEnum.name() << "\");\n";
}
@@ -7012,7 +6546,7 @@ bool CppGenerator::finishGeneration()
s << "PySide::registerCleanupFunction(cleanTypesAttributes);\n\n";
}
- // finish the rest of __signature__ initialization.
+ // finish the rest of get_signature() initialization.
s << "FinishSignatureInitialization(module, " << moduleName()
<< "_SignatureStrings);\n"
<< "\nreturn module;\n" << outdent << "}\n";
@@ -7038,17 +6572,17 @@ static bool useParentHeuristics(const ApiExtractorResult &api,
{
if (!ComplexTypeEntry::isParentManagementEnabled()) // FIXME PYSIDE 7: Remove this
return true;
- auto *owner = func->ownerClass();
- if (owner == nullptr)
+ const auto owner = func->ownerClass();
+ if (!owner)
return false;
- auto ownerEntry = owner->parentManagementEntry();
- if (ownerEntry.isNull())
+ auto ownerEntry = parentManagementEntry(owner);
+ if (!ownerEntry)
return false;
auto argTypeEntry = argType.typeEntry();
if (!argTypeEntry->isComplex())
return false;
- auto *argClass = AbstractMetaClass::findClass(api.classes(), argTypeEntry);
- return argClass != nullptr && argClass->parentManagementEntry() == ownerEntry;
+ const auto argClass = AbstractMetaClass::findClass(api.classes(), argTypeEntry);
+ return argClass && parentManagementEntry(argClass) == ownerEntry;
}
bool CppGenerator::writeParentChildManagement(TextStream &s, const AbstractMetaFunctionCPtr &func,
@@ -7087,7 +6621,7 @@ bool CppGenerator::writeParentChildManagement(TextStream &s, const AbstractMetaF
if (parentIndex == 0) {
parentVariable = PYTHON_RETURN_VAR;
} else if (parentIndex == -1) {
- parentVariable = u"self"_s;
+ parentVariable = PYTHON_SELF_VAR;
} else {
parentVariable = usePyArgs
? pythonArgsAt(parentIndex - 1) : PYTHON_ARG;
@@ -7097,7 +6631,7 @@ bool CppGenerator::writeParentChildManagement(TextStream &s, const AbstractMetaF
if (childIndex == 0) {
childVariable = PYTHON_RETURN_VAR;
} else if (childIndex == -1) {
- childVariable = u"self"_s;
+ childVariable = PYTHON_SELF_VAR;
} else {
childVariable = usePyArgs
? pythonArgsAt(childIndex - 1) : PYTHON_ARG;
@@ -7154,9 +6688,9 @@ void CppGenerator::writeReturnValueHeuristics(TextStream &s, const AbstractMetaF
}
}
-void CppGenerator::writeHashFunction(TextStream &s, const GeneratorContext &context) const
+void CppGenerator::writeHashFunction(TextStream &s, const GeneratorContext &context)
{
- const AbstractMetaClass *metaClass = context.metaClass();
+ const auto metaClass = context.metaClass();
const char hashType[] = "Py_hash_t";
s << "static " << hashType << ' ' << cpythonBaseName(metaClass)
<< "_HashFunc(PyObject *self)\n{\n" << indent;
@@ -7180,7 +6714,7 @@ void CppGenerator::writeHashFunction(TextStream &s, const GeneratorContext &cont
void CppGenerator::writeDefaultSequenceMethods(TextStream &s,
const GeneratorContext &context) const
{
- const AbstractMetaClass *metaClass = context.metaClass();
+ const auto metaClass = context.metaClass();
ErrorReturn errorReturn = ErrorReturn::Zero;
// __len__
@@ -7247,14 +6781,20 @@ void CppGenerator::writeIndexError(TextStream &s, const QString &errorMsg,
<< errorReturn << outdent << "}\n";
}
+QString CppGenerator::writeReprFunctionHeader(TextStream &s, const GeneratorContext &context)
+{
+ QString funcName = cpythonBaseName(context.metaClass()) + REPR_FUNCTION;
+ s << "extern \"C\"\n{\n"
+ << "static PyObject *" << funcName << "(PyObject *self)\n{\n" << indent;
+ return funcName;
+}
+
QString CppGenerator::writeReprFunction(TextStream &s,
const GeneratorContext &context,
- uint indirections) const
+ uint indirections)
{
- const AbstractMetaClass *metaClass = context.metaClass();
- QString funcName = cpythonBaseName(metaClass) + reprFunction();
- s << "extern \"C\"\n{\n"
- << "static PyObject *" << funcName << "(PyObject *self)\n{\n" << indent;
+ const auto metaClass = context.metaClass();
+ QString funcName = writeReprFunctionHeader(s, context);
writeCppSelfDefinition(s, context);
s << R"(QBuffer buffer;
buffer.open(QBuffer::ReadWrite);
@@ -7269,15 +6809,21 @@ const auto idx = str.indexOf('(');
auto *typeName = Py_TYPE(self)->tp_name;
if (idx >= 0)
)" << indent << "str.replace(0, idx, typeName);\n" << outdent
- << "str = str.trimmed();\n"
- << "PyObject *mod = PyDict_GetItem(Py_TYPE(self)->tp_dict, Shiboken::PyMagicName::module());\n";
+ << "str = str.trimmed();\n"
+ << "Shiboken::AutoDecRef tpDict(PepType_GetDict(Py_TYPE(self)));\n"
+ << "PyObject *mod = PyDict_GetItem(tpDict.object(), Shiboken::PyMagicName::module());\n";
// PYSIDE-595: The introduction of heap types has the side effect that the module name
// is always prepended to the type name. Therefore the strchr check:
s << "if (mod != nullptr && std::strchr(typeName, '.') == nullptr)\n" << indent
<< "return Shiboken::String::fromFormat(\"<%s.%s at %p>\","
" Shiboken::String::toCString(mod), str.constData(), self);\n"
<< outdent
- << "return Shiboken::String::fromFormat(\"<%s at %p>\", str.constData(), self);\n"
- << outdent << "}\n} // extern C\n\n";
+ << "return Shiboken::String::fromFormat(\"<%s at %p>\", str.constData(), self);\n";
+ writeReprFunctionFooter(s);
return funcName;
}
+
+void CppGenerator::writeReprFunctionFooter(TextStream &s)
+{
+ s << outdent << "}\n} // extern C\n\n";
+}
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator.h b/sources/shiboken6/generator/shiboken/cppgenerator.h
index f16f5cce4..f369ab01b 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -5,13 +5,15 @@
#define CPPGENERATOR_H
#include "shibokengenerator.h"
-#include "abstractmetalang_enums.h"
#include "include.h"
#include "modifications_typedefs.h"
#include <QtCore/QFlags>
+#include <QtCore/QSet>
#include <QtCore/QHash>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
+#include <utility>
class OverloadDataNode;
class OverloadDataRootNode;
@@ -43,19 +45,16 @@ public:
protected:
QString fileNameForContext(const GeneratorContext &context) const override;
- static QList<AbstractMetaFunctionCList>
- filterGroupedOperatorFunctions(const AbstractMetaClass *metaClass,
- OperatorQueryOptions query);
void generateClass(TextStream &s, const GeneratorContext &classContext) override;
bool finishGeneration() override;
private:
- struct BoolCastFunction
+ struct VirtualMethodReturn
{
- AbstractMetaFunctionCPtr function;
- bool invert = false; // Function is isNull() (invert result).
+ QString statement;
+ bool needsReference = false;
};
- using BoolCastFunctionOptional = std::optional<BoolCastFunction>;
+
void generateSmartPointerClass(TextStream &s, const GeneratorContext &classContext);
void generateIncludes(TextStream &s, const GeneratorContext &classContext,
@@ -63,46 +62,50 @@ private:
const AbstractMetaClassCList &innerClasses = {}) const;
static void writeInitFunc(TextStream &declStr, TextStream &callStr,
const QString &initFunctionName,
- const TypeEntryCPtr &enclosingEntry = {});
+ const TypeEntryCPtr &enclosingEntry,
+ const QString &pythonName, bool lazy = true);
static void writeCacheResetNative(TextStream &s, const GeneratorContext &classContext);
void writeConstructorNative(TextStream &s, const GeneratorContext &classContext,
const AbstractMetaFunctionCPtr &func) const;
- void writeDestructorNative(TextStream &s, const GeneratorContext &classContext) const;
+ static void writeDestructorNative(TextStream &s, const GeneratorContext &classContext);
QString getVirtualFunctionReturnTypeName(const AbstractMetaFunctionCPtr &func) const;
- static QPair<QString, QChar>
- virtualMethodNativeArg(const AbstractMetaFunctionCPtr &func,
+ static std::pair<QString, QChar> virtualMethodNativeArg(const AbstractMetaFunctionCPtr &func,
const AbstractMetaArgument &arg);
- void writeVirtualMethodNativeVectorCallArgs(TextStream &s,
- const AbstractMetaFunctionCPtr &func,
- const AbstractMetaArgumentList &arguments,
- const QList<int> &invalidateArgs) const;
- void writeVirtualMethodNativeArgs(TextStream &s,
- const AbstractMetaFunctionCPtr &func,
- const AbstractMetaArgumentList &arguments,
- const QList<int> &invalidateArgs) const;
- void writeVirtualMethodNative(TextStream &s, const AbstractMetaFunctionCPtr &func,
+ static void writeVirtualMethodNativeVectorCallArgs(TextStream &s,
+ const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaArgumentList &arguments,
+ const QList<int> &invalidateArgs);
+ static void writeVirtualMethodNativeArgs(TextStream &s,
+ const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaArgumentList &arguments,
+ const QList<int> &invalidateArgs);
+ void writeVirtualMethodNative(TextStream &s,
+ const AbstractMetaFunctionCPtr &func,
int cacheIndex) const;
+ void writeVirtualMethodPythonOverride(TextStream &s,
+ const AbstractMetaFunctionCPtr &func,
+ const CodeSnipList &snips,
+ const VirtualMethodReturn &returnStatement) const;
+ void writeUserAddedPythonOverride(TextStream &s,
+ const AbstractMetaFunctionCPtr &func) const;
void writeVirtualMethodCppCall(TextStream &s, const AbstractMetaFunctionCPtr &func,
const QString &funcName, const QList<CodeSnip> &snips,
const AbstractMetaArgument *lastArg, const TypeEntryCPtr &retType,
const QString &returnStatement, bool hasGil) const;
- static QString virtualMethodReturn(TextStream &s, const ApiExtractorResult &api,
- const AbstractMetaFunctionCPtr &func,
- const FunctionModificationList &functionModifications);
+
+ static VirtualMethodReturn virtualMethodReturn(const ApiExtractorResult &api,
+ const AbstractMetaFunctionCPtr &func,
+ const FunctionModificationList &functionModifications);
void writeMetaObjectMethod(TextStream &s, const GeneratorContext &classContext) const;
static void writeMetaCast(TextStream &s, const GeneratorContext &classContext);
- void writeFlagsConverterFunctions(TextStream &s, const FlagsTypeEntryCPtr &flagsType,
- const QString &enumTypeName,
- const QString &flagsCppTypeName,
- const QString &enumTypeCheck) const;
void writeEnumConverterFunctions(TextStream &s, const AbstractMetaEnum &metaEnum) const;
- void writeConverterFunctions(TextStream &s, const AbstractMetaClass *metaClass,
+ void writeConverterFunctions(TextStream &s, const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext) const;
void writeCustomConverterFunctions(TextStream &s,
const CustomConversionPtr &customConversion) const;
- void writeConverterRegister(TextStream &s, const AbstractMetaClass *metaClass,
+ void writeConverterRegister(TextStream &s, const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext) const;
static void writeCustomConverterRegister(TextStream &s,
const CustomConversionPtr &customConversion,
@@ -122,16 +125,21 @@ private:
OpaqueContainerData
writeOpaqueContainerConverterFunctions(TextStream &s,
- const AbstractMetaType &containerType) const;
+ const AbstractMetaType &containerType,
+ QSet<AbstractMetaType> *valueTypes) const;
+ void writeOpaqueContainerValueConverter(TextStream &s,
+ const AbstractMetaType &valueType) const;
void writeSmartPointerConverterFunctions(TextStream &s,
const AbstractMetaType &smartPointerType) const;
- bool needsArgumentErrorHandling(const OverloadData &overloadData) const;
- void writeMethodWrapperPreamble(TextStream &s, const OverloadData &overloadData,
- const GeneratorContext &context,
- ErrorReturn errorReturn = ErrorReturn::Default) const;
- void writeConstructorWrapper(TextStream &s, const OverloadData &overloadData,
+ static bool needsArgumentErrorHandling(const OverloadData &overloadData);
+ static void writeMethodWrapperPreamble(TextStream &s,
+ const OverloadData &overloadData,
+ const GeneratorContext &context,
+ ErrorReturn errorReturn = ErrorReturn::Default);
+ void writeConstructorWrapper(TextStream &s,
+ const OverloadData &overloadData,
const GeneratorContext &classContext) const;
void writeMethodWrapper(TextStream &s, const OverloadData &overloadData,
const GeneratorContext &classContext) const;
@@ -147,22 +155,29 @@ private:
bool useWrapperClass);
static void writeSmartPointerCppSelfConversion(TextStream &s,
const GeneratorContext &context);
+
+ static void writeCppSelfVarDef(TextStream &s, CppSelfDefinitionFlags flags = {});
static void writeSmartPointerCppSelfDefinition(TextStream &s,
const GeneratorContext &,
ErrorReturn errorReturn = ErrorReturn::Default,
CppSelfDefinitionFlags flags = {});
- void writeCppSelfDefinition(TextStream &s,
- const AbstractMetaFunctionCPtr &func,
- const GeneratorContext &context,
- ErrorReturn errorReturn = ErrorReturn::Default,
- CppSelfDefinitionFlags flags = {}) const;
- void writeCppSelfDefinition(TextStream &s,
- const GeneratorContext &context,
- ErrorReturn errorReturn = ErrorReturn::Default,
- CppSelfDefinitionFlags flags = {}) const;
-
- static void writeErrorSection(TextStream &s, const OverloadData &overloadData,
+ static void writeCppSelfDefinition(TextStream &s,
+ const AbstractMetaFunctionCPtr &func,
+ const GeneratorContext &context,
+ ErrorReturn errorReturn = ErrorReturn::Default,
+ CppSelfDefinitionFlags flags = {});
+ static void writeCppSelfDefinition(TextStream &s,
+ const GeneratorContext &context,
+ ErrorReturn errorReturn = ErrorReturn::Default,
+ CppSelfDefinitionFlags flags = {});
+
+ static void writeErrorSection(TextStream &s,
+ const OverloadData &overloadData,
ErrorReturn errorReturn);
+
+ static QString returnErrorWrongArguments(const OverloadData &overloadData,
+ ErrorReturn errorReturn);
+
static void writeFunctionReturnErrorCheckSection(TextStream &s,
ErrorReturn errorReturn,
bool hasReturnValue = true);
@@ -176,18 +191,22 @@ private:
bool isNumber = false, bool rejectNull = false);
static void writeTypeCheck(TextStream &s, const QString &customType,
const QString &argumentName);
- static void writeTypeCheck(TextStream& s, const QSharedPointer<OverloadDataNode> &overloadData,
+ static void writeTypeCheck(TextStream& s, const std::shared_ptr<OverloadDataNode> &overloadData,
const QString &argumentName);
- static void writeTypeDiscoveryFunction(TextStream &s, const AbstractMetaClass *metaClass);
+ static void replacePolymorphicIdPlaceHolders(const AbstractMetaClassCPtr &metaClass,
+ QString *id);
+ static void writeTypeDiscoveryFunction(TextStream &s,
+ const AbstractMetaClassCPtr &metaClass);
- void writeSetattroDefinition(TextStream &s, const AbstractMetaClass *metaClass) const;
+ static void writeSetattroDefinition(TextStream &s, const AbstractMetaClassCPtr &metaClass);
static void writeSetattroDefaultReturn(TextStream &s);
- void writeSmartPointerSetattroFunction(TextStream &s,
- const GeneratorContext &context) const;
- void writeSetattroFunction(TextStream &s, AttroCheck attroCheck,
+ static void writeSmartPointerSetattroFunction(TextStream &s,
+ const GeneratorContext &context);
+ void writeSetattroFunction(TextStream &s,
+ AttroCheck attroCheck,
const GeneratorContext &context) const;
- static void writeGetattroDefinition(TextStream &s, const AbstractMetaClass *metaClass);
+ static void writeGetattroDefinition(TextStream &s, const AbstractMetaClassCPtr &metaClass);
static void writeSmartPointerGetattroFunction(TextStream &s,
const GeneratorContext &context,
const BoolCastFunctionOptional &boolCast);
@@ -195,11 +214,10 @@ private:
const GeneratorContext &context) const;
QString qObjectGetAttroFunction() const;
- void writeNbBoolFunction(const GeneratorContext &context,
- const BoolCastFunction &f,
- TextStream &s) const;
- static void writeNbBoolExpression(TextStream &s, const BoolCastFunction &f,
- bool invert = false);
+ static void writeNbBoolFunction(const GeneratorContext &context,
+ const BoolCastFunction &f,
+ TextStream &s);
+ static void writeNbBoolExpression(TextStream &s, const BoolCastFunction &f, bool invert = false);
/**
* Writes Python to C++ conversions for arguments on Python wrappers.
@@ -216,7 +234,7 @@ private:
qsizetype writeArgumentConversion(TextStream &s, const AbstractMetaType &argType,
const QString &argName, const QString &pyArgName,
ErrorReturn errorReturn,
- const AbstractMetaClass *context = nullptr,
+ const AbstractMetaClassCPtr &context = {},
const QString &defaultValue = QString(),
bool castArgumentAsUnused = false) const;
@@ -238,7 +256,7 @@ private:
const AbstractMetaType &type,
const QString &pyIn,
const QString &cppOut,
- const AbstractMetaClass *context = nullptr,
+ const AbstractMetaClassCPtr &context = {},
const QString &defaultValue = {}) const;
/// Writes the conversion rule for arguments of regular and virtual methods.
@@ -266,7 +284,8 @@ private:
* \param s text stream to write
* \param overloadData the overload data describing all the possible overloads for the function/method
*/
- void writeOverloadedFunctionDecisor(TextStream &s, const OverloadData &overloadData) const;
+ void writeOverloadedFunctionDecisor(TextStream &s, const OverloadData &overloadData,
+ ErrorReturn errorReturn) const;
/// Recursive auxiliar method to the other writeOverloadedFunctionDecisor.
void writeOverloadedFunctionDecisorEngine(TextStream &s,
const OverloadData &overloadData,
@@ -305,6 +324,8 @@ private:
QString targetTypeName = QString()) const;
void writeCppToPythonFunction(TextStream &s, const CustomConversionPtr &customConversion) const;
void writeCppToPythonFunction(TextStream &s, const AbstractMetaType &containerType) const;
+ /// Main target type name of a container (for naming the functions).
+ static QString containerNativeToTargetTypeName(const ContainerTypeEntryCPtr &type);
/// Writes a Python to C++ conversion function.
void writePythonToCppFunction(TextStream &s, const QString &code, const QString &sourceTypeName,
@@ -334,6 +355,10 @@ private:
void writePythonToCppConversionFunctions(TextStream &s,
const AbstractMetaType &containerType) const;
+ void writePythonToCppConversionFunction(TextStream &s,
+ const AbstractMetaType &containerType,
+ const TargetToNativeConversion &conv) const;
+
static void writeAddPythonToCppConversion(TextStream &s, const QString &converterVar,
const QString &pythonToCppFunc,
const QString &isConvertibleFunc);
@@ -342,15 +367,18 @@ private:
const QString &pythonToCppFunc,
const QString &isConvertibleFunc);
- void writeNamedArgumentResolution(TextStream &s, const AbstractMetaFunctionCPtr &func,
- bool usePyArgs, const OverloadData &overloadData) const;
+ static void writeNamedArgumentResolution(TextStream &s,
+ const AbstractMetaFunctionCPtr &func,
+ bool usePyArgs,
+ const OverloadData &overloadData,
+ ErrorReturn errorReturn);
/// Returns a string containing the name of an argument for the given function and argument index.
static QString argumentNameFromIndex(const ApiExtractorResult &api,
const AbstractMetaFunctionCPtr &func, int argIndex);
/// Returns the class for an ownership modification of the argument.
/// Throws if the argument is not a class or cannot be found.
- static const AbstractMetaClass *
+ static AbstractMetaClassCPtr
argumentClassFromIndex(const ApiExtractorResult &api,
const AbstractMetaFunctionCPtr &func, int argIndex);
@@ -360,112 +388,102 @@ private:
ErrorReturn errorReturn) const;
static QString getInitFunctionName(const GeneratorContext &context) ;
- static QString getSimpleClassInitFunctionName(const AbstractMetaClass *metaClass) ;
- static QString getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClass *metaClass);
+ static QString getSimpleClassInitFunctionName(const AbstractMetaClassCPtr &metaClass);
+ static QString
+ getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClassCPtr &metaClass);
static void writeSignatureStrings(TextStream &s, const QString &signatures,
const QString &arrayName,
const char *comment);
+ void writeInitInheritance(TextStream &s) const;
void writeClassRegister(TextStream &s,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext,
const QString &signatures) const;
- QString destructorClassName(const AbstractMetaClass *metaClass,
- const GeneratorContext &classContext) const;
+ static QStringList pyBaseTypes(const AbstractMetaClassCPtr &metaClass);
+ static QString destructorClassName(const AbstractMetaClassCPtr &metaClass,
+ const GeneratorContext &classContext);
static void writeStaticFieldInitialization(TextStream &s,
- const AbstractMetaClass *metaClass);
+ const AbstractMetaClassCPtr &metaClass);
void writeClassDefinition(TextStream &s,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext);
QByteArrayList methodDefinitionParameters(const OverloadData &overloadData) const;
QList<PyMethodDefEntry> methodDefinitionEntries(const OverloadData &overloadData) const;
void writeSignatureInfo(TextStream &s, const OverloadData &overloads) const;
QString signatureParameter(const AbstractMetaArgument &arg) const;
+ QString pythonSignature(const AbstractMetaType &type) const;
/// Writes the implementation of all methods part of python sequence protocol
void writeSequenceMethods(TextStream &s,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &context) const;
static void writeTypeAsSequenceDefinition(TextStream &s,
- const AbstractMetaClass *metaClass);
+ const AbstractMetaClassCPtr &metaClass);
/// Writes the PyMappingMethods structure for types that supports the python mapping protocol.
static void writeTypeAsMappingDefinition(TextStream &s,
- const AbstractMetaClass *metaClass);
+ const AbstractMetaClassCPtr &metaClass);
void writeMappingMethods(TextStream &s,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &context) const;
- void writeTypeAsNumberDefinition(TextStream &s, const AbstractMetaClass *metaClass) const;
-
- static void writeTpTraverseFunction(TextStream &s, const AbstractMetaClass *metaClass);
- static void writeTpClearFunction(TextStream &s, const AbstractMetaClass *metaClass);
-
- void writeCopyFunction(TextStream &s, const GeneratorContext &context) const;
-
- QString cppFieldAccess(const AbstractMetaField &metaField,
- const GeneratorContext &context) const;
- void writeGetterFunction(TextStream &s,
- const AbstractMetaField &metaField,
- const GeneratorContext &context) const;
- void writeGetterFunction(TextStream &s,
- const QPropertySpec &property,
- const GeneratorContext &context) const;
- void writeSetterFunctionPreamble(TextStream &s,
- const QString &name,
- const QString &funcName,
- const AbstractMetaType &type,
- const GeneratorContext &context) const;
- void writeSetterFunction(TextStream &s,
- const AbstractMetaField &metaField,
- const GeneratorContext &context) const;
- void writeSetterFunction(TextStream &s,
- const QPropertySpec &property,
- const GeneratorContext &context) const;
-
- void writeRichCompareFunctionHeader(TextStream &s,
- const QString &baseName,
- const GeneratorContext &context) const;
- static void writeRichCompareFunctionFooter(TextStream &s,
+ void writeTypeAsNumberDefinition(TextStream &s, const AbstractMetaClassCPtr &metaClass) const;
+
+ static void writeTpTraverseFunction(TextStream &s, const AbstractMetaClassCPtr &metaClass);
+ static void writeTpClearFunction(TextStream &s, const AbstractMetaClassCPtr &metaClass);
+
+ static QString writeCopyFunction(TextStream &s, TextStream &definitionStream,
+ TextStream &signatureStream, const GeneratorContext &context);
+
+ static QString cppFieldAccess(const AbstractMetaField &metaField,
+ const GeneratorContext &context);
+ static void writeGetterFunction(TextStream &s,
+ const AbstractMetaField &metaField,
+ const GeneratorContext &context);
+ static void writeGetterFunction(TextStream &s,
+ const QPropertySpec &property,
+ const GeneratorContext &context);
+ static void writeSetterFunctionPreamble(TextStream &s,
+ const QString &name,
+ const QString &funcName,
+ const AbstractMetaType &type,
+ const GeneratorContext &context);
+ static void writeSetterFunction(TextStream &s,
+ const AbstractMetaField &metaField,
+ const GeneratorContext &context);
+ static void writeSetterFunction(TextStream &s,
+ const QPropertySpec &property,
+ const GeneratorContext &context);
+
+ static void writeRichCompareFunctionHeader(TextStream &s,
const QString &baseName,
- bool writeLabel);
+ const GeneratorContext &context);
void writeRichCompareFunction(TextStream &s, const GeneratorContext &context) const;
void writeSmartPointerRichCompareFunction(TextStream &s, const GeneratorContext &context) const;
- void writeEnumsInitialization(TextStream &s, AbstractMetaEnumList &enums,
- ErrorReturn errorReturn) const;
- void writeEnumInitialization(TextStream &s, const AbstractMetaEnum &metaEnum,
- ErrorReturn errorReturn) const;
+ static void writeEnumsInitialization(TextStream &s, AbstractMetaEnumList &enums);
+ static bool writeEnumInitialization(TextStream &s, const AbstractMetaEnum &metaEnum);
- static void writeSignalInitialization(TextStream &s, const AbstractMetaClass *metaClass);
-
- static void writeFlagsMethods(TextStream &s, const AbstractMetaEnum &cppEnum);
- static void writeFlagsToLong(TextStream &s, const AbstractMetaEnum &cppEnum);
- static void writeFlagsNonZero(TextStream &s, const AbstractMetaEnum &cppEnum);
- static void writeFlagsNumberMethodsDefinition(TextStream &s, const AbstractMetaEnum &cppEnum);
- static void writeFlagsNumberMethodsDefinitions(TextStream &s,
- const AbstractMetaEnumList &enums);
- static void writeFlagsBinaryOperator(TextStream &s,
- const AbstractMetaEnum &cppEnum,
- const QString &pyOpName,
- const QString &cppOpName);
- static void writeFlagsUnaryOperator(TextStream &s,
- const AbstractMetaEnum &cppEnum,
- const QString &pyOpName,
- const QString &cppOpName,
- bool boolResult = false);
-
- /// Writes the function that registers the multiple inheritance information for the classes that need it.
- static void writeMultipleInheritanceInitializerFunction(TextStream &s, const AbstractMetaClass *metaClass);
- /// Writes the implementation of special cast functions, used when we need to cast a class with multiple inheritance.
- static void writeSpecialCastFunction(TextStream &s, const AbstractMetaClass *metaClass);
+ static void writeSignalInitialization(TextStream &s, const AbstractMetaClassCPtr &metaClass);
+
+ /// Writes the function that registers the multiple inheritance information
+ /// for the classes that need it.
+ static void writeMultipleInheritanceInitializerFunction(TextStream &s,
+ const AbstractMetaClassCPtr &metaClass);
+ /// Writes the implementation of special cast functions, used when we need
+ /// to cast a class with multiple inheritance.
+ static void writeSpecialCastFunction(TextStream &s, const AbstractMetaClassCPtr &metaClass);
static void writePrimitiveConverterInitialization(TextStream &s,
const CustomConversionPtr &customConversion);
- static void writeFlagsConverterInitialization(TextStream &s, const FlagsTypeEntryCPtr &enumType);
static void writeEnumConverterInitialization(TextStream &s, const AbstractMetaEnum &metaEnum);
- QString writeContainerConverterInitialization(TextStream &s, const AbstractMetaType &type) const;
+ static QString writeContainerConverterInitialization(TextStream &s,
+ const AbstractMetaType &type,
+ const ApiExtractorResult &api);
void writeSmartPointerConverterInitialization(TextStream &s, const AbstractMetaType &ype) const;
+
+ static QString typeInitStruct(const TypeEntryCPtr &te);
static void writeExtendedConverterInitialization(TextStream &s,
const TypeEntryCPtr &externalType,
const AbstractMetaClassCList &conversions);
@@ -486,24 +504,25 @@ private:
* \return name of the multiple inheritance information initializer function or
* an empty string if there is no multiple inheritance in its ancestry.
*/
- static QString multipleInheritanceInitializerFunctionName(const AbstractMetaClass *metaClass);
+ static QString multipleInheritanceInitializerFunctionName(const AbstractMetaClassCPtr &metaClass);
/// Returns a list of all classes to which the given class could be cast.
- static QStringList getAncestorMultipleInheritance(const AbstractMetaClass *metaClass);
+ static QStringList getAncestorMultipleInheritance(const AbstractMetaClassCPtr &metaClass);
/// Returns true if the given class supports the python number protocol
- bool supportsNumberProtocol(const AbstractMetaClass *metaClass) const;
+ static bool supportsNumberProtocol(const AbstractMetaClassCPtr &metaClass);
/// Returns true if the given class supports the python sequence protocol
- static bool supportsSequenceProtocol(const AbstractMetaClass *metaClass) ;
+ static bool supportsSequenceProtocol(const AbstractMetaClassCPtr &metaClass) ;
/// Returns true if the given class supports the python mapping protocol
- static bool supportsMappingProtocol(const AbstractMetaClass *metaClass) ;
+ static bool supportsMappingProtocol(const AbstractMetaClassCPtr &metaClass) ;
/// Returns true if generator should produce getters and setters for the given class.
- bool shouldGenerateGetSetList(const AbstractMetaClass *metaClass) const;
+ static bool shouldGenerateGetSetList(const AbstractMetaClassCPtr &metaClass);
- void writeHashFunction(TextStream &s, const GeneratorContext &context) const;
+ static bool hasHashFunction(const AbstractMetaClassCPtr &c);
+ static void writeHashFunction(TextStream &s, const GeneratorContext &context);
/// Write default implementations for sequence protocol
void writeDefaultSequenceMethods(TextStream &s, const GeneratorContext &context) const;
@@ -511,23 +530,36 @@ private:
static void writeIndexError(TextStream &s, const QString &errorMsg,
ErrorReturn errorReturn);
- QString writeReprFunction(TextStream &s, const GeneratorContext &context,
- uint indirections) const;
-
- BoolCastFunctionOptional boolCast(const AbstractMetaClass *metaClass) const;
- bool hasBoolCast(const AbstractMetaClass *metaClass) const
+ static QString writeReprFunctionHeader(TextStream &s, const GeneratorContext &context);
+ static QString writeReprFunction(TextStream &s,
+ const GeneratorContext &context,
+ uint indirections);
+ static QString writeSmartPointerReprFunction(TextStream &s,
+ const GeneratorContext &context);
+ static QString writeSmartPointerDirFunction(TextStream &s,
+ TextStream &definitionStream,
+ TextStream &signatureStream,
+ const GeneratorContext &context);
+ static void writeReprFunctionFooter(TextStream &s);
+ static void writePyMethodDefs(TextStream &s, const QString &className,
+ const QString &methodsDefinitions);
+
+ void writeModuleCodeSnips(TextStream &s, const CodeSnipList &codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language) const;
+
+ static bool hasBoolCast(const AbstractMetaClassCPtr &metaClass)
{ return boolCast(metaClass).has_value(); }
- std::optional<AbstractMetaType>
- findSmartPointerInstantiation(const SmartPointerTypeEntryCPtr &pointer,
- const TypeEntryCPtr &pointee) const;
void clearTpFuncs();
+ static QString chopType(QString s);
QHash<QString, QString> m_tpFuncs;
-
- static const char *PYTHON_TO_CPPCONVERSION_STRUCT;
+ QHash<QString, QString> m_nbFuncs;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(CppGenerator::CppSelfDefinitionFlags)
+TextStream &operator<<(TextStream &s, CppGenerator::ErrorReturn r);
+
#endif // CPPGENERATOR_H
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator_container.cpp b/sources/shiboken6/generator/shiboken/cppgenerator_container.cpp
index 38cb5b3c1..00e0cabea 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator_container.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator_container.cpp
@@ -2,11 +2,13 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "cppgenerator.h"
+#include "generatorstrings.h"
#include <abstractmetalang.h>
#include "apiextractorresult.h"
#include "ctypenames.h"
#include "containertypeentry.h"
#include "textstream.h"
+#include "typedatabase.h"
#include <QtCore/QDebug>
@@ -53,23 +55,37 @@ static void writeSlot(TextStream &s, const QString &privateObjType,
// Write creation function from C++ reference, used by field accessors
// and getters which are within extern "C"
+
+enum ContainerCreationFlag
+{
+ None = 0,
+ Const = 0x1,
+ Allocate = 0x2
+};
+
+Q_DECLARE_FLAGS(ContainerCreationFlags, ContainerCreationFlag)
+Q_DECLARE_OPERATORS_FOR_FLAGS(ContainerCreationFlags)
+
static void writeContainerCreationFunc(TextStream &s,
const QString &funcName,
const QString &typeFName,
const QString &containerSignature,
- bool isConst = false)
+ ContainerCreationFlags flags = {})
{
// creation function from C++ reference, used by field accessors
// which are within extern "C"
s << "extern \"C\" PyObject *" << funcName << '(';
- if (isConst)
+ if (flags.testFlag(ContainerCreationFlag::Const))
s << "const ";
s << containerSignature << "* ct)\n{\n" << indent
<< "auto *container = PyObject_New(ShibokenContainer, " << typeFName << "());\n"
<< "auto *d = new ShibokenSequenceContainerPrivate<"
<< containerSignature << ">();\n";
- if (isConst) {
+ if (flags.testFlag(ContainerCreationFlag::Allocate)) {
+ s << "d->m_list = new " << containerSignature << "(*ct);\n"
+ << "d->m_ownsList = true;\n";
+ } else if (flags.testFlag(ContainerCreationFlag::Const)) {
s << "d->m_list = const_cast<" << containerSignature << " *>(ct);\n"
<< "d->m_const = true;\n";
} else {
@@ -80,34 +96,22 @@ static void writeContainerCreationFunc(TextStream &s,
<< "}\n\n";
}
-// Generate code for a type wrapping a C++ container instantiation
-CppGenerator::OpaqueContainerData
- CppGenerator::writeOpaqueContainerConverterFunctions(TextStream &s,
- const AbstractMetaType &containerType) const
+// Generate template specialization of value converter helper
+void CppGenerator::writeOpaqueContainerValueConverter(TextStream &s,
+ const AbstractMetaType &valueType) const
{
- OpaqueContainerData result;
- const auto &valueType = containerType.instantiations().constFirst();
- const auto containerTypeEntry = qSharedPointerCast<const ContainerTypeEntry>(containerType.typeEntry());
- result.name = containerTypeEntry->opaqueContainerName(valueType.typeEntry()->name());
-
- const auto cppSignature = containerType.cppSignature();
- s << "\n// Binding for " << cppSignature << "\n\n";
-
// Generate template specialization of value converter helper unless it is already there
- const QString pyArg = u"pyArg"_s;
- const QString cppArg = u"cppArg"_s;
-
const QString valueTypeName = valueType.cppSignature();
const QString checkFunction = cpythonCheckFunction(valueType);
s << "template <>\nstruct ShibokenContainerValueConverter<"
<< valueTypeName << ">\n{\n";
// Type check
- s << indent << "static bool checkValue(PyObject *" << pyArg << ")\n{\n"
+ s << indent << "static bool checkValue(PyObject *" << PYTHON_ARG << ")\n{\n"
<< indent << "return " << checkFunction;
if (!checkFunction.contains(u'('))
s << '(';
- s << pyArg << ");\n"
+ s << PYTHON_ARG << ");\n"
<< outdent << "}\n\n";
// C++ to Python
@@ -119,42 +123,68 @@ CppGenerator::OpaqueContainerData
s << valueTypeName << ' ';
if (passByConstRef)
s << '&';
- s << cppArg << ")\n{\n" << indent << "return ";
- writeToPythonConversion(s, valueType, nullptr, cppArg);
+ s << CPP_ARG << ")\n{\n" << indent << "return ";
+ writeToPythonConversion(s, valueType, nullptr, CPP_ARG);
s << ";\n" << outdent << "}\n\n";
// Python to C++
s << "static std::optional<" << valueTypeName << "> convertValueToCpp(PyObject *"
- << pyArg << ")\n{\n" << indent;
+ << PYTHON_ARG << ")\n{\n" << indent;
s << PYTHON_TO_CPPCONVERSION_STRUCT << ' ' << PYTHON_TO_CPP_VAR << ";\n"
<< "if (!(";
- writeTypeCheck(s, valueType, pyArg), isNumber(valueType.typeEntry());
+ writeTypeCheck(s, valueType, PYTHON_ARG), isNumber(valueType.typeEntry());
s << ")) {\n" << indent
<< "Shiboken::Errors::setWrongContainerType();\n"
<< "return {};\n" << outdent << "}\n";
- writePythonToCppTypeConversion(s, valueType, pyArg, cppArg, nullptr, {});
- s << "return " << cppArg << ";\n" << outdent << "}\n" << outdent << "};\n\n";
+ writePythonToCppTypeConversion(s, valueType, PYTHON_ARG, CPP_ARG, nullptr, {});
+ s << "return " << CPP_ARG << ";\n" << outdent << "}\n" << outdent << "};\n\n";
+}
+
+// Generate code for a type wrapping a C++ container instantiation
+CppGenerator::OpaqueContainerData
+ CppGenerator::writeOpaqueContainerConverterFunctions(TextStream &s,
+ const AbstractMetaType &containerType,
+ QSet<AbstractMetaType> *valueTypes) const
+{
+ OpaqueContainerData result;
+ const auto &valueType = containerType.instantiations().constFirst();
+ const auto containerTypeEntry = std::static_pointer_cast<const ContainerTypeEntry>(containerType.typeEntry());
+ result.name =
+ containerTypeEntry->opaqueContainerName(containerType.instantiationCppSignatures());
+
+ const auto cppSignature = containerType.cppSignature();
+ s << "\n// Binding for " << cppSignature << "\n\n";
+
+ if (!valueTypes->contains(valueType)) {
+ valueTypes->insert(valueType);
+ writeOpaqueContainerValueConverter(s, valueType);
+ }
const QString privateObjType = u"ShibokenSequenceContainerPrivate<"_s
+ cppSignature + u'>';
// methods
- const bool isStdVector = containerType.name() == u"std::vector";
+ const QString &containerName = containerType.name();
+ const bool isStdVector = containerName == u"std::vector";
+ const auto kind = containerTypeEntry->containerKind();
+ const bool isFixed = kind == ContainerTypeEntry::SpanContainer || containerName == u"std::array";
const QString methods = result.name + u"_methods"_s;
s << "static PyMethodDef " << methods << "[] = {\n" << indent;
- writeMethod(s, privateObjType, "push_back");
- writeMethod(s, privateObjType, "push_back", "append"); // Qt convention
- writeNoArgsMethod(s, privateObjType, "clear");
- writeNoArgsMethod(s, privateObjType, "pop_back");
- writeNoArgsMethod(s, privateObjType, "pop_back", "removeLast"); // Qt convention
- if (!isStdVector) {
- writeMethod(s, privateObjType, "push_front");
- writeMethod(s, privateObjType, "push_front", "prepend"); // Qt convention
- writeNoArgsMethod(s, privateObjType, "pop_front");
- writeMethod(s, privateObjType, "pop_front", "removeFirst"); // Qt convention
+ if (!isFixed) {
+ writeMethod(s, privateObjType, "push_back");
+ writeMethod(s, privateObjType, "push_back", "append"); // Qt convention
+ writeNoArgsMethod(s, privateObjType, "clear");
+ writeNoArgsMethod(s, privateObjType, "pop_back");
+ writeNoArgsMethod(s, privateObjType, "pop_back", "removeLast"); // Qt convention
+ if (!isStdVector) {
+ writeMethod(s, privateObjType, "push_front");
+ writeMethod(s, privateObjType, "push_front", "prepend"); // Qt convention
+ writeNoArgsMethod(s, privateObjType, "pop_front");
+ writeMethod(s, privateObjType, "pop_front", "removeFirst"); // Qt convention
+ }
+ writeMethod(s, privateObjType, "reserve"); // SFINAE'd out for list
+ writeNoArgsMethod(s, privateObjType, "capacity");
}
- writeMethod(s, privateObjType, "reserve");
- writeNoArgsMethod(s, privateObjType, "capacity");
writeNoArgsMethod(s, privateObjType, "data");
writeNoArgsMethod(s, privateObjType, "constData");
s << "{nullptr, nullptr, 0, nullptr} // Sentinel\n"
@@ -164,7 +194,8 @@ CppGenerator::OpaqueContainerData
const QString slotsList = result.name + u"_slots"_s;
s << "static PyType_Slot " << slotsList << "[] = {\n" << indent;
writeSlot(s, privateObjType, "Py_tp_init", "tpInit");
- writeSlot(s, privateObjType, "Py_tp_new", "tpNew");
+ const auto *tpNew = containerTypeEntry->viewOn() == nullptr ? "tpNew" : "tpNewInvalid";
+ writeSlot(s, privateObjType, "Py_tp_new", tpNew);
writeSlot(s, privateObjType, "Py_tp_free", "tpFree");
writeSlot(s, "Py_tp_dealloc", "Sbk_object_dealloc"); // FIXME?
writeSlot(s, "Py_tp_methods", methods.toUtf8().constData());
@@ -175,7 +206,8 @@ CppGenerator::OpaqueContainerData
// spec
const QString specName = result.name + u"_spec"_s;
- const QString name = moduleName() + u'.' + result.name;
+ const QString name = TypeDatabase::instance()->defaultPackageName()
+ + u'.' + result.name;
s << "static PyType_Spec " << specName << " = {\n" << indent
<< "\"" << name.count(u'.') << ':' << name << "\",\n"
<< "sizeof(ShibokenContainer),\n0,\nPy_TPFLAGS_DEFAULT,\n"
@@ -186,7 +218,8 @@ CppGenerator::OpaqueContainerData
s << "static inline PyTypeObject *" << typeCreationFName << "()\n{\n" << indent
<< "auto *result = reinterpret_cast<PyTypeObject *>(SbkType_FromSpec(&"
<< specName << "));\nPy_INCREF(Py_True);\n"
- << "PyDict_SetItem(result->tp_dict, "
+ << "Shiboken::AutoDecRef tpDict(PepType_GetDict(result));\n"
+ << "PyDict_SetItem(tpDict.object(), "
"Shiboken::PyMagicName::opaque_container(), Py_True);\n"
<< "return result;\n" << outdent << "}\n\n";
@@ -197,32 +230,37 @@ CppGenerator::OpaqueContainerData
<< "();\nreturn type;\n" << outdent << "}\n\n";
// creation functions from C++ references
+ ContainerCreationFlags flags;
+ if (kind == ContainerTypeEntry::SpanContainer)
+ flags.setFlag(ContainerCreationFlag::Allocate);
+
writeContainerCreationFunc(s, u"create"_s + result.name, typeFName,
- containerType.cppSignature());
+ containerType.cppSignature(), flags);
+ flags.setFlag(ContainerCreationFlag::Const);
writeContainerCreationFunc(s, u"createConst"_s + result.name, typeFName,
- containerType.cppSignature(), true);
+ containerType.cppSignature(), flags);
// Check function
result.checkFunctionName = result.name + u"_Check"_s;
- s << "extern \"C\" int " << result.checkFunctionName << "(PyObject *" << pyArg
- << ")\n{\n" << indent << "return " << pyArg << " != nullptr && "
- << pyArg << " != Py_None && " << pyArg << "->ob_type == "
+ s << "extern \"C\" int " << result.checkFunctionName << "(PyObject *" << PYTHON_ARG
+ << ")\n{\n" << indent << "return " << PYTHON_ARG << " != nullptr && "
+ << PYTHON_ARG << " != Py_None && " << PYTHON_ARG << "->ob_type == "
<< typeFName << "();\n" << outdent << "}\n\n";
// SBK converter Python to C++
result.pythonToConverterFunctionName = u"PythonToCpp"_s + result.name;
s << "extern \"C\" void " << result.pythonToConverterFunctionName
- << "(PyObject *" << pyArg << ", void *cppOut)\n{\n" << indent
+ << "(PyObject *" << PYTHON_ARG << ", void *cppOut)\n{\n" << indent
<< "auto *d = ShibokenSequenceContainerPrivate<" << cppSignature
- << ">::get(" << pyArg << ");\n"
+ << ">::get(" << PYTHON_ARG << ");\n"
<< "*reinterpret_cast<" << cppSignature << "**>(cppOut) = d->m_list;\n"
<< outdent << "}\n\n";
// SBK check function for converting Python to C++ that returns the converter
result.converterCheckFunctionName = u"is"_s + result.name + u"PythonToCppConvertible"_s;
s << "extern \"C\" PythonToCppFunc " << result.converterCheckFunctionName
- << "(PyObject *" << pyArg << ")\n{\n" << indent << "if ("
- << result.checkFunctionName << '(' << pyArg << "))\n" << indent
+ << "(PyObject *" << PYTHON_ARG << ")\n{\n" << indent << "if ("
+ << result.checkFunctionName << '(' << PYTHON_ARG << "))\n" << indent
<< "return " << result.pythonToConverterFunctionName << ";\n"
<< outdent << "return {};\n" << outdent << "}\n\n";
diff --git a/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp b/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp
new file mode 100644
index 000000000..a00c2ba50
--- /dev/null
+++ b/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp
@@ -0,0 +1,474 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "cppgenerator.h"
+#include "generatorstrings.h"
+#include "generatorcontext.h"
+#include <apiextractorresult.h>
+#include <abstractmetafunction.h>
+#include <abstractmetalang.h>
+#include <codesnip.h>
+#include <exception.h>
+#include <messages.h>
+#include <textstream.h>
+#include <overloaddata.h>
+#include <smartpointertypeentry.h>
+
+#include <QtCore/QDebug>
+
+using namespace Qt::StringLiterals;
+
+static const char smartPtrComment[] =
+ "// Try to find the 'name' attribute, by retrieving the PyObject for "
+ "the corresponding C++ object held by the smart pointer.\n";
+
+static QString smartPointerGetter(const GeneratorContext &context)
+{
+ const auto te = context.metaClass()->typeEntry();
+ Q_ASSERT(te->isSmartPointer());
+ return std::static_pointer_cast<const SmartPointerTypeEntry>(te)->getter();
+}
+
+struct callGetter
+{
+ explicit callGetter(const GeneratorContext &context) : m_context(context) {}
+
+ const GeneratorContext &m_context;
+};
+
+TextStream &operator<<(TextStream &str, const callGetter &c)
+{
+ str << "PyObject_CallMethod(self, \"" << smartPointerGetter(c.m_context) << "\", 0)";
+ return str;
+}
+
+// Helpers to collect all smart pointer pointee base classes
+static AbstractMetaClassCList
+ findSmartPointeeBaseClasses(const ApiExtractorResult &api,
+ const AbstractMetaType &smartPointerType)
+{
+ AbstractMetaClassCList result;
+ auto instantiationsTe = smartPointerType.instantiations().at(0).typeEntry();
+ auto targetClass = AbstractMetaClass::findClass(api.classes(), instantiationsTe);
+ if (targetClass != nullptr)
+ result = targetClass->allTypeSystemAncestors();
+ return result;
+}
+
+using ComparisonOperatorList = QList<AbstractMetaFunction::ComparisonOperatorType>;
+
+// Return the available comparison operators for smart pointers
+static ComparisonOperatorList smartPointeeComparisons(const GeneratorContext &context)
+{
+ Q_ASSERT(context.forSmartPointer());
+ auto te = context.preciseType().instantiations().constFirst().typeEntry();
+ if (isExtendedCppPrimitive(te)) { // Primitive pointee types have all
+ return {AbstractMetaFunction::OperatorEqual,
+ AbstractMetaFunction::OperatorNotEqual,
+ AbstractMetaFunction::OperatorLess,
+ AbstractMetaFunction::OperatorLessEqual,
+ AbstractMetaFunction::OperatorGreater,
+ AbstractMetaFunction::OperatorGreaterEqual};
+ }
+
+ const auto pointeeClass = context.pointeeClass();
+ if (!pointeeClass)
+ return {};
+
+ ComparisonOperatorList result;
+ const auto &comparisons =
+ pointeeClass->operatorOverloads(OperatorQueryOption::SymmetricalComparisonOp);
+ for (const auto &f : comparisons) {
+ const auto ct = f->comparisonOperatorType().value();
+ if (!result.contains(ct))
+ result.append(ct);
+ }
+ return result;
+}
+
+static bool hasParameterPredicate(const AbstractMetaFunctionCPtr &f)
+{
+ return !f->arguments().isEmpty();
+}
+
+void CppGenerator::generateSmartPointerClass(TextStream &s, const GeneratorContext &classContext)
+{
+ s.setLanguage(TextStream::Language::Cpp);
+ AbstractMetaClassCPtr metaClass = classContext.metaClass();
+ const auto typeEntry = std::static_pointer_cast<const SmartPointerTypeEntry>(metaClass->typeEntry());
+ const bool hasPointeeClass = classContext.pointeeClass() != nullptr;
+ const auto smartPointerType = typeEntry->smartPointerType();
+ const bool isValueHandle = smartPointerType ==TypeSystem::SmartPointerType::ValueHandle;
+
+ IncludeGroup includes{u"Extra includes"_s, typeEntry->extraIncludes()};
+ if (hasPointeeClass)
+ includes.append(classContext.pointeeClass()->typeEntry()->include());
+ includes.includes.append({Include::IncludePath, u"sbksmartpointer.h"_s});
+ generateIncludes(s, classContext, {includes});
+
+ s << '\n';
+
+ // class inject-code native/beginning
+ if (!typeEntry->codeSnips().isEmpty()) {
+ writeClassCodeSnips(s, typeEntry->codeSnips(),
+ TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode,
+ classContext);
+ s << '\n';
+ }
+
+ StringStream smd(TextStream::Language::Cpp);
+ StringStream md(TextStream::Language::Cpp);
+ StringStream signatureStream(TextStream::Language::Cpp);
+
+ s << openTargetExternC;
+
+ const auto &functionGroups = getFunctionGroups(metaClass);
+
+ // Skip all public methods of the smart pointer except for the special
+ // methods declared in the type entry.
+
+ auto ctors = metaClass->queryFunctions(FunctionQueryOption::Constructors);
+ if (!hasPointeeClass && !isValueHandle) { // Cannot generate "int*"
+ auto end = std::remove_if(ctors.begin(), ctors.end(), hasParameterPredicate);
+ ctors.erase(end, ctors.end());
+ }
+
+ if (!ctors.isEmpty()) {
+ OverloadData overloadData(ctors, api());
+ writeConstructorWrapper(s, overloadData, classContext);
+ writeSignatureInfo(signatureStream, overloadData);
+ }
+
+ if (!typeEntry->resetMethod().isEmpty()) {
+ auto it = functionGroups.constFind(typeEntry->resetMethod());
+ if (it == functionGroups.cend())
+ throw Exception(msgCannotFindSmartPointerMethod(typeEntry, typeEntry->resetMethod()));
+ AbstractMetaFunctionCList resets = it.value();
+ if (!hasPointeeClass && !isValueHandle) { // Cannot generate "int*"
+ auto end = std::remove_if(resets.begin(), resets.end(), hasParameterPredicate);
+ resets.erase(end, resets.end());
+ }
+ if (!resets.isEmpty())
+ writeMethodWrapper(s, md, signatureStream, resets, classContext);
+ }
+
+ auto it = functionGroups.constFind(typeEntry->getter());
+ if (it == functionGroups.cend() || it.value().size() != 1)
+ throw Exception(msgCannotFindSmartPointerGetter(typeEntry));
+
+ writeMethodWrapper(s, md, signatureStream, it.value(), classContext);
+
+ QStringList optionalMethods;
+ if (!typeEntry->refCountMethodName().isEmpty())
+ optionalMethods.append(typeEntry->refCountMethodName());
+ const QString valueCheckMethod = typeEntry->valueCheckMethod();
+ if (!valueCheckMethod.isEmpty() && !valueCheckMethod.startsWith(u"operator"))
+ optionalMethods.append(valueCheckMethod);
+ if (!typeEntry->nullCheckMethod().isEmpty())
+ optionalMethods.append(typeEntry->nullCheckMethod());
+
+ for (const QString &optionalMethod : optionalMethods) {
+ auto it = functionGroups.constFind(optionalMethod);
+ if (it == functionGroups.cend() || it.value().size() != 1)
+ throw Exception(msgCannotFindSmartPointerMethod(typeEntry, optionalMethod));
+ writeMethodWrapper(s, md, signatureStream, it.value(), classContext);
+ }
+
+ writeCopyFunction(s, md, signatureStream, classContext);
+ writeSmartPointerDirFunction(s, md, signatureStream, classContext);
+
+ const QString methodsDefinitions = md.toString();
+ const QString singleMethodDefinitions = smd.toString();
+
+ const QString className = chopType(cpythonTypeName(typeEntry));
+
+ // Write single method definitions
+ s << singleMethodDefinitions;
+
+ // Write methods definition
+ writePyMethodDefs(s, className, methodsDefinitions);
+
+ // Write tp_s/getattro function
+ const auto boolCastOpt = boolCast(metaClass);
+ writeSmartPointerGetattroFunction(s, classContext, boolCastOpt);
+ writeSmartPointerSetattroFunction(s, classContext);
+
+ if (boolCastOpt.has_value())
+ writeNbBoolFunction(classContext, boolCastOpt.value(), s);
+
+ if (smartPointerType == TypeSystem::SmartPointerType::Shared)
+ writeSmartPointerRichCompareFunction(s, classContext);
+
+ s << closeExternC;
+
+ if (hasHashFunction(metaClass))
+ writeHashFunction(s, classContext);
+
+ // Write tp_traverse and tp_clear functions.
+ writeTpTraverseFunction(s, metaClass);
+ writeTpClearFunction(s, metaClass);
+
+ writeClassDefinition(s, metaClass, classContext);
+
+ s << '\n';
+
+ writeConverterFunctions(s, metaClass, classContext);
+ writeClassRegister(s, metaClass, classContext, signatureStream);
+
+ // class inject-code native/end
+ if (!typeEntry->codeSnips().isEmpty()) {
+ writeClassCodeSnips(s, typeEntry->codeSnips(),
+ TypeSystem::CodeSnipPositionEnd, TypeSystem::NativeCode,
+ classContext);
+ s << '\n';
+ }
+}
+
+void CppGenerator::writeSmartPointerConverterFunctions(TextStream &s,
+ const AbstractMetaType &smartPointerType) const
+{
+ const auto baseClasses = findSmartPointeeBaseClasses(api(), smartPointerType);
+ if (baseClasses.isEmpty())
+ return;
+
+ auto smartPointerTypeEntry =
+ std::static_pointer_cast<const SmartPointerTypeEntry>(smartPointerType.typeEntry());
+
+ // TODO: Missing conversion to smart pointer pointer type:
+
+ s << "// Register smartpointer conversion for all derived classes\n";
+ for (const auto &base : baseClasses) {
+ auto baseTe = base->typeEntry();
+ if (smartPointerTypeEntry->matchesInstantiation(baseTe)) {
+ if (auto opt = api().findSmartPointerInstantiation(smartPointerTypeEntry, baseTe)) {
+ const auto &smartTargetType = opt.value().type;
+ s << "// SmartPointer derived class: "
+ << smartTargetType.cppSignature() << "\n";
+ writePythonToCppConversionFunctions(s, smartPointerType,
+ smartTargetType, {}, {}, {});
+ }
+ }
+ }
+}
+
+void CppGenerator::writeSmartPointerCppSelfConversion(TextStream &s,
+ const GeneratorContext &context)
+{
+ Q_ASSERT(context.forSmartPointer());
+ s << cpythonWrapperCPtr(context.preciseType(), u"self"_s);
+}
+
+void CppGenerator::writeSmartPointerCppSelfDefinition(TextStream &s,
+ const GeneratorContext &context,
+ ErrorReturn errorReturn,
+ CppSelfDefinitionFlags flags)
+{
+ Q_ASSERT(context.forSmartPointer());
+ writeInvalidPyObjectCheck(s, u"self"_s, errorReturn);
+ writeCppSelfVarDef(s, flags);
+ writeSmartPointerCppSelfConversion(s, context);
+ s << ";\n";
+}
+
+void CppGenerator::writeSmartPointerConverterInitialization(TextStream &s,
+ const AbstractMetaType &type) const
+{
+ const QByteArray cppSignature = type.cppSignature().toUtf8();
+ auto writeConversionRegister = [&s](const AbstractMetaType &sourceType,
+ const QString &targetTypeName,
+ const QString &targetConverter)
+ {
+ const QString sourceTypeName = fixedCppTypeName(sourceType);
+ const QString toCpp = pythonToCppFunctionName(sourceTypeName, targetTypeName);
+ const QString isConv = convertibleToCppFunctionName(sourceTypeName, targetTypeName);
+
+ writeAddPythonToCppConversion(s, targetConverter, toCpp, isConv);
+ };
+
+ const auto classes = findSmartPointeeBaseClasses(api(), type);
+ if (classes.isEmpty())
+ return;
+
+ auto smartPointerTypeEntry = std::static_pointer_cast<const SmartPointerTypeEntry>(type.typeEntry());
+
+ s << "// Register SmartPointer converter for type '" << cppSignature << "'." << '\n'
+ << "///////////////////////////////////////////////////////////////////////////////////////\n\n";
+
+ for (const auto &base : classes) {
+ auto baseTe = base->typeEntry();
+ if (auto opt = api().findSmartPointerInstantiation(smartPointerTypeEntry, baseTe)) {
+ const auto &smartTargetType = opt.value().type;
+ s << "// Convert to SmartPointer derived class: ["
+ << smartTargetType.cppSignature() << "]\n";
+ const QString converter = u"Shiboken::Conversions::getConverter(\""_s
+ + smartTargetType.cppSignature() + u"\")"_s;
+ writeConversionRegister(type, fixedCppTypeName(smartTargetType), converter);
+ } else {
+ s << "// Class not found:" << type.instantiations().at(0).cppSignature();
+ }
+ }
+
+ s << "///////////////////////////////////////////////////////////////////////////////////////" << '\n' << '\n';
+}
+
+void CppGenerator::writeSmartPointerRichCompareFunction(TextStream &s,
+ const GeneratorContext &context) const
+{
+ static const char selfPointeeVar[] = "cppSelfPointee";
+ static const char cppArg0PointeeVar[] = "cppArg0Pointee";
+
+ const auto metaClass = context.metaClass();
+ QString baseName = cpythonBaseName(metaClass);
+ writeRichCompareFunctionHeader(s, baseName, context);
+
+ s << "if (";
+ writeTypeCheck(s, context.preciseType(), PYTHON_ARG);
+ s << ") {\n" << indent;
+ writeArgumentConversion(s, context.preciseType(), CPP_ARG0,
+ PYTHON_ARG, ErrorReturn::Default, metaClass);
+
+ const auto te = context.preciseType().typeEntry();
+ Q_ASSERT(te->isSmartPointer());
+ const auto ste = std::static_pointer_cast<const SmartPointerTypeEntry>(te);
+
+ s << "const auto *" << selfPointeeVar << " = " << CPP_SELF_VAR
+ << '.' << ste->getter() << "();\n";
+ s << "const auto *" << cppArg0PointeeVar << " = " << CPP_ARG0
+ << '.' << ste->getter() << "();\n";
+
+ // If we have an object without any comparisons, only generate a simple
+ // equality check by pointee address
+ auto availableOps = smartPointeeComparisons(context);
+ const bool comparePointeeAddressOnly = availableOps.isEmpty();
+ if (comparePointeeAddressOnly) {
+ availableOps << AbstractMetaFunction::OperatorEqual
+ << AbstractMetaFunction::OperatorNotEqual;
+ } else {
+ // For value types with operators, we complain about nullptr
+ s << "if (" << selfPointeeVar << " == nullptr || " << cppArg0PointeeVar
+ << " == nullptr) {\n" << indent
+ << "PyErr_SetString(PyExc_NotImplementedError, \"nullptr passed to comparison.\");\n"
+ << ErrorReturn::Default << '\n' << outdent << "}\n";
+ }
+
+ s << "bool " << CPP_RETURN_VAR << "= false;\n"
+ << "switch (op) {\n";
+ for (auto op : availableOps) {
+ s << "case " << AbstractMetaFunction::pythonRichCompareOpCode(op) << ":\n"
+ << indent << CPP_RETURN_VAR << " = ";
+ if (comparePointeeAddressOnly) {
+ s << selfPointeeVar << ' ' << AbstractMetaFunction::cppComparisonOperator(op)
+ << ' ' << cppArg0PointeeVar << ";\n";
+ } else {
+ // Shortcut for equality: Check pointee address
+ if (op == AbstractMetaFunction::OperatorEqual
+ || op == AbstractMetaFunction::OperatorLessEqual
+ || op == AbstractMetaFunction::OperatorGreaterEqual) {
+ s << selfPointeeVar << " == " << cppArg0PointeeVar << " || ";
+ }
+ // Generate object's comparison
+ s << "*" << selfPointeeVar << ' '
+ << AbstractMetaFunction::cppComparisonOperator(op) << " *"
+ << cppArg0PointeeVar << ";\n";
+ }
+ s << "break;\n" << outdent;
+
+ }
+ if (availableOps.size() < 6) {
+ s << "default:\n" << indent
+ << richCompareComment
+ << "return FallbackRichCompare(self, " << PYTHON_ARG << ", op);\n" << outdent;
+ }
+ s << "}\n" << PYTHON_RETURN_VAR << " = " << CPP_RETURN_VAR
+ << " ? Py_True : Py_False;\n"
+ << "Py_INCREF(" << PYTHON_RETURN_VAR << ");\n"
+ << outdent << "}\n"
+ << "return Shiboken::returnFromRichCompare(" << PYTHON_RETURN_VAR << ");\n"
+ << outdent << "}\n\n";
+}
+
+void CppGenerator::writeSmartPointerSetattroFunction(TextStream &s,
+ const GeneratorContext &context)
+{
+ Q_ASSERT(context.forSmartPointer());
+ writeSetattroDefinition(s, context.metaClass());
+ s << smartPtrComment
+ << "if (auto *rawObj = " << callGetter(context) << ") {\n" << indent
+ << "if (PyObject_HasAttr(rawObj, name) != 0)\n" << indent
+ << "return PyObject_GenericSetAttr(rawObj, name, value);\n" << outdent
+ << "Py_DECREF(rawObj);\n" << outdent
+ << "}\n";
+ writeSetattroDefaultReturn(s);
+}
+
+void CppGenerator::writeSmartPointerGetattroFunction(TextStream &s,
+ const GeneratorContext &context,
+ const BoolCastFunctionOptional &boolCast)
+{
+ Q_ASSERT(context.forSmartPointer());
+ const auto metaClass = context.metaClass();
+ writeGetattroDefinition(s, metaClass);
+ s << "PyObject *tmp = PyObject_GenericGetAttr(self, name);\n"
+ << "if (tmp)\n" << indent << "return tmp;\n" << outdent
+ << "if (PyErr_ExceptionMatches(PyExc_AttributeError) == 0)\n"
+ << indent << "return nullptr;\n" << outdent
+ << "PyErr_Clear();\n";
+
+ if (boolCast.has_value()) {
+ writeSmartPointerCppSelfDefinition(s, context);
+ s << "if (";
+ writeNbBoolExpression(s, boolCast.value(), true /* invert */);
+ s << ") {\n" << indent
+ << R"(PyTypeObject *tp = Py_TYPE(self);
+PyErr_Format(PyExc_AttributeError, "Attempt to retrieve '%s' from null object '%s'.",
+ Shiboken::String::toCString(name), tp->tp_name);
+return nullptr;
+)" << outdent << "}\n";
+ }
+
+ // This generates the code which dispatches access to member functions
+ // and fields from the smart pointer to its pointee.
+ s << smartPtrComment
+ << "if (auto *rawObj = " << callGetter(context) << ") {\n" << indent
+ << "if (auto *attribute = PyObject_GetAttr(rawObj, name))\n"
+ << indent << "tmp = attribute;\n" << outdent
+ << "Py_DECREF(rawObj);\n" << outdent
+ << "}\n"
+ << "if (!tmp) {\n" << indent
+ << R"(PyTypeObject *tp = Py_TYPE(self);
+PyErr_Format(PyExc_AttributeError,
+ "'%.50s' object has no attribute '%.400s'",
+ tp->tp_name, Shiboken::String::toCString(name));
+)" << outdent
+ << "}\n"
+ << "return tmp;\n" << outdent << "}\n\n";
+}
+
+QString CppGenerator::writeSmartPointerReprFunction(TextStream &s,
+ const GeneratorContext &context)
+{
+ const auto metaClass = context.metaClass();
+ QString funcName = writeReprFunctionHeader(s, context);
+ s << "Shiboken::AutoDecRef pointee(" << callGetter(context) << ");\n"
+ << "return Shiboken::SmartPointer::repr(self, pointee);\n";
+ writeReprFunctionFooter(s);
+ return funcName;
+}
+
+QString CppGenerator::writeSmartPointerDirFunction(TextStream &s, TextStream &definitionStream,
+ TextStream &signatureStream,
+ const GeneratorContext &context)
+{
+ QString funcName = cpythonBaseName(context.metaClass()) + u"__dir__"_s;
+
+ signatureStream << fullPythonClassName(context.metaClass()) << ".__dir__()\n";
+ definitionStream << PyMethodDefEntry{u"__dir__"_s, funcName, {"METH_NOARGS"_ba}, {}}
+ << ",\n";
+
+ s << "extern \"C\"\n{\n"
+ << "static PyObject *" << funcName << "(PyObject *self)\n{\n" << indent
+ << "Shiboken::AutoDecRef pointee(" << callGetter(context) << ");\n"
+ << "return Shiboken::SmartPointer::dir(self, pointee);\n"
+ << outdent << "}\n} // extern C\n\n";
+ return funcName;
+}
diff --git a/sources/shiboken6/generator/shiboken/ctypenames.h b/sources/shiboken6/generator/shiboken/ctypenames.h
index 0444c99f2..f665b30ff 100644
--- a/sources/shiboken6/generator/shiboken/ctypenames.h
+++ b/sources/shiboken6/generator/shiboken/ctypenames.h
@@ -6,26 +6,26 @@
#include <QtCore/QString>
-static inline QString boolT() { return QStringLiteral("bool"); }
-static inline QString intT() { return QStringLiteral("int"); }
-static inline QString unsignedT() { return QStringLiteral("unsigned"); }
-static inline QString unsignedIntT() { return QStringLiteral("unsigned int"); }
-static inline QString longT() { return QStringLiteral("long"); }
-static inline QString unsignedLongT() { return QStringLiteral("unsigned long"); }
-static inline QString shortT() { return QStringLiteral("short"); }
-static inline QString unsignedShortT() { return QStringLiteral("unsigned short"); }
-static inline QString unsignedCharT() { return QStringLiteral("unsigned char"); }
-static inline QString longLongT() { return QStringLiteral("long long"); }
-static inline QString unsignedLongLongT() { return QStringLiteral("unsigned long long"); }
-static inline QString charT() { return QStringLiteral("char"); }
-static inline QString floatT() { return QStringLiteral("float"); }
-static inline QString doubleT() { return QStringLiteral("double"); }
-static inline QString constCharPtrT() { return QStringLiteral("const char*"); }
+constexpr auto boolT = QLatin1StringView("bool");
+constexpr auto intT = QLatin1StringView("int");
+constexpr auto unsignedT = QLatin1StringView("unsigned");
+constexpr auto unsignedIntT = QLatin1StringView("unsigned int");
+constexpr auto longT = QLatin1StringView("long");
+constexpr auto unsignedLongT = QLatin1StringView("unsigned long");
+constexpr auto shortT = QLatin1StringView("short");
+constexpr auto unsignedShortT = QLatin1StringView("unsigned short");
+constexpr auto unsignedCharT = QLatin1StringView("unsigned char");
+constexpr auto longLongT = QLatin1StringView("long long");
+constexpr auto unsignedLongLongT = QLatin1StringView("unsigned long long");
+constexpr auto charT = QLatin1StringView("char");
+constexpr auto floatT = QLatin1StringView("float");
+constexpr auto doubleT = QLatin1StringView("double");
+constexpr auto constCharPtrT = QLatin1StringView("const char*");
-static inline QString qByteArrayT() { return QStringLiteral("QByteArray"); }
-static inline QString qMetaObjectT() { return QStringLiteral("QMetaObject"); }
-static inline QString qObjectT() { return QStringLiteral("QObject"); }
-static inline QString qStringT() { return QStringLiteral("QString"); }
-static inline QString qVariantT() { return QStringLiteral("QVariant"); }
+constexpr auto qByteArrayT = QLatin1StringView("QByteArray");
+constexpr auto qMetaObjectT = QLatin1StringView("QMetaObject");
+constexpr auto qObjectT = QLatin1StringView("QObject");
+constexpr auto qStringT = QLatin1StringView("QString");
+constexpr auto qVariantT = QLatin1StringView("QVariant");
#endif // CTYPENAMES_H
diff --git a/sources/shiboken6/generator/shiboken/generatorstrings.h b/sources/shiboken6/generator/shiboken/generatorstrings.h
new file mode 100644
index 000000000..9ce91e599
--- /dev/null
+++ b/sources/shiboken6/generator/shiboken/generatorstrings.h
@@ -0,0 +1,39 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef GENERATORSTRINGS_H
+#define GENERATORSTRINGS_H
+
+#include <QtCore/QString>
+
+QString CPP_ARG_N(int i);
+QString CPP_ARG_REMOVED(int i);
+
+constexpr auto CPP_RETURN_VAR = QLatin1StringView("cppResult");
+constexpr auto CPP_SELF_VAR = QLatin1StringView("cppSelf");
+constexpr auto CPP_ARG = QLatin1StringView("cppArg");
+constexpr auto NULL_PTR = QLatin1StringView("nullptr");
+constexpr auto PYTHON_ARG = QLatin1StringView("pyArg");
+constexpr auto PYTHON_ARGS = QLatin1StringView("pyArgs");
+constexpr auto PYTHON_OVERRIDE_VAR = QLatin1StringView("pyOverride");
+constexpr auto PYTHON_RETURN_VAR = QLatin1StringView("pyResult");
+constexpr auto PYTHON_SELF_VAR = QLatin1StringView("self");
+constexpr auto PYTHON_TO_CPP_VAR = QLatin1StringView("pythonToCpp");
+
+constexpr auto CONV_RULE_OUT_VAR_SUFFIX = QLatin1StringView("_out");
+constexpr auto BEGIN_ALLOW_THREADS
+ = QLatin1StringView("PyThreadState *_save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS");
+constexpr auto END_ALLOW_THREADS
+ = QLatin1StringView("PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS");
+
+constexpr auto REPR_FUNCTION = QLatin1StringView("__repr__");
+
+constexpr auto CPP_ARG0 = QLatin1StringView("cppArg0");
+
+extern const char *const METHOD_DEF_SENTINEL;
+extern const char *const PYTHON_TO_CPPCONVERSION_STRUCT;
+extern const char *const openTargetExternC;
+extern const char *const closeExternC;
+extern const char *const richCompareComment;
+
+#endif // GENERATORSTRINGS_H
diff --git a/sources/shiboken6/generator/shiboken/headergenerator.cpp b/sources/shiboken6/generator/shiboken/headergenerator.cpp
index d8e745f3e..35d0d114f 100644
--- a/sources/shiboken6/generator/shiboken/headergenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/headergenerator.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "headergenerator.h"
+#include "configurablescope.h"
#include "generatorcontext.h"
#include <apiextractorresult.h>
#include <abstractmetaargument.h>
@@ -12,6 +13,7 @@
#include <abstractmetalang_helpers.h>
#include <codesnip.h>
#include <clangparser/compilersupport.h>
+#include <exception.h>
#include <typedatabase.h>
#include <reporthandler.h>
#include <textstream.h>
@@ -19,6 +21,7 @@
#include "containertypeentry.h"
#include "enumtypeentry.h"
#include "flagstypeentry.h"
+#include <messages.h>
#include "namespacetypeentry.h"
#include "primitivetypeentry.h"
#include "typedefentry.h"
@@ -36,6 +39,22 @@
using namespace Qt::StringLiterals;
+struct IndexValue
+{
+ QString name; // "SBK_..."
+ int value;
+ QString comment;
+};
+
+TextStream &operator<<(TextStream &s, const IndexValue &iv)
+{
+ s << " " << AlignedField(iv.name, 56) << " = " << iv.value << ',';
+ if (!iv.comment.isEmpty())
+ s << " // " << iv.comment;
+ s << '\n';
+ return s;
+}
+
// PYSIDE-504: Handling the "protected hack"
// The problem: Creating wrappers when the class has private destructors.
// You can see an example on Windows in qclipboard_wrapper.h and others.
@@ -62,23 +81,26 @@ static bool alwaysGenerateDestructorDeclaration()
return clang::compiler() == Compiler::Msvc;
}
-QString HeaderGenerator::headerFileNameForContext(const GeneratorContext &context)
-{
- return fileNameForContextHelper(context, u"_wrapper.h"_s);
-}
+const char *HeaderGenerator::protectedHackDefine = R"(// Workaround to access protected functions
+#ifndef protected
+# define protected public
+#endif
+
+)";
QString HeaderGenerator::fileNameForContext(const GeneratorContext &context) const
{
return headerFileNameForContext(context);
}
-void HeaderGenerator::writeCopyCtor(TextStream &s, const AbstractMetaClass *metaClass) const
+void HeaderGenerator::writeCopyCtor(TextStream &s,
+ const AbstractMetaClassCPtr &metaClass)
{
s << wrapperName(metaClass) << "(const " << metaClass->qualifiedCppName()
<< "& self) : " << metaClass->qualifiedCppName() << "(self)\n{\n}\n\n";
}
-static void writeProtectedEnums(TextStream &s, const AbstractMetaClass *metaClass)
+static void writeProtectedEnums(TextStream &s, const AbstractMetaClassCPtr &metaClass)
{
const QString name = metaClass->qualifiedCppName();
for (const auto &e : metaClass->enums()) {
@@ -87,134 +109,181 @@ static void writeProtectedEnums(TextStream &s, const AbstractMetaClass *metaClas
}
}
-void HeaderGenerator::generateClass(TextStream &s, const GeneratorContext &classContextIn)
+void HeaderGenerator::generateClass(TextStream &s, const GeneratorContext &classContext)
{
- GeneratorContext classContext = classContextIn;
- const AbstractMetaClass *metaClass = classContext.metaClass();
- m_inheritedOverloads.clear();
+ const AbstractMetaClassCPtr metaClass = classContext.metaClass();
// write license comment
s << licenseComment();
QString wrapperName = classContext.effectiveClassName();
- QString outerHeaderGuard = getFilteredCppSignatureString(wrapperName).toUpper();
- QString innerHeaderGuard;
+ QString outerHeaderGuard = getFilteredCppSignatureString(wrapperName);
// Header
s << "#ifndef SBK_" << outerHeaderGuard << "_H\n";
s << "#define SBK_" << outerHeaderGuard << "_H\n\n";
if (!avoidProtectedHack())
- s << "#define protected public\n\n";
+ s << protectedHackDefine;
- //Includes
- auto typeEntry = metaClass->typeEntry();
- s << typeEntry->include() << '\n';
+ // Includes
+ s << metaClass->typeEntry()->include() << '\n';
for (auto &inst : metaClass->templateBaseClassInstantiations())
s << inst.typeEntry()->include();
- if (classContext.useWrapper() && avoidProtectedHack()) {
- const auto includeGroups = classIncludes(metaClass);
- for( const auto &includeGroup : includeGroups)
- s << includeGroup;
+ if (classContext.useWrapper())
+ writeWrapperClass(s, wrapperName, classContext);
+
+ s << "#endif // SBK_" << outerHeaderGuard << "_H\n\n";
+}
+
+void HeaderGenerator::writeWrapperClass(TextStream &s,
+ const QString &wrapperName,
+ const GeneratorContext &classContext) const
+{
+ const auto metaClass = classContext.metaClass();
+
+ if (avoidProtectedHack()) {
+ const auto includeGroups = classIncludes(metaClass);
+ for( const auto &includeGroup : includeGroups)
+ s << includeGroup;
}
- if (classContext.useWrapper() && usePySideExtensions() && metaClass->isQObject())
+ if (usePySideExtensions() && isQObject(metaClass))
s << "namespace PySide { class DynamicQMetaObject; }\n\n";
- while (classContext.useWrapper()) {
- if (!innerHeaderGuard.isEmpty()) {
- s << "# ifndef SBK_" << innerHeaderGuard << "_H\n";
- s << "# define SBK_" << innerHeaderGuard << "_H\n\n";
- s << "// Inherited base class:\n";
+ writeWrapperClassDeclaration(s, wrapperName, classContext);
+
+ // PYSIDE-500: Use also includes for inherited wrapper classes other
+ // modules, because without the protected hack, we sometimes need to
+ // cast inherited wrappers. CppGenerator generates include statements for
+ // the classes of the current module. For other modules, we insert the
+ // declarations as recursive headers, since wrapper headers are not
+ // installed. This keeps the file structure as simple as before the
+ // enhanced inheritance.
+ if (avoidProtectedHack()) {
+ const auto &baseClasses = allBaseClasses(classContext.metaClass());
+ for (const auto &baseClass : baseClasses) {
+ const auto gen = baseClass->typeEntry()->codeGeneration();
+ if (gen == TypeEntry::GenerateForSubclass) { // other module
+ const auto baseContext = contextForClass(baseClass);
+ if (baseContext.useWrapper())
+ writeInheritedWrapperClassDeclaration(s, baseContext);
+ }
}
+ }
+}
- // Class
- s << "class " << wrapperName
- << " : public " << metaClass->qualifiedCppName()
- << "\n{\npublic:\n" << indent;
-
- // Make protected enums accessible
- if (avoidProtectedHack()) {
- recurseClassHierarchy(metaClass, [&s] (const AbstractMetaClass *metaClass) {
- writeProtectedEnums(s, metaClass);
- return false;
- });
- }
+void HeaderGenerator::writeInheritedWrapperClassDeclaration(TextStream &s,
+ const GeneratorContext &classContext) const
+{
+ const QString wrapperName = classContext.effectiveClassName();
+ const QString innerHeaderGuard =
+ getFilteredCppSignatureString(wrapperName).toUpper();
- if (avoidProtectedHack() && metaClass->hasProtectedFields()) {
- s << "\n// Make protected fields accessible\n";
- const QString name = metaClass->qualifiedCppName();
- for (const auto &f : metaClass->fields()) {
- if (f.isProtected())
- s << "using " << name << "::" << f.originalName() << ";\n";
- }
- s << '\n';
- }
+ s << "# ifndef SBK_" << innerHeaderGuard << "_H\n"
+ << "# define SBK_" << innerHeaderGuard << "_H\n\n"
+ << "// Inherited base class:\n";
- int maxOverrides = 0;
- for (const auto &func : metaClass->functions()) {
- const auto generation = functionGeneration(func);
- writeFunction(s, func, generation);
- // PYSIDE-803: Build a boolean cache for unused overrides.
- if (generation.testFlag(FunctionGenerationFlag::VirtualMethod))
- maxOverrides++;
- }
- if (!maxOverrides)
- maxOverrides = 1;
-
- //destructor
- // PYSIDE-504: When C++ 11 is used, then the destructor must always be declared.
- if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor()
- || alwaysGenerateDestructorDeclaration()) {
- if (avoidProtectedHack() && metaClass->hasPrivateDestructor())
- s << "// C++11: need to declare (unimplemented) destructor because "
- "the base class destructor is private.\n";
- s << '~' << wrapperName << "();\n";
- }
+ writeWrapperClassDeclaration(s, wrapperName, classContext);
+
+ s << "# endif // SBK_" << innerHeaderGuard << "_H\n\n";
+}
- writeClassCodeSnips(s, typeEntry->codeSnips(),
- TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode,
- classContext);
+void HeaderGenerator::writeWrapperClassDeclaration(TextStream &s,
+ const QString &wrapperName,
+ const GeneratorContext &classContext) const
+{
+ const AbstractMetaClassCPtr metaClass = classContext.metaClass();
+ const auto typeEntry = metaClass->typeEntry();
+ InheritedOverloadSet inheritedOverloads;
- if ((!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
- && usePySideExtensions() && metaClass->isQObject()) {
- s << outdent << "public:\n" << indent <<
-R"(int qt_metacall(QMetaObject::Call call, int id, void **args) override;
+ // write license comment
+ s << licenseComment();
+
+ // Class
+ s << "class " << wrapperName
+ << " : public " << metaClass->qualifiedCppName()
+ << "\n{\npublic:\n" << indent
+ << wrapperName << "(const " << wrapperName << " &) = delete;\n"
+ << wrapperName << "& operator=(const " << wrapperName << " &) = delete;\n"
+ << wrapperName << '(' << wrapperName << " &&) = delete;\n"
+ << wrapperName << "& operator=(" << wrapperName << " &&) = delete;\n\n";
+
+ // Make protected enums accessible
+ if (avoidProtectedHack()) {
+ recurseClassHierarchy(metaClass, [&s] (const AbstractMetaClassCPtr &metaClass) {
+ writeProtectedEnums(s, metaClass);
+ return false;
+ });
+ }
+
+ if (avoidProtectedHack() && metaClass->hasProtectedFields()) {
+ s << "\n// Make protected fields accessible\n";
+ const QString name = metaClass->qualifiedCppName();
+ for (const auto &f : metaClass->fields()) {
+ if (f.isProtected())
+ s << "using " << name << "::" << f.originalName() << ";\n";
+ }
+ s << '\n';
+ }
+
+ int maxOverrides = 0;
+ for (const auto &func : metaClass->functions()) {
+ const auto generation = functionGeneration(func);
+ writeFunction(s, func, &inheritedOverloads, generation);
+ // PYSIDE-803: Build a boolean cache for unused overrides.
+ if (generation.testFlag(FunctionGenerationFlag::VirtualMethod))
+ maxOverrides++;
+ }
+ if (!maxOverrides)
+ maxOverrides = 1;
+
+ //destructor
+ // PYSIDE-504: When C++ 11 is used, then the destructor must always be declared.
+ if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor()
+ || alwaysGenerateDestructorDeclaration()) {
+ if (avoidProtectedHack() && metaClass->hasPrivateDestructor())
+ s << "// C++11: need to declare (unimplemented) destructor because "
+ "the base class destructor is private.\n";
+ s << '~' << wrapperName << "()";
+ if (metaClass->hasVirtualDestructor())
+ s << " override";
+ s << ";\n";
+ }
+
+ writeClassCodeSnips(s, typeEntry->codeSnips(),
+ TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode,
+ classContext);
+
+ if (shouldGenerateMetaObjectFunctions(metaClass)) {
+ s << R"(
+const ::QMetaObject * metaObject() const override;
+int qt_metacall(QMetaObject::Call call, int id, void **args) override;
void *qt_metacast(const char *_clname) override;
)";
- }
+ }
- if (!m_inheritedOverloads.isEmpty()) {
- s << "// Inherited overloads, because the using keyword sux\n";
- for (const auto &func : std::as_const(m_inheritedOverloads))
- writeMemberFunctionWrapper(s, func);
- m_inheritedOverloads.clear();
- }
+ if (!inheritedOverloads.isEmpty()) {
+ s << "// Inherited overloads, because the using keyword sux\n";
+ for (const auto &func : std::as_const(inheritedOverloads))
+ writeMemberFunctionWrapper(s, func);
+ }
- if (usePySideExtensions())
- s << "static void pysideInitQtMetaTypes();\n";
+ if (usePySideExtensions())
+ s << "static void pysideInitQtMetaTypes();\n";
- s << "void resetPyMethodCache();\n"
- << outdent << "private:\n" << indent
- << "mutable bool m_PyMethodCache[" << maxOverrides << "];\n"
- << outdent << "};\n\n";
- if (!innerHeaderGuard.isEmpty())
- s << "# endif // SBK_" << innerHeaderGuard << "_H\n\n";
+ s << "void resetPyMethodCache();\n"
+ << outdent << "private:\n" << indent;
- // PYSIDE-500: Use also includes for inherited wrapper classes, because
- // without the protected hack, we sometimes need to cast inherited wrappers.
- // But we don't use multiple include files. Instead, they are inserted as recursive
- // headers. This keeps the file structure as simple as before the enhanced inheritance.
- metaClass = metaClass->baseClass();
- if (!metaClass || !avoidProtectedHack())
- break;
- classContext = contextForClass(metaClass);
- wrapperName = classContext.effectiveClassName();
- innerHeaderGuard = getFilteredCppSignatureString(wrapperName).toUpper();
+ if (!metaClass->userAddedPythonOverrides().isEmpty()) {
+ for (const auto &f : metaClass->userAddedPythonOverrides())
+ s << functionSignature(f, {}, {}, Generator::OriginalTypeDescription) << ";\n";
+ s << '\n';
}
- s << "#endif // SBK_" << outerHeaderGuard << "_H\n\n";
+ s << "mutable bool m_PyMethodCache[" << maxOverrides << "];\n"
+ << outdent << "};\n\n";
}
// Write an inline wrapper around a function
@@ -224,8 +293,6 @@ void HeaderGenerator::writeMemberFunctionWrapper(TextStream &s,
{
Q_ASSERT(!func->isConstructor() && !func->isOperatorOverload());
s << "inline ";
- if (func->isStatic())
- s << "static ";
s << functionSignature(func, {}, postfix, Generator::OriginalTypeDescription)
<< " { ";
if (!func->isVoid())
@@ -248,10 +315,10 @@ void HeaderGenerator::writeMemberFunctionWrapper(TextStream &s,
const auto &type = arg.type();
TypeEntryCPtr enumTypeEntry;
if (type.isFlags())
- enumTypeEntry = qSharedPointerCast<const FlagsTypeEntry>(type.typeEntry())->originator();
+ enumTypeEntry = std::static_pointer_cast<const FlagsTypeEntry>(type.typeEntry())->originator();
else if (type.isEnum())
enumTypeEntry = type.typeEntry();
- if (!enumTypeEntry.isNull()) {
+ if (enumTypeEntry) {
s << type.cppSignature() << '(' << arg.name() << ')';
} else if (type.passByValue() && type.isUniquePointer()) {
s << stdMove(arg.name());
@@ -263,7 +330,8 @@ void HeaderGenerator::writeMemberFunctionWrapper(TextStream &s,
}
void HeaderGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func,
- FunctionGeneration generation)
+ InheritedOverloadSet *inheritedOverloads,
+ FunctionGeneration generation) const
{
// do not write copy ctors here.
@@ -283,7 +351,7 @@ void HeaderGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPt
}
const bool isVirtual = generation.testFlag(FunctionGenerationFlag::VirtualMethod);
- if (isVirtual || generation.testFlag(FunctionGenerationFlag::QMetaObjectMethod)) {
+ if (isVirtual) {
s << functionSignature(func, {}, {}, Generator::OriginalTypeDescription)
<< " override;\n";
}
@@ -298,7 +366,7 @@ void HeaderGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPt
&& !f->isAbstract()
&& !f->isStatic()
&& f->name() == func->name()) {
- m_inheritedOverloads << f;
+ inheritedOverloads->insert(f);
}
}
@@ -308,28 +376,14 @@ void HeaderGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPt
}
}
-static void _writeTypeIndexValue(TextStream &s, const QString &variableName,
- int typeIndex)
-{
- s << " " << AlignedField(variableName, 56) << " = " << typeIndex;
-}
-
-static inline void _writeTypeIndexValueLine(TextStream &s,
- const QString &variableName,
- int typeIndex)
-{
- _writeTypeIndexValue(s, variableName, typeIndex);
- s << ",\n";
-}
-
// Find equivalent typedefs "using Foo=QList<int>", "using Bar=QList<int>"
-static const AbstractMetaClass *
+static AbstractMetaClassCPtr
findEquivalentTemplateTypedef(const AbstractMetaClassCList &haystack,
- const AbstractMetaClass *needle)
+ const AbstractMetaClassCPtr &needle)
{
- auto *templateBaseClass = needle->templateBaseClass();
+ auto templateBaseClass = needle->templateBaseClass();
const auto &instantiations = needle->templateBaseClassInstantiations();
- for (auto *candidate : haystack) {
+ for (const auto &candidate : haystack) {
if (candidate->isTypeDef()
&& candidate->templateBaseClass() == templateBaseClass
&& candidate->templateBaseClassInstantiations() == instantiations) {
@@ -339,19 +393,20 @@ static const AbstractMetaClass *
return nullptr;
}
-void HeaderGenerator::writeTypeIndexValueLine(TextStream &s, const ApiExtractorResult &api,
- const TypeEntryCPtr &typeEntry)
+void HeaderGenerator::collectTypeEntryTypeIndexes(const ApiExtractorResult &api,
+ const TypeEntryCPtr &typeEntry,
+ IndexValues *indexValues)
{
if (!typeEntry || !typeEntry->generateCode())
return;
- s.setFieldAlignment(QTextStream::AlignLeft);
const int typeIndex = typeEntry->sbkIndex();
- _writeTypeIndexValueLine(s, getTypeIndexVariableName(typeEntry), typeIndex);
+ indexValues->append({getTypeIndexVariableName(typeEntry), typeIndex, {}});
+
if (typeEntry->isComplex()) {
// For a typedef "using Foo=QList<int>", write a type index
// SBK_QLIST_INT besides SBK_FOO which is then matched by function
// argument. Check against duplicate typedefs for the same types.
- const auto cType = qSharedPointerCast<const ComplexTypeEntry>(typeEntry);
+ const auto cType = std::static_pointer_cast<const ComplexTypeEntry>(typeEntry);
if (cType->baseContainerType()) {
auto metaClass = AbstractMetaClass::findClass(api.classes(), cType);
Q_ASSERT(metaClass != nullptr);
@@ -361,20 +416,21 @@ void HeaderGenerator::writeTypeIndexValueLine(TextStream &s, const ApiExtractorR
metaClass) == nullptr) {
const QString indexVariable =
getTypeAlternateTemplateIndexVariableName(metaClass);
- _writeTypeIndexValueLine(s, indexVariable, typeIndex);
+ indexValues->append({indexVariable, typeIndex, {}});
m_alternateTemplateIndexes.append(m_alternateTemplateIndexes);
}
}
}
if (typeEntry->isEnum()) {
- auto ete = qSharedPointerCast<const EnumTypeEntry>(typeEntry);
+ auto ete = std::static_pointer_cast<const EnumTypeEntry>(typeEntry);
if (ete->flags())
- writeTypeIndexValueLine(s, api, ete->flags());
+ collectTypeEntryTypeIndexes(api, ete->flags(), indexValues);
}
}
-void HeaderGenerator::writeTypeIndexValueLines(TextStream &s, const ApiExtractorResult &api,
- const AbstractMetaClass *metaClass)
+void HeaderGenerator::collectClassTypeIndexes(const ApiExtractorResult &api,
+ const AbstractMetaClassCPtr &metaClass,
+ IndexValues *indexValues)
{
auto typeEntry = metaClass->typeEntry();
if (!typeEntry->generateCode())
@@ -382,10 +438,10 @@ void HeaderGenerator::writeTypeIndexValueLines(TextStream &s, const ApiExtractor
// enum indices are required for invisible namespaces as well.
for (const AbstractMetaEnum &metaEnum : metaClass->enums()) {
if (!metaEnum.isPrivate())
- writeTypeIndexValueLine(s, api, metaEnum.typeEntry());
+ collectTypeEntryTypeIndexes(api, metaEnum.typeEntry(), indexValues);
}
if (NamespaceTypeEntry::isVisibleScope(typeEntry))
- writeTypeIndexValueLine(s, api, typeEntry);
+ collectTypeEntryTypeIndexes(api, typeEntry, indexValues);
}
// Format the typedefs for the typedef entries to be generated
@@ -417,18 +473,18 @@ static void formatTypeDefEntries(TextStream &s)
// Helpers for forward-declaring classes in the module header for the
// specialization of the SbkType template functions. This is possible if the
// class does not have inner types or enums which need to be known.
-static bool canForwardDeclare(const AbstractMetaClass *c)
+static bool canForwardDeclare(const AbstractMetaClassCPtr &c)
{
if (c->isNamespace() || !c->enums().isEmpty()
|| !c->innerClasses().isEmpty() || c->isTypeDef()) {
return false;
}
- if (auto *encl = c->enclosingClass())
+ if (auto encl = c->enclosingClass())
return encl->isNamespace();
return true;
}
-static void writeForwardDeclaration(TextStream &s, const AbstractMetaClass *c)
+static void writeForwardDeclaration(TextStream &s, const AbstractMetaClassCPtr &c)
{
Q_ASSERT(!c->isNamespace());
const bool isStruct = c->attributes().testFlag(AbstractMetaClass::Struct);
@@ -447,7 +503,7 @@ static void writeForwardDeclaration(TextStream &s, const AbstractMetaClass *c)
// forward declarations to the module header. Ensure inline namespaces
// are marked as such (else clang complains) and namespaces are ordered.
struct NameSpace {
- const AbstractMetaClass *nameSpace;
+ AbstractMetaClassCPtr nameSpace;
AbstractMetaClassCList classes;
};
@@ -458,7 +514,7 @@ static bool operator<(const NameSpace &n1, const NameSpace &n2)
using NameSpaces = QList<NameSpace>;
-static qsizetype indexOf(const NameSpaces &nsps, const AbstractMetaClass *needle)
+static qsizetype indexOf(const NameSpaces &nsps, const AbstractMetaClassCPtr &needle)
{
for (qsizetype i = 0, count = nsps.size(); i < count; ++i) {
if (nsps.at(i).nameSpace == needle)
@@ -475,7 +531,7 @@ static void writeNamespaceForwardDeclarationRecursion(TextStream &s, qsizetype i
if (root.nameSpace->isInlineNamespace())
s << "inline ";
s << "namespace " << root.nameSpace->name() << " {\n" << indent;
- for (auto *c : root.classes)
+ for (const auto &c : root.classes)
writeForwardDeclaration(s, c);
for (qsizetype i = 0, count = nameSpaces.size(); i < count; ++i) {
@@ -490,15 +546,20 @@ static void writeForwardDeclarations(TextStream &s,
{
NameSpaces nameSpaces;
- for (auto *c : classList) {
- if (auto *encl = c->enclosingClass()) {
+ s << '\n';
+ auto typeSystemEntry = TypeDatabase::instance()->defaultTypeSystemType();
+ if (!typeSystemEntry->namespaceBegin().isEmpty())
+ s << typeSystemEntry->namespaceBegin() << '\n';
+
+ for (const auto &c : classList) {
+ if (auto encl = c->enclosingClass()) {
Q_ASSERT(encl->isNamespace());
auto idx = indexOf(nameSpaces, encl);
if (idx != -1) {
nameSpaces[idx].classes.append(c);
} else {
nameSpaces.append(NameSpace{encl, {c}});
- for (auto *enclNsp = encl->enclosingClass(); enclNsp != nullptr;
+ for (auto enclNsp = encl->enclosingClass(); enclNsp;
enclNsp = enclNsp->enclosingClass()) {
idx = indexOf(nameSpaces, enclNsp);
if (idx == -1)
@@ -518,103 +579,156 @@ static void writeForwardDeclarations(TextStream &s,
if (nsp.nameSpace->enclosingClass() == nullptr)
writeNamespaceForwardDeclarationRecursion(s, i, nameSpaces);
}
+
+ if (!typeSystemEntry->namespaceEnd().isEmpty())
+ s << typeSystemEntry->namespaceEnd() << '\n';
}
// Include parameters required for the module/private module header
+
+using ConditionalIncludeMap = QMap<QString, IncludeGroup>;
+
+static TextStream &operator<<(TextStream &s, const ConditionalIncludeMap &m)
+{
+ for (auto it = m.cbegin(), end = m.cend(); it != end; ++it)
+ s << it.key() << '\n' << it.value() << "#endif\n";
+ return s;
+}
+
struct ModuleHeaderParameters
{
AbstractMetaClassCList forwardDeclarations;
std::set<Include> includes;
+ ConditionalIncludeMap conditionalIncludes;
QString typeFunctions;
};
-bool HeaderGenerator::finishGeneration()
+HeaderGenerator::IndexValues
+ HeaderGenerator::collectTypeIndexes(const AbstractMetaClassCList &classList)
{
- // Generate the main header for this module. This header should be included
- // by binding modules extending on top of this one.
- ModuleHeaderParameters parameters;
- ModuleHeaderParameters privateParameters;
- StringStream macrosStream(TextStream::Language::Cpp);
+ IndexValues result;
- const auto snips = TypeDatabase::instance()->defaultTypeSystemType()->codeSnips();
- if (!snips.isEmpty()) {
- writeCodeSnips(macrosStream, snips, TypeSystem::CodeSnipPositionDeclaration,
- TypeSystem::TargetLangCode);
- }
-
- macrosStream << "// Type indices\nenum : int {\n";
- auto classList = api().classes();
-
- std::sort(classList.begin(), classList.end(),
- [](const AbstractMetaClass *a, const AbstractMetaClass *b) {
- return a->typeEntry()->sbkIndex() < b->typeEntry()->sbkIndex();
- });
-
- for (const AbstractMetaClass *metaClass : classList)
- writeTypeIndexValueLines(macrosStream, api(), metaClass);
+ for (const auto &metaClass : classList)
+ collectClassTypeIndexes(api(), metaClass, &result);
for (const AbstractMetaEnum &metaEnum : api().globalEnums())
- writeTypeIndexValueLine(macrosStream, api(), metaEnum.typeEntry());
+ collectTypeEntryTypeIndexes(api(), metaEnum.typeEntry(), &result);
// Write the smart pointer define indexes.
int smartPointerCountIndex = getMaxTypeIndex();
int smartPointerCount = 0;
for (const auto &smp : api().instantiatedSmartPointers()) {
QString indexName = getTypeIndexVariableName(smp.type);
- _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex);
- macrosStream << ", // " << smp.type.cppSignature() << '\n';
+ result.append({indexName, smartPointerCountIndex, smp.type.cppSignature()});
// Add a the same value for const pointees (shared_ptr<const Foo>).
const auto ptrName = smp.type.typeEntry()->entryName();
- int pos = indexName.indexOf(ptrName, 0, Qt::CaseInsensitive);
+ const auto pos = indexName.indexOf(ptrName, 0, Qt::CaseInsensitive);
if (pos >= 0) {
- indexName.insert(pos + ptrName.size() + 1, u"CONST"_s);
- _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex);
- macrosStream << ", // (const)\n";
+ indexName.insert(pos + ptrName.size() + 1, u"const"_s);
+ result.append({indexName, smartPointerCountIndex, "(const)"_L1});
}
++smartPointerCountIndex;
++smartPointerCount;
}
+ result.append({"SBK_"_L1 + moduleName() + "_IDX_COUNT"_L1,
+ getMaxTypeIndex() + smartPointerCount, {}});
+ return result;
+}
- _writeTypeIndexValue(macrosStream,
- u"SBK_"_s + moduleName() + u"_IDX_COUNT"_s,
- getMaxTypeIndex() + smartPointerCount);
- macrosStream << "\n};\n";
-
- macrosStream << "// This variable stores all Python types exported by this module.\n";
- macrosStream << "extern PyTypeObject **" << cppApiVariableName() << ";\n\n";
- macrosStream << "// This variable stores the Python module object exported by this module.\n";
- macrosStream << "extern PyObject *" << pythonModuleObjectName() << ";\n\n";
- macrosStream << "// This variable stores all type converters exported by this module.\n";
- macrosStream << "extern SbkConverter **" << convertersVariableName() << ";\n\n";
-
- // TODO-CONVERTER ------------------------------------------------------------------------------
- // Using a counter would not do, a fix must be made to APIExtractor's getTypeIndex().
- macrosStream << "// Converter indices\nenum : int {\n";
+HeaderGenerator::IndexValues HeaderGenerator::collectConverterIndexes() const
+{
+ IndexValues result;
const auto &primitives = primitiveTypes();
int pCount = 0;
for (const auto &ptype : primitives) {
- /* Note: do not generate indices for typedef'd primitive types
- * as they'll use the primitive type converters instead, so we
- * don't need to create any other.
- */
- if (!ptype->generateCode() || !ptype->customConversion())
- continue;
-
- _writeTypeIndexValueLine(macrosStream, getTypeIndexVariableName(ptype), pCount++);
+ // Note: do not generate indices for typedef'd primitive types as
+ // they'll use the primitive type converters instead, so we
+ // don't need to create any other.
+ if (ptype->generateCode() && ptype->customConversion() != nullptr)
+ result.append({getTypeIndexVariableName(ptype), pCount++, {}});
}
for (const AbstractMetaType &container : api().instantiatedContainers()) {
- _writeTypeIndexValue(macrosStream, getTypeIndexVariableName(container), pCount);
- macrosStream << ", // " << container.cppSignature() << '\n';
- pCount++;
+ result.append({getTypeIndexVariableName(container),
+ pCount++, container.cppSignature()});
}
// Because on win32 the compiler will not accept a zero length array.
if (pCount == 0)
pCount++;
- _writeTypeIndexValue(macrosStream, QStringLiteral("SBK_%1_CONVERTERS_IDX_COUNT")
- .arg(moduleName()), pCount);
- macrosStream << "\n};\n";
+ result.append({"SBK_"_L1 + moduleName() + "_CONVERTERS_IDX_COUNT"_L1,
+ pCount, {}});
+ return result;
+}
+
+// PYSIDE-2404: Write the enums in unchanged case for reuse in type imports.
+// For conpatibility, we create them in uppercase, too and with
+// doubled index for emulating the former type-only case.
+//
+// FIXME: Remove in PySide 7. (See the note in `parser.py`)
+//
+static IndexValue typeIndexUpper(struct IndexValue const &ti)
+{
+ QString modi = ti.name.toUpper();
+ if (modi == ti.name)
+ modi = u"// "_s + modi;
+ return {modi, ti.value * 2, ti.comment};
+}
+
+bool HeaderGenerator::finishGeneration()
+{
+ // Generate the main header for this module. This header should be included
+ // by binding modules extending on top of this one.
+ ModuleHeaderParameters parameters;
+ ModuleHeaderParameters privateParameters;
+ StringStream macrosStream(TextStream::Language::Cpp);
+
+ const auto snips = TypeDatabase::instance()->defaultTypeSystemType()->codeSnips();
+ writeModuleCodeSnips(macrosStream, snips, TypeSystem::CodeSnipPositionDeclaration,
+ TypeSystem::TargetLangCode);
+
+ auto classList = api().classes();
+
+ std::sort(classList.begin(), classList.end(),
+ [](const AbstractMetaClassCPtr &a, const AbstractMetaClassCPtr &b) {
+ return a->typeEntry()->sbkIndex() < b->typeEntry()->sbkIndex();
+ });
+
+ const auto typeIndexes = collectTypeIndexes(classList);
+
+ macrosStream << "\n// Type indices\nenum [[deprecated]] : int {\n";
+ for (const auto &ti : typeIndexes)
+ macrosStream << typeIndexUpper(ti);
+ macrosStream << "};\n";
+
+ macrosStream << "\n// Type indices\nenum : int {\n";
+ for (const auto &ti : typeIndexes)
+ macrosStream << ti;
+ macrosStream << "};\n\n";
+
+ // FIXME: Remove backwards compatible variable in PySide 7.
+ macrosStream << "// This variable stores all Python types exported by this module.\n";
+ macrosStream << "extern Shiboken::Module::TypeInitStruct *" << cppApiVariableName() << ";\n\n";
+ macrosStream << "// This variable stores all Python types exported by this module ";
+ macrosStream << "in a backwards compatible way with identical indexing.\n";
+ macrosStream << "[[deprecated]] extern PyTypeObject **" << cppApiVariableNameOld() << ";\n\n";
+ macrosStream << "// This variable stores the Python module object exported by this module.\n";
+ macrosStream << "extern PyObject *" << pythonModuleObjectName() << ";\n\n";
+ macrosStream << "// This variable stores all type converters exported by this module.\n";
+ macrosStream << "extern SbkConverter **" << convertersVariableName() << ";\n\n";
+
+ // TODO-CONVERTER ------------------------------------------------------------------------------
+ // Using a counter would not do, a fix must be made to APIExtractor's getTypeIndex().
+ const auto converterIndexes = collectConverterIndexes();
+ macrosStream << "// Converter indices\nenum [[deprecated]] : int {\n";
+ for (const auto &ci : converterIndexes)
+ macrosStream << typeIndexUpper(ci);
+ macrosStream << "};\n\n";
+
+ macrosStream << "// Converter indices\nenum : int {\n";
+ for (const auto &ci : converterIndexes)
+ macrosStream << ci;
+ macrosStream << "};\n";
formatTypeDefEntries(macrosStream);
@@ -627,28 +741,36 @@ bool HeaderGenerator::finishGeneration()
for (const AbstractMetaEnum &cppEnum : api().globalEnums()) {
if (!cppEnum.isAnonymous()) {
- parameters.includes.insert(cppEnum.typeEntry()->include());
+ const auto te = cppEnum.typeEntry();
+ if (te->hasConfigCondition())
+ parameters.conditionalIncludes[te->configCondition()].append(te->include());
+ else
+ parameters.includes.insert(cppEnum.typeEntry()->include());
writeSbkTypeFunction(typeFunctions, cppEnum);
}
}
StringStream protEnumsSurrogates(TextStream::Language::Cpp);
- for (auto metaClass : classList) {
+ for (const auto &metaClass : classList) {
const auto classType = metaClass->typeEntry();
if (!shouldGenerate(classType))
continue;
- //Includes
+ // Includes
const bool isPrivate = classType->isPrivate();
auto &par = isPrivate ? privateParameters : parameters;
const auto classInclude = classType->include();
+ const bool hasConfigCondition = classType->hasConfigCondition();
if (leanHeaders() && canForwardDeclare(metaClass))
par.forwardDeclarations.append(metaClass);
+ else if (hasConfigCondition)
+ par.conditionalIncludes[classType->configCondition()].append(classInclude);
else
par.includes.insert(classInclude);
auto &typeFunctionsStr = isPrivate ? privateTypeFunctions : typeFunctions;
+ ConfigurableScope configScope(typeFunctionsStr, classType);
for (const AbstractMetaEnum &cppEnum : metaClass->enums()) {
if (cppEnum.isAnonymous() || cppEnum.isPrivate())
continue;
@@ -688,6 +810,7 @@ bool HeaderGenerator::finishGeneration()
}
s << "#include <sbkpython.h>\n";
+ s << "#include <sbkmodule.h>\n";
s << "#include <sbkconverter.h>\n";
QStringList requiredTargetImports = TypeDatabase::instance()->requiredTargetImports();
@@ -701,6 +824,7 @@ bool HeaderGenerator::finishGeneration()
s << "// Bound library includes\n";
for (const Include &include : parameters.includes)
s << include;
+ s << parameters.conditionalIncludes;
if (leanHeaders()) {
writeForwardDeclarations(s, parameters.forwardDeclarations);
@@ -751,8 +875,7 @@ void HeaderGenerator::writePrivateHeader(const QString &moduleHeaderDir,
TextStream &ps = privateFile.stream;
ps.setLanguage(TextStream::Language::Cpp);
QString privateIncludeShield =
- publicIncludeShield.left(publicIncludeShield.size() - 2)
- + QStringLiteral("_P_H");
+ publicIncludeShield.left(publicIncludeShield.size() - 2) + "_P_H"_L1;
ps << licenseComment()<< "\n\n";
@@ -761,6 +884,7 @@ void HeaderGenerator::writePrivateHeader(const QString &moduleHeaderDir,
for (const Include &include : parameters.includes)
ps << include;
+ ps << parameters.conditionalIncludes;
ps << '\n';
if (leanHeaders())
@@ -789,36 +913,52 @@ void HeaderGenerator::writeTypeFunctions(TextStream &s, const QString &typeFunct
s << "QT_WARNING_POP\n";
}
-void HeaderGenerator::writeProtectedEnumSurrogate(TextStream &s, const AbstractMetaEnum &cppEnum) const
+void HeaderGenerator::writeProtectedEnumSurrogate(TextStream &s, const AbstractMetaEnum &cppEnum)
{
if (avoidProtectedHack() && cppEnum.isProtected())
s << "enum " << protectedEnumSurrogateName(cppEnum) << " {};\n";
}
-void HeaderGenerator::writeSbkTypeFunction(TextStream &s, const AbstractMetaEnum &cppEnum) const
+void HeaderGenerator::writeSbkTypeFunction(TextStream &s, const AbstractMetaEnum &cppEnum)
{
const QString enumName = avoidProtectedHack() && cppEnum.isProtected()
? protectedEnumSurrogateName(cppEnum)
: cppEnum.qualifiedCppName();
-
- s << "template<> inline PyTypeObject *SbkType< ::" << enumName << " >() ";
- s << "{ return " << cpythonTypeNameExt(cppEnum.typeEntry()) << "; }\n";
+ const auto te = cppEnum.typeEntry();
+ ConfigurableScope configScope(s, te);
+ s << "template<> inline PyTypeObject *SbkType< " << m_gsp << enumName << " >() ";
+ s << "{ return " << cpythonTypeNameExt(te) << "; }\n";
const auto flag = cppEnum.typeEntry()->flags();
- if (!flag.isNull()) {
- s << "template<> inline PyTypeObject *SbkType< ::" << flag->name() << " >() "
+ if (flag) {
+ s << "template<> inline PyTypeObject *SbkType< " << m_gsp << flag->name() << " >() "
<< "{ return " << cpythonTypeNameExt(flag) << "; }\n";
}
}
-void HeaderGenerator::writeSbkTypeFunction(TextStream &s, const AbstractMetaClass *cppClass)
+void HeaderGenerator::writeSbkTypeFunction(TextStream &s, const AbstractMetaClassCPtr &cppClass)
{
- s << "template<> inline PyTypeObject *SbkType< ::" << cppClass->qualifiedCppName() << " >() "
- << "{ return reinterpret_cast<PyTypeObject *>(" << cpythonTypeNameExt(cppClass->typeEntry()) << "); }\n";
+ s << "template<> inline PyTypeObject *SbkType< "
+ << getFullTypeName(cppClass) << " >() "
+ << "{ return " << cpythonTypeNameExt(cppClass->typeEntry()) << "; }\n";
}
void HeaderGenerator::writeSbkTypeFunction(TextStream &s, const AbstractMetaType &metaType)
{
- s << "template<> inline PyTypeObject *SbkType< ::" << metaType.cppSignature() << " >() "
+ s << "template<> inline PyTypeObject *SbkType< "
+ << m_gsp << metaType.cppSignature() << " >() "
<< "{ return " << cpythonTypeNameExt(metaType) << "; }\n";
}
+
+void HeaderGenerator::writeModuleCodeSnips(TextStream &s, const CodeSnipList &codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language) const
+{
+ if (!codeSnips.isEmpty()) {
+ try {
+ writeCodeSnips(s, codeSnips, position, language);
+ } catch (const std::exception &e) {
+ throw Exception(msgSnippetError("module header of "_L1 + moduleName(), e.what()));
+ }
+ }
+}
diff --git a/sources/shiboken6/generator/shiboken/headergenerator.h b/sources/shiboken6/generator/shiboken/headergenerator.h
index f1735cd9f..03b98e743 100644
--- a/sources/shiboken6/generator/shiboken/headergenerator.h
+++ b/sources/shiboken6/generator/shiboken/headergenerator.h
@@ -6,9 +6,12 @@
#include "shibokengenerator.h"
#include "include.h"
+#include "modifications_typedefs.h"
+#include <QtCore/QList>
#include <QtCore/QSet>
+struct IndexValue;
class AbstractMetaFunction;
struct ModuleHeaderParameters;
@@ -18,11 +21,9 @@ struct ModuleHeaderParameters;
class HeaderGenerator : public ShibokenGenerator
{
public:
- OptionDescriptions options() const override { return OptionDescriptions(); }
-
const char *name() const override { return "Header generator"; }
- static QString headerFileNameForContext(const GeneratorContext &context);
+ static const char *protectedHackDefine;
protected:
QString fileNameForContext(const GeneratorContext &context) const override;
@@ -30,26 +31,44 @@ protected:
bool finishGeneration() override;
private:
- void writeCopyCtor(TextStream &s, const AbstractMetaClass *metaClass) const;
- void writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func,
- FunctionGeneration generation);
- void writeSbkTypeFunction(TextStream &s, const AbstractMetaEnum &cppEnum) const;
- static void writeSbkTypeFunction(TextStream &s, const AbstractMetaClass *cppClass) ;
- static void writeSbkTypeFunction(TextStream &s, const AbstractMetaType &metaType) ;
- void writeTypeIndexValueLine(TextStream &s, const ApiExtractorResult &api,
- const TypeEntryCPtr &typeEntry);
- void writeTypeIndexValueLines(TextStream &s, const ApiExtractorResult &api,
- const AbstractMetaClass *metaClass);
- void writeProtectedEnumSurrogate(TextStream &s, const AbstractMetaEnum &cppEnum) const;
+ using InheritedOverloadSet = QSet<AbstractMetaFunctionCPtr>;
+ using IndexValues = QList<IndexValue>;
+
+ IndexValues collectTypeIndexes(const AbstractMetaClassCList &classList);
+ IndexValues collectConverterIndexes() const;
+
+ static void writeCopyCtor(TextStream &s, const AbstractMetaClassCPtr &metaClass);
+ void writeFunction(TextStream &s,
+ const AbstractMetaFunctionCPtr &func,
+ InheritedOverloadSet *inheritedOverloads,
+ FunctionGeneration generation) const;
+ static void writeSbkTypeFunction(TextStream &s, const AbstractMetaEnum &cppEnum);
+ static void writeSbkTypeFunction(TextStream &s, const AbstractMetaClassCPtr &cppClass);
+ static void writeSbkTypeFunction(TextStream &s, const AbstractMetaType &metaType);
+ void collectTypeEntryTypeIndexes(const ApiExtractorResult &api,
+ const TypeEntryCPtr &typeEntry,
+ IndexValues *indexValues);
+ void collectClassTypeIndexes(const ApiExtractorResult &api,
+ const AbstractMetaClassCPtr &metaClass,
+ IndexValues *indexValues);
+ static void writeProtectedEnumSurrogate(TextStream &s, const AbstractMetaEnum &cppEnum);
void writeMemberFunctionWrapper(TextStream &s,
const AbstractMetaFunctionCPtr &func,
const QString &postfix = {}) const;
void writePrivateHeader(const QString &moduleHeaderDir,
const QString &publicIncludeShield,
const ModuleHeaderParameters &parameters);
- void writeTypeFunctions(TextStream &s, const QString &typeFunctions);
+ static void writeTypeFunctions(TextStream &s, const QString &typeFunctions);
+ void writeWrapperClassDeclaration(TextStream &s,
+ const QString &wrapperName,
+ const GeneratorContext &classContext) const;
+ void writeWrapperClass(TextStream &s, const QString &wrapperName, const GeneratorContext &classContext) const;
+ void writeInheritedWrapperClassDeclaration(TextStream &s,
+ const GeneratorContext &classContext) const;
+ void writeModuleCodeSnips(TextStream &s, const CodeSnipList &codeSnips,
+ TypeSystem::CodeSnipPosition position,
+ TypeSystem::Language language) const;
- QSet<AbstractMetaFunctionCPtr> m_inheritedOverloads;
AbstractMetaClassCList m_alternateTemplateIndexes;
};
diff --git a/sources/shiboken6/generator/shiboken/overloaddata.cpp b/sources/shiboken6/generator/shiboken/overloaddata.cpp
index a5594791e..c28fcdc1a 100644
--- a/sources/shiboken6/generator/shiboken/overloaddata.cpp
+++ b/sources/shiboken6/generator/shiboken/overloaddata.cpp
@@ -16,7 +16,6 @@
#include "pytypenames.h"
#include "textstream.h"
#include "exception.h"
-#include "messages.h"
#include "qtcompat.h"
@@ -126,6 +125,7 @@ using OverloadGraph = Graph<QString>;
void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
{
QHash<QString, OverloadDataList> typeToOverloads;
+ using Edge = std::pair<QString, QString>;
bool checkPyObject = false;
bool checkPySequence = false;
@@ -135,10 +135,10 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
// Primitive types that are not int, long, short,
// char and their respective unsigned counterparts.
- static const QStringList nonIntegerPrimitives{floatT(), doubleT(), boolT()};
+ static const QStringList nonIntegerPrimitives{floatT, doubleT, boolT};
// Signed integer primitive types.
- static const QStringList signedIntegerPrimitives{intT(), shortT(), longT(), longLongT()};
+ static const QStringList signedIntegerPrimitives{intT, shortT, longT, longLongT};
// sort the children overloads
for (const auto &ov : std::as_const(m_children))
@@ -162,15 +162,15 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
it.value().append(ov);
}
- if (!checkPyObject && typeName == cPyObjectT())
+ if (!checkPyObject && typeName == cPyObjectT)
checkPyObject = true;
- else if (!checkPySequence && typeName == cPySequenceT())
+ else if (!checkPySequence && typeName == cPySequenceT)
checkPySequence = true;
- else if (!checkPyBuffer && typeName == cPyBufferT())
+ else if (!checkPyBuffer && typeName == cPyBufferT)
checkPyBuffer = true;
- else if (!checkQVariant && typeName == qVariantT())
+ else if (!checkQVariant && typeName == qVariantT)
checkQVariant = true;
- else if (!checkQString && typeName == qStringT())
+ else if (!checkQString && typeName == qStringT)
checkQString = true;
for (const auto &instantiation : ov->argType().instantiations()) {
@@ -196,9 +196,9 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
// Create the graph of type dependencies based on implicit conversions.
// All C++ primitive types, add any forgotten type AT THE END OF THIS LIST!
- static const QStringList primitiveTypes{intT(), unsignedIntT(), longT(), unsignedLongT(),
- shortT(), unsignedShortT(), boolT(), unsignedCharT(), charT(), floatT(),
- doubleT(), constCharPtrT()};
+ static const QStringList primitiveTypes{intT, unsignedIntT, longT, unsignedLongT,
+ shortT, unsignedShortT, boolT, unsignedCharT, charT, floatT,
+ doubleT, constCharPtrT};
QStringList foundPrimitiveTypeIds;
for (const auto &p : primitiveTypes) {
@@ -207,7 +207,7 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
}
if (checkPySequence && checkPyObject)
- graph.addEdge(cPySequenceT(), cPyObjectT());
+ graph.addEdge(cPySequenceT, cPyObjectT);
QStringList classesWithIntegerImplicitConversion;
@@ -226,7 +226,7 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
else
convertibleType = getTypeName(function->arguments().constFirst().type());
- if (convertibleType == intT() || convertibleType == unsignedIntT())
+ if (convertibleType == intT || convertibleType == unsignedIntT)
classesWithIntegerImplicitConversion << targetTypeEntryName;
if (!graph.hasNode(convertibleType))
@@ -246,7 +246,7 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
if (!metaClass)
throw Exception(msgArgumentClassNotFound(m_overloads.constFirst(), te));
const auto &ancestors = metaClass->allTypeSystemAncestors();
- for (const AbstractMetaClass *ancestor : ancestors) {
+ for (const auto &ancestor : ancestors) {
QString ancestorTypeName = ancestor->typeEntry()->name();
if (!graph.hasNode(ancestorTypeName))
continue;
@@ -288,28 +288,28 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
if ((checkPySequence || checkPyObject || checkPyBuffer)
- && !targetTypeEntryName.contains(cPyObjectT())
- && !targetTypeEntryName.contains(cPyBufferT())
- && !targetTypeEntryName.contains(cPySequenceT())) {
+ && !targetTypeEntryName.contains(cPyObjectT)
+ && !targetTypeEntryName.contains(cPyBufferT)
+ && !targetTypeEntryName.contains(cPySequenceT)) {
if (checkPySequence) {
// PySequence will be checked after all more specific types, but before PyObject.
- graph.addEdge(targetTypeEntryName, cPySequenceT());
+ graph.addEdge(targetTypeEntryName, cPySequenceT);
} else if (checkPyBuffer) {
// PySequence will be checked after all more specific types, but before PyObject.
- graph.addEdge(targetTypeEntryName, cPyBufferT());
+ graph.addEdge(targetTypeEntryName, cPyBufferT);
} else {
// Add dependency on PyObject, so its check is the last one (too generic).
- graph.addEdge(targetTypeEntryName, cPyObjectT());
+ graph.addEdge(targetTypeEntryName, cPyObjectT);
}
- } else if (checkQVariant && targetTypeEntryName != qVariantT()) {
- if (!graph.containsEdge(qVariantT(), targetTypeEntryName)) // Avoid cyclic dependency.
- graph.addEdge(targetTypeEntryName, qVariantT());
+ } else if (checkQVariant && targetTypeEntryName != qVariantT) {
+ if (!graph.containsEdge(qVariantT, targetTypeEntryName)) // Avoid cyclic dependency.
+ graph.addEdge(targetTypeEntryName, qVariantT);
} else if (checkQString && ov->argType().isPointer()
- && targetTypeEntryName != qStringT()
- && targetTypeEntryName != qByteArrayT()
- && (!checkPyObject || targetTypeEntryName != cPyObjectT())) {
- if (!graph.containsEdge(qStringT(), targetTypeEntryName)) // Avoid cyclic dependency.
- graph.addEdge(targetTypeEntryName, qStringT());
+ && targetTypeEntryName != qStringT
+ && targetTypeEntryName != qByteArrayT
+ && (!checkPyObject || targetTypeEntryName != cPyObjectT)) {
+ if (!graph.containsEdge(qStringT, targetTypeEntryName)) // Avoid cyclic dependency.
+ graph.addEdge(targetTypeEntryName, qStringT);
}
if (targetType.isEnum()) {
@@ -320,8 +320,19 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
}
// QByteArray args need to be checked after QString args
- if (graph.hasNode(qStringT()) && graph.hasNode(qByteArrayT()))
- graph.addEdge(qStringT(), qByteArrayT());
+ if (graph.hasNode(qStringT) && graph.hasNode(qByteArrayT))
+ graph.addEdge(qStringT, qByteArrayT);
+
+ static const Edge rangeOrder[] =
+ {{doubleT, floatT},
+ {longLongT, longT}, {longLongT, intT}, {intT, shortT},
+ {unsignedLongLongT, unsignedLongT}, {unsignedLongLongT, unsignedT},
+ {unsignedLongLongT, unsignedIntT}, {unsignedT, unsignedShortT}
+ };
+ for (const auto &r : rangeOrder) {
+ if (graph.hasNode(r.first) && graph.hasNode(r.second))
+ graph.addEdge(r.first, r.second);
+ }
for (const auto &ov : std::as_const(m_children)) {
const AbstractMetaType &targetType = ov->argType();
@@ -381,8 +392,7 @@ static std::pair<int, int> getMinMaxArgs(const AbstractMetaFunctionCPtr &func)
int defaultValueIndex = -1;
const auto &arguments = func->arguments();
int argIndex = 0;
- for (qsizetype i = 0, size = arguments.size(); i < size; ++i) {
- const auto &arg = arguments.at(i);
+ for (const auto &arg : arguments) {
if (!arg.isModifiedRemoved()) {
if (defaultValueIndex < 0 && arg.hasDefaultValueExpression())
defaultValueIndex = argIndex;
@@ -475,13 +485,13 @@ OverloadDataNode *OverloadDataRootNode::addOverloadDataNode(const AbstractMetaFu
}
}
- if (overloadData.isNull()) {
+ if (!overloadData) {
const int argpos = argPos() + 1;
overloadData.reset(new OverloadDataNode(func, this, arg, argpos));
m_children.append(overloadData);
}
- return overloadData.data();
+ return overloadData.get();
}
bool OverloadData::hasNonVoidReturnType() const
@@ -604,7 +614,7 @@ const AbstractMetaArgument *OverloadDataNode::overloadArgument(const AbstractMet
bool OverloadDataRootNode::nextArgumentHasDefaultValue() const
{
for (const auto &overloadData : m_children) {
- if (!overloadData->getFunctionWithDefaultValue().isNull())
+ if (overloadData->getFunctionWithDefaultValue())
return true;
}
return false;
@@ -612,20 +622,20 @@ bool OverloadDataRootNode::nextArgumentHasDefaultValue() const
static const OverloadDataRootNode *_findNextArgWithDefault(const OverloadDataRootNode *overloadData)
{
- if (!overloadData->getFunctionWithDefaultValue().isNull())
+ if (overloadData->getFunctionWithDefaultValue())
return overloadData;
const OverloadDataRootNode *result = nullptr;
const OverloadDataList &data = overloadData->children();
for (const auto &odata : data) {
- const auto *tmp = _findNextArgWithDefault(odata.data());
+ const auto *tmp = _findNextArgWithDefault(odata.get());
if (!result || (tmp && result->argPos() > tmp->argPos()))
result = tmp;
}
return result;
}
-const OverloadDataRootNode *OverloadDataRootNode::findNextArgWithDefault()
+const OverloadDataRootNode *OverloadDataRootNode::findNextArgWithDefault() const
{
return _findNextArgWithDefault(this);
}
diff --git a/sources/shiboken6/generator/shiboken/overloaddata.h b/sources/shiboken6/generator/shiboken/overloaddata.h
index 3fc9eef50..875a5a8b5 100644
--- a/sources/shiboken6/generator/shiboken/overloaddata.h
+++ b/sources/shiboken6/generator/shiboken/overloaddata.h
@@ -9,13 +9,14 @@
#include <QtCore/QBitArray>
#include <QtCore/QList>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
QT_FORWARD_DECLARE_CLASS(QDebug)
QT_FORWARD_DECLARE_CLASS(QTextStream)
class OverloadDataNode;
-using OverloadDataNodePtr = QSharedPointer<OverloadDataNode>;
+using OverloadDataNodePtr = std::shared_ptr<OverloadDataNode>;
using OverloadDataList = QList<OverloadDataNodePtr>;
/// The root node of OverloadData. It contains all functions
@@ -45,7 +46,7 @@ public:
AbstractMetaFunctionCPtr getFunctionWithDefaultValue() const;
/// Returns the nearest occurrence, including this instance, of an argument with a default value.
- const OverloadDataRootNode *findNextArgWithDefault();
+ const OverloadDataRootNode *findNextArgWithDefault() const;
bool isFinalOccurrence(const AbstractMetaFunctionCPtr &func) const;
int functionNumber(const AbstractMetaFunctionCPtr &func) const;
diff --git a/sources/shiboken6/generator/shiboken/pytypenames.h b/sources/shiboken6/generator/shiboken/pytypenames.h
index 696e0d88d..6c7658ff6 100644
--- a/sources/shiboken6/generator/shiboken/pytypenames.h
+++ b/sources/shiboken6/generator/shiboken/pytypenames.h
@@ -6,24 +6,24 @@
#include <QtCore/QString>
-static inline QString pyBoolT() { return QStringLiteral("PyBool"); }
-static inline QString pyFloatT() { return QStringLiteral("PyFloat"); }
-static inline QString pyLongT() { return QStringLiteral("PyLong"); }
-static inline QString pyObjectT() { return QStringLiteral("object"); }
-static inline QString pyStrT() { return QStringLiteral("str"); }
+constexpr auto pyBoolT = QLatin1StringView ("PyBool");
+constexpr auto pyFloatT = QLatin1StringView ("PyFloat");
+constexpr auto pyLongT = QLatin1StringView ("PyLong");
+constexpr auto pyObjectT = QLatin1StringView ("object");
+constexpr auto pyStrT = QLatin1StringView ("str");
// PYSIDE-1499: A custom type determined by existence of an `__fspath__` attribute.
-static inline QString pyPathLikeT() { return QStringLiteral("PyPathLike"); }
+constexpr auto pyPathLikeT = QLatin1StringView ("PyPathLike");
-static inline QString cPyBufferT() { return QStringLiteral("PyBuffer"); }
-static inline QString cPyListT() { return QStringLiteral("PyList"); }
-static inline QString cPyObjectT() { return QStringLiteral("PyObject"); }
-static inline QString cPySequenceT() { return QStringLiteral("PySequence"); }
-static inline QString cPyTypeObjectT() { return QStringLiteral("PyTypeObject"); }
+constexpr auto cPyBufferT = QLatin1StringView ("PyBuffer");
+constexpr auto cPyListT = QLatin1StringView ("PyList");
+constexpr auto cPyObjectT = QLatin1StringView ("PyObject");
+constexpr auto cPySequenceT = QLatin1StringView ("PySequence");
+constexpr auto cPyTypeObjectT = QLatin1StringView ("PyTypeObject");
// numpy
-static inline QString cPyArrayObjectT() { return QStringLiteral("PyArrayObject"); }
+constexpr auto cPyArrayObjectT = QLatin1StringView ("PyArrayObject");
-static inline QString sbkCharT() { return QStringLiteral("SbkChar"); }
+constexpr auto sbkCharT = QLatin1StringView ("SbkChar");
#endif // PYTYPENAMES_H
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
index 1810235b7..67fd9c994 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "shibokengenerator.h"
+#include "generatorstrings.h"
#include "generatorargument.h"
#include "defaultvalue.h"
#include "generatorcontext.h"
@@ -20,12 +21,12 @@
#include <messages.h>
#include <modifications.h>
#include "overloaddata.h"
+#include <optionsparser.h>
#include "propertyspec.h"
#include "pytypenames.h"
#include <reporthandler.h>
#include <textstream.h>
#include <typedatabase.h>
-#include <abstractmetabuilder.h>
#include <containertypeentry.h>
#include <customtypenentry.h>
#include <enumtypeentry.h>
@@ -33,6 +34,7 @@
#include <namespacetypeentry.h>
#include <primitivetypeentry.h>
#include <pythontypeentry.h>
+#include <smartpointertypeentry.h>
#include <valuetypeentry.h>
#include <iostream>
@@ -42,44 +44,73 @@
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtCore/QRegularExpression>
+
+#include <algorithm>
#include <limits>
#include <memory>
+#include <utility>
using namespace Qt::StringLiterals;
-static const char PARENT_CTOR_HEURISTIC[] = "enable-parent-ctor-heuristic";
-static const char RETURN_VALUE_HEURISTIC[] = "enable-return-value-heuristic";
-static const char DISABLE_VERBOSE_ERROR_MESSAGES[] = "disable-verbose-error-messages";
-static const char USE_ISNULL_AS_NB_NONZERO[] = "use-isnull-as-nb_nonzero";
-static const char USE_OPERATOR_BOOL_AS_NB_NONZERO[] = "use-operator-bool-as-nb_nonzero";
-static const char WRAPPER_DIAGNOSTICS[] = "wrapper-diagnostics";
-static const char NO_IMPLICIT_CONVERSIONS[] = "no-implicit-conversions";
-static const char LEAN_HEADERS[] = "lean-headers";
-
-const QString CPP_ARG = u"cppArg"_s;
-const QString CPP_ARG_REMOVED = u"removed_cppArg"_s;
-const QString CPP_RETURN_VAR = u"cppResult"_s;
-const QString CPP_SELF_VAR = u"cppSelf"_s;
-const QString NULL_PTR = u"nullptr"_s;
-const QString PYTHON_ARG = u"pyArg"_s;
-const QString PYTHON_ARGS = u"pyArgs"_s;
-const QString PYTHON_OVERRIDE_VAR = u"pyOverride"_s;
-const QString PYTHON_RETURN_VAR = u"pyResult"_s;
-const QString PYTHON_TO_CPP_VAR = u"pythonToCpp"_s;
-const QString SMART_POINTER_GETTER = u"kSmartPointerGetter"_s;
-
-const QString CONV_RULE_OUT_VAR_SUFFIX = u"_out"_s;
-const QString BEGIN_ALLOW_THREADS =
- u"PyThreadState *_save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS"_s;
-const QString END_ALLOW_THREADS = u"PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS"_s;
+static constexpr auto PARENT_CTOR_HEURISTIC = "enable-parent-ctor-heuristic"_L1;
+static constexpr auto RETURN_VALUE_HEURISTIC = "enable-return-value-heuristic"_L1;
+static constexpr auto DISABLE_VERBOSE_ERROR_MESSAGES = "disable-verbose-error-messages"_L1;
+static constexpr auto USE_ISNULL_AS_NB_BOOL = "use-isnull-as-nb-bool"_L1;
+// FIXME PYSIDE 7: Remove USE_ISNULL_AS_NB_NONZERO/USE_OPERATOR_BOOL_AS_NB_NONZERO
+static constexpr auto USE_ISNULL_AS_NB_NONZERO = "use-isnull-as-nb_nonzero"_L1;
+static constexpr auto USE_OPERATOR_BOOL_AS_NB_BOOL = "use-operator-bool-as-nb-bool"_L1;
+static constexpr auto USE_OPERATOR_BOOL_AS_NB_NONZERO = "use-operator-bool-as-nb-nonzero"_L1;
+static constexpr auto WRAPPER_DIAGNOSTICS = "wrapper-diagnostics"_L1;
+static constexpr auto NO_IMPLICIT_CONVERSIONS = "no-implicit-conversions"_L1;
+static constexpr auto LEAN_HEADERS = "lean-headers"_L1;
+
+QString CPP_ARG_N(int i)
+{
+ return CPP_ARG + QString::number(i);
+}
+
+constexpr auto CPP_ARG_REMOVED_PREFIX = "removed_cppArg"_L1;
+
+QString CPP_ARG_REMOVED(int i)
+{
+ return CPP_ARG_REMOVED_PREFIX + QString::number(i);
+}
+
+const char *const METHOD_DEF_SENTINEL = "{nullptr, nullptr, 0, nullptr} // Sentinel\n";
+const char *const PYTHON_TO_CPPCONVERSION_STRUCT = "Shiboken::Conversions::PythonToCppConversion";
+
+const char *const openTargetExternC = R"(
+// Target ---------------------------------------------------------
+
+extern "C" {
+)";
+const char *const closeExternC = "} // extern \"C\"\n\n";
+const char *const richCompareComment =
+ "// PYSIDE-74: By default, we redirect to object's tp_richcompare (which is `==`, `!=`).\n";
+
+struct ShibokenGeneratorOptions
+{
+ bool useCtorHeuristic = false;
+ bool userReturnValueHeuristic = false;
+ bool verboseErrorMessagesDisabled = false;
+ bool useIsNullAsNbBool = false;
+ // FIXME PYSIDE 7 Flip m_leanHeaders default or remove?
+ bool leanHeaders = false;
+ bool useOperatorBoolAsNbBool = false;
+ // FIXME PYSIDE 7 Flip generateImplicitConversions default or remove?
+ bool generateImplicitConversions = true;
+ bool wrapperDiagnostics = false;
+};
struct GeneratorClassInfoCacheEntry
{
ShibokenGenerator::FunctionGroups functionGroups;
+ QList<AbstractMetaFunctionCList> numberProtocolOperators;
+ BoolCastFunctionOptional boolCastFunctionO;
bool needsGetattroFunction = false;
};
-using GeneratorClassInfoCache = QHash<const AbstractMetaClass *, GeneratorClassInfoCacheEntry>;
+using GeneratorClassInfoCache = QHash<AbstractMetaClassCPtr, GeneratorClassInfoCacheEntry>;
Q_GLOBAL_STATIC(GeneratorClassInfoCache, generatorClassInfoCache)
@@ -103,6 +134,10 @@ const ShibokenGenerator::TypeSystemConverterRegExps &
return result;
}
+// Options are static to avoid duplicated handling since ShibokenGenerator
+// is instantiated for HeaderGenerator and CppGenerator.
+ShibokenGeneratorOptions ShibokenGenerator::m_options;
+
ShibokenGenerator::ShibokenGenerator() = default;
ShibokenGenerator::~ShibokenGenerator() = default;
@@ -111,32 +146,32 @@ ShibokenGenerator::~ShibokenGenerator() = default;
static const QHash<QString, QString> &primitiveTypesCorrespondences()
{
static const QHash<QString, QString> result = {
- {u"bool"_s, pyBoolT()},
- {u"char"_s, sbkCharT()},
- {u"signed char"_s, sbkCharT()},
- {u"unsigned char"_s, sbkCharT()},
- {intT(), pyLongT()},
- {u"signed int"_s, pyLongT()},
- {u"uint"_s, pyLongT()},
- {u"unsigned int"_s, pyLongT()},
- {shortT(), pyLongT()},
- {u"ushort"_s, pyLongT()},
- {u"signed short"_s, pyLongT()},
- {u"signed short int"_s, pyLongT()},
- {unsignedShortT(), pyLongT()},
- {u"unsigned short int"_s, pyLongT()},
- {longT(), pyLongT()},
- {doubleT(), pyFloatT()},
- {floatT(), pyFloatT()},
- {u"unsigned long"_s, pyLongT()},
- {u"signed long"_s, pyLongT()},
- {u"ulong"_s, pyLongT()},
- {u"unsigned long int"_s, pyLongT()},
- {u"long long"_s, pyLongT()},
- {u"__int64"_s, pyLongT()},
- {u"unsigned long long"_s, pyLongT()},
- {u"unsigned __int64"_s, pyLongT()},
- {u"size_t"_s, pyLongT()}
+ {u"bool"_s, pyBoolT},
+ {u"char"_s, sbkCharT},
+ {u"signed char"_s, sbkCharT},
+ {u"unsigned char"_s, sbkCharT},
+ {intT, pyLongT},
+ {u"signed int"_s, pyLongT},
+ {u"uint"_s, pyLongT},
+ {u"unsigned int"_s, pyLongT},
+ {shortT, pyLongT},
+ {u"ushort"_s, pyLongT},
+ {u"signed short"_s, pyLongT},
+ {u"signed short int"_s, pyLongT},
+ {unsignedShortT, pyLongT},
+ {u"unsigned short int"_s, pyLongT},
+ {longT, pyLongT},
+ {doubleT, pyFloatT},
+ {floatT, pyFloatT},
+ {u"unsigned long"_s, pyLongT},
+ {u"signed long"_s, pyLongT},
+ {u"ulong"_s, pyLongT},
+ {u"unsigned long int"_s, pyLongT},
+ {u"long long"_s, pyLongT},
+ {u"__int64"_s, pyLongT},
+ {u"unsigned long long"_s, pyLongT},
+ {u"unsigned __int64"_s, pyLongT},
+ {u"size_t"_s, pyLongT}
};
return result;
}
@@ -146,24 +181,24 @@ const QHash<QString, QChar> &ShibokenGenerator::formatUnits()
static const QHash<QString, QChar> result = {
{u"char"_s, u'b'},
{u"unsigned char"_s, u'B'},
- {intT(), u'i'},
+ {intT, u'i'},
{u"unsigned int"_s, u'I'},
- {shortT(), u'h'},
- {unsignedShortT(), u'H'},
- {longT(), u'l'},
- {unsignedLongLongT(), u'k'},
- {longLongT(), u'L'},
+ {shortT, u'h'},
+ {unsignedShortT, u'H'},
+ {longT, u'l'},
+ {unsignedLongLongT, u'k'},
+ {longLongT, u'L'},
{u"__int64"_s, u'L'},
- {unsignedLongLongT(), u'K'},
+ {unsignedLongLongT, u'K'},
{u"unsigned __int64"_s, u'K'},
- {doubleT(), u'd'},
- {floatT(), u'f'},
+ {doubleT, u'd'},
+ {floatT, u'f'},
};
return result;
}
QString ShibokenGenerator::translateTypeForWrapperMethod(const AbstractMetaType &cType,
- const AbstractMetaClass *context,
+ const AbstractMetaClassCPtr &context,
Options options) const
{
if (cType.isArray()) {
@@ -180,7 +215,7 @@ QString ShibokenGenerator::translateTypeForWrapperMethod(const AbstractMetaType
return translateType(cType, context, options);
}
-bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass *metaClass) const
+bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClassCPtr &metaClass)
{
const auto wrapper = metaClass->cppWrapper();
return wrapper.testFlag(AbstractMetaClass::CppVirtualMethodWrapper)
@@ -188,8 +223,17 @@ bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass *metaCl
&& wrapper.testFlag(AbstractMetaClass::CppProtectedHackWrapper));
}
-ShibokenGenerator::FunctionGeneration
- ShibokenGenerator::functionGeneration(const AbstractMetaFunctionCPtr &func) const
+bool ShibokenGenerator::shouldGenerateMetaObjectFunctions(const AbstractMetaClassCPtr &metaClass)
+{
+ return usePySideExtensions()
+ && (!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
+ && !metaClass->typeEntry()->typeFlags()
+ .testFlag(ComplexTypeEntry::DisableQtMetaObjectFunctions)
+ && isQObject(metaClass);
+}
+
+ShibokenGenerator::FunctionGeneration ShibokenGenerator::functionGeneration(
+ const AbstractMetaFunctionCPtr &func)
{
FunctionGeneration result;
@@ -232,7 +276,7 @@ ShibokenGenerator::FunctionGeneration
// Check on virtuals (including operators).
const bool isAbstract = func->isAbstract();
if (!(isAbstract || func->isVirtual())
- || func->attributes().testFlag(AbstractMetaFunction::FinalCppMethod)
+ || func->cppAttributes().testFlag(FunctionAttribute::Final)
|| func->isModifiedFinal()) {
return result;
}
@@ -240,7 +284,7 @@ ShibokenGenerator::FunctionGeneration
// MetaObject virtuals only need to be declared; CppGenerator creates a
// special implementation.
if (functionType == AbstractMetaFunction::NormalFunction
- && usePySideExtensions() && func->ownerClass()->isQObject()) {
+ && usePySideExtensions() && isQObject(func->ownerClass())) {
const QString &name = func->name();
if (name == u"metaObject"_s || name == u"qt_metacall") {
result.setFlag(FunctionGenerationFlag::QMetaObjectMethod);
@@ -259,9 +303,9 @@ AbstractMetaFunctionCList ShibokenGenerator::implicitConversions(const TypeEntry
{
if (!generateImplicitConversions() || !t->isValue())
return {};
- auto vte = qSharedPointerCast<const ValueTypeEntry>(t);
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(t);
auto customConversion = vte->customConversion();
- if (!customConversion.isNull() && customConversion->replaceOriginalTargetToNativeConversions())
+ if (customConversion && customConversion->replaceOriginalTargetToNativeConversions())
return {};
auto result = api().implicitConversions(t);
@@ -273,7 +317,7 @@ AbstractMetaFunctionCList ShibokenGenerator::implicitConversions(const TypeEntry
return result;
}
-QString ShibokenGenerator::wrapperName(const AbstractMetaClass *metaClass) const
+QString ShibokenGenerator::wrapperName(const AbstractMetaClassCPtr &metaClass)
{
Q_ASSERT(shouldGenerateCppWrapper(metaClass));
QString result = metaClass->name();
@@ -282,19 +326,55 @@ QString ShibokenGenerator::wrapperName(const AbstractMetaClass *metaClass) const
return result + u"Wrapper"_s;
}
-QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::fullPythonClassName(const AbstractMetaClassCPtr &metaClass)
{
QString fullClassName = metaClass->name();
- const AbstractMetaClass *enclosing = metaClass->enclosingClass();
+ auto enclosing = metaClass->enclosingClass();
while (enclosing) {
if (NamespaceTypeEntry::isVisibleScope(enclosing->typeEntry()))
fullClassName.prepend(enclosing->name() + u'.');
enclosing = enclosing->enclosingClass();
}
- fullClassName.prepend(packageName() + u'.');
+ fullClassName.prepend(metaClass->typeEntry()->targetLangPackage() + u'.');
return fullClassName;
}
+QString ShibokenGenerator::headerFileNameForContext(const GeneratorContext &context)
+{
+ return fileNameForContextHelper(context, u"_wrapper.h"_s);
+}
+
+// PYSIDE-500: When avoiding the protected hack, also include the inherited
+// wrapper classes of the *current* module, because without the protected hack,
+// we sometimes need to cast inherited wrappers. Inherited classes
+// of *other* modules are completely regenerated by the header generator
+// since the wrapper headers are not installed.
+
+IncludeGroup ShibokenGenerator::baseWrapperIncludes(const GeneratorContext &classContext) const
+{
+ IncludeGroup result{u"Wrappers"_s, {}};
+ if (!classContext.useWrapper() || !avoidProtectedHack()
+ || classContext.forSmartPointer()) {
+ return result;
+ }
+
+ const auto moduleEntry = TypeDatabase::instance()->defaultTypeSystemType();
+ const auto &baseClasses = allBaseClasses(classContext.metaClass());
+ for (const auto &base : baseClasses) {
+ const auto te = base->typeEntry();
+ if (te->codeGeneration() == TypeEntry::GenerateCode) { // current module
+ const auto context = contextForClass(base);
+ if (context.useWrapper()) {
+ const QString header = headerFileNameForContext(context);
+ const auto type = typeSystemTypeEntry(te) == moduleEntry
+ ? Include::LocalPath : Include::IncludePath;
+ result.append(Include(type, header));
+ }
+ }
+ }
+ return result;
+}
+
QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunctionCPtr &func, bool forceFunc)
{
QString funcName;
@@ -319,6 +399,11 @@ QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunctionCPtr
return funcName;
}
+bool ShibokenGenerator::wrapperDiagnostics()
+{
+ return m_options.wrapperDiagnostics;
+}
+
QString ShibokenGenerator::protectedEnumSurrogateName(const AbstractMetaEnum &metaEnum)
{
QString result = metaEnum.fullName();
@@ -354,37 +439,37 @@ QString ShibokenGenerator::cpythonFunctionName(const AbstractMetaFunctionCPtr &f
QString ShibokenGenerator::cpythonMethodDefinitionName(const AbstractMetaFunctionCPtr &func)
{
if (!func->ownerClass())
- return QString();
+ return {};
return cpythonBaseName(func->ownerClass()->typeEntry()) + u"Method_"_s
+ func->name();
}
-QString ShibokenGenerator::cpythonGettersSettersDefinitionName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonGettersSettersDefinitionName(const AbstractMetaClassCPtr &metaClass)
{
return cpythonBaseName(metaClass) + u"_getsetlist"_s;
}
-QString ShibokenGenerator::cpythonSetattroFunctionName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonSetattroFunctionName(const AbstractMetaClassCPtr &metaClass)
{
return cpythonBaseName(metaClass) + u"_setattro"_s;
}
-QString ShibokenGenerator::cpythonGetattroFunctionName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonGetattroFunctionName(const AbstractMetaClassCPtr &metaClass)
{
return cpythonBaseName(metaClass) + u"_getattro"_s;
}
QString ShibokenGenerator::cpythonGetterFunctionName(const QString &name,
- const AbstractMetaClass *enclosingClass)
+ const AbstractMetaClassCPtr &enclosingClass)
{
- return cpythonBaseName(enclosingClass) + QStringLiteral("_get_") + name;
+ return cpythonBaseName(enclosingClass) + "_get_"_L1 + name;
}
QString ShibokenGenerator::cpythonSetterFunctionName(const QString &name,
- const AbstractMetaClass *enclosingClass)
+ const AbstractMetaClassCPtr &enclosingClass)
{
- return cpythonBaseName(enclosingClass) + QStringLiteral("_set_") + name;
+ return cpythonBaseName(enclosingClass) + "_set_"_L1 + name;
}
QString ShibokenGenerator::cpythonGetterFunctionName(const AbstractMetaField &metaField)
@@ -398,13 +483,13 @@ QString ShibokenGenerator::cpythonSetterFunctionName(const AbstractMetaField &me
}
QString ShibokenGenerator::cpythonGetterFunctionName(const QPropertySpec &property,
- const AbstractMetaClass *metaClass)
+ const AbstractMetaClassCPtr &metaClass)
{
return cpythonGetterFunctionName(property.name(), metaClass);
}
QString ShibokenGenerator::cpythonSetterFunctionName(const QPropertySpec &property,
- const AbstractMetaClass *metaClass)
+ const AbstractMetaClassCPtr &metaClass)
{
return cpythonSetterFunctionName(property.name(), metaClass);
}
@@ -439,15 +524,15 @@ QString ShibokenGenerator::cpythonFlagsName(const FlagsTypeEntryCPtr &flagsEntry
QString ShibokenGenerator::cpythonFlagsName(const AbstractMetaEnum *metaEnum)
{
const auto flags = metaEnum->typeEntry()->flags();
- return flags.isNull() ? QString{} : cpythonFlagsName(flags);
+ return flags ? cpythonFlagsName(flags) : QString{};
}
-QString ShibokenGenerator::cpythonSpecialCastFunctionName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonSpecialCastFunctionName(const AbstractMetaClassCPtr &metaClass)
{
return cpythonBaseName(metaClass->typeEntry()) + u"SpecialCastFunction"_s;
}
-QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaClass *metaClass,
+QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaClassCPtr &metaClass,
const QString &argName)
{
return cpythonWrapperCPtr(metaClass->typeEntry(), argName);
@@ -457,7 +542,7 @@ QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaType &metaType,
const QString &argName)
{
if (!metaType.isWrapperType())
- return QString();
+ return {};
return u"reinterpret_cast< ::"_s + metaType.cppSignature()
+ u" *>(Shiboken::Conversions::cppPointer("_s + cpythonTypeNameExt(metaType)
+ u", reinterpret_cast<SbkObject *>("_s + argName + u")))"_s;
@@ -468,29 +553,30 @@ QString ShibokenGenerator::cpythonWrapperCPtr(const TypeEntryCPtr &type,
{
if (!type->isWrapperType())
return QString();
- return u"reinterpret_cast< ::"_s + type->qualifiedCppName()
+ return u"reinterpret_cast< "_s + getFullTypeName(type)
+ u" *>(Shiboken::Conversions::cppPointer("_s + cpythonTypeNameExt(type)
+ u", reinterpret_cast<SbkObject *>("_s + argName + u")))"_s;
}
void ShibokenGenerator::writeToPythonConversion(TextStream & s, const AbstractMetaType &type,
- const AbstractMetaClass * /* context */,
+ const AbstractMetaClassCPtr & /* context */,
const QString &argumentName)
{
s << cpythonToPythonConversionFunction(type) << argumentName << ')';
}
-void ShibokenGenerator::writeToCppConversion(TextStream &s, const AbstractMetaClass *metaClass,
+void ShibokenGenerator::writeToCppConversion(TextStream &s,
+ const AbstractMetaClassCPtr &metaClass,
const QString &inArgName, const QString &outArgName)
{
s << cpythonToCppConversionFunction(metaClass) << inArgName << ", &" << outArgName << ')';
}
void ShibokenGenerator::writeToCppConversion(TextStream &s, const AbstractMetaType &type,
- const AbstractMetaClass *context, const QString &inArgName,
+ const QString &inArgName,
const QString &outArgName)
{
- s << cpythonToCppConversionFunction(type, context) << inArgName << ", &" << outArgName << ')';
+ s << cpythonToCppConversionFunction(type) << inArgName << ", &" << outArgName << ')';
}
bool ShibokenGenerator::shouldRejectNullPointerArgument(const AbstractMetaFunctionCPtr &func,
@@ -525,11 +611,29 @@ QString ShibokenGenerator::cpythonBaseName(const AbstractMetaType &type)
return cpythonBaseName(type.typeEntry());
}
-QString ShibokenGenerator::cpythonBaseName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonBaseName(const AbstractMetaClassCPtr &metaClass)
{
return cpythonBaseName(metaClass->typeEntry());
}
+QString ShibokenGenerator::containerCpythonBaseName(const ContainerTypeEntryCPtr &ctype)
+{
+ switch (ctype->containerKind()) {
+ case ContainerTypeEntry::SetContainer:
+ return u"PySet"_s;
+ case ContainerTypeEntry::MapContainer:
+ case ContainerTypeEntry::MultiMapContainer:
+ return u"PyDict"_s;
+ case ContainerTypeEntry::ListContainer:
+ case ContainerTypeEntry::PairContainer:
+ case ContainerTypeEntry::SpanContainer:
+ break;
+ default:
+ Q_ASSERT(false);
+ }
+ return cPySequenceT;
+}
+
QString ShibokenGenerator::cpythonBaseName(const TypeEntryCPtr &type)
{
QString baseName;
@@ -540,36 +644,19 @@ QString ShibokenGenerator::cpythonBaseName(const TypeEntryCPtr &type)
baseName = ptype->hasTargetLangApiType()
? ptype->targetLangApiName() : pythonPrimitiveTypeName(ptype->name());
} else if (type->isEnum()) {
- baseName = cpythonEnumName(qSharedPointerCast<const EnumTypeEntry>(type));
+ baseName = cpythonEnumName(std::static_pointer_cast<const EnumTypeEntry>(type));
} else if (type->isFlags()) {
- baseName = cpythonFlagsName(qSharedPointerCast<const FlagsTypeEntry>(type));
+ baseName = cpythonFlagsName(std::static_pointer_cast<const FlagsTypeEntry>(type));
} else if (type->isContainer()) {
- const auto ctype = qSharedPointerCast<const ContainerTypeEntry>(type);
- switch (ctype->containerKind()) {
- case ContainerTypeEntry::ListContainer:
- //baseName = "PyList";
- //break;
- case ContainerTypeEntry::PairContainer:
- //baseName = "PyTuple";
- baseName = cPySequenceT();
- break;
- case ContainerTypeEntry::SetContainer:
- baseName = u"PySet"_s;
- break;
- case ContainerTypeEntry::MapContainer:
- case ContainerTypeEntry::MultiMapContainer:
- baseName = u"PyDict"_s;
- break;
- default:
- Q_ASSERT(false);
- }
+ const auto ctype = std::static_pointer_cast<const ContainerTypeEntry>(type);
+ baseName = containerCpythonBaseName(ctype);
} else {
- baseName = cPyObjectT();
+ baseName = cPyObjectT;
}
return baseName.replace(u"::"_s, u"_"_s);
}
-QString ShibokenGenerator::cpythonTypeName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonTypeName(const AbstractMetaClassCPtr &metaClass)
{
return cpythonTypeName(metaClass->typeEntry());
}
@@ -579,12 +666,6 @@ QString ShibokenGenerator::cpythonTypeName(const TypeEntryCPtr &type)
return cpythonBaseName(type) + u"_TypeF()"_s;
}
-QString ShibokenGenerator::cpythonTypeNameExt(const TypeEntryCPtr &type)
-{
- return cppApiVariableName(type->targetLangPackage()) + u'['
- + getTypeIndexVariableName(type) + u']';
-}
-
QString ShibokenGenerator::converterObject(const AbstractMetaType &type)
{
if (type.isCString())
@@ -593,7 +674,7 @@ QString ShibokenGenerator::converterObject(const AbstractMetaType &type)
return u"Shiboken::Conversions::PrimitiveTypeConverter<void *>()"_s;
const AbstractMetaTypeList nestedArrayTypes = type.nestedArrayTypes();
if (!nestedArrayTypes.isEmpty() && nestedArrayTypes.constLast().isCppPrimitive()) {
- return QStringLiteral("Shiboken::Conversions::ArrayTypeConverter<")
+ return "Shiboken::Conversions::ArrayTypeConverter<"_L1
+ nestedArrayTypes.constLast().minimalSignature()
+ u">("_s + QString::number(nestedArrayTypes.size())
+ u')';
@@ -615,23 +696,20 @@ QString ShibokenGenerator::converterObject(const TypeEntryCPtr &type)
if (type->isWrapperType())
return QString::fromLatin1("PepType_SOTP(reinterpret_cast<PyTypeObject *>(%1))->converter")
.arg(cpythonTypeNameExt(type));
- if (type->isEnum())
+ if (type->isEnum() || type->isFlags())
return QString::fromLatin1("PepType_SETP(reinterpret_cast<SbkEnumType *>(%1))->converter")
.arg(cpythonTypeNameExt(type));
- if (type->isFlags())
- return QString::fromLatin1("PepType_PFTP(reinterpret_cast<PySideQFlagsType *>(%1))->converter")
- .arg(cpythonTypeNameExt(type));
if (type->isArray()) {
qDebug() << "Warning: no idea how to handle the Qt5 type " << type->qualifiedCppName();
- return QString();
+ return {};
}
/* the typedef'd primitive types case */
- auto pte = qSharedPointerDynamicCast<const PrimitiveTypeEntry>(type);
- if (pte.isNull()) {
+ auto pte = std::dynamic_pointer_cast<const PrimitiveTypeEntry>(type);
+ if (!pte) {
qDebug() << "Warning: the Qt5 primitive type is unknown" << type->qualifiedCppName();
- return QString();
+ return {};
}
pte = basicReferencedTypeEntry(pte);
if (pte->isPrimitive() && !isCppPrimitive(pte) && !pte->customConversion()) {
@@ -643,13 +721,29 @@ QString ShibokenGenerator::converterObject(const TypeEntryCPtr &type)
+ u'[' + getTypeIndexVariableName(type) + u']';
}
-QString ShibokenGenerator::cpythonTypeNameExt(const AbstractMetaType &type)
+QString ShibokenGenerator::cpythonTypeNameExtSet(const TypeEntryCPtr &type)
+{
+ return cppApiVariableName(type->targetLangPackage()) + u'['
+ + getTypeIndexVariableName(type) + "].type"_L1;
+}
+
+QString ShibokenGenerator::cpythonTypeNameExtSet(const AbstractMetaType &type)
{
return cppApiVariableName(type.typeEntry()->targetLangPackage()) + u'['
- + getTypeIndexVariableName(type) + u']';
+ + getTypeIndexVariableName(type) + "].type"_L1;
+}
+
+QString ShibokenGenerator::cpythonTypeNameExt(const TypeEntryCPtr &type)
+{
+ return "Shiboken::Module::get("_L1 + cppApiVariableName(type->targetLangPackage())
+ + u'[' + getTypeIndexVariableName(type) + "])"_L1;
}
-static inline QString unknownOperator() { return QStringLiteral("__UNKNOWN_OPERATOR__"); }
+QString ShibokenGenerator::cpythonTypeNameExt(const AbstractMetaType &type)
+{
+ return u"Shiboken::Module::get("_s + cppApiVariableName(type.typeEntry()->targetLangPackage())
+ + u'[' + getTypeIndexVariableName(type) + "])"_L1;
+}
QString ShibokenGenerator::fixedCppTypeName(const TargetToNativeConversion &toNative)
{
@@ -698,8 +792,8 @@ QString ShibokenGenerator::pythonOperatorFunctionName(const AbstractMetaFunction
{
QString op = Generator::pythonOperatorFunctionName(func->originalName());
if (op.isEmpty()) {
- qCWarning(lcShiboken).noquote().nospace() << msgUnknownOperator(func.data());
- return unknownOperator();
+ qCWarning(lcShiboken).noquote().nospace() << msgUnknownOperator(func.get());
+ return "__UNKNOWN_OPERATOR__"_L1;
}
if (func->arguments().isEmpty()) {
if (op == u"__sub__")
@@ -716,8 +810,8 @@ QString ShibokenGenerator::pythonOperatorFunctionName(const AbstractMetaFunction
bool ShibokenGenerator::isNumber(const QString &cpythonApiName)
{
- return cpythonApiName == pyFloatT() || cpythonApiName == pyLongT()
- || cpythonApiName == pyBoolT();
+ return cpythonApiName == pyFloatT || cpythonApiName == pyLongT
+ || cpythonApiName == pyBoolT;
}
static std::optional<TypeSystem::CPythonType>
@@ -728,7 +822,7 @@ static std::optional<TypeSystem::CPythonType>
const auto cte = t->targetLangApiType();
if (cte->type() != TypeEntry::PythonType)
return {};
- return qSharedPointerCast<const PythonTypeEntry>(cte)->cPythonType();
+ return std::static_pointer_cast<const PythonTypeEntry>(cte)->cPythonType();
}
bool ShibokenGenerator::isNumber(const TypeEntryCPtr &type)
@@ -764,7 +858,7 @@ bool ShibokenGenerator::isPyInt(const TypeEntryCPtr &type)
if (!cPythonTypeOpt.has_value()) {
const auto &mapping = primitiveTypesCorrespondences();
const auto it = mapping.constFind(pte->name());
- return it != mapping.cend() && it.value() == pyLongT();
+ return it != mapping.cend() && it.value() == pyLongT;
}
return cPythonTypeOpt.value() == TypeSystem::CPythonType::Integer;
}
@@ -784,7 +878,7 @@ QString ShibokenGenerator::cpythonCheckFunction(AbstractMetaType metaType)
{
const auto typeEntry = metaType.typeEntry();
if (typeEntry->isCustom()) {
- const auto cte = qSharedPointerCast<const CustomTypeEntry>(typeEntry);
+ const auto cte = std::static_pointer_cast<const CustomTypeEntry>(typeEntry);
if (cte->hasCheckFunction())
return cte->checkFunction();
throw Exception(msgUnknownCheckFunction(typeEntry));
@@ -801,7 +895,7 @@ QString ShibokenGenerator::cpythonCheckFunction(AbstractMetaType metaType)
if (typeEntry->isContainer()) {
QString typeCheck = u"Shiboken::Conversions::"_s;
ContainerTypeEntry::ContainerKind type =
- qSharedPointerCast<const ContainerTypeEntry>(typeEntry)->containerKind();
+ std::static_pointer_cast<const ContainerTypeEntry>(typeEntry)->containerKind();
if (type == ContainerTypeEntry::ListContainer
|| type == ContainerTypeEntry::SetContainer) {
const QString containerType = type == ContainerTypeEntry::SetContainer
@@ -852,7 +946,7 @@ QString ShibokenGenerator::cpythonCheckFunction(AbstractMetaType metaType)
QString ShibokenGenerator::cpythonCheckFunction(TypeEntryCPtr type)
{
if (type->isCustom()) {
- const auto cte = qSharedPointerCast<const CustomTypeEntry>(type);
+ const auto cte = std::static_pointer_cast<const CustomTypeEntry>(type);
if (cte->hasCheckFunction())
return cte->checkFunction();
throw Exception(msgUnknownCheckFunction(type));
@@ -881,7 +975,7 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntryCPtr &typ
QString result = u"Shiboken::Conversions::"_s;
bool isValue = false;
if (type->isValue()) {
- const auto cte = qSharedPointerCast<const ComplexTypeEntry>(type);
+ const auto cte = std::static_pointer_cast<const ComplexTypeEntry>(type);
isValue = !cte->isValueTypeWithCopyConstructorOnly();
}
result += isValue ? u"isPythonToCppValueConvertible"_s
@@ -893,11 +987,11 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntryCPtr &typ
.arg(converterObject(type));
}
-QString ShibokenGenerator::cpythonIsConvertibleFunction(AbstractMetaType metaType)
+QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType &metaType)
{
const auto typeEntry = metaType.typeEntry();
if (typeEntry->isCustom()) {
- const auto cte = qSharedPointerCast<const CustomTypeEntry>(typeEntry);
+ const auto cte = std::static_pointer_cast<const CustomTypeEntry>(typeEntry);
if (cte->hasCheckFunction())
return cte->checkFunction();
throw Exception(msgUnknownCheckFunction(typeEntry));
@@ -910,12 +1004,14 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(AbstractMetaType metaTyp
return result;
}
if (metaType.isWrapperType()) {
- if (metaType.isPointer() || metaType.isValueTypeWithCopyConstructorOnly())
+ if (metaType.isPointer() || metaType.isValueTypeWithCopyConstructorOnly()) {
result += u"pythonToCppPointerConversion"_s;
- else if (metaType.referenceType() == LValueReference)
+ } else if (metaType.referenceType() == LValueReference
+ || (metaType.referenceType() == RValueReference && typeEntry->isObject())) {
result += u"pythonToCppReferenceConversion"_s;
- else
+ } else {
result += u"pythonToCppValueConversion"_s;
+ }
result += u'(' + cpythonTypeNameExt(metaType) + u", "_s;
return result;
}
@@ -938,26 +1034,24 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaArgume
return cpythonIsConvertibleFunction(metaArg.type());
}
-QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaClassCPtr &metaClass)
{
return u"Shiboken::Conversions::pythonToCppPointer("_s
+ cpythonTypeNameExt(metaClass->typeEntry()) + u", "_s;
}
-QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaType &type,
- const AbstractMetaClass * /* context */)
+QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaType &type)
{
if (type.isWrapperType()) {
return u"Shiboken::Conversions::pythonToCpp"_s
+ (type.isPointer() ? u"Pointer"_s : u"Copy"_s)
+ u'(' + cpythonTypeNameExt(type) + u", "_s;
}
- return QStringLiteral("Shiboken::Conversions::pythonToCppCopy(%1, ")
- .arg(converterObject(type));
+ return "Shiboken::Conversions::pythonToCppCopy("_L1
+ + converterObject(type) + ", "_L1;
}
-QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaType &type,
- const AbstractMetaClass * /* context */)
+QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaType &type)
{
if (type.isWrapperType()) {
QString conversion;
@@ -976,12 +1070,13 @@ QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaT
result += u'&';
return result;
}
- return QStringLiteral("Shiboken::Conversions::copyToPython(%1, %2")
- .arg(converterObject(type),
- (type.isCString() || type.isVoidPointer()) ? QString() : u"&"_s);
+
+ const auto indirections = type.indirections() - 1;
+ return u"Shiboken::Conversions::copyToPython("_s + converterObject(type)
+ + u", "_s + AbstractMetaType::dereferencePrefix(indirections);
}
-QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonToPythonConversionFunction(const AbstractMetaClassCPtr &metaClass)
{
return cpythonToPythonConversionFunction(metaClass->typeEntry());
}
@@ -1009,13 +1104,14 @@ QString ShibokenGenerator::argumentString(const AbstractMetaFunctionCPtr &func,
auto type = options.testFlag(OriginalTypeDescription)
? argument.type() : argument.modifiedType();
+
QString arg = translateType(type, func->implementingClass(), options);
if (argument.isTypeModified())
arg.replace(u'$', u'.'); // Haehh?
// "int a", "int a[]"
- const int arrayPos = arg.indexOf(u'[');
+ const auto arrayPos = arg.indexOf(u'[');
if (arrayPos != -1)
arg.insert(arrayPos, u' ' + argument.name());
else
@@ -1051,6 +1147,10 @@ void ShibokenGenerator::writeFunctionArguments(TextStream &s,
Options options) const
{
int argUsed = 0;
+ if (func->isUserAddedPythonOverride()) {
+ s << "Shiboken::GilState &gil, PyObject *" << PYTHON_OVERRIDE_VAR;
+ argUsed += 2;
+ }
for (const auto &arg : func->arguments()) {
if (options.testFlag(Generator::SkipRemovedArguments) && arg.isModifiedRemoved())
continue;
@@ -1062,7 +1162,7 @@ void ShibokenGenerator::writeFunctionArguments(TextStream &s,
}
}
-GeneratorContext ShibokenGenerator::contextForClass(const AbstractMetaClass *c) const
+GeneratorContext ShibokenGenerator::contextForClass(const AbstractMetaClassCPtr &c) const
{
GeneratorContext result = Generator::contextForClass(c);
if (shouldGenerateCppWrapper(c)) {
@@ -1087,6 +1187,8 @@ QString ShibokenGenerator::functionSignature(const AbstractMetaFunctionCPtr &fun
{
StringStream s(TextStream::Language::Cpp);
// The actual function
+ if (!options.testFlag(Option::SkipDefaultValues) && func->isStatic()) // Declaration
+ s << "static ";
if (func->isEmptyFunction() || func->needsReturnType())
s << functionReturnType(func, options) << ' ';
else
@@ -1151,7 +1253,7 @@ void ShibokenGenerator::writeFunctionCall(TextStream &s,
ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverters() const
{
ExtendedConverterData extConvs;
- for (auto metaClass : api().classes()) {
+ for (const auto &metaClass : api().classes()) {
// Use only the classes for the current module.
if (!shouldGenerate(metaClass->typeEntry()))
continue;
@@ -1188,7 +1290,7 @@ static QString getArgumentsFromMethodCall(const QString &str)
// For more information check this:
// http://perl.plover.com/yak/regex/samples/slide083.html
static QLatin1String funcCall("%CPPSELF.%FUNCTION_NAME");
- int pos = str.indexOf(funcCall);
+ auto pos = str.indexOf(funcCall);
if (pos == -1)
return QString();
pos = pos + funcCall.size();
@@ -1232,7 +1334,7 @@ void ShibokenGenerator::processClassCodeSnip(QString &code, const GeneratorConte
code.replace(u"%TYPE"_s, className);
code.replace(u"%CPPTYPE"_s, metaClass->name());
- processCodeSnip(code);
+ processCodeSnip(code, context.effectiveClassName());
}
void ShibokenGenerator::processCodeSnip(QString &code) const
@@ -1250,6 +1352,15 @@ void ShibokenGenerator::processCodeSnip(QString &code) const
replaceTypeCheckTypeSystemVariable(code);
}
+void ShibokenGenerator::processCodeSnip(QString &code, const QString &context) const
+{
+ try {
+ processCodeSnip(code);
+ } catch (const std::exception &e) {
+ throw Exception(msgSnippetError(context, e.what()));
+ }
+}
+
ShibokenGenerator::ArgumentVarReplacementList
ShibokenGenerator::getArgumentReplacement(const AbstractMetaFunctionCPtr &func,
bool usePyArgs, TypeSystem::Language language,
@@ -1270,7 +1381,7 @@ ShibokenGenerator::ArgumentVarReplacementList
if (argRemoved && hasConversionRule)
argValue = arg.name() + CONV_RULE_OUT_VAR_SUFFIX;
else if (argRemoved || (lastArg && arg.argumentIndex() > lastArg->argumentIndex()))
- argValue = CPP_ARG_REMOVED + QString::number(i);
+ argValue = CPP_ARG_REMOVED(i);
if (!argRemoved && argValue.isEmpty()) {
int argPos = i - removed;
AbstractMetaType type = arg.modifiedType();
@@ -1280,7 +1391,7 @@ ShibokenGenerator::ArgumentVarReplacementList
} else {
argValue = hasConversionRule
? arg.name() + CONV_RULE_OUT_VAR_SUFFIX
- : CPP_ARG + QString::number(argPos);
+ : CPP_ARG_N(argPos);
const auto generatorArg = GeneratorArgument::fromMetaType(type);
AbstractMetaType::applyDereference(&argValue, generatorArg.indirections);
}
@@ -1322,7 +1433,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
static void replacePyArg0(TypeSystem::Language language, QString *code)
{
- static const QString pyArg0 = u"%PYARG_0"_s;
+ static constexpr auto pyArg0 = "%PYARG_0"_L1;
if (!code->contains(pyArg0))
return;
@@ -1361,18 +1472,18 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
// Replace %PYARG_# variables.
replacePyArg0(language, &code);
- static const QRegularExpression pyArgsRegex(QStringLiteral("%PYARG_(\\d+)"));
+ static const QRegularExpression pyArgsRegex("%PYARG_(\\d+)"_L1);
Q_ASSERT(pyArgsRegex.isValid());
if (language == TypeSystem::TargetLangCode) {
if (usePyArgs) {
code.replace(pyArgsRegex, PYTHON_ARGS + u"[\\1-1]"_s);
} else {
- static const QRegularExpression pyArgsRegexCheck(QStringLiteral("%PYARG_([2-9]+)"));
+ static const QRegularExpression pyArgsRegexCheck("%PYARG_([2-9]+)"_L1);
Q_ASSERT(pyArgsRegexCheck.isValid());
const QRegularExpressionMatch match = pyArgsRegexCheck.match(code);
if (match.hasMatch()) {
qCWarning(lcShiboken).noquote().nospace()
- << msgWrongIndex("%PYARG", match.captured(1), func.data());
+ << msgWrongIndex("%PYARG", match.captured(1), func.get());
return;
}
code.replace(u"%PYARG_1"_s, PYTHON_ARG);
@@ -1380,12 +1491,12 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
} else {
// Replaces the simplest case of attribution to a
// Python argument on the binding virtual method.
- static const QRegularExpression pyArgsAttributionRegex(QStringLiteral("%PYARG_(\\d+)\\s*=[^=]\\s*([^;]+)"));
+ static const QRegularExpression pyArgsAttributionRegex("%PYARG_(\\d+)\\s*=[^=]\\s*([^;]+)"_L1);
Q_ASSERT(pyArgsAttributionRegex.isValid());
code.replace(pyArgsAttributionRegex, u"PyTuple_SET_ITEM("_s
- + PYTHON_ARGS + u", \\1-1, \\2)"_s);
+ + PYTHON_ARGS + u".object(), \\1-1, \\2)"_s);
code.replace(pyArgsRegex, u"PyTuple_GET_ITEM("_s
- + PYTHON_ARGS + u", \\1-1)"_s);
+ + PYTHON_ARGS + u".object(), \\1-1)"_s);
}
// Replace %ARG#_TYPE variables.
@@ -1397,13 +1508,13 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
code.replace(argTypeVar, argTypeVal);
}
- static const QRegularExpression cppArgTypeRegexCheck(QStringLiteral("%ARG(\\d+)_TYPE"));
+ static const QRegularExpression cppArgTypeRegexCheck("%ARG(\\d+)_TYPE"_L1);
Q_ASSERT(cppArgTypeRegexCheck.isValid());
QRegularExpressionMatchIterator rit = cppArgTypeRegexCheck.globalMatch(code);
while (rit.hasNext()) {
QRegularExpressionMatch match = rit.next();
qCWarning(lcShiboken).noquote().nospace()
- << msgWrongIndex("%ARG#_TYPE", match.captured(1), func.data());
+ << msgWrongIndex("%ARG#_TYPE", match.captured(1), func.get());
}
// Replace template variable for return variable name.
@@ -1489,7 +1600,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
QStringList args;
for (const ArgumentVarReplacementPair &pair : argReplacements) {
- if (pair.second.startsWith(CPP_ARG_REMOVED))
+ if (pair.second.startsWith(CPP_ARG_REMOVED_PREFIX))
continue;
args << pair.second;
}
@@ -1539,8 +1650,8 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
if (isProtected) {
code.replace(u"%TYPE::%FUNCTION_NAME"_s,
- QStringLiteral("%1::%2_protected")
- .arg(wrapperName(func->ownerClass()), func->originalName()));
+ wrapperName(func->ownerClass()) + "::"_L1
+ + func->originalName() + "_protected"_L1);
code.replace(u"%FUNCTION_NAME"_s,
func->originalName() + u"_protected"_s);
}
@@ -1554,7 +1665,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
replaceTemplateVariables(code, func);
- processCodeSnip(code);
+ processCodeSnip(code, func->classQualifiedSignature());
s << "// Begin code injection\n" << code << "// End of code injection\n\n";
}
@@ -1562,7 +1673,7 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
// and false if it is a variable.
static bool isVariable(const QString &code)
{
- static const QRegularExpression expr(QStringLiteral("^\\s*\\*?\\s*[A-Za-z_][A-Za-z_0-9.]*\\s*(?:\\[[^\\[]+\\])*$"));
+ static const QRegularExpression expr("^\\s*\\*?\\s*[A-Za-z_][A-Za-z_0-9.]*\\s*(?:\\[[^\\[]+\\])*$"_L1);
Q_ASSERT(expr.isValid());
return expr.match(code.trimmed()).hasMatch();
}
@@ -1623,7 +1734,7 @@ const QHash<int, QString> &ShibokenGenerator::typeSystemConvName()
return result;
}
-using StringPair = QPair<QString, QString>;
+using StringPair = std::pair<QString, QString>;
void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVariable converterVariable,
QString &code) const
@@ -1658,9 +1769,6 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
varType = miniNormalizer(varType);
QString varName = list.at(1).trimmed();
if (!varType.isEmpty()) {
- const QString conversionSignature = conversionType.cppSignature();
- if (varType != u"auto" && varType != conversionSignature)
- throw Exception(msgConversionTypesDiffer(varType, conversionSignature));
c << getFullTypeName(conversionType) << ' ' << varName
<< minimalConstructorExpression(api(), conversionType) << ";\n";
}
@@ -1677,7 +1785,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
case TypeSystemCheckFunction:
conversion = cpythonCheckFunction(conversionType);
if (conversionType.typeEntry()->isPrimitive()
- && (conversionType.typeEntry()->name() == cPyObjectT()
+ && (conversionType.typeEntry()->name() == cPyObjectT
|| !conversion.endsWith(u' '))) {
conversion += u'(';
break;
@@ -1708,7 +1816,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
}
}
}
- replacements.append(qMakePair(conversionString, conversion));
+ replacements.append(std::make_pair(conversionString, conversion));
}
for (const StringPair &rep : std::as_const(replacements))
code.replace(rep.first, rep.second);
@@ -1735,12 +1843,13 @@ bool ShibokenGenerator::injectedCodeCallsCppFunction(const GeneratorContext &con
return func->injectedCodeContains(wrappedCtorCall);
}
-bool ShibokenGenerator::useOverrideCaching(const AbstractMetaClass *metaClass)
+bool ShibokenGenerator::useOverrideCaching(const AbstractMetaClassCPtr &metaClass)
{
return metaClass->isPolymorphic();
}
-ShibokenGenerator::AttroCheck ShibokenGenerator::checkAttroFunctionNeeds(const AbstractMetaClass *metaClass) const
+ShibokenGenerator::AttroCheck ShibokenGenerator::checkAttroFunctionNeeds(
+ const AbstractMetaClassCPtr &metaClass)
{
AttroCheck result;
if (metaClass->typeEntry()->isSmartPointer()) {
@@ -1752,7 +1861,7 @@ ShibokenGenerator::AttroCheck ShibokenGenerator::checkAttroFunctionNeeds(const A
FunctionQueryOption::GetAttroFunction)) {
result |= AttroCheckFlag::GetattroUser;
}
- if (usePySideExtensions() && metaClass->qualifiedCppName() == qObjectT())
+ if (usePySideExtensions() && metaClass->qualifiedCppName() == qObjectT)
result |= AttroCheckFlag::SetattroQObject;
if (useOverrideCaching(metaClass))
result |= AttroCheckFlag::SetattroMethodOverride;
@@ -1764,14 +1873,14 @@ ShibokenGenerator::AttroCheck ShibokenGenerator::checkAttroFunctionNeeds(const A
// QObject, the property code needs to be generated, too.
if ((result & AttroCheckFlag::SetattroMask) != 0
&& !result.testFlag(AttroCheckFlag::SetattroQObject)
- && metaClass->isQObject()) {
+ && isQObject(metaClass)) {
result |= AttroCheckFlag::SetattroQObject;
}
}
return result;
}
-bool ShibokenGenerator::classNeedsGetattroFunctionImpl(const AbstractMetaClass *metaClass)
+bool ShibokenGenerator::classNeedsGetattroFunctionImpl(const AbstractMetaClassCPtr &metaClass)
{
if (!metaClass)
return false;
@@ -1797,7 +1906,7 @@ bool ShibokenGenerator::classNeedsGetattroFunctionImpl(const AbstractMetaClass *
}
AbstractMetaFunctionCList
- ShibokenGenerator::getMethodsWithBothStaticAndNonStaticMethods(const AbstractMetaClass *metaClass)
+ ShibokenGenerator::getMethodsWithBothStaticAndNonStaticMethods(const AbstractMetaClassCPtr &metaClass)
{
AbstractMetaFunctionCList methods;
if (metaClass) {
@@ -1821,7 +1930,8 @@ AbstractMetaFunctionCList
return methods;
}
-const AbstractMetaClass *ShibokenGenerator::getMultipleInheritingClass(const AbstractMetaClass *metaClass)
+AbstractMetaClassCPtr
+ ShibokenGenerator::getMultipleInheritingClass(const AbstractMetaClassCPtr &metaClass)
{
if (!metaClass || metaClass->baseClassNames().isEmpty())
return nullptr;
@@ -1832,20 +1942,20 @@ const AbstractMetaClass *ShibokenGenerator::getMultipleInheritingClass(const Abs
QString ShibokenGenerator::getModuleHeaderFileBaseName(const QString &moduleName)
{
- return moduleCppPrefix(moduleName).toLower() + QStringLiteral("_python");
+ return moduleCppPrefix(moduleName).toLower() + "_python"_L1;
}
QString ShibokenGenerator::getModuleHeaderFileName(const QString &moduleName)
{
- return getModuleHeaderFileBaseName(moduleName) + QStringLiteral(".h");
+ return getModuleHeaderFileBaseName(moduleName) + ".h"_L1;
}
QString ShibokenGenerator::getPrivateModuleHeaderFileName(const QString &moduleName)
{
- return getModuleHeaderFileBaseName(moduleName) + QStringLiteral("_p.h");
+ return getModuleHeaderFileBaseName(moduleName) + "_p.h"_L1;
}
-IncludeGroupList ShibokenGenerator::classIncludes(const AbstractMetaClass *metaClass) const
+IncludeGroupList ShibokenGenerator::classIncludes(const AbstractMetaClassCPtr &metaClass) const
{
IncludeGroupList result;
const auto typeEntry = metaClass->typeEntry();
@@ -1859,9 +1969,9 @@ IncludeGroupList ShibokenGenerator::classIncludes(const AbstractMetaClass *metaC
result.append({u"Argument includes"_s, typeEntry->argumentIncludes()});
const auto implicitConvs = implicitConversions(typeEntry);
- for (auto &f : implicitConvs) {
+ for (const auto &f : implicitConvs) {
if (f->isConversionOperator()) {
- auto *source = f->ownerClass();
+ const auto source = f->ownerClass();
Q_ASSERT(source);
result.back().append(source->typeEntry()->include());
}
@@ -1917,29 +2027,47 @@ ShibokenGenerator::FunctionGroups ShibokenGenerator::getGlobalFunctionGroups() c
{
FunctionGroups results;
insertIntoFunctionGroups(api().globalFunctions(), &results);
- for (auto nsp : invisibleTopNamespaces())
+ for (const auto &nsp : invisibleTopNamespaces())
insertIntoFunctionGroups(nsp->functions(), &results);
return results;
}
-const GeneratorClassInfoCacheEntry &ShibokenGenerator::getGeneratorClassInfo(const AbstractMetaClass *scope)
+const GeneratorClassInfoCacheEntry &
+ ShibokenGenerator::getGeneratorClassInfo(const AbstractMetaClassCPtr &scope)
{
auto cache = generatorClassInfoCache();
auto it = cache->find(scope);
if (it == cache->end()) {
it = cache->insert(scope, {});
- it.value().functionGroups = getFunctionGroupsImpl(scope);
- it.value().needsGetattroFunction = classNeedsGetattroFunctionImpl(scope);
+ auto &entry = it.value();
+ entry.functionGroups = getFunctionGroupsImpl(scope);
+ entry.needsGetattroFunction = classNeedsGetattroFunctionImpl(scope);
+ entry.numberProtocolOperators = getNumberProtocolOperators(scope);
+ entry.boolCastFunctionO = getBoolCast(scope);
}
return it.value();
}
-ShibokenGenerator::FunctionGroups ShibokenGenerator::getFunctionGroups(const AbstractMetaClass *scope)
+ShibokenGenerator::FunctionGroups
+ ShibokenGenerator::getFunctionGroups(const AbstractMetaClassCPtr &scope)
{
Q_ASSERT(scope);
return getGeneratorClassInfo(scope).functionGroups;
}
+QList<AbstractMetaFunctionCList>
+ ShibokenGenerator::numberProtocolOperators(const AbstractMetaClassCPtr &scope)
+{
+ Q_ASSERT(scope);
+ return getGeneratorClassInfo(scope).numberProtocolOperators;
+}
+
+BoolCastFunctionOptional ShibokenGenerator::boolCast(const AbstractMetaClassCPtr &scope)
+{
+ Q_ASSERT(scope);
+ return getGeneratorClassInfo(scope).boolCastFunctionO;
+}
+
// Use non-const overloads only, for example, "foo()" and "foo()const"
// the second is removed.
static void removeConstOverloads(AbstractMetaFunctionCList *overloads)
@@ -1948,7 +2076,7 @@ static void removeConstOverloads(AbstractMetaFunctionCList *overloads)
const auto &f = overloads->at(i);
if (f->isConstant()) {
for (qsizetype c = 0, size = overloads->size(); c < size; ++c) {
- if (f->isConstOverloadOf(overloads->at(c).data())) {
+ if (f->isConstOverloadOf(overloads->at(c).get())) {
overloads->removeAt(i);
break;
}
@@ -1957,7 +2085,8 @@ static void removeConstOverloads(AbstractMetaFunctionCList *overloads)
}
}
-ShibokenGenerator::FunctionGroups ShibokenGenerator::getFunctionGroupsImpl(const AbstractMetaClass *scope)
+ShibokenGenerator::FunctionGroups
+ ShibokenGenerator::getFunctionGroupsImpl(const AbstractMetaClassCPtr &scope)
{
AbstractMetaFunctionCList lst = scope->functions();
scope->getFunctionsFromInvisibleNamespacesToBeGenerated(&lst);
@@ -1988,13 +2117,156 @@ ShibokenGenerator::FunctionGroups ShibokenGenerator::getFunctionGroupsImpl(const
return results;
}
+static bool removeNumberProtocolOperator(const AbstractMetaFunctionCPtr &f)
+{
+ return !f->generateBinding()
+ || (f->ownerClass() != f->implementingClass() && !f->isAbstract());
+}
+
+QList<AbstractMetaFunctionCList>
+ ShibokenGenerator::getNumberProtocolOperators(const AbstractMetaClassCPtr &metaClass)
+{
+ QList<AbstractMetaFunctionCList> result;
+ if (metaClass->isNamespace())
+ return result;
+ result = filterGroupedOperatorFunctions(
+ metaClass,
+ OperatorQueryOption::ArithmeticOp
+ | OperatorQueryOption::IncDecrementOp
+ | OperatorQueryOption::LogicalOp
+ | OperatorQueryOption::BitwiseOp
+ | OperatorQueryOption::ConversionOp);
+
+ for (auto i = result.size() - 1; i >= 0; --i) {
+ AbstractMetaFunctionCList &l = result[i];
+ auto rend = std::remove_if(l.begin(), l.end(), removeNumberProtocolOperator);
+ l.erase(rend, l.end());
+ if (l.isEmpty())
+ result.removeAt(i);
+ }
+
+ return result;
+}
+
+BoolCastFunctionOptional
+ShibokenGenerator::getBoolCast(const AbstractMetaClassCPtr &metaClass)
+{
+ if (metaClass->isNamespace())
+ return std::nullopt;
+
+ const auto te = metaClass->typeEntry();
+ if (te->isSmartPointer()) {
+ auto ste = std::static_pointer_cast<const SmartPointerTypeEntry>(te);
+
+ auto valueCheckMethod = ste->valueCheckMethod();
+ if (!valueCheckMethod.isEmpty()) {
+ const auto func = metaClass->findFunction(valueCheckMethod);
+ if (!func)
+ throw Exception(msgMethodNotFound(metaClass, valueCheckMethod));
+ return BoolCastFunction{func, false};
+ }
+
+ auto nullCheckMethod = ste->nullCheckMethod();
+ if (!nullCheckMethod.isEmpty()) {
+ const auto func = metaClass->findFunction(nullCheckMethod);
+ if (!func)
+ throw Exception(msgMethodNotFound(metaClass, nullCheckMethod));
+ return BoolCastFunction{func, true};
+ }
+ }
+
+ auto mode = te->operatorBoolMode();
+ if (useOperatorBoolAsNbBool()
+ ? mode != TypeSystem::BoolCast::Disabled : mode == TypeSystem::BoolCast::Enabled) {
+ const auto func = metaClass->findOperatorBool();
+ if (func)
+ return BoolCastFunction{func, false};
+ }
+
+ mode = te->isNullMode();
+ if (useIsNullAsNbBool()
+ ? mode != TypeSystem::BoolCast::Disabled : mode == TypeSystem::BoolCast::Enabled) {
+ const auto func = metaClass->findQtIsNullMethod();
+ if (func)
+ return BoolCastFunction{func, true};
+ }
+ return std::nullopt;
+}
+
+static bool isInplaceAdd(const AbstractMetaFunctionCPtr &func)
+{
+ return func->name() == u"operator+=";
+}
+
+static bool isIncrementOperator(const AbstractMetaFunctionCPtr &func)
+{
+ return func->functionType() == AbstractMetaFunction::IncrementOperator;
+}
+
+static bool isDecrementOperator(const AbstractMetaFunctionCPtr &func)
+{
+ return func->functionType() == AbstractMetaFunction::DecrementOperator;
+}
+
+// Filter predicate for operator functions
+static bool skipOperatorFunc(const AbstractMetaFunctionCPtr &func)
+{
+ if (func->isModifiedRemoved() || func->usesRValueReferences())
+ return true;
+ const auto &name = func->name();
+ return name == u"operator[]" || name == u"operator->" || name == u"operator!"
+ || name == u"operator/="; // __idiv__ is not needed in Python3
+}
+
+QList<AbstractMetaFunctionCList>
+ShibokenGenerator::filterGroupedOperatorFunctions(const AbstractMetaClassCPtr &metaClass,
+ OperatorQueryOptions query)
+{
+ // ( func_name, num_args ) => func_list
+ QMap<std::pair<QString, int>, AbstractMetaFunctionCList> results;
+ auto funcs = metaClass->operatorOverloads(query);
+ auto end = std::remove_if(funcs.begin(), funcs.end(), skipOperatorFunc);
+ funcs.erase(end, funcs.end());
+ // If we have operator+=, we remove the operator++/-- which would
+ // otherwise be used for emulating __iadd__, __isub__.
+ if (std::any_of(funcs.cbegin(), funcs.cend(), isInplaceAdd)) {
+ end = std::remove_if(funcs.begin(), funcs.end(),
+ [] (const AbstractMetaFunctionCPtr &func) {
+ return func->isIncDecrementOperator();
+ });
+ funcs.erase(end, funcs.end());
+ } else {
+ // If both prefix/postfix ++/-- are present, remove one
+ if (std::count_if(funcs.begin(), funcs.end(), isIncrementOperator) > 1)
+ funcs.erase(std::find_if(funcs.begin(), funcs.end(), isIncrementOperator));
+ if (std::count_if(funcs.begin(), funcs.end(), isDecrementOperator) > 1)
+ funcs.erase(std::find_if(funcs.begin(), funcs.end(), isDecrementOperator));
+ }
+ for (const auto &func : funcs) {
+ int args;
+ if (func->isComparisonOperator()) {
+ args = -1;
+ } else {
+ args = func->arguments().size();
+ }
+ auto op = std::make_pair(func->name(), args);
+ results[op].append(func);
+ }
+ QList<AbstractMetaFunctionCList> result;
+ result.reserve(results.size());
+ for (auto it = results.cbegin(), end = results.cend(); it != end; ++it)
+ result.append(it.value());
+ return result;
+}
+
static bool hidesBaseClassFunctions(const AbstractMetaFunctionCPtr &f)
{
- return 0 == (f->attributes()
- & (AbstractMetaFunction::OverriddenCppMethod | AbstractMetaFunction::FinalCppMethod));
+ auto attributes = f->cppAttributes();
+ return !attributes.testFlag(FunctionAttribute::Override)
+ && !attributes.testFlag(FunctionAttribute::Final);
}
-void ShibokenGenerator::getInheritedOverloads(const AbstractMetaClass *scope,
+void ShibokenGenerator::getInheritedOverloads(const AbstractMetaClassCPtr &scope,
AbstractMetaFunctionCList *overloads)
{
if (overloads->isEmpty() || scope->isNamespace() || scope->baseClasses().isEmpty())
@@ -2020,7 +2292,8 @@ void ShibokenGenerator::getInheritedOverloads(const AbstractMetaClass *scope,
AbstractMetaFunctionCList baseCandidates;
- auto basePredicate = [&functionName, &seenSignatures, &baseCandidates](const AbstractMetaClass *b) {
+ auto basePredicate = [&functionName, &seenSignatures, &baseCandidates]
+ (const AbstractMetaClassCPtr &b) {
for (const auto &f : b->functions()) {
if (f->generateBinding() && f->name() == functionName) {
const QString signature = f->minimalSignature();
@@ -2033,7 +2306,7 @@ void ShibokenGenerator::getInheritedOverloads(const AbstractMetaClass *scope,
return false; // Keep going
};
- for (const auto *baseClass : scope->baseClasses())
+ for (const auto &baseClass : scope->baseClasses())
recurseClassHierarchy(baseClass, basePredicate);
// Remove the ones that are not made visible with using declarations
@@ -2063,92 +2336,108 @@ void ShibokenGenerator::getInheritedOverloads(const AbstractMetaClass *scope,
}
}
-Generator::OptionDescriptions ShibokenGenerator::options() const
+QList<OptionDescription> ShibokenGenerator::options()
{
- auto result = Generator::options();
- result.append({
- {QLatin1StringView(DISABLE_VERBOSE_ERROR_MESSAGES),
+ return {
+ {DISABLE_VERBOSE_ERROR_MESSAGES,
u"Disable verbose error messages. Turn the python code hard to debug\n"
"but safe few kB on the generated bindings."_s},
- {QLatin1StringView(PARENT_CTOR_HEURISTIC),
+ {PARENT_CTOR_HEURISTIC,
u"Enable heuristics to detect parent relationship on constructors."_s},
- {QLatin1StringView(RETURN_VALUE_HEURISTIC),
+ {RETURN_VALUE_HEURISTIC,
u"Enable heuristics to detect parent relationship on return values\n"
"(USE WITH CAUTION!)"_s},
- {QLatin1StringView(USE_ISNULL_AS_NB_NONZERO),
+ {USE_ISNULL_AS_NB_BOOL,
u"If a class have an isNull() const method, it will be used to compute\n"
"the value of boolean casts"_s},
- {QLatin1StringView(LEAN_HEADERS),
+ {LEAN_HEADERS,
u"Forward declare classes in module headers"_s},
- {QLatin1StringView(USE_OPERATOR_BOOL_AS_NB_NONZERO),
+ {USE_OPERATOR_BOOL_AS_NB_BOOL,
u"If a class has an operator bool, it will be used to compute\n"
"the value of boolean casts"_s},
- {QLatin1StringView(NO_IMPLICIT_CONVERSIONS),
+ {NO_IMPLICIT_CONVERSIONS,
u"Do not generate implicit_conversions for function arguments."_s},
- {QLatin1StringView(WRAPPER_DIAGNOSTICS),
+ {WRAPPER_DIAGNOSTICS,
u"Generate diagnostic code around wrappers"_s}
- });
- return result;
+ };
}
-bool ShibokenGenerator::handleOption(const QString &key, const QString &value)
+class ShibokenGeneratorOptionsParser : public OptionsParser
{
- if (Generator::handleOption(key, value))
- return true;
- if (key == QLatin1StringView(PARENT_CTOR_HEURISTIC))
- return (m_useCtorHeuristic = true);
- if (key == QLatin1StringView(RETURN_VALUE_HEURISTIC))
- return (m_userReturnValueHeuristic = true);
- if (key == QLatin1StringView(DISABLE_VERBOSE_ERROR_MESSAGES))
- return (m_verboseErrorMessagesDisabled = true);
- if (key == QLatin1StringView(USE_ISNULL_AS_NB_NONZERO))
- return (m_useIsNullAsNbNonZero = true);
- if (key == QLatin1StringView(LEAN_HEADERS))
- return (m_leanHeaders= true);
- if (key == QLatin1StringView(USE_OPERATOR_BOOL_AS_NB_NONZERO))
- return (m_useOperatorBoolAsNbNonZero = true);
- if (key == QLatin1StringView(NO_IMPLICIT_CONVERSIONS)) {
- return m_generateImplicitConversions = false;
+public:
+ explicit ShibokenGeneratorOptionsParser(ShibokenGeneratorOptions *o) : m_options(o) {}
+
+ bool handleBoolOption(const QString & key, OptionSource source) override;
+
+private:
+ ShibokenGeneratorOptions *m_options;
+};
+
+bool ShibokenGeneratorOptionsParser::handleBoolOption(const QString &key, OptionSource source)
+{
+ if (source == OptionSource::CommandLineSingleDash)
+ return false;
+ if (key == PARENT_CTOR_HEURISTIC)
+ return (m_options->useCtorHeuristic = true);
+ if (key == RETURN_VALUE_HEURISTIC)
+ return (m_options->userReturnValueHeuristic = true);
+ if (key == DISABLE_VERBOSE_ERROR_MESSAGES)
+ return (m_options->verboseErrorMessagesDisabled = true);
+ if (key == USE_ISNULL_AS_NB_BOOL || key == USE_ISNULL_AS_NB_NONZERO) {
+ return (m_options->useIsNullAsNbBool = true);
+ }
+ if (key == LEAN_HEADERS)
+ return (m_options->leanHeaders= true);
+ if (key == USE_OPERATOR_BOOL_AS_NB_BOOL || key == USE_OPERATOR_BOOL_AS_NB_NONZERO) {
+ return (m_options->useOperatorBoolAsNbBool = true);
+ }
+ if (key == NO_IMPLICIT_CONVERSIONS) {
+ m_options->generateImplicitConversions = false;
return true;
}
- if (key == QLatin1StringView(WRAPPER_DIAGNOSTICS))
- return (m_wrapperDiagnostics = true);
+ if (key == WRAPPER_DIAGNOSTICS)
+ return (m_options->wrapperDiagnostics = true);
return false;
}
+std::shared_ptr<OptionsParser> ShibokenGenerator::createOptionsParser()
+{
+ return std::make_shared<ShibokenGeneratorOptionsParser>(&m_options);
+}
+
bool ShibokenGenerator::doSetup()
{
return true;
}
-bool ShibokenGenerator::useCtorHeuristic() const
+bool ShibokenGenerator::useCtorHeuristic()
{
- return m_useCtorHeuristic;
+ return m_options.useCtorHeuristic;
}
-bool ShibokenGenerator::useReturnValueHeuristic() const
+bool ShibokenGenerator::useReturnValueHeuristic()
{
- return m_userReturnValueHeuristic;
+ return m_options.userReturnValueHeuristic;
}
-bool ShibokenGenerator::useIsNullAsNbNonZero() const
+bool ShibokenGenerator::useIsNullAsNbBool()
{
- return m_useIsNullAsNbNonZero;
+ return m_options.useIsNullAsNbBool;
}
-bool ShibokenGenerator::leanHeaders() const
+bool ShibokenGenerator::leanHeaders()
{
- return m_leanHeaders;
+ return m_options.leanHeaders;
}
-bool ShibokenGenerator::useOperatorBoolAsNbNonZero() const
+bool ShibokenGenerator::useOperatorBoolAsNbBool()
{
- return m_useOperatorBoolAsNbNonZero;
+ return m_options.useOperatorBoolAsNbBool;
}
-bool ShibokenGenerator::generateImplicitConversions() const
+bool ShibokenGenerator::generateImplicitConversions()
{
- return m_generateImplicitConversions;
+ return m_options.generateImplicitConversions;
}
QString ShibokenGenerator::moduleCppPrefix(const QString &moduleName)
@@ -2158,19 +2447,24 @@ QString ShibokenGenerator::moduleCppPrefix(const QString &moduleName)
return result;
}
+QString ShibokenGenerator::cppApiVariableNameOld(const QString &moduleName)
+{
+ return "Sbk"_L1 + moduleCppPrefix(moduleName) + "Types"_L1;
+}
+
QString ShibokenGenerator::cppApiVariableName(const QString &moduleName)
{
- return u"Sbk"_s + moduleCppPrefix(moduleName) + u"Types"_s;
+ return "Sbk"_L1 + moduleCppPrefix(moduleName) + "TypeStructs"_L1;
}
QString ShibokenGenerator::pythonModuleObjectName(const QString &moduleName)
{
- return u"Sbk"_s + moduleCppPrefix(moduleName) + u"ModuleObject"_s;
+ return "Sbk"_L1 + moduleCppPrefix(moduleName) + "ModuleObject"_L1;
}
QString ShibokenGenerator::convertersVariableName(const QString &moduleName)
{
- QString result = cppApiVariableName(moduleName);
+ QString result = cppApiVariableNameOld(moduleName);
result.chop(1);
result.append(u"Converters"_s);
return result;
@@ -2178,11 +2472,11 @@ QString ShibokenGenerator::convertersVariableName(const QString &moduleName)
static QString processInstantiationsVariableName(const AbstractMetaType &type)
{
- QString res = u'_' + _fixedCppTypeName(type.typeEntry()->qualifiedCppName()).toUpper();
+ QString res = u'_' + _fixedCppTypeName(type.typeEntry()->qualifiedCppName());
for (const auto &instantiation : type.instantiations()) {
res += instantiation.isContainer()
? processInstantiationsVariableName(instantiation)
- : u'_' + _fixedCppTypeName(instantiation.cppSignature()).toUpper();
+ : u'_' + _fixedCppTypeName(instantiation.cppSignature());
}
return res;
}
@@ -2191,22 +2485,23 @@ static void appendIndexSuffix(QString *s)
{
if (!s->endsWith(u'_'))
s->append(u'_');
- s->append(QStringLiteral("IDX"));
+ s->append("IDX"_L1);
}
-QString ShibokenGenerator::getTypeAlternateTemplateIndexVariableName(const AbstractMetaClass *metaClass)
+QString
+ ShibokenGenerator::getTypeAlternateTemplateIndexVariableName(const AbstractMetaClassCPtr &metaClass)
{
- const AbstractMetaClass *templateBaseClass = metaClass->templateBaseClass();
+ const auto templateBaseClass = metaClass->templateBaseClass();
Q_ASSERT(templateBaseClass);
QString result = u"SBK_"_s
- + _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName()).toUpper();
+ + _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName());
for (const auto &instantiation : metaClass->templateBaseClassInstantiations())
result += processInstantiationsVariableName(instantiation);
appendIndexSuffix(&result);
return result;
}
-QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaClassCPtr &metaClass)
{
return getTypeIndexVariableName(metaClass->typeEntry());
}
@@ -2221,7 +2516,7 @@ QString ShibokenGenerator::getTypeIndexVariableName(TypeEntryCPtr type)
const int dot = package.lastIndexOf(u'.');
result += QStringView{package}.right(package.size() - (dot + 1));
}
- result += _fixedCppTypeName(type->qualifiedCppName()).toUpper();
+ result += _fixedCppTypeName(type->qualifiedCppName());
appendIndexSuffix(&result);
return result;
}
@@ -2229,15 +2524,49 @@ QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaType &type
{
QString result = u"SBK"_s;
if (type.typeEntry()->isContainer())
- result += u'_' + moduleName().toUpper();
+ result += u'_' + moduleName();
result += processInstantiationsVariableName(type);
appendIndexSuffix(&result);
return result;
}
-bool ShibokenGenerator::verboseErrorMessagesDisabled() const
+void collectfromTypeEntry(TypeEntryCPtr entry, QStringList &typeNames)
+{
+ if (entry->shouldGenerate()) {
+ typeNames[entry->sbkIndex()] = entry->qualifiedTargetLangName();
+ if (entry->isEnum()) {
+ auto ete = std::static_pointer_cast<const EnumTypeEntry>(entry);
+ if (ete->flags()) {
+ auto entry = ete->flags();
+ typeNames[entry->sbkIndex()] = entry->qualifiedTargetLangName();
+ }
+ }
+ }
+}
+
+void ShibokenGenerator::collectFullTypeNamesArray(QStringList &typeNames)
+{
+ for (const auto &metaClass : api().classes()) {
+ collectfromTypeEntry(metaClass->typeEntry(), typeNames);
+
+ for (const AbstractMetaEnum &metaEnum : metaClass->enums())
+ collectfromTypeEntry(metaEnum.typeEntry(), typeNames);
+
+ int smartPointerCountIndex = getMaxTypeIndex();
+ for (const auto &smp : api().instantiatedSmartPointers()) {
+ auto entry = smp.type.typeEntry();
+ typeNames[smartPointerCountIndex] =
+ smp.specialized->typeEntry()->qualifiedTargetLangName();
+ ++smartPointerCountIndex;
+ }
+ }
+ for (const AbstractMetaEnum &metaEnum : api().globalEnums())
+ collectfromTypeEntry(metaEnum.typeEntry(), typeNames);
+}
+
+bool ShibokenGenerator::verboseErrorMessagesDisabled()
{
- return m_verboseErrorMessagesDisabled;
+ return m_options.verboseErrorMessagesDisabled;
}
bool ShibokenGenerator::pythonFunctionWrapperUsesListOfArguments(const AbstractMetaFunctionCPtr &func) const
@@ -2290,7 +2619,7 @@ QString ShibokenGenerator::pythonArgsAt(int i)
void ShibokenGenerator::replaceTemplateVariables(QString &code,
const AbstractMetaFunctionCPtr &func) const
{
- const AbstractMetaClass *cpp_class = func->ownerClass();
+ const auto cpp_class = func->ownerClass();
if (cpp_class)
code.replace(u"%TYPE"_s, cpp_class->name());
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h
index d0b1158c6..22ee73fa2 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.h
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h
@@ -7,12 +7,14 @@
#include <generator.h>
#include "customconversion_typedefs.h"
+#include "abstractmetalang_enums.h"
#include "typesystem_typedefs.h"
#include "typesystem_enums.h"
#include <QtCore/QRegularExpression>
#include <array>
+#include <optional>
class EnumTypeEntry;
class FlagsTypeEntry;
@@ -23,8 +25,18 @@ class OverloadData;
class TargetToNativeConversion;
struct GeneratorClassInfoCacheEntry;
struct IncludeGroup;
+struct ShibokenGeneratorOptions;
-QT_FORWARD_DECLARE_CLASS(TextStream)
+class TextStream;
+
+// Function to be used for implementing nb_bool
+struct BoolCastFunction
+{
+ AbstractMetaFunctionCPtr function;
+ bool invert = false; // Function is "isNull()", (invert result).
+};
+
+using BoolCastFunctionOptional = std::optional<BoolCastFunction>;
/**
* Abstract generator that contains common methods used in CppGenerator and HeaderGenerator.
@@ -32,6 +44,8 @@ QT_FORWARD_DECLARE_CLASS(TextStream)
class ShibokenGenerator : public Generator
{
public:
+ Q_DISABLE_COPY_MOVE(ShibokenGenerator)
+
/// Besides the actual bindings (see AbstractMetaFunction::generateBinding(),
/// some functions need to be generated into the wrapper class
/// (virtual method/avoid protected hack expose).
@@ -75,6 +89,9 @@ public:
const char *name() const override { return "Shiboken"; }
+ static QList<OptionDescription> options();
+ static std::shared_ptr<OptionsParser> createOptionsParser();
+
static QString minimalConstructorExpression(const ApiExtractorResult &api,
const AbstractMetaType &type);
static QString minimalConstructorExpression(const ApiExtractorResult &api,
@@ -83,7 +100,7 @@ public:
protected:
bool doSetup() override;
- GeneratorContext contextForClass(const AbstractMetaClass *c) const override;
+ GeneratorContext contextForClass(const AbstractMetaClassCPtr &c) const override;
/**
* Returns a map with all functions grouped, the function name is used as key.
@@ -91,7 +108,12 @@ protected:
* \param scope Where to search for functions, null means all global functions.
*/
FunctionGroups getGlobalFunctionGroups() const;
- static FunctionGroups getFunctionGroups(const AbstractMetaClass *scope);
+ static FunctionGroups getFunctionGroups(const AbstractMetaClassCPtr &scope);
+
+ static QList<AbstractMetaFunctionCList>
+ numberProtocolOperators(const AbstractMetaClassCPtr &scope);
+
+ static BoolCastFunctionOptional boolCast(const AbstractMetaClassCPtr &scope);
/**
* Returns all different inherited overloads of func, and includes func as well.
@@ -123,6 +145,7 @@ protected:
/// Replaces variables for the user's custom code at global or class level.
void processCodeSnip(QString &code) const;
+ void processCodeSnip(QString &code, const QString &context) const;
void processClassCodeSnip(QString &code, const GeneratorContext &context) const;
/**
@@ -148,53 +171,65 @@ protected:
int arg_count = -1) const;
/// Returns the top-most class that has multiple inheritance in the ancestry.
- static const AbstractMetaClass *getMultipleInheritingClass(const AbstractMetaClass *metaClass);
+ static AbstractMetaClassCPtr
+ getMultipleInheritingClass(const AbstractMetaClassCPtr &metaClass);
- static bool useOverrideCaching(const AbstractMetaClass *metaClass);
- AttroCheck checkAttroFunctionNeeds(const AbstractMetaClass *metaClass) const;
+ static bool useOverrideCaching(const AbstractMetaClassCPtr &metaClass);
+ static AttroCheck checkAttroFunctionNeeds(const AbstractMetaClassCPtr &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.
+ /// 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.
static AbstractMetaFunctionCList
- getMethodsWithBothStaticAndNonStaticMethods(const AbstractMetaClass *metaClass);
+ getMethodsWithBothStaticAndNonStaticMethods(const AbstractMetaClassCPtr &metaClass);
static void writeToPythonConversion(TextStream &s,
const AbstractMetaType &type,
- const AbstractMetaClass *context,
+ const AbstractMetaClassCPtr &context,
const QString &argumentName);
static void writeToCppConversion(TextStream &s,
const AbstractMetaType &type,
- const AbstractMetaClass *context,
const QString &inArgName,
const QString &outArgName);
static void writeToCppConversion(TextStream &s,
- const AbstractMetaClass *metaClass, const QString &inArgName,
+ const AbstractMetaClassCPtr &metaClass,
+ const QString &inArgName,
const QString &outArgName);
/// Returns true if the argument is a pointer that rejects nullptr values.
static bool shouldRejectNullPointerArgument(const AbstractMetaFunctionCPtr &func,
int argIndex);
- /// Verifies if the class should have a C++ wrapper generated for it, instead of only a Python wrapper.
- bool shouldGenerateCppWrapper(const AbstractMetaClass *metaClass) const;
+ /// Verifies if the class should have a C++ wrapper generated for it,
+ /// instead of only a Python wrapper.
+ static bool shouldGenerateCppWrapper(const AbstractMetaClassCPtr &metaClass);
+
+ static bool shouldGenerateMetaObjectFunctions(const AbstractMetaClassCPtr &metaClass);
/// Returns which functions need to be generated into the wrapper class
- FunctionGeneration functionGeneration(const AbstractMetaFunctionCPtr &func) const;
+ static FunctionGeneration functionGeneration(const AbstractMetaFunctionCPtr &func);
// Return a list of implicit conversions if generation is enabled.
AbstractMetaFunctionCList implicitConversions(const TypeEntryCPtr &t) const;
- QString wrapperName(const AbstractMetaClass *metaClass) const;
+ static QString wrapperName(const AbstractMetaClassCPtr &metaClass);
+
+ static QString fullPythonClassName(const AbstractMetaClassCPtr &metaClass);
+
+ static QString headerFileNameForContext(const GeneratorContext &context);
+ IncludeGroup baseWrapperIncludes(const GeneratorContext &classContext) const;
- static QString fullPythonClassName(const AbstractMetaClass *metaClass);
static QString fullPythonFunctionName(const AbstractMetaFunctionCPtr &func, bool forceFunc);
- bool wrapperDiagnostics() const { return m_wrapperDiagnostics; }
+ static bool wrapperDiagnostics();
static QString protectedEnumSurrogateName(const AbstractMetaEnum &metaEnum);
static QString pythonPrimitiveTypeName(const QString &cppTypeName);
static QString pythonOperatorFunctionName(const AbstractMetaFunctionCPtr &func);
+ static QList<AbstractMetaFunctionCList>
+ filterGroupedOperatorFunctions(const AbstractMetaClassCPtr &metaClass,
+ OperatorQueryOptions query);
static QString fixedCppTypeName(const TargetToNativeConversion &toNative);
static QString fixedCppTypeName(const AbstractMetaType &type);
@@ -211,41 +246,42 @@ protected:
static QString converterObject(const AbstractMetaType &type) ;
static QString converterObject(const TypeEntryCPtr &type);
- static QString cpythonBaseName(const AbstractMetaClass *metaClass);
+ static QString cpythonBaseName(const AbstractMetaClassCPtr &metaClass);
static QString cpythonBaseName(const TypeEntryCPtr &type);
+ static QString containerCpythonBaseName(const ContainerTypeEntryCPtr &ctype);
static QString cpythonBaseName(const AbstractMetaType &type);
- static QString cpythonTypeName(const AbstractMetaClass *metaClass);
+ static QString cpythonTypeName(const AbstractMetaClassCPtr &metaClass);
static QString cpythonTypeName(const TypeEntryCPtr &type);
+ static QString cpythonTypeNameExtSet(const TypeEntryCPtr &type);
+ static QString cpythonTypeNameExtSet(const AbstractMetaType &type);
static QString cpythonTypeNameExt(const TypeEntryCPtr &type);
- static QString cpythonTypeNameExt(const AbstractMetaType &type) ;
+ static QString cpythonTypeNameExt(const AbstractMetaType &type);
static QString cpythonCheckFunction(TypeEntryCPtr type);
static QString cpythonCheckFunction(AbstractMetaType metaType);
static QString cpythonIsConvertibleFunction(const TypeEntryCPtr &type);
- static QString cpythonIsConvertibleFunction(AbstractMetaType metaType);
+ static QString cpythonIsConvertibleFunction(const AbstractMetaType &metaType);
static QString cpythonIsConvertibleFunction(const AbstractMetaArgument &metaArg);
- static QString cpythonToCppConversionFunction(const AbstractMetaClass *metaClass) ;
- static QString cpythonToCppConversionFunction(const AbstractMetaType &type,
- const AbstractMetaClass *context = nullptr);
- static QString cpythonToPythonConversionFunction(const AbstractMetaType &type,
- const AbstractMetaClass *context = nullptr);
- static QString cpythonToPythonConversionFunction(const AbstractMetaClass *metaClass);
+ static QString cpythonToCppConversionFunction(const AbstractMetaClassCPtr &metaClass) ;
+ static QString cpythonToCppConversionFunction(const AbstractMetaType &type);
+ static QString cpythonToPythonConversionFunction(const AbstractMetaType &type);
+ static QString cpythonToPythonConversionFunction(const AbstractMetaClassCPtr &metaClass);
static QString cpythonToPythonConversionFunction(const TypeEntryCPtr &type);
static QString cpythonFunctionName(const AbstractMetaFunctionCPtr &func) ;
static QString cpythonMethodDefinitionName(const AbstractMetaFunctionCPtr &func);
- static QString cpythonGettersSettersDefinitionName(const AbstractMetaClass *metaClass);
- static QString cpythonGetattroFunctionName(const AbstractMetaClass *metaClass);
- static QString cpythonSetattroFunctionName(const AbstractMetaClass *metaClass);
+ static QString cpythonGettersSettersDefinitionName(const AbstractMetaClassCPtr &metaClass);
+ static QString cpythonGetattroFunctionName(const AbstractMetaClassCPtr &metaClass);
+ static QString cpythonSetattroFunctionName(const AbstractMetaClassCPtr &metaClass);
static QString cpythonGetterFunctionName(const AbstractMetaField &metaField);
static QString cpythonSetterFunctionName(const AbstractMetaField &metaField);
static QString cpythonGetterFunctionName(const QPropertySpec &property,
- const AbstractMetaClass *metaClass);
+ const AbstractMetaClassCPtr &metaClass);
static QString cpythonSetterFunctionName(const QPropertySpec &property,
- const AbstractMetaClass *metaClass);
- static QString cpythonWrapperCPtr(const AbstractMetaClass *metaClass,
- const QString &argName = QStringLiteral("self"));
- static QString cpythonWrapperCPtr(const AbstractMetaType &metaType,
+ const AbstractMetaClassCPtr &metaClass);
+ static QString cpythonWrapperCPtr(const AbstractMetaClassCPtr &metaClass,
+ const QString &argName = QLatin1StringView("self"));
+ static QString cpythonWrapperCPtr(const AbstractMetaType &metaType,
const QString &argName);
static QString cpythonWrapperCPtr(const TypeEntryCPtr &type, const QString &argName);
@@ -254,44 +290,47 @@ protected:
static QString cpythonFlagsName(const FlagsTypeEntryCPtr &flagsEntry);
static QString cpythonFlagsName(const AbstractMetaEnum *metaEnum);
- /// Returns the special cast function name, the function used to proper cast class with multiple inheritance.
- static QString cpythonSpecialCastFunctionName(const AbstractMetaClass *metaClass);
+ /// Returns the special cast function name, the function used to proper cast
+ /// class with multiple inheritance.
+ static QString cpythonSpecialCastFunctionName(const AbstractMetaClassCPtr &metaClass);
- /// Returns the file name for the module global header. If no module name is provided the current will be used.
+ /// 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 getPrivateModuleHeaderFileName(const QString &moduleName = QString());
/// Includes for header (native wrapper class) or binding source
- QList<IncludeGroup> classIncludes(const AbstractMetaClass *metaClass) const;
-
- OptionDescriptions options() const override;
- bool handleOption(const QString &key, const QString &value) override;
+ QList<IncludeGroup> classIncludes(const AbstractMetaClassCPtr &metaClass) const;
/// Returns true if the user enabled the so called "parent constructor heuristic".
- bool useCtorHeuristic() const;
+ static bool useCtorHeuristic();
/// Returns true if the user enabled the so called "return value heuristic".
- bool useReturnValueHeuristic() const;
+ static bool useReturnValueHeuristic();
/// Returns true if the generator should use the result of isNull()const to compute boolean casts.
- bool useIsNullAsNbNonZero() const;
+ static bool useIsNullAsNbBool();
/// Whether to generate lean module headers
- bool leanHeaders() const;
+ static bool leanHeaders();
/// Returns true if the generator should use operator bool to compute boolean casts.
- bool useOperatorBoolAsNbNonZero() const;
+ static bool useOperatorBoolAsNbBool();
/// Generate implicit conversions of function arguments
- bool generateImplicitConversions() const;
+ static bool generateImplicitConversions();
+ static QString cppApiVariableNameOld(const QString &moduleName = {});
static QString cppApiVariableName(const QString &moduleName = QString());
static QString pythonModuleObjectName(const QString &moduleName = QString());
static QString convertersVariableName(const QString &moduleName = QString());
/// Returns the type index variable name for a given class.
- static QString getTypeIndexVariableName(const AbstractMetaClass *metaClass);
+ static QString getTypeIndexVariableName(const AbstractMetaClassCPtr &metaClass);
/// Returns the type index variable name for a given typedef for a template
/// class instantiation made of the template class and the instantiation values
- static QString getTypeAlternateTemplateIndexVariableName(const AbstractMetaClass *metaClass);
+ static QString getTypeAlternateTemplateIndexVariableName(const AbstractMetaClassCPtr &metaClass);
static QString getTypeIndexVariableName(TypeEntryCPtr type);
static QString getTypeIndexVariableName(const AbstractMetaType &type) ;
+ /// Collect all type names as an array for initializing the type/name struct.
+ void collectFullTypeNamesArray(QStringList &typeNames);
+
/// Returns true if the user don't want verbose error messages on the generated bindings.
- bool verboseErrorMessagesDisabled() const;
+ static bool verboseErrorMessagesDisabled();
void collectContainerTypesFromConverterMacros(const QString &code, bool toPythonMacro);
@@ -324,16 +363,20 @@ protected:
private:
static QString getModuleHeaderFileBaseName(const QString &moduleName = QString());
static QString cpythonGetterFunctionName(const QString &name,
- const AbstractMetaClass *enclosingClass);
+ const AbstractMetaClassCPtr &enclosingClass);
static QString cpythonSetterFunctionName(const QString &name,
- const AbstractMetaClass *enclosingClass);
+ const AbstractMetaClassCPtr &enclosingClass);
- static const GeneratorClassInfoCacheEntry &getGeneratorClassInfo(const AbstractMetaClass *scope);
- static FunctionGroups getFunctionGroupsImpl(const AbstractMetaClass *scope);
- static bool classNeedsGetattroFunctionImpl(const AbstractMetaClass *metaClass);
+ static const GeneratorClassInfoCacheEntry &
+ getGeneratorClassInfo(const AbstractMetaClassCPtr &scope);
+ static FunctionGroups getFunctionGroupsImpl(const AbstractMetaClassCPtr &scope);
+ static QList<AbstractMetaFunctionCList>
+ getNumberProtocolOperators(const AbstractMetaClassCPtr &metaClass);
+ static BoolCastFunctionOptional getBoolCast(const AbstractMetaClassCPtr &metaClass);
+ static bool classNeedsGetattroFunctionImpl(const AbstractMetaClassCPtr &metaClass);
QString translateTypeForWrapperMethod(const AbstractMetaType &cType,
- const AbstractMetaClass *context,
+ const AbstractMetaClassCPtr &context,
Options opt = NoOption) const;
/**
@@ -342,7 +385,7 @@ private:
* \param func the metafunction to be searched in subclasses.
* \param seen the function's minimal signatures already seen.
*/
- static void getInheritedOverloads(const AbstractMetaClass *scope,
+ static void getInheritedOverloads(const AbstractMetaClassCPtr &scope,
AbstractMetaFunctionCList *overloads);
@@ -371,7 +414,7 @@ private:
QString functionReturnType(const AbstractMetaFunctionCPtr &func, Options options = NoOption) const;
/// Utility function for writeCodeSnips.
- using ArgumentVarReplacementPair = QPair<AbstractMetaArgument, QString>;
+ using ArgumentVarReplacementPair = std::pair<AbstractMetaArgument, QString>;
using ArgumentVarReplacementList = QList<ArgumentVarReplacementPair>;
static ArgumentVarReplacementList
getArgumentReplacement(const AbstractMetaFunctionCPtr &func,
@@ -433,16 +476,7 @@ private:
void replaceTemplateVariables(QString &code,
const AbstractMetaFunctionCPtr &func) const;
- bool m_useCtorHeuristic = false;
- bool m_userReturnValueHeuristic = false;
- bool m_verboseErrorMessagesDisabled = false;
- bool m_useIsNullAsNbNonZero = false;
- // FIXME PYSIDE 7 Flip m_leanHeaders default or remove?
- bool m_leanHeaders = false;
- bool m_useOperatorBoolAsNbNonZero = false;
- // FIXME PYSIDE 7 Flip generateImplicitConversions default or remove?
- bool m_generateImplicitConversions = true;
- bool m_wrapperDiagnostics = false;
+ static ShibokenGeneratorOptions m_options;
/// Type system converter variable replacement names and regular expressions.
static const QHash<int, QString> &typeSystemConvName();
@@ -454,20 +488,4 @@ private:
Q_DECLARE_OPERATORS_FOR_FLAGS(ShibokenGenerator::FunctionGeneration);
Q_DECLARE_OPERATORS_FOR_FLAGS(ShibokenGenerator::AttroCheck);
-extern const QString CPP_ARG;
-extern const QString CPP_ARG_REMOVED;
-extern const QString CPP_RETURN_VAR;
-extern const QString CPP_SELF_VAR;
-extern const QString NULL_PTR;
-extern const QString PYTHON_ARG;
-extern const QString PYTHON_ARGS;
-extern const QString PYTHON_OVERRIDE_VAR;
-extern const QString PYTHON_RETURN_VAR;
-extern const QString PYTHON_TO_CPP_VAR;
-extern const QString SMART_POINTER_GETTER;
-
-extern const QString CONV_RULE_OUT_VAR_SUFFIX;
-extern const QString BEGIN_ALLOW_THREADS;
-extern const QString END_ALLOW_THREADS;
-
#endif // SHIBOKENGENERATOR_H
diff --git a/sources/shiboken6/generators/shiboken/shiboken.cpp b/sources/shiboken6/generators/shiboken/shiboken.cpp
deleted file mode 100644
index 193b8e902..000000000
--- a/sources/shiboken6/generators/shiboken/shiboken.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-
-#include "cppgenerator.h"
-#include "headergenerator.h"
-
-EXPORT_GENERATOR_PLUGIN(new CppGenerator << new HeaderGenerator)
diff --git a/sources/shiboken6/icecc.cmake b/sources/shiboken6/icecc.cmake
index b2bf071aa..fa8d3b7cf 100644
--- a/sources/shiboken6/icecc.cmake
+++ b/sources/shiboken6/icecc.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
include (CMakeForceCompiler)
option(ENABLE_ICECC "Enable icecc checking, for distributed compilation")
if (ENABLE_ICECC)
diff --git a/sources/shiboken6/libshiboken/CMakeLists.txt b/sources/shiboken6/libshiboken/CMakeLists.txt
index 2dd4e86ae..b5bbb498a 100644
--- a/sources/shiboken6/libshiboken/CMakeLists.txt
+++ b/sources/shiboken6/libshiboken/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(libshiboken)
option(ENABLE_VERSION_SUFFIX "Used to use current version in suffix to generated files. This is used to allow multiples versions installed simultaneous." FALSE)
@@ -27,7 +30,7 @@ if(SHIBOKEN_IS_CROSS_BUILD)
set(host_python_path "${QFP_PYTHON_HOST_PATH}")
set(use_pyc_in_embedding FALSE)
else()
- set(host_python_path "${PYTHON_EXECUTABLE}")
+ set(host_python_path "${Python_EXECUTABLE}")
if(PYTHON_LIMITED_API)
set(use_pyc_in_embedding FALSE)
else()
@@ -55,38 +58,50 @@ set(libshiboken_VERSION "${libshiboken_MAJOR_VERSION}.${libshiboken_MINOR_VERSIO
set(libshiboken_SOVERSION "${shiboken6_library_so_version}")
set(libshiboken_SRC
-basewrapper.cpp
-debugfreehook.cpp
-gilstate.cpp
-helper.cpp
-sbkarrayconverter.cpp
-sbkcontainer.cpp
-sbkconverter.cpp
-sbkenum.cpp
-sbkerrors.cpp
-sbkfeature_base.cpp
-sbkmodule.cpp
-sbknumpy.cpp
-sbkcppstring.cpp
-sbkstring.cpp
-sbkstaticstrings.cpp
-sbktypefactory.cpp
-bindingmanager.cpp
-threadstatesaver.cpp
-shibokenbuffer.cpp
-pep384impl.cpp
-voidptr.cpp
-bufferprocs_py37.cpp
+autodecref.h
+basewrapper.cpp basewrapper.h basewrapper_p.h
+bindingmanager.cpp bindingmanager.h
+bufferprocs_py37.cpp bufferprocs_py37.h
+debugfreehook.cpp debugfreehook.h
+gilstate.cpp gilstate.h
+helper.cpp helper.h
+pep384impl.cpp pep384impl.h
+pyobjectholder.h
+sbkarrayconverter.cpp sbkarrayconverter.h sbkarrayconverter_p.h
+sbkcontainer.cpp sbkcontainer.h
+sbkconverter.cpp sbkconverter.h sbkconverter_p.h
+sbkcppstring.cpp sbkcppstring.h sbkcpptonumpy.h
+sbkenum.cpp sbkenum.h
+sbkerrors.cpp sbkerrors.h
+sbkfeature_base.cpp sbkfeature_base.h
+sbkmodule.cpp sbkmodule.h
+sbknumpy.cpp sbknumpycheck.h
+sbknumpyview.h
+sbkpython.h
+sbksmartpointer.cpp sbksmartpointer.h
+sbkstaticstrings.cpp sbkstaticstrings.h sbkstaticstrings_p.h
+sbkstring.cpp sbkstring.h
+sbktypefactory.cpp sbktypefactory.h
+sbkwindows.h
+shiboken.h
+shibokenbuffer.cpp shibokenbuffer.h
+shibokenmacros.h
+threadstatesaver.cpp threadstatesaver.h
+voidptr.cpp voidptr.h
embed/signature_bootstrap_inc.h
embed/signature_inc.h
-signature/signature.cpp
+signature/signature.cpp signature.h signature_p.h
signature/signature_globals.cpp
signature/signature_extend.cpp
signature/signature_helper.cpp
)
+# This is needed to let the header obey a variable in "pep384impl.h".
+# Note: This must be set on the cpp file!
+set_property(SOURCE "pep384impl.cpp" PROPERTY SKIP_UNITY_BUILD_INCLUSION ON)
+
add_library(libshiboken SHARED ${libshiboken_SRC})
add_library(Shiboken6::libshiboken ALIAS libshiboken)
@@ -144,12 +159,12 @@ install(FILES
bindingmanager.h
gilstate.h
helper.h
+ pyobjectholder.h
sbkarrayconverter.h
sbkcontainer.h
sbkconverter.h
sbkcpptonumpy.h
sbkenum.h
- sbkenum_p.h
sbkerrors.h
sbkfeature_base.h
sbkmodule.h
@@ -157,6 +172,7 @@ install(FILES
sbknumpyview.h
sbkstring.h
sbkcppstring.h
+ sbksmartpointer.h
sbkstaticstrings.h
sbktypefactory.h
shiboken.h
@@ -164,7 +180,9 @@ install(FILES
threadstatesaver.h
shibokenbuffer.h
sbkpython.h
+ sbkwindows.h
pep384impl.h
+ pep384ext.h
voidptr.h
bufferprocs_py37.h
"${CMAKE_CURRENT_BINARY_DIR}/sbkversion.h"
diff --git a/sources/shiboken6/libshiboken/autodecref.h b/sources/shiboken6/libshiboken/autodecref.h
index d2b660676..62a8584e1 100644
--- a/sources/shiboken6/libshiboken/autodecref.h
+++ b/sources/shiboken6/libshiboken/autodecref.h
@@ -5,7 +5,8 @@
#define AUTODECREF_H
#include "sbkpython.h"
-#include "basewrapper.h"
+
+#include <utility>
struct SbkObject;
namespace Shiboken
@@ -14,29 +15,27 @@ namespace Shiboken
/**
* AutoDecRef holds a PyObject pointer and decrement its reference counter when destroyed.
*/
-struct LIBSHIBOKEN_API AutoDecRef
+struct AutoDecRef
{
public:
AutoDecRef(const AutoDecRef &) = delete;
- AutoDecRef(AutoDecRef &&) = delete;
+ AutoDecRef(AutoDecRef &&o) noexcept : m_pyObj{std::exchange(o.m_pyObj, nullptr)} {}
AutoDecRef &operator=(const AutoDecRef &) = delete;
- AutoDecRef &operator=(AutoDecRef &&) = delete;
+ AutoDecRef &operator=(AutoDecRef &&o) noexcept
+ {
+ m_pyObj = std::exchange(o.m_pyObj, nullptr);
+ return *this;
+ }
- /**
- * AutoDecRef constructor.
- * \param pyobj A borrowed reference to a Python object
- */
- explicit AutoDecRef(PyObject *pyObj) : m_pyObj(pyObj) {}
- /**
- * AutoDecRef constructor.
- * \param pyobj A borrowed reference to a Python object
- */
- explicit AutoDecRef(SbkObject *pyObj) : m_pyObj(reinterpret_cast<PyObject *>(pyObj)) {}
- /**
- * AutoDecref constructor.
- * To be used later with reset():
- */
- AutoDecRef() : m_pyObj(nullptr) {}
+ /// AutoDecRef constructor.
+ /// \param pyobj A borrowed reference to a Python object
+ explicit AutoDecRef(PyObject *pyObj) noexcept : m_pyObj(pyObj) {}
+ /// AutoDecRef constructor.
+ /// \param pyobj A borrowed reference to a wrapped Python object
+ explicit AutoDecRef(SbkObject *pyObj) noexcept : m_pyObj(reinterpret_cast<PyObject *>(pyObj)) {}
+ /// AutoDecref default constructor.
+ /// To be used later with reset():
+ AutoDecRef() noexcept = default;
/// Decref the borrowed python reference
~AutoDecRef()
@@ -44,18 +43,19 @@ public:
Py_XDECREF(m_pyObj);
}
- inline bool isNull() const { return m_pyObj == nullptr; }
+ [[nodiscard]] bool isNull() const { return m_pyObj == nullptr; }
/// Returns the pointer of the Python object being held.
- inline PyObject *object() { return m_pyObj; }
- inline operator PyObject *() { return m_pyObj; }
+ [[nodiscard]] PyObject *object() const { return m_pyObj; }
+ [[nodiscard]] operator PyObject *() const { return m_pyObj; }
#ifndef Py_LIMITED_API
- inline operator PyTupleObject *() { return reinterpret_cast<PyTupleObject *>(m_pyObj); }
+ [[deprecated]] inline operator PyTupleObject *()
+ { return reinterpret_cast<PyTupleObject *>(m_pyObj); }
#endif
inline operator bool() const { return m_pyObj != nullptr; }
inline PyObject *operator->() { return m_pyObj; }
template<typename T>
- T cast()
+ [[deprecated]] T cast()
{
return reinterpret_cast<T>(m_pyObj);
}
@@ -79,10 +79,9 @@ public:
}
private:
- PyObject *m_pyObj;
+ PyObject *m_pyObj = nullptr;
};
} // namespace Shiboken
#endif // AUTODECREF_H
-
diff --git a/sources/shiboken6/libshiboken/basewrapper.cpp b/sources/shiboken6/libshiboken/basewrapper.cpp
index 24980239d..0ce80d0c6 100644
--- a/sources/shiboken6/libshiboken/basewrapper.cpp
+++ b/sources/shiboken6/libshiboken/basewrapper.cpp
@@ -5,9 +5,12 @@
#include "basewrapper_p.h"
#include "bindingmanager.h"
#include "helper.h"
+#include "pep384ext.h"
#include "sbkconverter.h"
#include "sbkenum.h"
+#include "sbkerrors.h"
#include "sbkfeature_base.h"
+#include "sbkmodule.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
#include "sbkstaticstrings_p.h"
@@ -24,7 +27,9 @@
#include "signature_p.h"
#include "voidptr.h"
+#include <string>
#include <iostream>
+#include <sstream>
#if defined(__APPLE__)
#include <dlfcn.h>
@@ -34,7 +39,73 @@ namespace {
void _destroyParentInfo(SbkObject *obj, bool keepReference);
}
-static void callDestructor(const Shiboken::DtorAccumulatorVisitor::DestructorEntries &dts)
+namespace Shiboken
+{
+// Walk through the first level of non-user-type Sbk base classes relevant for
+// C++ object allocation. Return true from the predicate to terminate.
+template <class Predicate>
+bool walkThroughBases(PyTypeObject *currentType, Predicate predicate)
+{
+ PyObject *bases = currentType->tp_bases;
+ const Py_ssize_t numBases = PyTuple_Size(bases);
+ bool result = false;
+ for (Py_ssize_t i = 0; !result && i < numBases; ++i) {
+ auto type = reinterpret_cast<PyTypeObject *>(PyTuple_GetItem(bases, i));
+ if (PyType_IsSubtype(type, SbkObject_TypeF()) != 0) {
+ result = PepType_SOTP(type)->is_user_type
+ ? walkThroughBases(type, predicate) : predicate(type);
+ }
+ }
+ return result;
+}
+
+int getTypeIndexOnHierarchy(PyTypeObject *baseType, PyTypeObject *desiredType)
+{
+ int index = -1;
+ walkThroughBases(baseType, [&index, desiredType](PyTypeObject *node) {
+ ++index;
+ return PyType_IsSubtype(node, desiredType) != 0;
+ });
+ return index;
+}
+
+int getNumberOfCppBaseClasses(PyTypeObject *baseType)
+{
+ int count = 0;
+ walkThroughBases(baseType, [&count](PyTypeObject *) {
+ ++count;
+ return false;
+ });
+ return count;
+}
+
+std::vector<PyTypeObject *> getCppBaseClasses(PyTypeObject *baseType)
+{
+ std::vector<PyTypeObject *> cppBaseClasses;
+ walkThroughBases(baseType, [&cppBaseClasses](PyTypeObject *node) {
+ cppBaseClasses.push_back(node);
+ return false;
+ });
+ return cppBaseClasses;
+}
+
+using DestructorEntries = std::vector<DestructorEntry>;
+
+DestructorEntries getDestructorEntries(SbkObject *o)
+{
+ DestructorEntries result;
+ void **cptrs = o->d->cptr;
+ walkThroughBases(Py_TYPE(o), [&result, cptrs](PyTypeObject *node) {
+ auto *sotp = PepType_SOTP(node);
+ auto index = result.size();
+ result.push_back(DestructorEntry{sotp->cpp_dtor,
+ cptrs[index]});
+ return false;
+ });
+ return result;
+}
+
+static void callDestructor(const DestructorEntries &dts)
{
for (const auto &e : dts) {
Shiboken::ThreadStateSaver threadSaver;
@@ -43,6 +114,8 @@ static void callDestructor(const Shiboken::DtorAccumulatorVisitor::DestructorEnt
}
}
+} // namespace Shiboken
+
extern "C"
{
@@ -54,7 +127,7 @@ void Sbk_object_dealloc(PyObject *self)
// This was not needed before Python 3.8 (Python issue 35810)
Py_DECREF(Py_TYPE(self));
}
- Py_TYPE(self)->tp_free(self);
+ PepExt_TypeCallFree(self);
}
static void SbkObjectType_tp_dealloc(PyTypeObject *pyType);
@@ -71,6 +144,7 @@ void setDestroyQApplication(DestroyQAppHook func)
// PYSIDE-535: Use the C API in PyPy instead of `op->ob_dict`, directly
LIBSHIBOKEN_API PyObject *SbkObject_GetDict_NoRef(PyObject *op)
{
+ assert(Shiboken::Object::checkType(op));
#ifdef PYPY_VERSION
Shiboken::GilState state;
auto *ret = PyObject_GenericGetDict(op, nullptr);
@@ -109,15 +183,13 @@ type_set_doc(PyTypeObject *type, PyObject *value, void * /* context */)
if (!check_set_special_type_attr(type, value, "__doc__"))
return -1;
PyType_Modified(type);
- return PyDict_SetItem(type->tp_dict, Shiboken::PyMagicName::doc(), value);
+ Shiboken::AutoDecRef tpDict(PepType_GetDict(type));
+ return PyDict_SetItem(tpDict.object(), Shiboken::PyMagicName::doc(), value);
}
// PYSIDE-908: The function PyType_Modified does not work in PySide, so we need to
-// explicitly pass __doc__. For __signature__ it _did_ actually work, because
-// it was not existing before. We add them both for clarity.
+// explicitly pass __doc__.
static PyGetSetDef SbkObjectType_tp_getset[] = {
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(Sbk_TypeGet___signature__),
- nullptr, nullptr, nullptr},
{const_cast<char *>("__doc__"), reinterpret_cast<getter>(Sbk_TypeGet___doc__),
reinterpret_cast<setter>(type_set_doc), nullptr, nullptr},
{const_cast<char *>("__dict__"), reinterpret_cast<getter>(Sbk_TypeGet___dict__),
@@ -125,31 +197,53 @@ static PyGetSetDef SbkObjectType_tp_getset[] = {
{nullptr, nullptr, nullptr, nullptr, nullptr} // Sentinel
};
-static PyType_Slot SbkObjectType_Type_slots[] = {
- {Py_tp_dealloc, reinterpret_cast<void *>(SbkObjectType_tp_dealloc)},
- {Py_tp_getattro, reinterpret_cast<void *>(mangled_type_getattro)},
- {Py_tp_base, static_cast<void *>(&PyType_Type)},
- {Py_tp_alloc, reinterpret_cast<void *>(PyType_GenericAlloc)},
- {Py_tp_new, reinterpret_cast<void *>(SbkObjectType_tp_new)},
- {Py_tp_free, reinterpret_cast<void *>(PyObject_GC_Del)},
- {Py_tp_getset, reinterpret_cast<void *>(SbkObjectType_tp_getset)},
- {0, nullptr}
-};
-
-// PYSIDE-535: The tp_itemsize field is inherited and does not need to be set.
-// In PyPy, it _must_ not be set, because it would have the meaning that a
-// `__len__` field must be defined. Not doing so creates a hard-to-find crash.
-static PyType_Spec SbkObjectType_Type_spec = {
- "1:Shiboken.ObjectType",
- 0,
- 0, // sizeof(PyMemberDef), not for PyPy without a __len__ defined
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
- SbkObjectType_Type_slots,
-};
+static PyTypeObject *createObjectTypeType()
+{
+ PyType_Slot SbkObjectType_Type_slots[] = {
+ {Py_tp_dealloc, reinterpret_cast<void *>(SbkObjectType_tp_dealloc)},
+ {Py_tp_getattro, reinterpret_cast<void *>(mangled_type_getattro)},
+ {Py_tp_base, static_cast<void *>(&PyType_Type)},
+ {Py_tp_alloc, reinterpret_cast<void *>(PyType_GenericAlloc)},
+ {Py_tp_new, reinterpret_cast<void *>(SbkObjectType_tp_new)},
+ {Py_tp_free, reinterpret_cast<void *>(PyObject_GC_Del)},
+ {Py_tp_getset, reinterpret_cast<void *>(SbkObjectType_tp_getset)},
+ {0, nullptr}
+ };
+
+ // PYSIDE-535: The tp_itemsize field is inherited and does not need to be set.
+ // In PyPy, it _must_ not be set, because it would have the meanin
+ // that a `__len__` field must be defined. Not doing so creates
+ // a hard-to-find crash.
+ //
+ // PYSIDE-2230: In Python < 3.12, the decision which base class should create
+ // the instance is arbitrarily drawn by the size of the type.
+ // Ignoring this creates a bug in the new version of bug_825 that
+ // selects the wrong metatype.
+ //
+ PyType_Spec SbkObjectType_Type_spec = {
+ "1:Shiboken.ObjectType",
+ static_cast<int>(PyType_Type.tp_basicsize) + 1, // see above
+ 0, // sizeof(PyMemberDef), not for PyPy without a __len__ defined
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_TYPE_SUBCLASS,
+ SbkObjectType_Type_slots,
+ };
+
+ PyType_Spec SbkObjectType_Type_spec_312 = {
+ "1:Shiboken.ObjectType",
+ -long(sizeof(SbkObjectTypePrivate)),
+ 0, // sizeof(PyMemberDef), not for PyPy without a __len__ defined
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_TYPE_SUBCLASS,
+ SbkObjectType_Type_slots,
+ };
+
+ return SbkType_FromSpec(_PepRuntimeVersion() >= 0x030C00 ?
+ &SbkObjectType_Type_spec_312 :
+ &SbkObjectType_Type_spec);
+}
PyTypeObject *SbkObjectType_TypeF(void)
{
- static auto *type = SbkType_FromSpec(&SbkObjectType_Type_spec);
+ static auto *type = createObjectTypeType();
return type;
}
@@ -186,10 +280,8 @@ static int SbkObject_tp_traverse(PyObject *self, visitproc visit, void *arg)
if (sbkSelf->ob_dict)
Py_VISIT(sbkSelf->ob_dict);
-#if PY_VERSION_HEX >= 0x03090000
// This was not needed before Python 3.9 (Python issue 35810 and 40217)
Py_VISIT(Py_TYPE(self));
-#endif
return 0;
}
@@ -209,40 +301,53 @@ static int SbkObject_tp_clear(PyObject *self)
return 0;
}
-static PyType_Slot SbkObject_Type_slots[] = {
- {Py_tp_getattro, reinterpret_cast<void *>(SbkObject_GenericGetAttr)},
- {Py_tp_setattro, reinterpret_cast<void *>(SbkObject_GenericSetAttr)},
- {Py_tp_dealloc, reinterpret_cast<void *>(SbkDeallocWrapperWithPrivateDtor)},
- {Py_tp_traverse, reinterpret_cast<void *>(SbkObject_tp_traverse)},
- {Py_tp_clear, reinterpret_cast<void *>(SbkObject_tp_clear)},
- // unsupported: {Py_tp_weaklistoffset, (void *)offsetof(SbkObject, weakreflist)},
- {Py_tp_getset, reinterpret_cast<void *>(SbkObject_tp_getset)},
- // unsupported: {Py_tp_dictoffset, (void *)offsetof(SbkObject, ob_dict)},
- {0, nullptr}
-};
-static PyType_Spec SbkObject_Type_spec = {
- "1:Shiboken.Object",
- sizeof(SbkObject),
- 0,
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC,
- SbkObject_Type_slots,
-};
-
-static const char *SbkObject_SignatureStrings[] = {
- "Shiboken.Object(self)",
- nullptr}; // Sentinel
+static PyTypeObject *createObjectType()
+{
+ PyType_Slot SbkObject_Type_slots[] = {
+ {Py_tp_getattro, reinterpret_cast<void *>(SbkObject_GenericGetAttr)},
+ {Py_tp_setattro, reinterpret_cast<void *>(SbkObject_GenericSetAttr)},
+ {Py_tp_dealloc, reinterpret_cast<void *>(SbkDeallocWrapperWithPrivateDtor)},
+ {Py_tp_traverse, reinterpret_cast<void *>(SbkObject_tp_traverse)},
+ {Py_tp_clear, reinterpret_cast<void *>(SbkObject_tp_clear)},
+ // unsupported: {Py_tp_weaklistoffset, (void *)offsetof(SbkObject, weakreflist)},
+ {Py_tp_getset, reinterpret_cast<void *>(SbkObject_tp_getset)},
+ // unsupported: {Py_tp_dictoffset, (void *)offsetof(SbkObject, ob_dict)},
+ {0, nullptr}
+ };
+
+ PyType_Spec SbkObject_Type_spec = {
+ "1:Shiboken.Object",
+ sizeof(SbkObject),
+ 0,
+ Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC,
+ SbkObject_Type_slots,
+ };
+
+ // PYSIDE-2230: When creating this type, we cannot easily handle the metaclass.
+ // In versions < Python 3.12, the metaclass can only be set
+ // indirectly by a base which has that metaclass.
+ // But before 3.12 is the minimum version, we cannot use the new
+ // function, although we would need this for 3.12 :-D
+ // We do a special patching here that is triggered through Py_None.
+ auto *type = SbkType_FromSpec_BMDWB(&SbkObject_Type_spec,
+ Py_None, // bases, spectial flag!
+ SbkObjectType_TypeF(),
+ offsetof(SbkObject, ob_dict),
+ offsetof(SbkObject, weakreflist),
+ nullptr); // bufferprocs
+ return type;
+}
PyTypeObject *SbkObject_TypeF(void)
{
- static auto *type = SbkType_FromSpec_BMDWB(&SbkObject_Type_spec,
- nullptr, // bases
- SbkObjectType_TypeF(),
- offsetof(SbkObject, ob_dict),
- offsetof(SbkObject, weakreflist),
- nullptr); // bufferprocs
+ static auto *type = createObjectType(); // bufferprocs
return type;
}
+static const char *SbkObject_SignatureStrings[] = {
+ "Shiboken.Object(self)",
+ nullptr}; // Sentinel
+
static int mainThreadDeletionHandler(void *)
{
if (Py_IsInitialized())
@@ -305,9 +410,8 @@ static void SbkDeallocWrapperCommon(PyObject *pyObj, bool canDelete)
if (sotp->delete_in_main_thread && Shiboken::currentThreadId() != Shiboken::mainThreadId()) {
auto &bindingManager = Shiboken::BindingManager::instance();
if (sotp->is_multicpp) {
- Shiboken::DtorAccumulatorVisitor visitor(sbkObj);
- Shiboken::walkThroughClassHierarchy(Py_TYPE(pyObj), &visitor);
- for (const auto &e : visitor.entries())
+ const auto entries = Shiboken::getDestructorEntries(sbkObj);
+ for (const auto &e : entries)
bindingManager.addToDeletionInMainThread(e);
} else {
Shiboken::DestructorEntry e{sotp->cpp_dtor, sbkObj->d->cptr[0]};
@@ -325,10 +429,9 @@ static void SbkDeallocWrapperCommon(PyObject *pyObj, bool canDelete)
if (canDelete) {
if (sotp->is_multicpp) {
- Shiboken::DtorAccumulatorVisitor visitor(sbkObj);
- Shiboken::walkThroughClassHierarchy(Py_TYPE(pyObj), &visitor);
+ const auto entries = Shiboken::getDestructorEntries(sbkObj);
Shiboken::Object::deallocData(sbkObj, true);
- callDestructor(visitor.entries());
+ callDestructor(entries);
} else {
void *cptr = sbkObj->d->cptr[0];
Shiboken::Object::deallocData(sbkObj, true);
@@ -388,7 +491,7 @@ void SbkObjectType_tp_dealloc(PyTypeObject *sbkType)
auto pyObj = reinterpret_cast<PyObject *>(sbkType);
PyObject_GC_UnTrack(pyObj);
-#ifndef Py_LIMITED_API
+#if !defined(Py_LIMITED_API) && !defined(PYPY_VERSION)
# if PY_VERSION_HEX >= 0x030A0000
Py_TRASHCAN_BEGIN(pyObj, 1);
# else
@@ -406,7 +509,7 @@ void SbkObjectType_tp_dealloc(PyTypeObject *sbkType)
Shiboken::Conversions::deleteConverter(sotp->converter);
PepType_SOTP_delete(sbkType);
}
-#ifndef Py_LIMITED_API
+#if !defined(Py_LIMITED_API) && !defined(PYPY_VERSION)
# if PY_VERSION_HEX >= 0x030A0000
Py_TRASHCAN_END;
# else
@@ -477,7 +580,7 @@ static PyTypeObject *SbkObjectType_tp_new(PyTypeObject *metatype, PyObject *args
PyObject *dict;
static const char *kwlist[] = { "name", "bases", "dict", nullptr};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO!O!:sbktype", const_cast<char **>(kwlist),
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO!O!:sbktype", const_cast<char **>(kwlist),
&name,
&PyTuple_Type, &pyBases,
&PyDict_Type, &dict))
@@ -485,22 +588,26 @@ static PyTypeObject *SbkObjectType_tp_new(PyTypeObject *metatype, PyObject *args
for (int i=0, i_max=PyTuple_GET_SIZE(pyBases); i < i_max; i++) {
PyObject *baseType = PyTuple_GET_ITEM(pyBases, i);
- if (reinterpret_cast<PyTypeObject *>(baseType)->tp_new == SbkDummyNew) {
+ if (PepExt_Type_GetNewSlot(reinterpret_cast<PyTypeObject *>(baseType)) == SbkDummyNew) {
// PYSIDE-595: A base class does not allow inheritance.
return reinterpret_cast<PyTypeObject *>(SbkDummyNew(metatype, args, kwds));
}
}
- // PYSIDE-939: This is a temporary patch that circumvents the problem
- // with Py_TPFLAGS_METHOD_DESCRIPTOR until this is finally solved.
- // PyType_Ready uses mro(). We need to temporarily remove the flag from it's type.
- // We cannot use PyMethodDescr_Type since it is not exported by Python 2.7 .
- static PyTypeObject *PyMethodDescr_TypePtr = Py_TYPE(
- PyObject_GetAttr(reinterpret_cast<PyObject *>(&PyType_Type), Shiboken::PyName::mro()));
- auto hold = PyMethodDescr_TypePtr->tp_flags;
- PyMethodDescr_TypePtr->tp_flags &= ~Py_TPFLAGS_METHOD_DESCRIPTOR;
- auto *newType = PepType_Type_tp_new(metatype, args, kwds);
- PyMethodDescr_TypePtr->tp_flags = hold;
+ // PYSIDE-939: This is still a temporary patch that circumvents the problem
+ // with Py_TPFLAGS_METHOD_DESCRIPTOR. The problem exists in Python 3.8
+ // until 3.9.12, only. We check the runtime and hope for this version valishing.
+ // https://github.com/python/cpython/issues/92112 will not be fixed for 3.8 :/
+ PyTypeObject *newType{};
+ static auto triplet = _PepRuntimeVersion();
+ if (triplet >= (3 << 16 | 8 << 8 | 0) && triplet < (3 << 16 | 9 << 8 | 13)) {
+ auto hold = PyMethodDescr_Type.tp_flags;
+ PyMethodDescr_Type.tp_flags &= ~Py_TPFLAGS_METHOD_DESCRIPTOR;
+ newType = PepType_Type_tp_new(metatype, args, kwds);
+ PyMethodDescr_Type.tp_flags = hold;
+ } else {
+ newType = PepType_Type_tp_new(metatype, args, kwds);
+ }
if (!newType)
return nullptr;
@@ -598,9 +705,9 @@ PyObject *SbkQApp_tp_new(PyTypeObject *subtype, PyObject *, PyObject *)
PyObject *SbkDummyNew(PyTypeObject *type, PyObject *, PyObject *)
{
// PYSIDE-595: Give the same error as type_call does when tp_new is NULL.
+ const char regret[] = "¯\\_(ツ)_/¯";
PyErr_Format(PyExc_TypeError,
- "cannot create '%.100s' instances ¯\\_(ツ)_/¯",
- type->tp_name);
+ "cannot create '%.100s' instances %s", type->tp_name, regret);
return nullptr;
}
@@ -631,6 +738,12 @@ PyObject *FallbackRichCompare(PyObject *self, PyObject *other, int op)
return res;
}
+bool SbkObjectType_Check(PyTypeObject *type)
+{
+ static auto *meta = SbkObjectType_TypeF();
+ return Py_TYPE(type) == meta || PyType_IsSubtype(Py_TYPE(type), meta);
+}
+
} //extern "C"
@@ -655,54 +768,24 @@ void _destroyParentInfo(SbkObject *obj, bool keepReference)
namespace Shiboken
{
-bool walkThroughClassHierarchy(PyTypeObject *currentType, HierarchyVisitor *visitor)
-{
- PyObject *bases = currentType->tp_bases;
- Py_ssize_t numBases = PyTuple_GET_SIZE(bases);
- bool result = false;
- for (int i = 0; !result && i < numBases; ++i) {
- auto type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(bases, i));
- if (PyType_IsSubtype(type, reinterpret_cast<PyTypeObject *>(SbkObject_TypeF()))) {
- result = PepType_SOTP(type)->is_user_type
- ? walkThroughClassHierarchy(type, visitor) : visitor->visit(type);
- }
- }
- return result;
-}
// Wrapper metatype and base type ----------------------------------------------------------
-HierarchyVisitor::HierarchyVisitor() = default;
-HierarchyVisitor::~HierarchyVisitor() = default;
-
-bool BaseCountVisitor::visit(PyTypeObject *)
-{
- m_count++;
- return false;
-}
-
-bool BaseAccumulatorVisitor::visit(PyTypeObject *node)
-{
- m_bases.push_back(node);
- return false;
-}
-
-bool GetIndexVisitor::visit(PyTypeObject *node)
-{
- m_index++;
- return PyType_IsSubtype(node, m_desiredType);
-}
+void _initMainThreadId(); // helper.cpp
-bool DtorAccumulatorVisitor::visit(PyTypeObject *node)
+static std::string msgFailedToInitializeType(const char *description)
{
- auto *sotp = PepType_SOTP(node);
- m_entries.push_back(DestructorEntry{sotp->cpp_dtor,
- m_pyObject->d->cptr[m_entries.size()]});
- return false;
+ std::ostringstream stream;
+ stream << "[libshiboken] Failed to initialize " << description;
+ if (auto *error = PepErr_GetRaisedException()) {
+ if (auto *str = PyObject_Str(error))
+ stream << ": " << Shiboken::String::toCString(str);
+ Py_DECREF(error);
+ }
+ stream << '.';
+ return stream.str();
}
-void _initMainThreadId(); // helper.cpp
-
namespace Conversions { void init(); }
void init()
@@ -718,14 +801,13 @@ void init()
//Init private data
Pep384_Init();
- if (PyType_Ready(SbkEnumType_TypeF()) < 0)
- Py_FatalError("[libshiboken] Failed to initialize Shiboken.SbkEnumType metatype.");
+ auto *type = SbkObjectType_TypeF();
+ if (type == nullptr || PyType_Ready(type) < 0)
+ Py_FatalError(msgFailedToInitializeType("Shiboken.BaseWrapperType metatype").c_str());
- if (PyType_Ready(SbkObjectType_TypeF()) < 0)
- Py_FatalError("[libshiboken] Failed to initialize Shiboken.BaseWrapperType metatype.");
-
- if (PyType_Ready(SbkObject_TypeF()) < 0)
- Py_FatalError("[libshiboken] Failed to initialize Shiboken.BaseWrapper type.");
+ type = SbkObject_TypeF();
+ if (type == nullptr || PyType_Ready(type) < 0)
+ Py_FatalError(msgFailedToInitializeType("Shiboken.BaseWrapper type").c_str());
VoidPtr::init();
@@ -756,6 +838,32 @@ void setErrorAboutWrongArguments(PyObject *args, const char *funcName, PyObject
SetError_Argument(args, funcName, info);
}
+PyObject *returnWrongArguments(PyObject *args, const char *funcName, PyObject *info)
+{
+ setErrorAboutWrongArguments(args, funcName, info);
+ return {};
+}
+
+int returnWrongArguments_Zero(PyObject *args, const char *funcName, PyObject *info)
+{
+ setErrorAboutWrongArguments(args, funcName, info);
+ return 0;
+}
+
+int returnWrongArguments_MinusOne(PyObject *args, const char *funcName, PyObject *info)
+{
+ setErrorAboutWrongArguments(args, funcName, info);
+ return -1;
+}
+
+PyObject *returnFromRichCompare(PyObject *result)
+{
+ if (result && !PyErr_Occurred())
+ return result;
+ Shiboken::Errors::setOperatorNotImplemented();
+ return {};
+}
+
PyObject *checkInvalidArgumentCount(Py_ssize_t numArgs, Py_ssize_t minArgs, Py_ssize_t maxArgs)
{
PyObject *result = nullptr;
@@ -773,20 +881,6 @@ PyObject *checkInvalidArgumentCount(Py_ssize_t numArgs, Py_ssize_t minArgs, Py_s
return result;
}
-class FindBaseTypeVisitor : public HierarchyVisitor
-{
-public:
- explicit FindBaseTypeVisitor(PyTypeObject *typeToFind) : m_typeToFind(typeToFind) {}
-
- bool visit(PyTypeObject *node) override
- {
- return node == m_typeToFind;
- }
-
-private:
- PyTypeObject *m_typeToFind;
-};
-
std::vector<SbkObject *> splitPyObject(PyObject *pyObj)
{
std::vector<SbkObject *> result;
@@ -827,8 +921,8 @@ bool isUserType(PyTypeObject *type)
bool canCallConstructor(PyTypeObject *myType, PyTypeObject *ctorType)
{
- FindBaseTypeVisitor visitor(ctorType);
- if (!walkThroughClassHierarchy(myType, &visitor)) {
+ auto findBasePred = [ctorType](PyTypeObject *type) { return type == ctorType; };
+ if (!walkThroughBases(myType, findBasePred)) {
PyErr_Format(PyExc_TypeError, "%s isn't a direct base class of %s", ctorType->tp_name, myType->tp_name);
return false;
}
@@ -900,31 +994,34 @@ introduceWrapperType(PyObject *enclosingObject,
const char *originalName,
PyType_Spec *typeSpec,
ObjectDestructor cppObjDtor,
- PyTypeObject *baseType,
- PyObject *baseTypes,
+ PyObject *bases,
unsigned wrapperFlags)
{
- auto *base = baseType ? baseType : SbkObject_TypeF();
- typeSpec->slots[0].pfunc = reinterpret_cast<void *>(base);
- auto *bases = baseTypes ? baseTypes : PyTuple_Pack(1, base);
+ assert(PySequence_Fast_GET_SIZE(bases) > 0);
+ typeSpec->slots[0].pfunc = PySequence_Fast_GET_ITEM(bases, 0);
auto *type = SbkType_FromSpecBasesMeta(typeSpec, bases, SbkObjectType_TypeF());
- for (int i = 0; i < PySequence_Fast_GET_SIZE(bases); ++i) {
- auto *st = reinterpret_cast<PyTypeObject *>(PySequence_Fast_GET_ITEM(bases, i));
- BindingManager::instance().addClassInheritance(st, type);
- }
-
auto sotp = PepType_SOTP(type);
if (wrapperFlags & DeleteInMainThread)
sotp->delete_in_main_thread = 1;
+ sotp->type_behaviour = (wrapperFlags & Value) != 0
+ ? BEHAVIOUR_VALUETYPE : BEHAVIOUR_OBJECTTYPE;
setOriginalName(type, originalName);
setDestructorFunction(type, cppObjDtor);
auto *ob_type = reinterpret_cast<PyObject *>(type);
- if (wrapperFlags & InnerClass)
+ if (wrapperFlags & InnerClass) {
+ // PYSIDE-2230: Instead of tp_dict, use the enclosing type.
+ // This stays interface compatible.
+ if (PyType_Check(enclosingObject)) {
+ AutoDecRef tpDict(PepType_GetDict(reinterpret_cast<PyTypeObject *>(enclosingObject)));
+ return PyDict_SetItemString(tpDict, typeName, ob_type) == 0 ? type : nullptr;
+ }
+ assert(PyDict_Check(enclosingObject));
return PyDict_SetItemString(enclosingObject, typeName, ob_type) == 0 ? type : nullptr;
+ }
// PyModule_AddObject steals type's reference.
Py_INCREF(ob_type);
@@ -939,16 +1036,19 @@ introduceWrapperType(PyObject *enclosingObject,
void setSubTypeInitHook(PyTypeObject *type, SubTypeInitHook func)
{
+ assert(SbkObjectType_Check(type));
PepType_SOTP(type)->subtype_init = func;
}
void *getTypeUserData(PyTypeObject *type)
{
+ assert(SbkObjectType_Check(type));
return PepType_SOTP(type)->user_data;
}
void setTypeUserData(PyTypeObject *type, void *userData, DeleteUserDataFunc d_func)
{
+ assert(SbkObjectType_Check(type));
auto *sotp = PepType_SOTP(type);
sotp->user_data = userData;
sotp->d_func = d_func;
@@ -971,6 +1071,26 @@ bool hasSpecialCastFunction(PyTypeObject *sbkType)
return d != nullptr && d->mi_specialcast != nullptr;
}
+// Find whether base is a direct single line base class of type
+// (no multiple inheritance), that is, a C++ pointer cast can safely be done.
+static bool isDirectAncestor(PyTypeObject *type, PyTypeObject *base)
+{
+ if (type == base)
+ return true;
+ if (PyTuple_Size(type->tp_bases) == 0)
+ return false;
+ auto *sbkObjectType = SbkObject_TypeF();
+ auto *firstBase = reinterpret_cast<PyTypeObject *>(PyTuple_GetItem(type->tp_bases, 0));
+ return firstBase != sbkObjectType
+ && PyType_IsSubtype(type, sbkObjectType) != 0
+ && isDirectAncestor(firstBase, base);
+}
+
+bool canDowncastTo(PyTypeObject *baseType, PyTypeObject *targetType)
+{
+ return isDirectAncestor(targetType, baseType);
+}
+
} // namespace ObjectType
@@ -1059,9 +1179,7 @@ void callCppDestructors(SbkObject *pyObj)
PyTypeObject *type = Py_TYPE(pyObj);
auto *sotp = PepType_SOTP(type);
if (sotp->is_multicpp) {
- Shiboken::DtorAccumulatorVisitor visitor(pyObj);
- Shiboken::walkThroughClassHierarchy(type, &visitor);
- callDestructor(visitor.entries());
+ callDestructor(getDestructorEntries(pyObj));
} else {
Shiboken::ThreadStateSaver threadSaver;
threadSaver.save();
@@ -1210,11 +1328,10 @@ void makeValid(SbkObject *self)
// If has ref to other objects make all valid again
if (self->d->referredObjects) {
- RefCountMap &refCountMap = *(self->d->referredObjects);
- RefCountMap::iterator iter;
- for (auto it = refCountMap.begin(), end = refCountMap.end(); it != end; ++it) {
- if (Shiboken::Object::checkType(it->second))
- makeValid(reinterpret_cast<SbkObject *>(it->second));
+ const RefCountMap &refCountMap = *(self->d->referredObjects);
+ for (const auto &p : refCountMap) {
+ if (Shiboken::Object::checkType(p.second))
+ makeValid(reinterpret_cast<SbkObject *>(p.second));
}
}
}
@@ -1250,7 +1367,8 @@ bool setCppPointer(SbkObject *sbkObj, PyTypeObject *desiredType, void *cptr)
const bool alreadyInitialized = sbkObj->d->cptr[idx] != nullptr;
if (alreadyInitialized)
- PyErr_SetString(PyExc_RuntimeError, "You can't initialize an object twice!");
+ PyErr_Format(PyExc_RuntimeError, "You can't initialize an %s object in class %s twice!",
+ desiredType->tp_name, type->tp_name);
else
sbkObj->d->cptr[idx] = cptr;
@@ -1342,20 +1460,67 @@ SbkObject *findColocatedChild(SbkObject *wrapper,
return nullptr;
}
+// Legacy, for compatibility only.
PyObject *newObject(PyTypeObject *instanceType,
void *cptr,
bool hasOwnership,
bool isExactType,
const char *typeName)
{
- // Try to find the exact type of cptr.
- if (!isExactType) {
- if (PyTypeObject *exactType = ObjectType::typeForTypeName(typeName))
- instanceType = exactType;
- else
- instanceType = BindingManager::instance().resolveType(&cptr, instanceType);
+ return isExactType
+ ? newObjectForType(instanceType, cptr, hasOwnership)
+ : newObjectWithHeuristics(instanceType, cptr, hasOwnership, typeName);
+}
+
+static PyObject *newObjectWithHeuristicsHelper(PyTypeObject *instanceType,
+ PyTypeObject *exactType,
+ void *cptr,
+ bool hasOwnership)
+{
+ // Try to find the exact type of cptr. For hierarchies with
+ // non-virtual destructors, typeid() will return the base name.
+ // Try type discovery in these cases.
+ if (exactType == nullptr || exactType == instanceType) {
+ auto resolved = BindingManager::instance().findDerivedType(cptr, instanceType);
+ if (resolved.first != nullptr
+ && Shiboken::ObjectType::canDowncastTo(instanceType, resolved.first)) {
+ exactType = resolved.first;
+ cptr = resolved.second;
+ }
}
+ return newObjectForType(exactType != nullptr ? exactType : instanceType,
+ cptr, hasOwnership);
+}
+
+PyObject *newObjectForPointer(PyTypeObject *instanceType,
+ void *cptr,
+ bool hasOwnership,
+ const char *typeName)
+{
+ // Try to find the exact type of cptr.
+ PyTypeObject *exactType = ObjectType::typeForTypeName(typeName);
+ // PYSIDE-868: In case of multiple inheritance, (for example,
+ // a function returning a QPaintDevice * from a QWidget *),
+ // use instance type to avoid pointer offset errors.
+ return exactType != nullptr && !Shiboken::ObjectType::canDowncastTo(instanceType, exactType)
+ ? newObjectForType(instanceType, cptr, hasOwnership)
+ : newObjectWithHeuristicsHelper(instanceType, exactType, cptr, hasOwnership);
+}
+
+
+PyObject *newObjectWithHeuristics(PyTypeObject *instanceType,
+ void *cptr,
+ bool hasOwnership,
+ const char *typeName)
+{
+ return newObjectWithHeuristicsHelper(instanceType,
+ ObjectType::typeForTypeName(typeName),
+ cptr, hasOwnership);
+}
+
+PyObject *newObjectForType(PyTypeObject *instanceType, void *cptr, bool hasOwnership)
+{
bool shouldCreate = true;
bool shouldRegister = true;
SbkObject *self = nullptr;
@@ -1564,7 +1729,7 @@ void deallocData(SbkObject *self, bool cleanup)
}
delete self->d; // PYSIDE-205: always delete d.
Py_XDECREF(self->ob_dict);
- Py_TYPE(self)->tp_free(self);
+ PepExt_TypeCallFree(reinterpret_cast<PyObject *>(self));
}
void setTypeUserData(SbkObject *wrapper, void *userData, DeleteUserDataFunc d_func)
@@ -1656,6 +1821,11 @@ static std::vector<PyTypeObject *> getBases(SbkObject *self)
: std::vector<PyTypeObject *>(1, Py_TYPE(self));
}
+static bool isValueType(SbkObject *self)
+{
+ return PepType_SOTP(Py_TYPE(self))->type_behaviour == BEHAVIOUR_VALUETYPE;
+}
+
void _debugFormat(std::ostream &s, SbkObject *self)
{
assert(self);
@@ -1679,6 +1849,8 @@ void _debugFormat(std::ostream &s, SbkObject *self)
s << " [validCppObject]";
if (d->cppObjectCreated)
s << " [wasCreatedByPython]";
+ s << (isValueType(self) ? " [value]" : " [object]");
+
if (d->parentInfo) {
if (auto *parent = d->parentInfo->parent)
s << ", parent=" << reinterpret_cast<PyObject *>(parent)->ob_type->tp_name
@@ -1709,8 +1881,9 @@ std::string info(SbkObject *self)
s << "hasOwnership...... " << bool(self->d->hasOwnership) << "\n"
"containsCppWrapper " << self->d->containsCppWrapper << "\n"
"validCppObject.... " << self->d->validCppObject << "\n"
- "wasCreatedByPython " << self->d->cppObjectCreated << "\n";
-
+ "wasCreatedByPython " << self->d->cppObjectCreated << "\n"
+ "value...... " << isValueType(self) << "\n"
+ "reference count... " << reinterpret_cast<PyObject *>(self)->ob_refcnt << '\n';
if (self->d->parentInfo && self->d->parentInfo->parent) {
s << "parent............ ";
@@ -1728,17 +1901,17 @@ std::string info(SbkObject *self)
}
if (self->d->referredObjects && !self->d->referredObjects->empty()) {
- Shiboken::RefCountMap &map = *self->d->referredObjects;
+ const Shiboken::RefCountMap &map = *self->d->referredObjects;
s << "referred objects.. ";
std::string lastKey;
- for (auto it = map.begin(), end = map.end(); it != end; ++it) {
- if (it->first != lastKey) {
+ for (const auto &p : map) {
+ if (p.first != lastKey) {
if (!lastKey.empty())
s << " ";
- s << '"' << it->first << "\" => ";
- lastKey = it->first;
+ s << '"' << p.first << "\" => ";
+ lastKey = p.first;
}
- Shiboken::AutoDecRef obj(PyObject_Str(it->second));
+ Shiboken::AutoDecRef obj(PyObject_Str(p.second));
s << String::toCString(obj) << ' ';
}
s << '\n';
diff --git a/sources/shiboken6/libshiboken/basewrapper.h b/sources/shiboken6/libshiboken/basewrapper.h
index 86806c917..ec5545aea 100644
--- a/sources/shiboken6/libshiboken/basewrapper.h
+++ b/sources/shiboken6/libshiboken/basewrapper.h
@@ -38,28 +38,30 @@ LIBSHIBOKEN_API void SbkDeallocQAppWrapper(PyObject *pyObj);
LIBSHIBOKEN_API void SbkDeallocWrapperWithPrivateDtor(PyObject *self);
/// Function signature for the multiple inheritance information initializers that should be provided by classes with multiple inheritance.
-typedef int *(*MultipleInheritanceInitFunction)(const void *);
+using MultipleInheritanceInitFunction = int *(*)(const void *);
/**
* Special cast function is used to correctly cast an object when it's
* part of a multiple inheritance hierarchy.
* The implementation of this function is auto generated by the generator and you don't need to care about it.
*/
-typedef void *(*SpecialCastFunction)(void *, PyTypeObject *);
-typedef PyTypeObject *(*TypeDiscoveryFunc)(void *, PyTypeObject *);
-typedef void *(*TypeDiscoveryFuncV2)(void *, PyTypeObject *);
+using SpecialCastFunction = void *(*)(void *, PyTypeObject *);
+using TypeDiscoveryFunc = PyTypeObject *(*)(void *, PyTypeObject *);
+using TypeDiscoveryFuncV2 = void *(*)(void *, PyTypeObject *);
// Used in userdata dealloc function
-typedef void (*DeleteUserDataFunc)(void *);
+using DeleteUserDataFunc = void (*)(void *);
-typedef void (*ObjectDestructor)(void *);
+using ObjectDestructor = void (*)(void *);
-typedef void (*SubTypeInitHook)(PyTypeObject *, PyObject *, PyObject *);
+using SubTypeInitHook = void (*)(PyTypeObject *, PyObject *, PyObject *);
/// PYSIDE-1019: Set the function to select the current feature.
/// Return value is the previous content.
-typedef void (*SelectableFeatureHook)(PyTypeObject *);
+using SelectableFeatureHook = void (*)(PyTypeObject *);
+using SelectableFeatureCallback = void (*)(bool);
LIBSHIBOKEN_API SelectableFeatureHook initSelectableFeature(SelectableFeatureHook func);
+LIBSHIBOKEN_API void setSelectableFeatureCallback(SelectableFeatureCallback func);
/// PYSIDE-1626: Enforcing a context switch without further action.
LIBSHIBOKEN_API void SbkObjectType_UpdateFeature(PyTypeObject *type);
@@ -72,7 +74,7 @@ LIBSHIBOKEN_API void SbkObjectType_SetPropertyStrings(PyTypeObject *type, const
LIBSHIBOKEN_API void SbkObjectType_SetEnumFlagInfo(PyTypeObject *type, const char **strings);
/// PYSIDE-1470: Set the function to kill a Q*Application.
-typedef void(*DestroyQAppHook)();
+using DestroyQAppHook = void(*)();
LIBSHIBOKEN_API void setDestroyQApplication(DestroyQAppHook func);
/// PYSIDE-535: Use the C API in PyPy instead of `op->ob_dict`, directly (borrowed ref)
@@ -110,6 +112,9 @@ LIBSHIBOKEN_API PyObject *FallbackRichCompare(PyObject *self, PyObject *other, i
/// PYSIDE-1970: Be easily able to see what is happening in the running code.
LIBSHIBOKEN_API void disassembleFrame(const char *marker);
+/// PYSIDE-2230: Check if an object is an SbkObject.
+LIBSHIBOKEN_API bool SbkObjectType_Check(PyTypeObject *type);
+
} // extern "C"
namespace Shiboken
@@ -130,11 +135,25 @@ void callCppDestructor(void *cptr)
delete reinterpret_cast<T *>(cptr);
}
-// setErrorAboutWrongArguments now gets overload information from the signature module.
-// The extra info argument can contain additional data about the error.
+/// setErrorAboutWrongArguments now gets overload information from the signature module.
+/// The extra info argument can contain additional data about the error.
LIBSHIBOKEN_API void setErrorAboutWrongArguments(PyObject *args, const char *funcName,
PyObject *info);
+/// Return values for the different retun variants.
+/// This is used instead of goto.
+LIBSHIBOKEN_API PyObject *returnWrongArguments(PyObject *args, const char *funcName,
+ PyObject *info);
+
+LIBSHIBOKEN_API int returnWrongArguments_Zero(PyObject *args, const char *funcName,
+ PyObject *info);
+
+LIBSHIBOKEN_API int returnWrongArguments_MinusOne(PyObject *args, const char *funcName,
+ PyObject *info);
+
+/// A simple special version for the end of rich comparison.
+LIBSHIBOKEN_API PyObject *returnFromRichCompare(PyObject *result);
+
// Return error information object if the argument count is wrong
LIBSHIBOKEN_API PyObject *checkInvalidArgumentCount(Py_ssize_t numArgs,
Py_ssize_t minArgs,
@@ -181,14 +200,15 @@ LIBSHIBOKEN_API const char *getOriginalName(PyTypeObject *self);
LIBSHIBOKEN_API void setTypeDiscoveryFunctionV2(PyTypeObject *self, TypeDiscoveryFuncV2 func);
LIBSHIBOKEN_API void copyMultipleInheritance(PyTypeObject *self, PyTypeObject *other);
LIBSHIBOKEN_API void setMultipleInheritanceFunction(PyTypeObject *self, MultipleInheritanceInitFunction func);
-LIBSHIBOKEN_API MultipleInheritanceInitFunction getMultipleInheritanceFunction(PyTypeObject *self);
+LIBSHIBOKEN_API MultipleInheritanceInitFunction getMultipleInheritanceFunction(PyTypeObject *type);
LIBSHIBOKEN_API void setDestructorFunction(PyTypeObject *self, ObjectDestructor func);
enum WrapperFlags
{
InnerClass = 0x1,
- DeleteInMainThread = 0x2
+ DeleteInMainThread = 0x2,
+ Value = 0x4
};
/**
@@ -209,13 +229,12 @@ enum WrapperFlags
* \returns true if the initialization went fine, false otherwise.
*/
LIBSHIBOKEN_API PyTypeObject *introduceWrapperType(PyObject *enclosingObject,
- const char *typeName,
- const char *originalName,
- PyType_Spec *typeSpec,
- ObjectDestructor cppObjDtor,
- PyTypeObject *baseType,
- PyObject *baseTypes,
- unsigned wrapperFlags = 0);
+ const char *typeName,
+ const char *originalName,
+ PyType_Spec *typeSpec,
+ ObjectDestructor cppObjDtor,
+ PyObject *bases,
+ unsigned wrapperFlags = 0);
/**
* Set the subtype init hook for a type.
@@ -246,6 +265,14 @@ LIBSHIBOKEN_API PyTypeObject *typeForTypeName(const char *typeName);
* \since 5.12
*/
LIBSHIBOKEN_API bool hasSpecialCastFunction(PyTypeObject *sbkType);
+
+/// Returns whether a C++ pointer of \p baseType can be safely downcast
+/// to \p targetType (base is a direct, single line base class of targetType).
+/// (is a direct, single-line inheritance)
+/// \param baseType Python type of base class
+/// \param targetType Python type of derived class
+/// \since 6.8
+LIBSHIBOKEN_API bool canDowncastTo(PyTypeObject *baseType, PyTypeObject *targetType);
}
namespace Object {
@@ -278,7 +305,8 @@ LIBSHIBOKEN_API SbkObject *findColocatedChild(SbkObject *wrapper,
const PyTypeObject *instanceType);
/**
- * Bind a C++ object to Python.
+ * Bind a C++ object to Python. Forwards to
+ * newObjectWithHeuristics(), newObjectForType() depending on \p isExactType.
* \param instanceType equivalent Python type for the C++ object.
* \param hasOwnership if true, Python will try to delete the underlying C++ object when there's no more refs.
* \param isExactType if false, Shiboken will use some heuristics to detect the correct Python type of this C++
@@ -292,6 +320,40 @@ LIBSHIBOKEN_API PyObject *newObject(PyTypeObject *instanceType,
bool isExactType = false,
const char *typeName = nullptr);
+/// Bind a C++ object to Python for polymorphic pointers. Calls
+/// newObjectWithHeuristics() with an additional check for multiple
+/// inheritance, in which case it will fall back to instanceType.
+/// \param instanceType Equivalent Python type for the C++ object.
+/// \param hasOwnership if true, Python will try to delete the underlying C++ object
+/// when there's no more refs.
+/// \param typeName If non-null, this will be used as helper to find the correct
+/// Python type for this object (obtained by typeid().name().
+LIBSHIBOKEN_API PyObject *newObjectForPointer(PyTypeObject *instanceType,
+ void *cptr,
+ bool hasOwnership = true,
+ const char *typeName = nullptr);
+
+/// Bind a C++ object to Python using some heuristics to detect the correct
+/// Python type of this C++ object. In any case \p instanceType must be provided;
+/// it'll be used as search starting point and as fallback.
+/// \param instanceType Equivalent Python type for the C++ object.
+/// \param hasOwnership if true, Python will try to delete the underlying C++ object
+/// C++ object when there are no more references.
+/// when there's no more refs.
+/// \param typeName If non-null, this will be used as helper to find the correct
+/// Python type for this object (obtained by typeid().name().
+LIBSHIBOKEN_API PyObject *newObjectWithHeuristics(PyTypeObject *instanceType,
+ void *cptr,
+ bool hasOwnership = true,
+ const char *typeName = nullptr);
+
+/// Bind a C++ object to Python using the given type.
+/// \param instanceType Equivalent Python type for the C++ object.
+/// \param hasOwnership if true, Python will try to delete the underlying
+/// C++ object when there are no more references.
+LIBSHIBOKEN_API PyObject *newObjectForType(PyTypeObject *instanceType,
+ void *cptr, bool hasOwnership = true);
+
/**
* Changes the valid flag of a PyObject, invalid objects will raise an exception when someone tries to access it.
*/
diff --git a/sources/shiboken6/libshiboken/basewrapper_p.h b/sources/shiboken6/libshiboken/basewrapper_p.h
index fc3cc321c..fb9140793 100644
--- a/sources/shiboken6/libshiboken/basewrapper_p.h
+++ b/sources/shiboken6/libshiboken/basewrapper_p.h
@@ -30,14 +30,12 @@ using ChildrenList = std::set<SbkObject *>;
/// Structure used to store information about object parent and children.
struct ParentInfo
{
- /// Default ctor.
- ParentInfo() : parent(nullptr), hasWrapperRef(false) {}
/// Pointer to parent object.
- SbkObject *parent;
+ SbkObject *parent = nullptr;
/// List of object children.
ChildrenList children;
/// has internal ref
- bool hasWrapperRef;
+ bool hasWrapperRef = false;
};
} // namespace Shiboken
@@ -51,6 +49,12 @@ extern "C"
*/
struct SbkObjectPrivate
{
+ SbkObjectPrivate() noexcept = default;
+ SbkObjectPrivate(const SbkObjectPrivate &) = delete;
+ SbkObjectPrivate(SbkObjectPrivate &&o) = delete;
+ SbkObjectPrivate &operator=(const SbkObjectPrivate &) = delete;
+ SbkObjectPrivate &operator=(SbkObjectPrivate &&o) = delete;
+
/// Pointer to the C++ class.
void ** cptr;
/// True when Python is responsible for freeing the used memory.
@@ -110,7 +114,8 @@ struct SbkObjectTypePrivate
/// True if this type holds two or more C++ instances, e.g.: a Python class which inherits from two C++ classes.
unsigned int is_multicpp : 1;
- /// True if this type was defined by the user.
+ /// True if this type was defined by the user (a class written in Python inheriting
+ /// a class provided by a Shiboken binding).
unsigned int is_user_type : 1;
/// Tells is the type is a value type or an object-type, see BEHAVIOUR_ *constants.
unsigned int type_behaviour : 2;
@@ -138,107 +143,7 @@ struct DestructorEntry
**/
std::vector<SbkObject *> splitPyObject(PyObject *pyObj);
-/**
-* Visitor class used by walkOnClassHierarchy function.
-*/
-class HierarchyVisitor
-{
-public:
- HierarchyVisitor(const HierarchyVisitor &) = delete;
- HierarchyVisitor(HierarchyVisitor &&) = delete;
- HierarchyVisitor &operator=(const HierarchyVisitor &) = delete;
- HierarchyVisitor &operator=(HierarchyVisitor &&) = delete;
-
- HierarchyVisitor();
- virtual ~HierarchyVisitor();
-
- virtual bool visit(PyTypeObject *node) = 0; // return true to terminate
-};
-
-class BaseCountVisitor : public HierarchyVisitor
-{
-public:
- bool visit(PyTypeObject *) override;
-
- int count() const { return m_count; }
-
-private:
- int m_count = 0;
-};
-
-class BaseAccumulatorVisitor : public HierarchyVisitor
-{
-public:
- using Result = std::vector<PyTypeObject *>;
-
- bool visit(PyTypeObject *node) override;
-
- Result bases() const { return m_bases; }
-
-private:
- Result m_bases;
-};
-
-class GetIndexVisitor : public HierarchyVisitor
-{
-public:
- explicit GetIndexVisitor(PyTypeObject *desiredType) : m_desiredType(desiredType) {}
-
- bool visit(PyTypeObject *node) override;
-
- int index() const { return m_index; }
-
-private:
- int m_index = -1;
- PyTypeObject *m_desiredType;
-};
-
-/// Collect destructors and C++ instances of each C++ object held by a Python
-/// object
-class DtorAccumulatorVisitor : public HierarchyVisitor
-{
-public:
- explicit DtorAccumulatorVisitor(SbkObject *pyObj) : m_pyObject(pyObj) {}
-
- bool visit(PyTypeObject *node) override;
-
- using DestructorEntries = std::vector<DestructorEntry>;
-
- const DestructorEntries &entries() const { return m_entries; }
-
-private:
- DestructorEntries m_entries;
- SbkObject *m_pyObject;
-};
-
-/// \internal Internal function used to walk on classes inheritance trees.
-/**
-* Walk on class hierarchy using a DFS algorithm.
-* For each pure Shiboken type found, HierarchyVisitor::visit is called and the algorithm
-* considers all children of this type as visited.
-*/
-bool walkThroughClassHierarchy(PyTypeObject *currentType, HierarchyVisitor *visitor);
-
-inline int getTypeIndexOnHierarchy(PyTypeObject *baseType, PyTypeObject *desiredType)
-{
- GetIndexVisitor visitor(desiredType);
- walkThroughClassHierarchy(baseType, &visitor);
- return visitor.index();
-}
-
-inline int getNumberOfCppBaseClasses(PyTypeObject *baseType)
-{
- BaseCountVisitor visitor;
- walkThroughClassHierarchy(baseType, &visitor);
- return visitor.count();
-}
-
-inline std::vector<PyTypeObject *> getCppBaseClasses(PyTypeObject *baseType)
-{
- BaseAccumulatorVisitor visitor;
- walkThroughClassHierarchy(baseType, &visitor);
- return visitor.bases();
-}
+int getNumberOfCppBaseClasses(PyTypeObject *baseType);
namespace Object
{
diff --git a/sources/shiboken6/libshiboken/bindingmanager.cpp b/sources/shiboken6/libshiboken/bindingmanager.cpp
index 9d74e9721..83c927ae5 100644
--- a/sources/shiboken6/libshiboken/bindingmanager.cpp
+++ b/sources/shiboken6/libshiboken/bindingmanager.cpp
@@ -6,101 +6,162 @@
#include "basewrapper_p.h"
#include "bindingmanager.h"
#include "gilstate.h"
+#include "helper.h"
+#include "sbkmodule.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
#include "sbkfeature_base.h"
#include "debugfreehook.h"
#include <cstddef>
+#include <cstring>
#include <fstream>
+#include <iostream>
#include <mutex>
+#include <string_view>
#include <unordered_map>
+#include <unordered_set>
+
+// GraphNode for the dependency graph. It keeps a pointer to
+// the TypeInitStruct to be able to lazily create the type and hashes
+// by the full type name.
+struct GraphNode
+{
+ explicit GraphNode(Shiboken::Module::TypeInitStruct *i) : name(i->fullName), initStruct(i) {}
+ explicit GraphNode(const char *n) : name(n), initStruct(nullptr) {} // Only for searching
+
+ std::string_view name;
+ Shiboken::Module::TypeInitStruct *initStruct;
+
+ friend bool operator==(const GraphNode &n1, const GraphNode &n2) { return n1.name == n2.name; }
+ friend bool operator!=(const GraphNode &n1, const GraphNode &n2) { return n1.name != n2.name; }
+};
+
+template <>
+struct std::hash<GraphNode> {
+ size_t operator()(const GraphNode &n) const noexcept
+ {
+ return std::hash<std::string_view>{}(n.name);
+ }
+};
namespace Shiboken
{
using WrapperMap = std::unordered_map<const void *, SbkObject *>;
-class Graph
+template <class NodeType>
+class BaseGraph
{
public:
- using NodeList = std::vector<PyTypeObject *>;
- using Edges = std::unordered_map<PyTypeObject *, NodeList>;
+ using NodeList = std::vector<NodeType>;
+ using NodeSet = std::unordered_set<NodeType>;
+
+ using Edges = std::unordered_map<NodeType, NodeList>;
Edges m_edges;
- Graph() = default;
+ BaseGraph() = default;
- void addEdge(PyTypeObject *from, PyTypeObject *to)
+ void addEdge(NodeType from, NodeType to)
{
m_edges[from].push_back(to);
}
-#ifndef NDEBUG
- void dumpDotGraph()
+ NodeSet nodeSet() const
{
- std::ofstream file("/tmp/shiboken_graph.dot");
-
- file << "digraph D {\n";
-
- for (auto i = m_edges.begin(), end = m_edges.end(); i != end; ++i) {
- auto *node1 = i->first;
- const NodeList &nodeList = i->second;
- for (const PyTypeObject *o : nodeList) {
- auto *node2 = o;
- file << '"' << node2->tp_name << "\" -> \""
- << node1->tp_name << "\"\n";
- }
+ NodeSet result;
+ for (const auto &p : m_edges) {
+ result.insert(p.first);
+ for (const auto node2 : p.second)
+ result.insert(node2);
}
- file << "}\n";
+ return result;
}
-#endif
+};
+
+class Graph : public BaseGraph<GraphNode>
+{
+public:
+ using TypeCptrPair = BindingManager::TypeCptrPair;
- PyTypeObject *identifyType(void **cptr, PyTypeObject *type, PyTypeObject *baseType) const
+ TypeCptrPair identifyType(void *cptr, PyTypeObject *type, PyTypeObject *baseType) const
{
- auto edgesIt = m_edges.find(type);
- if (edgesIt != m_edges.end()) {
- const NodeList &adjNodes = m_edges.find(type)->second;
- for (PyTypeObject *node : adjNodes) {
- PyTypeObject *newType = identifyType(cptr, node, baseType);
- if (newType)
- return newType;
- }
- }
- void *typeFound = nullptr;
- auto *sotp = PepType_SOTP(type);
- if (sotp->type_discovery)
- typeFound = sotp->type_discovery(*cptr, baseType);
- if (typeFound) {
- // This "typeFound != type" is needed for backwards compatibility with old modules using a newer version of
- // libshiboken because old versions of type_discovery function used to return a PyTypeObject *instead of
- // a possible variation of the C++ instance pointer (*cptr).
- if (typeFound != type)
- *cptr = typeFound;
- return type;
- }
- return nullptr;
+ return identifyType(cptr, GraphNode(type->tp_name), type, baseType);
}
-};
+ bool dumpTypeGraph(const char *fileName) const;
-#ifndef NDEBUG
-static void showWrapperMap(const WrapperMap &wrapperMap)
+private:
+ TypeCptrPair identifyType(void *cptr, const GraphNode &typeNode, PyTypeObject *type,
+ PyTypeObject *baseType) const;
+};
+
+Graph::TypeCptrPair Graph::identifyType(void *cptr,
+ const GraphNode &typeNode, PyTypeObject *type,
+ PyTypeObject *baseType) const
{
- if (Py_VerboseFlag > 0) {
- fprintf(stderr, "-------------------------------\n");
- fprintf(stderr, "WrapperMap: %p (size: %d)\n", &wrapperMap, (int) wrapperMap.size());
- for (auto it = wrapperMap.begin(), end = wrapperMap.end(); it != end; ++it) {
- const SbkObject *sbkObj = it->second;
- fprintf(stderr, "key: %p, value: %p (%s, refcnt: %d)\n", it->first,
- static_cast<const void *>(sbkObj),
- (Py_TYPE(sbkObj))->tp_name,
- int(reinterpret_cast<const PyObject *>(sbkObj)->ob_refcnt));
+ assert(typeNode.initStruct != nullptr || type != nullptr);
+ auto edgesIt = m_edges.find(typeNode);
+ if (edgesIt != m_edges.end()) {
+ const NodeList &adjNodes = edgesIt->second;
+ for (const auto &node : adjNodes) {
+ auto newType = identifyType(cptr, node, nullptr, baseType);
+ if (newType.first != nullptr)
+ return newType;
}
- fprintf(stderr, "-------------------------------\n");
}
+
+ if (type == nullptr) {
+ if (typeNode.initStruct->type == nullptr) // Layzily create type
+ type = Shiboken::Module::get(*typeNode.initStruct);
+ else
+ type = typeNode.initStruct->type;
+ }
+
+ auto *sotp = PepType_SOTP(type);
+ if (sotp->type_discovery != nullptr) {
+ if (void *derivedCPtr = sotp->type_discovery(cptr, baseType))
+ return {type, derivedCPtr};
+ }
+ return {nullptr, nullptr};
+}
+
+static void formatDotNode(std::string_view name, std::ostream &file)
+{
+ auto lastDot = name.rfind('.');
+ file << " \"" << name << "\" [ label=";
+ if (lastDot != std::string::npos) {
+ file << '"' << name.substr(lastDot + 1) << "\" tooltip=\""
+ << name.substr(0, lastDot) << '"';
+ } else {
+ file << '"' << name << '"';
+ }
+ file << " ]\n";
+}
+
+bool Graph::dumpTypeGraph(const char *fileName) const
+{
+ std::ofstream file(fileName);
+ if (!file.good())
+ return false;
+
+ file << "digraph D {\n";
+
+ // Define nodes with short names
+ for (const auto &node : nodeSet())
+ formatDotNode(node.name, file);
+
+ // Write edges
+ for (const auto &p : m_edges) {
+ const auto &node1 = p.first;
+ const NodeList &nodeList = p.second;
+ for (const auto &node2 : nodeList)
+ file << " \"" << node2.name << "\" -> \"" << node1.name << "\"\n";
+ }
+ file << "}\n";
+ return true;
}
-#endif
struct BindingManager::BindingManagerPrivate {
using DestructorEntries = std::vector<DestructorEntry>;
@@ -113,20 +174,19 @@ struct BindingManager::BindingManagerPrivate {
std::recursive_mutex wrapperMapLock;
Graph classHierarchy;
DestructorEntries deleteInMainThread;
- bool destroying;
- BindingManagerPrivate() : destroying(false) {}
- bool releaseWrapper(void *cptr, SbkObject *wrapper);
- void assignWrapper(SbkObject *wrapper, const void *cptr);
+ bool releaseWrapper(void *cptr, SbkObject *wrapper, const int *bases = nullptr);
+ bool releaseWrapperHelper(void *cptr, SbkObject *wrapper);
+ void assignWrapper(SbkObject *wrapper, const void *cptr, const int *bases = nullptr);
+ void assignWrapperHelper(SbkObject *wrapper, const void *cptr);
};
-bool BindingManager::BindingManagerPrivate::releaseWrapper(void *cptr, SbkObject *wrapper)
+inline bool BindingManager::BindingManagerPrivate::releaseWrapperHelper(void *cptr, SbkObject *wrapper)
{
// The wrapper argument is checked to ensure that the correct wrapper is released.
// Returns true if the correct wrapper is found and released.
// If wrapper argument is NULL, no such check is performed.
- std::lock_guard<std::recursive_mutex> guard(wrapperMapLock);
auto iter = wrapperMapper.find(cptr);
if (iter != wrapperMapper.end() && (wrapper == nullptr || iter->second == wrapper)) {
wrapperMapper.erase(iter);
@@ -135,15 +195,41 @@ bool BindingManager::BindingManagerPrivate::releaseWrapper(void *cptr, SbkObject
return false;
}
-void BindingManager::BindingManagerPrivate::assignWrapper(SbkObject *wrapper, const void *cptr)
+bool BindingManager::BindingManagerPrivate::releaseWrapper(void *cptr, SbkObject *wrapper,
+ const int *bases)
{
assert(cptr);
std::lock_guard<std::recursive_mutex> guard(wrapperMapLock);
+ const bool result = releaseWrapperHelper(cptr, wrapper);
+ if (bases != nullptr) {
+ auto *base = static_cast<uint8_t *>(cptr);
+ for (const auto *offset = bases; *offset != -1; ++offset)
+ releaseWrapperHelper(base + *offset, wrapper);
+ }
+ return result;
+}
+
+inline void BindingManager::BindingManagerPrivate::assignWrapperHelper(SbkObject *wrapper,
+ const void *cptr)
+{
auto iter = wrapperMapper.find(cptr);
if (iter == wrapperMapper.end())
wrapperMapper.insert(std::make_pair(cptr, wrapper));
}
+void BindingManager::BindingManagerPrivate::assignWrapper(SbkObject *wrapper, const void *cptr,
+ const int *bases)
+{
+ assert(cptr);
+ std::lock_guard<std::recursive_mutex> guard(wrapperMapLock);
+ assignWrapperHelper(wrapper, cptr);
+ if (bases != nullptr) {
+ const auto *base = static_cast<const uint8_t *>(cptr);
+ for (const auto *offset = bases; *offset != -1; ++offset)
+ assignWrapperHelper(wrapper, base + *offset);
+ }
+}
+
BindingManager::BindingManager()
{
m_d = new BindingManager::BindingManagerPrivate;
@@ -159,7 +245,8 @@ BindingManager::~BindingManager()
debugRemoveFreeHook();
#endif
#ifndef NDEBUG
- showWrapperMap(m_d->wrapperMapper);
+ if (Shiboken::pyVerbose() > 0)
+ dumpWrapperMap();
#endif
/* Cleanup hanging references. We just invalidate them as when
* the BindingManager is being destroyed the interpreter is alredy
@@ -195,15 +282,7 @@ void BindingManager::registerWrapper(SbkObject *pyObj, void *cptr)
if (d->mi_init && !d->mi_offsets)
d->mi_offsets = d->mi_init(cptr);
- m_d->assignWrapper(pyObj, cptr);
- if (d->mi_offsets) {
- int *offset = d->mi_offsets;
- while (*offset != -1) {
- if (*offset > 0)
- m_d->assignWrapper(pyObj, reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(cptr) + *offset));
- offset++;
- }
- }
+ m_d->assignWrapper(pyObj, cptr, d->mi_offsets);
}
void BindingManager::releaseWrapper(SbkObject *sbkObj)
@@ -213,17 +292,10 @@ void BindingManager::releaseWrapper(SbkObject *sbkObj)
int numBases = ((d && d->is_multicpp) ? getNumberOfCppBaseClasses(Py_TYPE(sbkObj)) : 1);
void ** cptrs = reinterpret_cast<SbkObject *>(sbkObj)->d->cptr;
+ const int *mi_offsets = d != nullptr ? d->mi_offsets : nullptr;
for (int i = 0; i < numBases; ++i) {
- auto *cptr = reinterpret_cast<unsigned char *>(cptrs[i]);
- m_d->releaseWrapper(cptr, sbkObj);
- if (d && d->mi_offsets) {
- int *offset = d->mi_offsets;
- while (*offset != -1) {
- if (*offset > 0)
- m_d->releaseWrapper(reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(cptr) + *offset), sbkObj);
- offset++;
- }
- }
+ if (cptrs[i] != nullptr)
+ m_d->releaseWrapper(cptrs[i], sbkObj, mi_offsets);
}
sbkObj->d->validCppObject = false;
}
@@ -256,7 +328,7 @@ PyObject *BindingManager::getOverride(const void *cptr,
SbkObject *wrapper = retrieveWrapper(cptr);
// The refcount can be 0 if the object is dieing and someone called
// a virtual method from the destructor
- if (!wrapper || reinterpret_cast<const PyObject *>(wrapper)->ob_refcnt == 0)
+ if (!wrapper || Py_REFCNT(reinterpret_cast<const PyObject *>(wrapper)) == 0)
return nullptr;
// PYSIDE-1626: Touch the type to initiate switching early.
@@ -276,6 +348,8 @@ PyObject *BindingManager::getOverride(const void *cptr,
auto *obWrapper = reinterpret_cast<PyObject *>(wrapper);
auto *wrapper_dict = SbkObject_GetDict_NoRef(obWrapper);
if (PyObject *method = PyDict_GetItem(wrapper_dict, pyMethodName)) {
+ // Note: This special case was implemented for duck-punching, which happens
+ // in the instance dict. It does not work with properties.
Py_INCREF(method);
return method;
}
@@ -317,36 +391,53 @@ PyObject *BindingManager::getOverride(const void *cptr,
}
if (method != nullptr) {
- PyObject *defaultMethod;
+ PyObject *defaultMethod{};
PyObject *mro = Py_TYPE(wrapper)->tp_mro;
int size = PyTuple_GET_SIZE(mro);
+ bool defaultFound = false;
// The first class in the mro (index 0) is the class being checked and it should not be tested.
// The last class in the mro (size - 1) is the base Python object class which should not be tested also.
for (int idx = 1; idx < size - 1; ++idx) {
auto *parent = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
- if (parent->tp_dict) {
- defaultMethod = PyDict_GetItem(parent->tp_dict, pyMethodName);
- if (defaultMethod && function != defaultMethod)
- return method;
+ AutoDecRef tpDict(PepType_GetDict(parent));
+ auto *parentDict = tpDict.object();
+ if (parentDict) {
+ defaultMethod = PyDict_GetItem(parentDict, pyMethodName);
+ if (defaultMethod) {
+ defaultFound = true;
+ if (function != defaultMethod)
+ return method;
+ }
}
}
-
+ // PYSIDE-2255: If no default method was found, use the method.
+ if (!defaultFound)
+ return method;
Py_DECREF(method);
}
return nullptr;
}
-void BindingManager::addClassInheritance(PyTypeObject *parent, PyTypeObject *child)
+void BindingManager::addClassInheritance(Module::TypeInitStruct *parent,
+ Module::TypeInitStruct *child)
{
- m_d->classHierarchy.addEdge(parent, child);
+ m_d->classHierarchy.addEdge(GraphNode(parent), GraphNode(child));
}
+BindingManager::TypeCptrPair BindingManager::findDerivedType(void *cptr, PyTypeObject *type) const
+{
+ return m_d->classHierarchy.identifyType(cptr, type, type);
+}
+
+// FIXME PYSIDE7: remove, just for compatibility
PyTypeObject *BindingManager::resolveType(void **cptr, PyTypeObject *type)
{
- PyTypeObject *identifiedType = m_d->classHierarchy.identifyType(cptr, type, type);
- return identifiedType ? identifiedType : type;
+ auto result = findDerivedType(*cptr, type);
+ if (result.second != nullptr)
+ *cptr = result.second;
+ return result.first != nullptr ? result.first : type;
}
std::set<PyObject *> BindingManager::getAllPyObjects()
@@ -364,10 +455,94 @@ std::set<PyObject *> BindingManager::getAllPyObjects()
void BindingManager::visitAllPyObjects(ObjectVisitor visitor, void *data)
{
WrapperMap copy = m_d->wrapperMapper;
- for (auto it = copy.begin(); it != copy.end(); ++it) {
- if (hasWrapper(it->first))
- visitor(it->second, data);
+ for (const auto &p : copy) {
+ if (hasWrapper(p.first))
+ visitor(p.second, data);
+ }
+}
+
+bool BindingManager::dumpTypeGraph(const char *fileName) const
+{
+ return m_d->classHierarchy.dumpTypeGraph(fileName);
+}
+
+void BindingManager::dumpWrapperMap()
+{
+ const auto &wrapperMap = m_d->wrapperMapper;
+ std::cerr << "-------------------------------\n"
+ << "WrapperMap size: " << wrapperMap.size() << " Types: "
+ << m_d->classHierarchy.nodeSet().size() << '\n';
+ for (auto it = wrapperMap.begin(), end = wrapperMap.end(); it != end; ++it) {
+ const SbkObject *sbkObj = it->second;
+ std::cerr << "key: " << it->first << ", value: "
+ << static_cast<const void *>(sbkObj) << " ("
+ << (Py_TYPE(sbkObj))->tp_name << ", refcnt: "
+ << Py_REFCNT(reinterpret_cast<const PyObject *>(sbkObj)) << ")\n";
+ }
+ std::cerr << "-------------------------------\n";
+}
+
+static bool isPythonType(PyTypeObject *type)
+{
+ // This is a type which should be called by multiple inheritance.
+ // It is either a pure Python type or a derived PySide type.
+ return !ObjectType::checkType(type) || ObjectType::isUserType(type);
+}
+
+bool callInheritedInit(PyObject *self, PyObject *args, PyObject *kwds,
+ const char *fullName)
+{
+ using Shiboken::AutoDecRef;
+
+ static PyObject *const _init = String::createStaticString("__init__");
+ static PyObject *objectInit =
+ PyObject_GetAttr(reinterpret_cast<PyObject *>(&PyBaseObject_Type), _init);
+
+ // A native C++ self cannot have multiple inheritance.
+ if (!Object::isUserType(self))
+ return false;
+
+ auto *startType = Py_TYPE(self);
+ auto *mro = startType->tp_mro;
+ Py_ssize_t idx, n = PyTuple_GET_SIZE(mro);
+ auto classNameLen = std::strrchr(fullName, '.') - fullName;
+ /* No need to check the last one: it's gonna be skipped anyway. */
+ for (idx = 0; idx + 1 < n; ++idx) {
+ auto *lookType = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
+ const char *lookName = lookType->tp_name;
+ auto lookLen = long(std::strlen(lookName));
+ if (std::strncmp(lookName, fullName, classNameLen) == 0 && lookLen == classNameLen)
+ break;
+ }
+ // We are now at the first non-Python class `QObject`.
+ // mro: ('C', 'A', 'QObject', 'Object', 'B', 'object')
+ // We want to catch class `B` and call its `__init__`.
+ for (idx += 1; idx + 1 < n; ++idx) {
+ auto *t = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
+ if (isPythonType(t))
+ break;
}
+ if (idx >= n)
+ return false;
+
+ auto *obSubType = PyTuple_GET_ITEM(mro, idx);
+ auto *subType = reinterpret_cast<PyTypeObject *>(obSubType);
+ if (subType == &PyBaseObject_Type)
+ return false;
+ AutoDecRef func(PyObject_GetAttr(obSubType, _init));
+ // PYSIDE-2654: If this has no implementation then we get object.__init__
+ // but that is the same case like above.
+ if (func == objectInit)
+ return false;
+ // PYSIDE-2294: We need to explicitly ignore positional args in a mixin class.
+ SBK_UNUSED(args);
+ AutoDecRef newArgs(PyTuple_New(1));
+ auto *newArgsOb = newArgs.object();
+ Py_INCREF(self);
+ PyTuple_SET_ITEM(newArgsOb, 0, self);
+ // Note: This can fail, so please always check the error status.
+ AutoDecRef result(PyObject_Call(func, newArgs, kwds));
+ return true;
}
} // namespace Shiboken
diff --git a/sources/shiboken6/libshiboken/bindingmanager.h b/sources/shiboken6/libshiboken/bindingmanager.h
index e299dad96..54c4e486a 100644
--- a/sources/shiboken6/libshiboken/bindingmanager.h
+++ b/sources/shiboken6/libshiboken/bindingmanager.h
@@ -5,17 +5,23 @@
#define BINDINGMANAGER_H
#include "sbkpython.h"
-#include <set>
#include "shibokenmacros.h"
+#include <set>
+#include <utility>
+
struct SbkObject;
namespace Shiboken
{
+namespace Module {
+struct TypeInitStruct;
+}
+
struct DestructorEntry;
-typedef void (*ObjectVisitor)(SbkObject *, void *);
+using ObjectVisitor = void (*)(SbkObject *, void *);
class LIBSHIBOKEN_API BindingManager
{
@@ -38,7 +44,15 @@ public:
SbkObject *retrieveWrapper(const void *cptr);
PyObject *getOverride(const void *cptr, PyObject *nameCache[], const char *methodName);
- void addClassInheritance(PyTypeObject *parent, PyTypeObject *child);
+ void addClassInheritance(Module::TypeInitStruct *parent, Module::TypeInitStruct *child);
+ /// Try to find the correct type of cptr via type discovery knowing that it's at least
+ /// of type \p type. If a derived class is found, it returns a cptr cast to the type
+ /// (which may be different in case of multiple inheritance.
+ /// \param cptr a pointer to the instance of type \p type
+ /// \param type type of cptr
+ using TypeCptrPair = std::pair<PyTypeObject *, void *>;
+ TypeCptrPair findDerivedType(void *cptr, PyTypeObject *type) const;
+
/**
* Try to find the correct type of *cptr knowing that it's at least of type \p type.
* In case of multiple inheritance this function may change the contents of cptr.
@@ -46,7 +60,7 @@ public:
* \param type type of *cptr
* \warning This function is slow, use it only as last resort.
*/
- PyTypeObject *resolveType(void **cptr, PyTypeObject *type);
+ [[deprecated]] PyTypeObject *resolveType(void **cptr, PyTypeObject *type);
std::set<PyObject *> getAllPyObjects();
@@ -59,6 +73,9 @@ public:
*/
void visitAllPyObjects(ObjectVisitor visitor, void *data);
+ bool dumpTypeGraph(const char *fileName) const;
+ void dumpWrapperMap();
+
private:
~BindingManager();
BindingManager();
@@ -67,6 +84,9 @@ private:
BindingManagerPrivate *m_d;
};
+LIBSHIBOKEN_API bool callInheritedInit(PyObject *self, PyObject *args, PyObject *kwds,
+ const char *fullName);
+
} // namespace Shiboken
#endif // BINDINGMANAGER_H
diff --git a/sources/shiboken6/libshiboken/bufferprocs_py37.h b/sources/shiboken6/libshiboken/bufferprocs_py37.h
index 06b42cabd..e16194e50 100644
--- a/sources/shiboken6/libshiboken/bufferprocs_py37.h
+++ b/sources/shiboken6/libshiboken/bufferprocs_py37.h
@@ -67,8 +67,8 @@ typedef struct bufferinfo {
void *internal;
} Pep_buffer;
-typedef int (*getbufferproc)(PyObject *, Pep_buffer *, int);
-typedef void (*releasebufferproc)(PyObject *, Pep_buffer *);
+using getbufferproc =int (*)(PyObject *, Pep_buffer *, int);
+using releasebufferproc = void (*)(PyObject *, Pep_buffer *);
/* Maximum number of dimensions */
#define PyBUF_MAX_NDIM 64
diff --git a/sources/shiboken6/libshiboken/debugfreehook.cpp b/sources/shiboken6/libshiboken/debugfreehook.cpp
index 1a80a2514..13df6bd6c 100644
--- a/sources/shiboken6/libshiboken/debugfreehook.cpp
+++ b/sources/shiboken6/libshiboken/debugfreehook.cpp
@@ -6,8 +6,8 @@
#include "gilstate.h"
#if defined(_WIN32) && defined(_DEBUG)
-#include <crtdbg.h>
-#include <windows.h>
+# include <sbkwindows.h>
+# include <crtdbg.h>
#endif
#ifdef __GLIBC__
diff --git a/sources/shiboken6/libshiboken/embed/embedding_generator.py b/sources/shiboken6/libshiboken/embed/embedding_generator.py
index 96f66b949..a058fd372 100644
--- a/sources/shiboken6/libshiboken/embed/embedding_generator.py
+++ b/sources/shiboken6/libshiboken/embed/embedding_generator.py
@@ -122,22 +122,23 @@ def _embed_file(fin, fout):
limit = 50
text = fin.readlines()
print(textwrap.dedent("""
- /*
- * This is a ZIP archive of all Python files in the directory
- * "shiboken6/shibokenmodule/files.dir/shibokensupport/signature"
- * There is also a toplevel file "signature_bootstrap.py[c]" that will be
- * directly executed from C++ as a bootstrap loader.
- */
+ // This is a ZIP archive of all Python files in the directory
+ // "shiboken6/shibokenmodule/files.dir/shibokensupport/signature"
+ // There is also a toplevel file "signature_bootstrap.py[c]" that will be
+ // directly executed from C++ as a bootstrap loader.
""").strip(), file=fout)
block, blocks = 0, len(text) // limit + 1
for idx, line in enumerate(text):
if idx % limit == 0:
+ if block:
+ fout.write(')"\n')
comma = "," if block else ""
block += 1
- print(file=fout)
- print(f'/* Block {block} of {blocks} */{comma}', file=fout)
- print(f'\"{line.strip()}\"', file=fout)
- print(f'/* Sentinel */, \"\"', file=fout)
+ fout.write(f'\n{comma} // Block {block} of {blocks}\nR"(')
+ else:
+ fout.write('\n')
+ fout.write(line.strip())
+ fout.write(')"\n\n/* Sentinel */, ""\n')
def _embed_bytefile(fin, fout, is_text):
diff --git a/sources/shiboken6/libshiboken/embed/signature_bootstrap.py b/sources/shiboken6/libshiboken/embed/signature_bootstrap.py
index c11a0367a..37f95cd35 100644
--- a/sources/shiboken6/libshiboken/embed/signature_bootstrap.py
+++ b/sources/shiboken6/libshiboken/embed/signature_bootstrap.py
@@ -26,6 +26,7 @@ recursion_trap = 0
import base64
import importlib
import io
+import os
import sys
import traceback
import zipfile
@@ -61,21 +62,83 @@ def bootstrap():
import shibokensupport
yield
except Exception as e:
- print("Problem importing shibokensupport:")
- print(f"{e.__class__.__name__}: {e}")
+ f = sys.stderr
+ print("Problem importing shibokensupport:", file=f)
+ print(f"{e.__class__.__name__}: {e}", file=f)
traceback.print_exc()
- print("sys.path:")
+ print("sys.path:", file=f)
for p in sys.path:
- print(" " + p)
- sys.stdout.flush()
+ print(" " + p, file=f)
+ f.flush()
sys.exit(-1)
target.remove(support_path)
- target, support_path = prepare_zipfile()
+ # Here we decide if we re-incarnate the embedded files or use embedding.
+ incarnated = find_incarnated_files()
+ if incarnated:
+ target, support_path = sys.path, os.fspath(incarnated)
+ else:
+ target, support_path = prepare_zipfile()
with ensure_shibokensupport(target, support_path):
from shibokensupport.signature import loader
return loader
+# Newer functionality:
+# This function checks if the support directory exist and returns it.
+# If does not exist, we try to create it and return it.
+# Otherwise, we return None.
+
+def find_incarnated_files():
+ import shiboken6 as root
+ files_dir = Path(root.__file__).resolve().parent / "files.dir"
+ handle_embedding_switch(files_dir)
+ if files_dir.exists():
+ sys.path.insert(0, os.fspath(files_dir))
+ # Note: To avoid recursion problems, we need to preload the loader.
+ # But that has the side-effect that we need to delay the feature
+ # initialization until all function pointers are set.
+ # See `post_init_func` in signature_globals.cpp .
+ import shibokensupport.signature.loader
+ del sys.path[0]
+ return files_dir
+ return None
+
+
+def handle_embedding_switch(files_dir):
+ """
+ This handles the optional environment variable `SBK_EMBED`
+ if not set : do nothing
+ if set to 0, false, no : de-virtualize the Python files
+ if set to 1, true, yes : virtualize again (delete "files.dir")
+ """
+ env_name = "SBK_EMBED"
+ env_var = os.environ.get(env_name)
+ if not env_var:
+ return
+ if env_var.lower() in ("1", "t", "true", "y", "yes"):
+ import shutil
+ shutil.rmtree(files_dir, ignore_errors=True)
+ elif env_var.lower() in ("0", "f", "false", "n", "no"):
+ reincarnate_files(files_dir)
+
+
+def reincarnate_files(files_dir):
+ target, zip = prepare_zipfile()
+ names = (_ for _ in zip.zfile.namelist() if _.endswith(".py"))
+ try:
+ # First check mkdir to get an error when we cannot write.
+ files_dir.mkdir(exist_ok=True)
+ except os.error as e:
+ print(f"SBK_EMBED=False: Warning: Cannot write into {files_dir}")
+ return None
+ try:
+ # Then check for a real error when unpacking the zip file.
+ zip.zfile.extractall(path=files_dir, members=names)
+ return files_dir
+ except Exception as e:
+ print(f"{e.__class__.__name__}: {e}", file=sys.stderr)
+ traceback.print_exc()
+ raise
# New functionality: Loading from a zip archive.
# There exists the zip importer, but as it is written, only real zip files are
diff --git a/sources/shiboken6/libshiboken/helper.cpp b/sources/shiboken6/libshiboken/helper.cpp
index 8f836316e..46af68956 100644
--- a/sources/shiboken6/libshiboken/helper.cpp
+++ b/sources/shiboken6/libshiboken/helper.cpp
@@ -5,28 +5,60 @@
#include "basewrapper_p.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
+#include "sbkstaticstrings.h"
+#include "pep384impl.h"
+
+#include <algorithm>
+#include <optional>
#include <iomanip>
#include <iostream>
-
+#include <climits>
+#include <cstring>
#include <cstdarg>
+#include <cctype>
#ifdef _WIN32
-# ifndef NOMINMAX
-# define NOMINMAX
-# endif
-# include <windows.h>
+# include <sbkwindows.h>
#else
# include <pthread.h>
#endif
-#include <algorithm>
+static std::optional<std::string> getStringAttr(PyObject *obj, const char *what)
+{
+ if (PyObject_HasAttrString(obj, what) != 0) { // Check first to suppress error.
+ Shiboken::AutoDecRef result(PyObject_GetAttrString(obj, what));
+ if (PyUnicode_Check(result.object()) != 0)
+ return _PepUnicode_AsString(result.object());
+ }
+ return std::nullopt;
+}
-static void formatPyTypeObject(const PyTypeObject *obj, std::ostream &str)
+static std::optional<int> getIntAttr(PyObject *obj, const char *what)
{
- if (obj) {
- str << '"' << obj->tp_name << "\", 0x" << std::hex
- << obj->tp_flags << std::dec;
+ if (PyObject_HasAttrString(obj, what) != 0) { // Check first to suppress error.
+ Shiboken::AutoDecRef result(PyObject_GetAttrString(obj, what));
+ if (PyLong_Check(result.object()) != 0)
+ return PyLong_AsLong(result.object());
+ }
+ return std::nullopt;
+}
+
+static bool verbose = false;
+
+static void formatTypeTuple(PyObject *t, const char *what, std::ostream &str);
+
+static void formatPyTypeObject(const PyTypeObject *obj, std::ostream &str, bool verbose)
+{
+ if (obj == nullptr) {
+ str << '0';
+ return;
+ }
+
+ str << '"' << obj->tp_name << '"';
+ if (verbose) {
+ bool immutableType = false;
+ str << ", 0x" << std::hex << obj->tp_flags << std::dec;
if (obj->tp_flags & Py_TPFLAGS_HEAPTYPE)
str << " [heaptype]";
if (obj->tp_flags & Py_TPFLAGS_BASETYPE)
@@ -49,30 +81,59 @@ static void formatPyTypeObject(const PyTypeObject *obj, std::ostream &str)
str << " [type]";
if (obj->tp_flags & Py_TPFLAGS_IS_ABSTRACT)
str << " [abstract]";
-#if PY_VERSION_HEX >= 0x03080000
+ if (obj->tp_flags & Py_TPFLAGS_READY)
+ str << " [ready]";
+ if (obj->tp_flags & Py_TPFLAGS_READYING)
+ str << " [readying]";
if (obj->tp_flags & Py_TPFLAGS_METHOD_DESCRIPTOR)
str << " [method_descriptor]";
-# if PY_VERSION_HEX >= 0x03090000
-# ifndef Py_LIMITED_API
+# ifndef Py_LIMITED_API
if (obj->tp_flags & Py_TPFLAGS_HAVE_VECTORCALL)
str << " [vectorcall]";
-# endif // !Py_LIMITED_API
-# if PY_VERSION_HEX >= 0x030A0000
- if (obj->tp_flags & Py_TPFLAGS_IMMUTABLETYPE)
+# endif // !Py_LIMITED_API
+# if PY_VERSION_HEX >= 0x030A0000
+ immutableType = (obj->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) != 0;
+ if (immutableType)
str << " [immutabletype]";
if (obj->tp_flags & Py_TPFLAGS_DISALLOW_INSTANTIATION)
str << " [disallow_instantiation]";
-# ifndef Py_LIMITED_API
+# ifndef Py_LIMITED_API
if (obj->tp_flags & Py_TPFLAGS_MAPPING)
str << " [mapping]";
if (obj->tp_flags & Py_TPFLAGS_SEQUENCE)
str << " [sequence]";
# endif // !Py_LIMITED_API
-# endif // 3.10
-# endif // 3.9
-#endif // 3.8
- } else {
- str << '0';
+# endif // 3.10
+ if (obj->tp_basicsize != 0)
+ str << ", basicsize=" << obj->tp_basicsize;
+ if (verbose) {
+ formatTypeTuple(obj->tp_bases, "bases", str);
+ formatTypeTuple(obj->tp_mro, "mro", str);
+ if (!immutableType) {
+ auto *underlying = reinterpret_cast<const PyObject *>(obj)->ob_type;
+ if (underlying != nullptr && underlying != obj) {
+ str << ", underlying=\"" << underlying->tp_name << '"';
+ }
+ }
+ }
+ }
+}
+
+static void formatTypeTuple(PyObject *t, const char *what, std::ostream &str)
+{
+ const Py_ssize_t size = t != nullptr && PyTuple_Check(t) != 0 ? PyTuple_Size(t) : 0;
+ if (size > 0) {
+ str << ", " << what << "=[" << size << "]{";
+ for (Py_ssize_t i = 0; i < size; ++i) {
+ if (i != 0)
+ str << ", ";
+ Shiboken::AutoDecRef item(PyTuple_GetItem(t, i));
+ if (item.isNull())
+ str << '0'; // Observed with non-ready types
+ else
+ str << '"' << reinterpret_cast<PyTypeObject *>(item.object())->tp_name << '"';
+ }
+ str << '}';
}
}
@@ -151,13 +212,17 @@ static void formatPyUnicode(PyObject *obj, std::ostream &str)
{
// Note: The below call create the PyCompactUnicodeObject.utf8 representation
str << '"' << _PepUnicode_AsString(obj) << '"';
+ if (!verbose)
+ return;
str << " (" << PyUnicode_GetLength(obj) << ')';
const auto kind = _PepUnicode_KIND(obj);
switch (kind) {
+#if PY_VERSION_HEX < 0x030C0000
case PepUnicode_WCHAR_KIND:
str << " [wchar]";
break;
+#endif
case PepUnicode_1BYTE_KIND:
str << " [1byte]";
break;
@@ -178,8 +243,10 @@ static void formatPyUnicode(PyObject *obj, std::ostream &str)
void *data =_PepUnicode_DATA(obj);
str << ", data=";
switch (kind) {
+#if PY_VERSION_HEX < 0x030C0000
case PepUnicode_WCHAR_KIND:
formatCharSequence(reinterpret_cast<const wchar_t *>(data), str);
+#endif
break;
case PepUnicode_1BYTE_KIND:
formatCharSequence(reinterpret_cast<const Py_UCS1 *>(data), str);
@@ -208,22 +275,92 @@ static void formatPyUnicode(PyObject *obj, std::ostream &str)
#endif // !Py_LIMITED_API
}
+static std::string getQualName(PyObject *obj)
+{
+ Shiboken::AutoDecRef result(PyObject_GetAttr(obj, Shiboken::PyMagicName::qualname()));
+ return result.object() != nullptr
+ ? _PepUnicode_AsString(result.object()) : std::string{};
+}
+
+static void formatPyFunction(PyObject *obj, std::ostream &str)
+{
+ str << '"' << getQualName(obj) << "()\"";
+}
+
+static void formatPyMethod(PyObject *obj, std::ostream &str)
+{
+ if (auto *func = PyMethod_Function(obj))
+ formatPyFunction(func, str);
+ str << ", instance=" << PyMethod_Self(obj);
+}
+
+static void formatPyCodeObject(PyObject *obj, std::ostream &str)
+{
+ if (auto name = getStringAttr(obj, "co_name"))
+ str << '"' << name.value() << '"';
+ if (auto qualName = getStringAttr(obj, "co_qualname"))
+ str << ", co_qualname=\"" << qualName.value() << '"';
+ if (auto flags = getIntAttr(obj, "co_flags"))
+ str << ", flags=0x" << std::hex << flags.value() << std::dec;
+ if (auto c = getIntAttr(obj, "co_argcount"))
+ str << ", co_argcounts=" << c.value();
+ if (auto c = getIntAttr(obj, "co_posonlyargcount"))
+ str << ", co_posonlyargcount=" << c.value();
+ if (auto c = getIntAttr(obj, "co_kwonlyargcount"))
+ str << ", co_kwonlyargcount=" << c.value();
+ if (auto fileName = getStringAttr(obj, "co_filename")) {
+ str << " @" << fileName.value();
+ if (auto l = getIntAttr(obj, "co_firstlineno"))
+ str << ':'<< l.value();
+ }
+}
+
static void formatPyObjectHelper(PyObject *obj, std::ostream &str)
{
- str << ", refs=" << obj->ob_refcnt << ", ";
+ str << ", ";
+ if (obj == Py_None) {
+ str << "None";
+ return;
+ }
+ if (obj == Py_True) {
+ str << "True";
+ return;
+ }
+ if (obj == Py_False) {
+ str << "False";
+ return;
+ }
+ const auto refs = Py_REFCNT(obj);
+ if (refs == UINT_MAX) // _Py_IMMORTAL_REFCNT
+ str << "immortal, ";
+ else
+ str << "refs=" << refs << ", ";
if (PyType_Check(obj)) {
str << "type: ";
- formatPyTypeObject(reinterpret_cast<PyTypeObject *>(obj), str);
+ formatPyTypeObject(reinterpret_cast<PyTypeObject *>(obj), str, true);
return;
}
- formatPyTypeObject(obj->ob_type, str);
+ formatPyTypeObject(obj->ob_type, str, false);
str << ", ";
- if (PyLong_Check(obj))
- str << PyLong_AsLong(obj);
+ if (PyLong_Check(obj)) {
+ const auto llv = PyLong_AsLongLong(obj);
+ if (PyErr_Occurred() != PyExc_OverflowError) {
+ str << llv;
+ } else {
+ PyErr_Clear();
+ str << "0x" << std::hex << PyLong_AsUnsignedLongLong(obj) << std::dec;
+ }
+ }
else if (PyFloat_Check(obj))
str << PyFloat_AsDouble(obj);
else if (PyUnicode_Check(obj))
formatPyUnicode(obj, str);
+ else if (PyFunction_Check(obj) != 0)
+ formatPyFunction(obj, str);
+ else if (PyMethod_Check(obj) != 0)
+ formatPyMethod(obj, str);
+ else if (PepCode_Check(obj) != 0)
+ formatPyCodeObject(obj, str);
else if (PySequence_Check(obj))
formatPySequence(obj, str);
else if (PyDict_Check(obj))
@@ -263,7 +400,7 @@ debugPyBuffer::debugPyBuffer(const Py_buffer &b) : m_buffer(b)
std::ostream &operator<<(std::ostream &str, const debugPyTypeObject &o)
{
str << "PyTypeObject(";
- formatPyTypeObject(o.m_object, str);
+ formatPyTypeObject(o.m_object, str, true);
str << ')';
return str;
}
@@ -299,6 +436,18 @@ std::ostream &operator<<(std::ostream &str, const debugPyBuffer &b)
return str;
}
+std::ios_base &debugVerbose(std::ios_base &s)
+{
+ verbose = true;
+ return s;
+}
+
+std::ios_base &debugBrief(std::ios_base &s)
+{
+ verbose = false;
+ return s;
+}
+
#ifdef _WIN32
// Converts a Unicode string to a string encoded in the Windows console's
// code page via wchar_t for use with argv (PYSIDE-1425).
@@ -442,4 +591,47 @@ ThreadId mainThreadId()
return _mainThreadId;
}
+const char *typeNameOf(const char *typeIdName)
+{
+ auto size = std::strlen(typeIdName);
+#if defined(Q_CC_MSVC) // MSVC: "class QPaintDevice * __ptr64"
+ if (auto *lastStar = strchr(typeName, '*')) {
+ // MSVC: "class QPaintDevice * __ptr64"
+ while (*--lastStar == ' ') {
+ }
+ size = lastStar - typeName + 1;
+ }
+#else // g++, Clang: "QPaintDevice *" -> "P12QPaintDevice"
+ if (size > 2 && typeIdName[0] == 'P' && std::isdigit(typeIdName[1])) {
+ ++typeIdName;
+ --size;
+ }
+#endif
+ char *result = new char[size + 1];
+ result[size] = '\0';
+ std::memcpy(result, typeIdName, size);
+ return result;
+}
+
+#if !defined(Py_LIMITED_API) && PY_VERSION_HEX >= 0x030A0000 && !defined(PYPY_VERSION)
+static int _getPyVerbose()
+{
+ PyConfig config;
+ PyConfig_InitPythonConfig(&config);
+ return config.verbose;
+}
+#endif // !Py_LIMITED_API >= 3.10
+
+int pyVerbose()
+{
+#ifdef Py_LIMITED_API
+ return Pep_GetVerboseFlag();
+#elif PY_VERSION_HEX >= 0x030A0000 && !defined(PYPY_VERSION)
+ static const int result = _getPyVerbose();
+ return result;
+#else
+ return Py_VerboseFlag;
+#endif
+}
+
} // namespace Shiboken
diff --git a/sources/shiboken6/libshiboken/helper.h b/sources/shiboken6/libshiboken/helper.h
index 265bb6581..f226e8c24 100644
--- a/sources/shiboken6/libshiboken/helper.h
+++ b/sources/shiboken6/libshiboken/helper.h
@@ -36,6 +36,10 @@ LIBSHIBOKEN_API bool listToArgcArgv(PyObject *argList, int *argc, char ***argv,
*/
LIBSHIBOKEN_API int *sequenceToIntArray(PyObject *obj, bool zeroTerminated = false);
+/// Fix a type name returned by typeid(t).name(), depending on compiler.
+/// \returns Fixed name (allocated).
+LIBSHIBOKEN_API const char *typeNameOf(const char *typeIdName);
+
/**
* Creates and automatically deallocates C++ arrays.
*/
@@ -61,6 +65,8 @@ using ThreadId = unsigned long long;
LIBSHIBOKEN_API ThreadId currentThreadId();
LIBSHIBOKEN_API ThreadId mainThreadId();
+LIBSHIBOKEN_API int pyVerbose();
+
/**
* An utility function used to call PyErr_WarnEx with a formatted message.
*/
@@ -106,7 +112,8 @@ LIBSHIBOKEN_API std::ostream &operator<<(std::ostream &str, const debugSbkObject
LIBSHIBOKEN_API std::ostream &operator<<(std::ostream &str, const debugPyTypeObject &o);
LIBSHIBOKEN_API std::ostream &operator<<(std::ostream &str, const debugPyBuffer &b);
LIBSHIBOKEN_API std::ostream &operator<<(std::ostream &str, const debugPyArrayObject &b);
-
+LIBSHIBOKEN_API std::ios_base &debugVerbose(std::ios_base &s);
+LIBSHIBOKEN_API std::ios_base &debugBrief(std::ios_base &s);
} // namespace Shiboken
diff --git a/sources/shiboken6/libshiboken/pep384_issue33738.cpp b/sources/shiboken6/libshiboken/pep384_issue33738.cpp
deleted file mode 100644
index 7f3872a58..000000000
--- a/sources/shiboken6/libshiboken/pep384_issue33738.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-// There is a bug in Python 3.6 that turned the Index_Check function
-// into a macro without taking care of the limited API.
-// This leads to the single problem that we don't have
-// access to PyLong_Type's nb_index field which is no heap type.
-// We cannot easily create this function by inheritance since it is
-// not inherited.
-//
-// Simple solution: Create the structure and write such a function.
-// Long term: Submit a patch to python.org .
-
-// This structure comes from Python 3.7, but we have checked that
-// it also works for Python 3.8 and 3.9.
-
-typedef struct {
- /* Number implementations must check *both*
- arguments for proper type and implement the necessary conversions
- in the slot functions themselves. */
-
- binaryfunc nb_add;
- binaryfunc nb_subtract;
- binaryfunc nb_multiply;
- binaryfunc nb_remainder;
- binaryfunc nb_divmod;
- ternaryfunc nb_power;
- unaryfunc nb_negative;
- unaryfunc nb_positive;
- unaryfunc nb_absolute;
- inquiry nb_bool;
- unaryfunc nb_invert;
- binaryfunc nb_lshift;
- binaryfunc nb_rshift;
- binaryfunc nb_and;
- binaryfunc nb_xor;
- binaryfunc nb_or;
- unaryfunc nb_int;
- void *nb_reserved; /* the slot formerly known as nb_long */
- unaryfunc nb_float;
-
- binaryfunc nb_inplace_add;
- binaryfunc nb_inplace_subtract;
- binaryfunc nb_inplace_multiply;
- binaryfunc nb_inplace_remainder;
- ternaryfunc nb_inplace_power;
- binaryfunc nb_inplace_lshift;
- binaryfunc nb_inplace_rshift;
- binaryfunc nb_inplace_and;
- binaryfunc nb_inplace_xor;
- binaryfunc nb_inplace_or;
-
- binaryfunc nb_floor_divide;
- binaryfunc nb_true_divide;
- binaryfunc nb_inplace_floor_divide;
- binaryfunc nb_inplace_true_divide;
-
- unaryfunc nb_index;
-
- binaryfunc nb_matrix_multiply;
- binaryfunc nb_inplace_matrix_multiply;
-} PyNumberMethods;
-
-// temporary structure until we have a generator for the offsets
-typedef struct _oldtypeobject {
- PyVarObject ob_base;
- void *X01; // const char *tp_name;
- void *X02; // Py_ssize_t tp_basicsize;
- void *X03; // Py_ssize_t tp_itemsize;
- void *X04; // destructor tp_dealloc;
- void *X05; // printfunc tp_print;
- void *X06; // getattrfunc tp_getattr;
- void *X07; // setattrfunc tp_setattr;
- void *X08; // PyAsyncMethods *tp_as_async;
- void *X09; // reprfunc tp_repr;
- PyNumberMethods *tp_as_number;
-
-} PyOldTypeObject;
-
-static bool is_compatible_version()
-{
- auto *sysmodule = PyImport_AddModule("sys");
- auto *dic = PyModule_GetDict(sysmodule);
- auto *version = PyDict_GetItemString(dic, "version_info");
- auto *major = PyTuple_GetItem(version, 0);
- auto *minor = PyTuple_GetItem(version, 1);
- auto number = PyLong_AsLong(major) * 1000 + PyLong_AsLong(minor);
- return number < 3010;
-}
-
-///////////////////////////////////////////////////////////////////////
-//
-// PYSIE-1797: The Solution
-// ========================
-//
-// Inspecting the data structures of Python 3.6, 3.7, 3.8 and 3.9
-// shows that concerning the here needed offset of nb_index, they
-// are all compatible.
-// That means: We can use the above definition for all these versions.
-//
-// From Python 3.10 on, the `PyType_GetSlot` function also works with
-// non-heap types. That means this solution will always work.
-//
-// Note: When we have moved to Python 3.8 as the minimum version,
-// this whole nonsense can be trashed.
-// There is an automatic warning about this in parser.py .
-//
-
-LIBSHIBOKEN_API int PepIndex_Check(PyObject *obj)
-{
- static bool old_python_version = is_compatible_version();
- if (old_python_version) {
- auto *type = reinterpret_cast<PyOldTypeObject *>(Py_TYPE(obj));
- return type->tp_as_number != nullptr &&
- type->tp_as_number->nb_index != nullptr;
- }
- // From Python 3.10 on, we can use PyType_GetSlot also with normal types!
- unaryfunc nb_index = reinterpret_cast<unaryfunc>(PyType_GetSlot(Py_TYPE(obj), Py_nb_index));
- return nb_index != nullptr;
-}
-
diff --git a/sources/shiboken6/libshiboken/pep384ext.h b/sources/shiboken6/libshiboken/pep384ext.h
new file mode 100644
index 000000000..021c53d16
--- /dev/null
+++ b/sources/shiboken6/libshiboken/pep384ext.h
@@ -0,0 +1,89 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PEP384EXT_H
+#define PEP384EXT_H
+
+#include "pep384impl.h"
+
+/// Returns the allocator slot of the PyTypeObject.
+inline allocfunc PepExt_Type_GetAllocSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<allocfunc>(PepType_GetSlot(t, Py_tp_alloc));
+}
+
+/// Invokes the allocator slot of the PyTypeObject.
+template <class Type>
+inline Type *PepExt_TypeCallAlloc(PyTypeObject *t, Py_ssize_t nitems)
+{
+ PyObject *result = PepExt_Type_GetAllocSlot(t)(t, nitems);
+ return reinterpret_cast<Type *>(result);
+}
+
+/// Returns the getattro slot of the PyTypeObject.
+inline getattrofunc PepExt_Type_GetGetAttroSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<getattrofunc>(PepType_GetSlot(t, Py_tp_getattro));
+}
+
+/// Returns the setattro slot of the PyTypeObject.
+inline setattrofunc PepExt_Type_GetSetAttroSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<setattrofunc>(PepType_GetSlot(t, Py_tp_setattro));
+}
+
+/// Returns the descr_get slot of the PyTypeObject.
+inline descrgetfunc PepExt_Type_GetDescrGetSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<descrgetfunc>(PepType_GetSlot(t, Py_tp_descr_get));
+}
+
+/// Invokes the descr_get slot of the PyTypeObject.
+inline PyObject *PepExt_Type_CallDescrGet(PyObject *self, PyObject *obj, PyObject *type)
+{
+ return PepExt_Type_GetDescrGetSlot(Py_TYPE(self))(self, obj, type);
+}
+
+/// Returns the descr_set slot of the PyTypeObject.
+inline descrsetfunc PepExt_Type_GetDescrSetSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<descrsetfunc>(PepType_GetSlot(t, Py_tp_descr_set));
+}
+
+/// Returns the call slot of the PyTypeObject.
+inline ternaryfunc PepExt_Type_GetCallSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<ternaryfunc>(PepType_GetSlot(t, Py_tp_call));
+}
+
+/// Returns the new slot of the PyTypeObject.
+inline newfunc PepExt_Type_GetNewSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<newfunc>(PepType_GetSlot(t, Py_tp_new));
+}
+
+/// Returns the init slot of the PyTypeObject.
+inline initproc PepExt_Type_GetInitSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<initproc>(PepType_GetSlot(t, Py_tp_init));
+}
+
+/// Returns the free slot of the PyTypeObject.
+inline freefunc PepExt_Type_GetFreeSlot(PyTypeObject *t)
+{
+ return reinterpret_cast<freefunc>(PepType_GetSlot(t, Py_tp_free));
+}
+
+/// Invokes the free slot of the PyTypeObject.
+inline void PepExt_TypeCallFree(PyTypeObject *t, void *object)
+{
+ PepExt_Type_GetFreeSlot(t)(object);
+}
+
+/// Invokes the free slot of the PyTypeObject.
+inline void PepExt_TypeCallFree(PyObject *object)
+{
+ PepExt_Type_GetFreeSlot(Py_TYPE(object))(object);
+}
+
+#endif // PEP384EXT_H
diff --git a/sources/shiboken6/libshiboken/pep384impl.cpp b/sources/shiboken6/libshiboken/pep384impl.cpp
index 3a9a60f74..5310207a3 100644
--- a/sources/shiboken6/libshiboken/pep384impl.cpp
+++ b/sources/shiboken6/libshiboken/pep384impl.cpp
@@ -1,6 +1,8 @@
-// Copyright (C) 2018 The Qt Company Ltd.
+// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+#define PEP384_INTERN
+
#include "sbkpython.h"
#include "autodecref.h"
#include "sbkstaticstrings.h"
@@ -8,8 +10,6 @@
#include "basewrapper.h"
#include "basewrapper_p.h"
#include "sbkenum.h"
-#include "sbkenum_p.h"
-#include "sbkconverter.h"
#include "voidptr.h"
#include <cstdlib>
@@ -19,7 +19,7 @@ extern "C"
{
/*
- * The documentation is located in pep384impl_doc.rst
+ * The documentation is located in `sources/pyside6/doc/developer/limited_api.rst`.
* Here is the verification code for PyTypeObject.
* We create a type object and check if its fields
@@ -105,18 +105,20 @@ static PyType_Spec typeprobe_spec = {
static void
check_PyTypeObject_valid()
{
- auto *obtype = reinterpret_cast<PyObject *>(&PyType_Type);
- auto *probe_tp_base = reinterpret_cast<PyTypeObject *>(
- PyObject_GetAttr(obtype, Shiboken::PyMagicName::base()));
+ auto *typetype = &PyType_Type;
+ auto *obtype = reinterpret_cast<PyObject *>(typetype);
+ auto *probe_tp_base_obj = PyObject_GetAttr(obtype, Shiboken::PyMagicName::base());
+ auto *probe_tp_base = reinterpret_cast<PyTypeObject *>(probe_tp_base_obj);
auto *probe_tp_bases = PyObject_GetAttr(obtype, Shiboken::PyMagicName::bases());
- auto *check = reinterpret_cast<PyTypeObject *>(
- PyType_FromSpecWithBases(&typeprobe_spec, probe_tp_bases));
- auto *typetype = reinterpret_cast<PyTypeObject *>(obtype);
+ auto *checkObj = PyType_FromSpecWithBases(&typeprobe_spec, probe_tp_bases);
+ auto *check = reinterpret_cast<PyTypeObject *>(checkObj);
PyObject *w = PyObject_GetAttr(obtype, Shiboken::PyMagicName::weakrefoffset());
long probe_tp_weakrefoffset = PyLong_AsLong(w);
PyObject *d = PyObject_GetAttr(obtype, Shiboken::PyMagicName::dictoffset());
long probe_tp_dictoffset = PyLong_AsLong(d);
PyObject *probe_tp_mro = PyObject_GetAttr(obtype, Shiboken::PyMagicName::mro());
+ Shiboken::AutoDecRef tpDict(PepType_GetDict(check));
+ auto *checkDict = tpDict.object();
if (false
|| strcmp(probe_tp_name, check->tp_name) != 0
|| probe_tp_basicsize != check->tp_basicsize
@@ -133,8 +135,8 @@ check_PyTypeObject_valid()
|| probe_tp_methods != check->tp_methods
|| probe_tp_getset != check->tp_getset
|| probe_tp_base != typetype->tp_base
- || !PyDict_Check(check->tp_dict)
- || !PyDict_GetItemString(check->tp_dict, "dummy")
+ || !PyDict_Check(checkDict)
+ || !PyDict_GetItemString(checkDict, "dummy")
|| probe_tp_descr_get != check->tp_descr_get
|| probe_tp_descr_set != check->tp_descr_set
|| probe_tp_dictoffset != typetype->tp_dictoffset
@@ -147,17 +149,14 @@ check_PyTypeObject_valid()
|| probe_tp_mro != typetype->tp_mro
|| Py_TPFLAGS_DEFAULT != (check->tp_flags & Py_TPFLAGS_DEFAULT))
Py_FatalError("The structure of type objects has changed!");
- Py_DECREF(check);
- Py_DECREF(probe_tp_base);
+ Py_DECREF(checkObj);
+ Py_DECREF(probe_tp_base_obj);
Py_DECREF(w);
Py_DECREF(d);
Py_DECREF(probe_tp_bases);
Py_DECREF(probe_tp_mro);
}
-// PYSIDE-1797: This must be a runtime decision.
-#include "pep384_issue33738.cpp"
-
#endif // Py_LIMITED_API
/*****************************************************************************
@@ -179,7 +178,7 @@ static PyObject *
find_name_in_mro(PyTypeObject *type, PyObject *name, int *error)
{
Py_ssize_t i, n;
- PyObject *mro, *res, *base, *dict;
+ PyObject *mro, *res, *base;
/* Look in tp_dict of types in MRO */
mro = type->tp_mro;
@@ -193,9 +192,10 @@ find_name_in_mro(PyTypeObject *type, PyObject *name, int *error)
for (i = 0; i < n; i++) {
base = PyTuple_GET_ITEM(mro, i);
assert(PyType_Check(base));
- dict = ((PyTypeObject *)base)->tp_dict;
- assert(dict && PyDict_Check(dict));
- res = PyDict_GetItem(dict, name);
+ auto *type = reinterpret_cast<PyTypeObject *>(base);
+ Shiboken::AutoDecRef dict(PepType_GetDict(type));
+ assert(!dict.isNull() && PyDict_Check(dict.object()));
+ res = PyDict_GetItem(dict.object(), name);
if (res != nullptr)
break;
if (PyErr_Occurred()) {
@@ -251,7 +251,7 @@ _PepType_Lookup(PyTypeObject *type, PyObject *name)
// structs and macros modelled after their equivalents in
// cpython/Include/cpython/unicodeobject.h
-struct PepASCIIObject
+struct PepASCIIObject // since 3.12
{
PyObject_HEAD
Py_ssize_t length; /* Number of code points in the string */
@@ -264,18 +264,29 @@ struct PepASCIIObject
unsigned int ready:1;
unsigned int :24;
} state;
+};
+
+struct PepASCIIObject_311 : public PepASCIIObject
+{
wchar_t *wstr; /* wchar_t representation (null-terminated) */
};
-struct PepCompactUnicodeObject
+struct PepCompactUnicodeObject // since 3.12
{
PepASCIIObject _base;
Py_ssize_t utf8_length;
char *utf8; /* UTF-8 representation (null-terminated) */
+};
+
+struct PepCompactUnicodeObject_311 // since 3.12
+{
+ PepASCIIObject_311 _base;
+ Py_ssize_t utf8_length;
+ char *utf8; /* UTF-8 representation (null-terminated) */
Py_ssize_t wstr_length; /* Number of code points in wstr */
};
-struct PepUnicodeObject
+struct PepUnicodeObject // since 3.12
{
PepCompactUnicodeObject _base;
union {
@@ -286,6 +297,17 @@ struct PepUnicodeObject
} data; /* Canonical, smallest-form Unicode buffer */
};
+struct PepUnicodeObject_311
+{
+ PepCompactUnicodeObject_311 _base;
+ union {
+ void *any;
+ Py_UCS1 *latin1;
+ Py_UCS2 *ucs2;
+ Py_UCS4 *ucs4;
+ } data; /* Canonical, smallest-form Unicode buffer */
+};
+
int _PepUnicode_KIND(PyObject *str)
{
return reinterpret_cast<PepASCIIObject *>(str)->state.kind;
@@ -303,18 +325,33 @@ int _PepUnicode_IS_COMPACT(PyObject *str)
return asciiObj->state.compact;
}
-static void *_PepUnicode_COMPACT_DATA(PyObject *str)
+static void *_PepUnicode_ASCII_DATA(PyObject *str)
{
+ if (_PepRuntimeVersion() < 0x030C00) {
+ auto *asciiObj_311 = reinterpret_cast<PepASCIIObject_311 *>(str);
+ return asciiObj_311 + 1;
+ }
auto *asciiObj = reinterpret_cast<PepASCIIObject *>(str);
- if (asciiObj->state.ascii)
- return asciiObj + 1;
+ return asciiObj + 1;
+}
+
+static void *_PepUnicode_COMPACT_DATA(PyObject *str)
+{
+ if (_PepUnicode_IS_ASCII(str) != 0)
+ return _PepUnicode_ASCII_DATA(str);
+ if (_PepRuntimeVersion() < 0x030C00) {
+ auto *compactObj_311 = reinterpret_cast<PepCompactUnicodeObject_311 *>(str);
+ return compactObj_311 + 1;
+ }
auto *compactObj = reinterpret_cast<PepCompactUnicodeObject *>(str);
return compactObj + 1;
}
static void *_PepUnicode_NONCOMPACT_DATA(PyObject *str)
{
- return reinterpret_cast<PepUnicodeObject *>(str)->data.any;
+ return _PepRuntimeVersion() < 0x030C00
+ ? reinterpret_cast<PepUnicodeObject_311 *>(str)->data.any
+ : reinterpret_cast<PepUnicodeObject *>(str)->data.any;
}
void *_PepUnicode_DATA(PyObject *str)
@@ -325,6 +362,23 @@ void *_PepUnicode_DATA(PyObject *str)
// Fast path accessing UTF8 data without doing a conversion similar
// to _PyUnicode_AsUTF8String
+static const char *utf8FastPath_311(PyObject *str)
+{
+ if (PyUnicode_GetLength(str) == 0)
+ return "";
+ auto *asciiObj = reinterpret_cast<PepASCIIObject_311 *>(str);
+ if (asciiObj->state.kind != PepUnicode_1BYTE_KIND || asciiObj->state.compact == 0)
+ return nullptr; // Empirical: PyCompactUnicodeObject.utf8 is only valid for 1 byte
+ if (asciiObj->state.ascii) {
+ auto *data = asciiObj + 1;
+ return reinterpret_cast<const char *>(data);
+ }
+ auto *compactObj = reinterpret_cast<PepCompactUnicodeObject_311 *>(str);
+ if (compactObj->utf8_length)
+ return compactObj->utf8;
+ return nullptr;
+}
+
static const char *utf8FastPath(PyObject *str)
{
if (PyUnicode_GetLength(str) == 0)
@@ -356,8 +410,10 @@ const char *_PepUnicode_AsString(PyObject *str)
#define TOSTRING(x) STRINGIFY(x)
#define AT __FILE__ ":" TOSTRING(__LINE__)
- if (const auto *utf8 = utf8FastPath(str))
+ if (const auto *utf8 = _PepRuntimeVersion() < 0x030C00
+ ? utf8FastPath_311(str) : utf8FastPath(str)) {
return utf8;
+ }
static PyObject *cstring_dict = nullptr;
if (cstring_dict == nullptr) {
@@ -426,6 +482,47 @@ Pep_GetVerboseFlag()
}
#endif // Py_LIMITED_API
+// Support for pyerrors.h
+
+#if defined(Py_LIMITED_API) || PY_VERSION_HEX < 0x030C0000
+// Emulate PyErr_GetRaisedException() using the deprecated PyErr_Fetch()/PyErr_Store()
+PyObject *PepErr_GetRaisedException()
+{
+ PyObject *type{};
+ PyObject *value{};
+ PyObject *traceback{};
+ PyErr_Fetch(&type, &value, &traceback);
+ Py_XINCREF(value);
+ PyErr_Restore(type, value, traceback);
+ return value;
+}
+
+struct PepException_HEAD
+{
+ PyObject_HEAD
+ PyObject *x1; // dict
+ PyObject *args;
+};
+
+// PyException_GetArgs/PyException_SetArgs were added to the stable API in 3.12
+PyObject *PepException_GetArgs(PyObject *ex)
+{
+ auto *h = reinterpret_cast<PepException_HEAD *>(ex);
+ Py_XINCREF(h->args);
+ return h->args;
+}
+
+LIBSHIBOKEN_API void PepException_SetArgs(PyObject *ex, PyObject *args)
+{
+ auto *h = reinterpret_cast<PepException_HEAD *>(ex);
+ Py_XINCREF(args);
+ auto *old = h->args; // Py_XSETREF()
+ h->args = args;
+ Py_XDECREF(old);
+
+}
+#endif // Limited or < 3.12
+
/*****************************************************************************
*
* Support for code.h
@@ -448,8 +545,24 @@ PepCode_Get(PepCodeObject *co, const char *name)
}
return ret;
}
+
+int PepCode_Check(PyObject *o)
+{
+ return o != nullptr && std::strcmp(Py_TYPE(o)->tp_name, "code") == 0 ? 1 : 0;
+}
+
#endif // Py_LIMITED_API
+#if defined(Py_LIMITED_API) || defined(PYPY_VERSION)
+PyObject *PepFunction_GetDefaults(PyObject *function)
+{
+ auto *ob_ret = PyObject_GetAttrString(function, "__defaults__");
+ Py_XDECREF(ob_ret); // returns borrowed ref
+ return ob_ret != Py_None ? ob_ret : nullptr;
+}
+
+#endif // defined(Py_LIMITED_API) || defined(PYPY_VERSION)
+
/*****************************************************************************
*
* Support for datetime.h
@@ -650,11 +763,8 @@ PyTypeObject *PepStaticMethod_TypePtr = nullptr;
static PyTypeObject *
getStaticMethodType(void)
{
- // this works for Python 3, only
- // "StaticMethodType = type(str.__dict__['maketrans'])\n";
static const char prog[] =
- "from xxsubtype import spamlist\n"
- "result = type(spamlist.__dict__['staticmeth'])\n";
+ "result = type(str.__dict__['maketrans'])\n";
return reinterpret_cast<PyTypeObject *>(PepRun_GetResult(prog));
}
@@ -719,12 +829,37 @@ PepType_GetNameStr(PyTypeObject *type)
return ret;
}
+// PYSIDE-2264: Find the _functools or functools module and retrieve the
+// partial function. This can be tampered with, check carefully.
+PyObject *
+Pep_GetPartialFunction(void)
+{
+ static bool initialized = false;
+ static PyObject *result{};
+ if (initialized) {
+ Py_INCREF(result);
+ return result;
+ }
+ auto *functools = PyImport_ImportModule("_functools");
+ if (!functools) {
+ PyErr_Clear();
+ functools = PyImport_ImportModule("functools");
+ }
+ if (!functools)
+ Py_FatalError("functools cannot be found");
+ result = PyObject_GetAttrString(functools, "partial");
+ if (!result || !PyCallable_Check(result))
+ Py_FatalError("partial not found or not a function");
+ initialized = true;
+ return result;
+}
+
/*****************************************************************************
*
* Newly introduced convenience functions
*
*/
-#if PY_VERSION_HEX < 0x03070000 || defined(Py_LIMITED_API)
+#ifdef Py_LIMITED_API
PyObject *
PyImport_GetModule(PyObject *name)
@@ -750,7 +885,7 @@ PyImport_GetModule(PyObject *name)
return m;
}
-#endif // PY_VERSION_HEX < 0x03070000 || defined(Py_LIMITED_API)
+#endif // Py_LIMITED_API
// 2020-06-16: For simplicity of creating arbitrary things, this function
// is now made public.
@@ -841,13 +976,13 @@ _Pep_PrivateMangle(PyObject *self, PyObject *name)
wchar_t bigbuf[big_stack];
wchar_t *resbuf = amount <= big_stack ? bigbuf : (wchar_t *)malloc(sizeof(wchar_t) * amount);
if (!resbuf)
- return 0;
+ return nullptr;
/* ident = "_" + priv[ipriv:] + ident # i.e. 1+plen+nlen bytes */
resbuf[0] = '_';
if (PyUnicode_AsWideChar(privateobj, resbuf + 1, ipriv + plen) < 0)
- return 0;
+ return nullptr;
if (PyUnicode_AsWideChar(name, resbuf + ipriv + plen + 1, nlen) < 0)
- return 0;
+ return nullptr;
PyObject *result = PyUnicode_FromWideChar(resbuf + ipriv, 1 + plen + nlen);
if (amount > big_stack)
free(resbuf);
@@ -873,6 +1008,21 @@ init_PepRuntime()
PepRuntime_38_flag = 1;
}
+static long _GetPepRuntimeVersion()
+{
+ auto *version = PySys_GetObject("version_info");
+ const auto major = PyLong_AsLong(PyTuple_GetItem(version, 0));
+ const auto minor = PyLong_AsLong(PyTuple_GetItem(version, 1));
+ const auto micro = PyLong_AsLong(PyTuple_GetItem(version, 2));
+ return major << 16 | minor << 8 | micro;
+}
+
+long _PepRuntimeVersion()
+{
+ static const auto number = _GetPepRuntimeVersion();
+ return number;
+}
+
/*****************************************************************************
*
* PYSIDE-535: Support for PyPy
@@ -882,33 +1032,108 @@ init_PepRuntime()
*
*/
+///////////////////////////////////////////////////////////////////////
+//
+// PEP 697: Support for embedded type structures.
+//
+// According to `https://docs.python.org/3/c-api/object.html?highlight=pyobject_gettypedata#c.PyObject_GetTypeData`
+// the function `PyObject_GetTypeData` should belong to the Stable API
+// since version 3.12.0, but it does not. We use instead some copies
+// from Python source code.
+
+#if !defined(Py_LIMITED_API) && PY_VERSION_HEX >= 0x030C0000
+
+# define PepObject_GetTypeData PyObject_GetTypeData
+
+SbkObjectTypePrivate *PepType_SOTP(PyTypeObject *type)
+{
+ // PYSIDE-2676: Use the meta type explicitly.
+ // A derived type would fail the offset calculation.
+ static auto *meta = SbkObjectType_TypeF();
+ assert(SbkObjectType_Check(type));
+ auto *obType = reinterpret_cast<PyObject *>(type);
+ void *data = PyObject_GetTypeData(obType, meta);
+ return reinterpret_cast<SbkObjectTypePrivate *>(data);
+}
+
+void PepType_SOTP_delete(PyTypeObject * /*type*/)
+{
+}
+
+#else
+
+// The following comments are directly copied from Python 3.12
+//
+
+// Make sure we have maximum alignment, even if the current compiler
+// does not support max_align_t. Note that:
+// - Autoconf reports alignment of unknown types to 0.
+// - 'long double' has maximum alignment on *most* platforms,
+// looks like the best we can do for pre-C11 compilers.
+// - The value is tested, see test_alignof_max_align_t
+# if !defined(ALIGNOF_MAX_ALIGN_T) || ALIGNOF_MAX_ALIGN_T == 0
+# undef ALIGNOF_MAX_ALIGN_T
+# define ALIGNOF_MAX_ALIGN_T alignof(long double)
+# endif
+
+/* Align up to the nearest multiple of alignof(max_align_t)
+ * (like _Py_ALIGN_UP, but for a size rather than pointer)
+ */
+static Py_ssize_t _align_up(Py_ssize_t size)
+{
+ return (size + ALIGNOF_MAX_ALIGN_T - 1) & ~(ALIGNOF_MAX_ALIGN_T - 1);
+}
+
+static void *PepObject_GetTypeData(PyObject *obj, PyTypeObject *cls)
+{
+ assert(PyObject_TypeCheck(obj, cls));
+ return reinterpret_cast<char *>(obj) + _align_up(cls->tp_base->tp_basicsize);
+}
+//
+///////////////////////////////////////////////////////////////////////
+
/*
* PyTypeObject extender
*/
+
static std::unordered_map<PyTypeObject *, SbkObjectTypePrivate > SOTP_extender{};
static thread_local PyTypeObject *SOTP_key{};
static thread_local SbkObjectTypePrivate *SOTP_value{};
-SbkObjectTypePrivate *PepType_SOTP(PyTypeObject *sbkType)
+SbkObjectTypePrivate *PepType_SOTP(PyTypeObject *type)
{
- if (sbkType == SOTP_key)
+ static auto *meta = SbkObjectType_TypeF();
+ static bool use_312 = _PepRuntimeVersion() >= 0x030C00;
+ assert(SbkObjectType_Check(type));
+ if (use_312) {
+ auto *obType = reinterpret_cast<PyObject *>(type);
+ void *data = PepObject_GetTypeData(obType, meta);
+ return reinterpret_cast<SbkObjectTypePrivate *>(data);
+ }
+ if (type == SOTP_key)
return SOTP_value;
- auto it = SOTP_extender.find(sbkType);
+ auto it = SOTP_extender.find(type);
if (it == SOTP_extender.end()) {
- it = SOTP_extender.insert({sbkType, {}}).first;
+ it = SOTP_extender.insert({type, {}}).first;
memset(&it->second, 0, sizeof(SbkObjectTypePrivate));
}
- SOTP_key = sbkType;
+ SOTP_key = type;
SOTP_value = &it->second;
return SOTP_value;
}
-void PepType_SOTP_delete(PyTypeObject *sbkType)
+void PepType_SOTP_delete(PyTypeObject *type)
{
- SOTP_extender.erase(sbkType);
+ static bool use_312 = _PepRuntimeVersion() >= 0x030C00;
+ assert(SbkObjectType_Check(type));
+ if (use_312)
+ return;
+ SOTP_extender.erase(type);
SOTP_key = nullptr;
}
+#endif // !defined(Py_LIMITED_API) && PY_VERSION_HEX >= 0x030C0000
+
/*
* SbkEnumType extender
*/
@@ -918,6 +1143,7 @@ static thread_local SbkEnumTypePrivate *SETP_value{};
SbkEnumTypePrivate *PepType_SETP(SbkEnumType *enumType)
{
+ // PYSIDE-2230: This makes no sense at all for Enum types.
if (enumType == SETP_key)
return SETP_value;
auto it = SETP_extender.find(enumType);
@@ -936,38 +1162,76 @@ void PepType_SETP_delete(SbkEnumType *enumType)
SETP_key = nullptr;
}
-/*
- * PySideQFlagsType extender
- */
-static std::unordered_map<PySideQFlagsType *, PySideQFlagsTypePrivate> PFTP_extender{};
-static thread_local PySideQFlagsType *PFTP_key{};
-static thread_local PySideQFlagsTypePrivate *PFTP_value{};
-
-PySideQFlagsTypePrivate *PepType_PFTP(PySideQFlagsType *flagsType)
-{
- static PyTypeObject *enumMeta = getPyEnumMeta();
- auto *mappedType = reinterpret_cast<PyTypeObject *>(flagsType);
- auto *metaType = Py_TYPE(mappedType);
- if (metaType == enumMeta) {
- return reinterpret_cast<PySideQFlagsTypePrivate *>(
- PepType_SETP(reinterpret_cast<SbkEnumType *>(flagsType)));
- }
- if (flagsType == PFTP_key)
- return PFTP_value;
- auto it = PFTP_extender.find(flagsType);
- if (it == PFTP_extender.end()) {
- it = PFTP_extender.insert({flagsType, {}}).first;
- memset(&it->second, 0, sizeof(PySideQFlagsTypePrivate));
+#ifdef Py_LIMITED_API
+static PyObject *emulatePyType_GetDict(PyTypeObject *type)
+{
+ if (_PepRuntimeVersion() < 0x030C00 || type->tp_dict) {
+ auto *res = type->tp_dict;
+ Py_XINCREF(res);
+ return res;
}
- PFTP_key = flagsType;
- PFTP_value = &it->second;
- return PFTP_value;
+ // PYSIDE-2230: Here we are really cheating. We don't know how to
+ // access an internal dict, and so we simply pretend
+ // it were an empty dict. This works great for our types.
+ // This was an unexpectedly simple solution :D
+ return PyDict_New();
}
+#endif
-void PepType_PFTP_delete(PySideQFlagsType *flagsType)
+// PyType_GetDict: replacement for <static type>.tp_dict, which is
+// zero for builtin types since 3.12.
+PyObject *PepType_GetDict(PyTypeObject *type)
{
- PFTP_extender.erase(flagsType);
- PFTP_key = nullptr;
+#if !defined(Py_LIMITED_API)
+# if PY_VERSION_HEX >= 0x030C0000
+ return PyType_GetDict(type);
+# else
+ // pre 3.12 fallback code, mimicking the addref-behavior.
+ Py_XINCREF(type->tp_dict);
+ return type->tp_dict;
+# endif
+#else
+ return emulatePyType_GetDict(type);
+#endif // Py_LIMITED_API
+}
+
+int PepType_SetDict(PyTypeObject *type, PyObject *dict)
+{
+ type->tp_dict = dict;
+ return 0;
+}
+
+// Pre 3.10, PyType_GetSlot() would only work for heap types.
+// FIXME: PyType_GetSlot() can be used unconditionally when the
+// minimum limited API version is >= 3.10.
+void *PepType_GetSlot(PyTypeObject *type, int aSlot)
+{
+ static const bool is310 = _PepRuntimeVersion() >= 0x030A00;
+ if (is310 || (type->tp_flags & Py_TPFLAGS_HEAPTYPE) != 0)
+ return PyType_GetSlot(type, aSlot);
+
+ switch (aSlot) {
+ case Py_tp_alloc:
+ return reinterpret_cast<void *>(type->tp_alloc);
+ case Py_tp_getattro:
+ return reinterpret_cast<void *>(type->tp_getattro);
+ case Py_tp_setattro:
+ return reinterpret_cast<void *>(type->tp_setattro);
+ case Py_tp_descr_get:
+ return reinterpret_cast<void *>(type->tp_descr_get);
+ case Py_tp_descr_set:
+ return reinterpret_cast<void *>(type->tp_descr_set);
+ case Py_tp_call:
+ return reinterpret_cast<void *>(type->tp_call);
+ case Py_tp_new:
+ return reinterpret_cast<void *>(type->tp_new);
+ case Py_tp_init:
+ return reinterpret_cast<void *>(type->tp_init);
+ case Py_tp_free:
+ return reinterpret_cast<void *>(type->tp_free);
+ }
+ assert(false);
+ return nullptr;
}
/***************************************************************************
@@ -1001,16 +1265,16 @@ static inline void *PepType_ExTP(PyTypeObject *type, size_t size)
static PyTypeObject *alias{};
const char *kind = size == sizeof(SbkObjectTypePrivate) ? "SOTP" :
size == sizeof(SbkEnumTypePrivate) ? "SETP" :
- size == sizeof(PySideQFlagsTypePrivate) ? "PFTP" :
+ size == sizeof(SbkQFlagsTypePrivate) ? "PFTP" :
"unk.";
fprintf(stderr, "%s:%d %p x %s s=%ld\n", __func__, __LINE__, type, kind, size);
PyObject *kill{};
if (strlen(env_p) > 0) {
- if (size == sizeof(PySideQFlagsTypePrivate)) {
+ if (size == sizeof(SbkQFlagsTypePrivate)) {
if (alias == nullptr)
alias = type;
}
- if (size != sizeof(PySideQFlagsTypePrivate)) {
+ if (size != sizeof(SbkQFlagsTypePrivate)) {
if (type == alias)
Py_INCREF(kill);
}
diff --git a/sources/shiboken6/libshiboken/pep384impl.h b/sources/shiboken6/libshiboken/pep384impl.h
index 07cdb3a6f..7188366e2 100644
--- a/sources/shiboken6/libshiboken/pep384impl.h
+++ b/sources/shiboken6/libshiboken/pep384impl.h
@@ -4,11 +4,6 @@
#ifndef PEP384IMPL_H
#define PEP384IMPL_H
-// PYSIDE-1436: Adapt to Python 3.10
-#if PY_VERSION_HEX < 0x030900A4
-# define Py_SET_REFCNT(obj, refcnt) ((Py_REFCNT(obj) = (refcnt)), (void)0)
-#endif
-
extern "C"
{
@@ -55,42 +50,79 @@ typedef struct _typeobject {
const char *tp_name;
Py_ssize_t tp_basicsize;
void *X03; // Py_ssize_t tp_itemsize;
+#ifdef PEP384_INTERN
destructor tp_dealloc;
+#else
+ destructor X04;
+#endif
void *X05; // Py_ssize_t tp_vectorcall_offset;
void *X06; // getattrfunc tp_getattr;
void *X07; // setattrfunc tp_setattr;
void *X08; // PyAsyncMethods *tp_as_async;
+#ifdef PEP384_INTERN
reprfunc tp_repr;
+#else
+ reprfunc X09;
+#endif
void *X10; // PyNumberMethods *tp_as_number;
void *X11; // PySequenceMethods *tp_as_sequence;
void *X12; // PyMappingMethods *tp_as_mapping;
void *X13; // hashfunc tp_hash;
+#ifdef PEP384_INTERN
ternaryfunc tp_call;
- reprfunc tp_str;
+#else
+ ternaryfunc X14;
+#endif
+ reprfunc tp_str; // Only used for PEP384_INTERN and a shiboken test
getattrofunc tp_getattro;
setattrofunc tp_setattro;
void *X18; // PyBufferProcs *tp_as_buffer;
unsigned long tp_flags;
void *X20; // const char *tp_doc;
+#ifdef PEP384_INTERN
traverseproc tp_traverse;
inquiry tp_clear;
+#else
+ traverseproc X21;
+ inquiry X22;
+#endif
void *X23; // richcmpfunc tp_richcompare;
Py_ssize_t tp_weaklistoffset;
void *X25; // getiterfunc tp_iter;
+#ifdef PEP384_INTERN
iternextfunc tp_iternext;
+#else
+ iternextfunc X26;
+#endif
struct PyMethodDef *tp_methods;
struct PyMemberDef *tp_members;
struct PyGetSetDef *tp_getset;
struct _typeobject *tp_base;
+#ifdef PEP384_INTERN
PyObject *tp_dict;
descrgetfunc tp_descr_get;
descrsetfunc tp_descr_set;
+#else
+ void *X31;
+ descrgetfunc X32;
+ descrsetfunc X33;
+#endif
Py_ssize_t tp_dictoffset;
+#ifdef PEP384_INTERN
initproc tp_init;
allocfunc tp_alloc;
+#else
+ initproc X39;
+ allocfunc X40;
+#endif
newfunc tp_new;
+#ifdef PEP384_INTERN
freefunc tp_free;
inquiry tp_is_gc; /* For PyObject_IS_GC */
+#else
+ freefunc X41;
+ inquiry X42; /* For PyObject_IS_GC */
+#endif
PyObject *tp_bases;
PyObject *tp_mro; /* method resolution order */
@@ -103,24 +135,16 @@ typedef struct _typeobject {
&& (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))
#endif
-// This was a macro error in the limited API from the beginning.
-// It was fixed in Python master, but did make it only into Python 3.8 .
-
-// PYSIDE-1797: This must be a runtime decision.
-// Remove that when the minimum Python version is 3.8,
-// because the macro PepIndex_Check bug was fixed then.
-/// FIXME: Remove PepIndex_Check and pep384_issue33738.cpp when Python 3.7 is gone.
-LIBSHIBOKEN_API int PepIndex_Check(PyObject *obj);
-
LIBSHIBOKEN_API PyObject *_PepType_Lookup(PyTypeObject *type, PyObject *name);
#else // Py_LIMITED_API
-#define PepIndex_Check(obj) PyIndex_Check(obj)
#define _PepType_Lookup(type, name) _PyType_Lookup(type, name)
#endif // Py_LIMITED_API
+/// PYSIDE-939: We need the runtime version, given major << 16 + minor << 8 + micro
+LIBSHIBOKEN_API long _PepRuntimeVersion();
/*****************************************************************************
*
* PYSIDE-535: Implement a clean type extension for PyPy
@@ -139,16 +163,15 @@ LIBSHIBOKEN_API SbkEnumTypePrivate *PepType_SETP(SbkEnumType *type);
LIBSHIBOKEN_API void PepType_SETP_delete(SbkEnumType *enumType);
struct PySideQFlagsType;
-struct PySideQFlagsTypePrivate;
-
-LIBSHIBOKEN_API PySideQFlagsTypePrivate *PepType_PFTP(PySideQFlagsType *type);
-LIBSHIBOKEN_API void PepType_PFTP_delete(PySideQFlagsType *flagsType);
+struct SbkQFlagsTypePrivate;
/*****************************************************************************/
// functions used everywhere
LIBSHIBOKEN_API const char *PepType_GetNameStr(PyTypeObject *type);
+LIBSHIBOKEN_API PyObject *Pep_GetPartialFunction(void);
+
/*****************************************************************************
*
* RESOLVED: pydebug.h
@@ -163,7 +186,17 @@ LIBSHIBOKEN_API const char *PepType_GetNameStr(PyTypeObject *type);
*/
LIBSHIBOKEN_API int Pep_GetFlag(const char *name);
LIBSHIBOKEN_API int Pep_GetVerboseFlag(void);
-#define Py_VerboseFlag Pep_GetVerboseFlag()
+#endif
+
+// pyerrors.h
+#if defined(Py_LIMITED_API) || PY_VERSION_HEX < 0x030C0000
+LIBSHIBOKEN_API PyObject *PepErr_GetRaisedException();
+LIBSHIBOKEN_API PyObject *PepException_GetArgs(PyObject *ex);
+LIBSHIBOKEN_API void PepException_SetArgs(PyObject *ex, PyObject *args);
+#else
+# define PepErr_GetRaisedException PyErr_GetRaisedException
+# define PepException_GetArgs PyException_GetArgs
+# define PepException_SetArgs PyException_SetArgs
#endif
/*****************************************************************************
@@ -201,7 +234,9 @@ LIBSHIBOKEN_API int Pep_GetVerboseFlag(void);
LIBSHIBOKEN_API const char *_PepUnicode_AsString(PyObject *);
enum PepUnicode_Kind {
+#if PY_VERSION_HEX < 0x030C0000
PepUnicode_WCHAR_KIND = 0,
+#endif
PepUnicode_1BYTE_KIND = 1,
PepUnicode_2BYTE_KIND = 2,
PepUnicode_4BYTE_KIND = 4
@@ -216,7 +251,9 @@ LIBSHIBOKEN_API void *_PepUnicode_DATA(PyObject *str);
#else
enum PepUnicode_Kind {
+#if PY_VERSION_HEX < 0x030C0000
PepUnicode_WCHAR_KIND = PyUnicode_WCHAR_KIND,
+#endif
PepUnicode_1BYTE_KIND = PyUnicode_1BYTE_KIND,
PepUnicode_2BYTE_KIND = PyUnicode_2BYTE_KIND,
PepUnicode_4BYTE_KIND = PyUnicode_4BYTE_KIND
@@ -278,7 +315,7 @@ enum PepUnicode_Kind {
#ifdef Py_LIMITED_API
-typedef struct _pycfunc PyCFunctionObject;
+using PyCFunctionObject = struct _pycfunc;
#define PyCFunction_GET_FUNCTION(func) PyCFunction_GetFunction((PyObject *)func)
#define PyCFunction_GET_SELF(func) PyCFunction_GetSelf((PyObject *)func)
#define PyCFunction_GET_FLAGS(func) PyCFunction_GetFlags((PyObject *)func)
@@ -393,10 +430,13 @@ LIBSHIBOKEN_API PyObject *PyMethod_Self(PyObject *);
typedef struct _code PepCodeObject;
LIBSHIBOKEN_API int PepCode_Get(PepCodeObject *co, const char *name);
+LIBSHIBOKEN_API int PepCode_Check(PyObject *o);
# define PepCode_GET_FLAGS(o) PepCode_Get(o, "co_flags")
# define PepCode_GET_ARGCOUNT(o) PepCode_Get(o, "co_argcount")
+LIBSHIBOKEN_API PyObject *PepFunction_GetDefaults(PyObject *function);
+
/* Masks for co_flags above */
# define CO_OPTIMIZED 0x0001
# define CO_NEWLOCALS 0x0002
@@ -410,7 +450,15 @@ LIBSHIBOKEN_API int PepCode_Get(PepCodeObject *co, const char *name);
# define PepCodeObject PyCodeObject
# define PepCode_GET_FLAGS(o) ((o)->co_flags)
# define PepCode_GET_ARGCOUNT(o) ((o)->co_argcount)
+# define PepCode_Check PyCode_Check
+
+# ifdef PYPY_VERSION
+
+LIBSHIBOKEN_API PyObject *PepFunction_GetDefaults(PyObject *function);
+# else
+# define PepFunction_GetDefaults PyFunction_GetDefaults
+# endif
#endif
/*****************************************************************************
@@ -511,9 +559,9 @@ extern LIBSHIBOKEN_API PyTypeObject *PepBuiltinMethod_TypePtr;
*
* This is not defined if Py_LIMITED_API is defined.
*/
-#if PY_VERSION_HEX < 0x03070000 || defined(Py_LIMITED_API)
+#ifdef Py_LIMITED_API
LIBSHIBOKEN_API PyObject *PyImport_GetModule(PyObject *name);
-#endif // PY_VERSION_HEX < 0x03070000 || defined(Py_LIMITED_API)
+#endif // Py_LIMITED_API
// Evaluate a script and return the variable `result`
LIBSHIBOKEN_API PyObject *PepRun_GetResult(const char *command);
@@ -538,6 +586,20 @@ extern LIBSHIBOKEN_API int PepRuntime_38_flag;
/*****************************************************************************
*
+ * Runtime support for Python 3.12 incompatibility
+ *
+ */
+
+LIBSHIBOKEN_API PyObject *PepType_GetDict(PyTypeObject *type);
+
+// This function does not exist as PyType_SetDict. But because tp_dict
+// is no longer considered to be accessible, we treat it as such.
+LIBSHIBOKEN_API int PepType_SetDict(PyTypeObject *type, PyObject *dict);
+
+LIBSHIBOKEN_API void *PepType_GetSlot(PyTypeObject *type, int aSlot);
+
+/*****************************************************************************
+ *
* Module Initialization
*
*/
diff --git a/sources/shiboken6/libshiboken/pyobjectholder.h b/sources/shiboken6/libshiboken/pyobjectholder.h
new file mode 100644
index 000000000..857748c2f
--- /dev/null
+++ b/sources/shiboken6/libshiboken/pyobjectholder.h
@@ -0,0 +1,86 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef PYOBJECTHOLDER_H
+#define PYOBJECTHOLDER_H
+
+#include "sbkpython.h"
+
+#include <cassert>
+#include <utility>
+
+namespace Shiboken
+{
+
+/// PyObjectHolder holds a PyObject pointer, keeping a reference decrementing
+/// its reference counter when destroyed. It makes sure to hold the GIL when
+/// releasing. It implements copy/move semantics and is mainly intended as a
+/// base class for functors holding a callable which can be passed around and
+/// stored in containers or moved from freely.
+/// For one-shot functors, release() can be invoked after the call.
+class PyObjectHolder
+{
+public:
+ PyObjectHolder() noexcept = default;
+
+ /// PyObjectHolder constructor.
+ /// \param pyobj A reference to a Python object
+ explicit PyObjectHolder(PyObject *pyObj) noexcept : m_pyObj(pyObj)
+ {
+ assert(pyObj != nullptr);
+ Py_INCREF(m_pyObj);
+ }
+
+ PyObjectHolder(const PyObjectHolder &o) noexcept : m_pyObj(o.m_pyObj)
+ {
+ Py_XINCREF(m_pyObj);
+ }
+
+ PyObjectHolder &operator=(const PyObjectHolder &o) noexcept
+ {
+ if (this != &o) {
+ m_pyObj = o.m_pyObj;
+ Py_XINCREF(m_pyObj);
+ }
+ return *this;
+ }
+
+ PyObjectHolder(PyObjectHolder &&o) noexcept : m_pyObj{std::exchange(o.m_pyObj, nullptr)} {}
+
+ PyObjectHolder &operator=(PyObjectHolder &&o) noexcept
+ {
+ m_pyObj = std::exchange(o.m_pyObj, nullptr);
+ return *this;
+ }
+
+ /// Decref the python reference
+ ~PyObjectHolder() { release(); }
+
+ [[nodiscard]] bool isNull() const { return m_pyObj == nullptr; }
+ [[nodiscard]] operator bool() const { return m_pyObj != nullptr; }
+
+ /// Returns the pointer of the Python object being held.
+ [[nodiscard]] PyObject *object() const { return m_pyObj; }
+ [[nodiscard]] operator PyObject *() const { return m_pyObj; }
+
+ [[nodiscard]] PyObject *operator->() { return m_pyObj; }
+
+protected:
+ void release()
+ {
+ if (m_pyObj != nullptr) {
+ assert(Py_IsInitialized());
+ auto gstate = PyGILState_Ensure();
+ Py_DECREF(m_pyObj);
+ PyGILState_Release(gstate);
+ m_pyObj = nullptr;
+ }
+ }
+
+private:
+ PyObject *m_pyObj = nullptr;
+};
+
+} // namespace Shiboken
+
+#endif // PYOBJECTHOLDER_H
diff --git a/sources/shiboken6/libshiboken/sbkarrayconverter.cpp b/sources/shiboken6/libshiboken/sbkarrayconverter.cpp
index 8af310a53..bcc3fb767 100644
--- a/sources/shiboken6/libshiboken/sbkarrayconverter.cpp
+++ b/sources/shiboken6/libshiboken/sbkarrayconverter.cpp
@@ -14,8 +14,7 @@
static SbkArrayConverter *ArrayTypeConverters[Shiboken::Conversions::SBK_ARRAY_IDX_SIZE] [2] = {};
-namespace Shiboken {
-namespace Conversions {
+namespace Shiboken::Conversions {
// Check whether Predicate is true for all elements of a sequence
template <class Predicate>
@@ -244,5 +243,4 @@ void setArrayTypeConverter(int index, int dimension, SbkArrayConverter *c)
ArrayTypeConverters[index][dimension - 1] = c;
}
-} // namespace Conversions
-} // namespace Shiboken
+} // namespace Shiboken::Conversions
diff --git a/sources/shiboken6/libshiboken/sbkarrayconverter.h b/sources/shiboken6/libshiboken/sbkarrayconverter.h
index 97bd8ac6f..f07cb1d70 100644
--- a/sources/shiboken6/libshiboken/sbkarrayconverter.h
+++ b/sources/shiboken6/libshiboken/sbkarrayconverter.h
@@ -11,8 +11,7 @@ extern "C" {
struct SbkArrayConverter;
}
-namespace Shiboken {
-namespace Conversions {
+namespace Shiboken::Conversions {
enum : int {
SBK_UNIMPLEMENTED_ARRAY_IDX,
@@ -132,7 +131,6 @@ void ArrayHandle<T>::destroy()
m_owned = false;
}
-} // namespace Conversions
-} // namespace Shiboken
+} // namespace Shiboken::Conversions
#endif // SBKARRAYCONVERTERS_H
diff --git a/sources/shiboken6/libshiboken/sbkarrayconverter_p.h b/sources/shiboken6/libshiboken/sbkarrayconverter_p.h
index db92e56af..63d03fb12 100644
--- a/sources/shiboken6/libshiboken/sbkarrayconverter_p.h
+++ b/sources/shiboken6/libshiboken/sbkarrayconverter_p.h
@@ -10,7 +10,7 @@
extern "C"
{
-typedef PythonToCppFunc (*IsArrayConvertibleToCppFunc)(PyObject *, int dim1, int dim2);
+using IsArrayConvertibleToCppFunc = PythonToCppFunc (*)(PyObject *, int dim1, int dim2);
/**
* \internal
* Private structure of SbkArrayConverter.
diff --git a/sources/shiboken6/libshiboken/sbkcontainer.cpp b/sources/shiboken6/libshiboken/sbkcontainer.cpp
index 13c9f1a29..7de1f03e6 100644
--- a/sources/shiboken6/libshiboken/sbkcontainer.cpp
+++ b/sources/shiboken6/libshiboken/sbkcontainer.cpp
@@ -3,14 +3,17 @@
#include "sbkcontainer.h"
#include "sbkstaticstrings.h"
+#include "autodecref.h"
namespace Shiboken
{
bool isOpaqueContainer(PyObject *o)
{
+ if (!o)
+ return false;
+ Shiboken::AutoDecRef tpDict(PepType_GetDict(o->ob_type));
return o != nullptr && o != Py_None
- && PyDict_Contains(o->ob_type->tp_dict,
- Shiboken::PyMagicName::opaque_container()) == 1;
+ && PyDict_Contains(tpDict.object(), Shiboken::PyMagicName::opaque_container()) == 1;
}
} // Shiboken
diff --git a/sources/shiboken6/libshiboken/sbkcontainer.h b/sources/shiboken6/libshiboken/sbkcontainer.h
index 22513d3a0..8ad5aadc6 100644
--- a/sources/shiboken6/libshiboken/sbkcontainer.h
+++ b/sources/shiboken6/libshiboken/sbkcontainer.h
@@ -63,7 +63,8 @@ public:
static PyObject *tpNew(PyTypeObject *subtype, PyObject * /* args */, PyObject * /* kwds */)
{
- auto *me = reinterpret_cast<ShibokenContainer *>(subtype->tp_alloc(subtype, 0));
+ allocfunc allocFunc = reinterpret_cast<allocfunc>(PepType_GetSlot(subtype, Py_tp_alloc));
+ auto *me = reinterpret_cast<ShibokenContainer *>(allocFunc(subtype, 0));
auto *d = new ShibokenSequenceContainerPrivate;
d->m_list = new SequenceContainer;
d->m_ownsList = true;
@@ -71,6 +72,13 @@ public:
return reinterpret_cast<PyObject *>(me);
}
+ static PyObject *tpNewInvalid(PyTypeObject * /* subtype */, PyObject * /* args */, PyObject * /* kwds */)
+ {
+ return PyErr_Format(PyExc_NotImplementedError,
+ "Opaque containers of type '%s' cannot be instantiated.",
+ typeid(SequenceContainer).name());
+ }
+
static int tpInit(PyObject * /* self */, PyObject * /* args */, PyObject * /* kwds */)
{
return 0;
@@ -83,7 +91,9 @@ public:
if (d->m_ownsList)
delete d->m_list;
delete d;
- Py_TYPE(pySelf)->tp_base->tp_free(self);
+ auto freeFunc = reinterpret_cast<freefunc>(PepType_GetSlot(Py_TYPE(pySelf)->tp_base,
+ Py_tp_free));
+ freeFunc(self);
}
static Py_ssize_t sqLen(PyObject *self)
@@ -94,11 +104,9 @@ public:
static PyObject *sqGetItem(PyObject *self, Py_ssize_t i)
{
auto *d = get(self);
- if (i < 0 || i >= Py_ssize_t(d->m_list->size())) {
- PyErr_SetString(PyExc_IndexError, "index out of bounds");
- return nullptr;
- }
- auto it = d->m_list->cbegin();
+ if (i < 0 || i >= Py_ssize_t(d->m_list->size()))
+ return PyErr_Format(PyExc_IndexError, "index out of bounds");
+ auto it = std::cbegin(*d->m_list);
std::advance(it, i);
return ShibokenContainerValueConverter<value_type>::convertValueToPython(*it);
}
@@ -110,7 +118,7 @@ public:
PyErr_SetString(PyExc_IndexError, "index out of bounds");
return -1;
}
- auto it = d->m_list->begin();
+ auto it = std::begin(*d->m_list);
std::advance(it, i);
OptionalValue value = ShibokenContainerValueConverter<value_type>::convertValueToCpp(pyArg);
if (!value.has_value())
@@ -122,14 +130,10 @@ public:
static PyObject *push_back(PyObject *self, PyObject *pyArg)
{
auto *d = get(self);
- if (!ShibokenContainerValueConverter<value_type>::checkValue(pyArg)) {
- PyErr_SetString(PyExc_TypeError, "wrong type passed to append.");
- return nullptr;
- }
- if (d->m_const) {
- PyErr_SetString(PyExc_TypeError, msgModifyConstContainer);
- return nullptr;
- }
+ if (!ShibokenContainerValueConverter<value_type>::checkValue(pyArg))
+ return PyErr_Format(PyExc_TypeError, "wrong type passed to append.");
+ if (d->m_const)
+ return PyErr_Format(PyExc_TypeError, msgModifyConstContainer);
OptionalValue value = ShibokenContainerValueConverter<value_type>::convertValueToCpp(pyArg);
if (!value.has_value())
@@ -141,14 +145,10 @@ public:
static PyObject *push_front(PyObject *self, PyObject *pyArg)
{
auto *d = get(self);
- if (!ShibokenContainerValueConverter<value_type>::checkValue(pyArg)) {
- PyErr_SetString(PyExc_TypeError, "wrong type passed to append.");
- return nullptr;
- }
- if (d->m_const) {
- PyErr_SetString(PyExc_TypeError, msgModifyConstContainer);
- return nullptr;
- }
+ if (!ShibokenContainerValueConverter<value_type>::checkValue(pyArg))
+ return PyErr_Format(PyExc_TypeError, "wrong type passed to append.");
+ if (d->m_const)
+ return PyErr_Format(PyExc_TypeError, msgModifyConstContainer);
OptionalValue value = ShibokenContainerValueConverter<value_type>::convertValueToCpp(pyArg);
if (!value.has_value())
@@ -160,10 +160,8 @@ public:
static PyObject *clear(PyObject *self)
{
auto *d = get(self);
- if (d->m_const) {
- PyErr_SetString(PyExc_TypeError, msgModifyConstContainer);
- return nullptr;
- }
+ if (d->m_const)
+ return PyErr_Format(PyExc_TypeError, msgModifyConstContainer);
d->m_list->clear();
Py_RETURN_NONE;
@@ -172,10 +170,8 @@ public:
static PyObject *pop_back(PyObject *self)
{
auto *d = get(self);
- if (d->m_const) {
- PyErr_SetString(PyExc_TypeError, msgModifyConstContainer);
- return nullptr;
- }
+ if (d->m_const)
+ return PyErr_Format(PyExc_TypeError, msgModifyConstContainer);
d->m_list->pop_back();
Py_RETURN_NONE;
@@ -184,10 +180,8 @@ public:
static PyObject *pop_front(PyObject *self)
{
auto *d = get(self);
- if (d->m_const) {
- PyErr_SetString(PyExc_TypeError, msgModifyConstContainer);
- return nullptr;
- }
+ if (d->m_const)
+ return PyErr_Format(PyExc_TypeError, msgModifyConstContainer);
d->m_list->pop_front();
Py_RETURN_NONE;
@@ -197,21 +191,16 @@ public:
static PyObject *reserve(PyObject *self, PyObject *pyArg)
{
auto *d = get(self);
- if (PyLong_Check(pyArg) == 0) {
- PyErr_SetString(PyExc_TypeError, "wrong type passed to reserve().");
- return nullptr;
- }
- if (d->m_const) {
- PyErr_SetString(PyExc_TypeError, msgModifyConstContainer);
- return nullptr;
- }
+ if (PyLong_Check(pyArg) == 0)
+ return PyErr_Format(PyExc_TypeError, "wrong type passed to reserve().");
+ if (d->m_const)
+ return PyErr_Format(PyExc_TypeError, msgModifyConstContainer);
if constexpr (ShibokenContainerHasReserve<SequenceContainer>::value) {
const Py_ssize_t size = PyLong_AsSsize_t(pyArg);
d->m_list->reserve(size);
} else {
- PyErr_SetString(PyExc_TypeError, "Container does not support reserve().");
- return nullptr;
+ return PyErr_Format(PyExc_TypeError, "Container does not support reserve().");
}
Py_RETURN_NONE;
diff --git a/sources/shiboken6/libshiboken/sbkconverter.cpp b/sources/shiboken6/libshiboken/sbkconverter.cpp
index 309810290..9ab674415 100644
--- a/sources/shiboken6/libshiboken/sbkconverter.cpp
+++ b/sources/shiboken6/libshiboken/sbkconverter.cpp
@@ -4,6 +4,7 @@
#include "sbkconverter.h"
#include "sbkconverter_p.h"
#include "sbkarrayconverter_p.h"
+#include "sbkmodule.h"
#include "basewrapper_p.h"
#include "bindingmanager.h"
#include "autodecref.h"
@@ -11,15 +12,19 @@
#include "voidptr.h"
#include <string>
+#include <cstring>
+#include <iostream>
#include <unordered_map>
+#include <unordered_set>
+#include <map>
+#include <set>
static SbkConverter **PrimitiveTypeConverters;
using ConvertersMap = std::unordered_map<std::string, SbkConverter *>;
static ConvertersMap converters;
-namespace Shiboken {
-namespace Conversions {
+namespace Shiboken::Conversions {
void initArrayConverters();
@@ -72,6 +77,103 @@ void init()
initArrayConverters();
}
+static void dumpPyTypeObject(std::ostream &str, PyTypeObject *t)
+{
+ str << "\nPython type ";
+ if (t == nullptr) {
+ str << "<None>";
+ return;
+ }
+ str << '"' << t->tp_name << '"';
+ if (t->tp_base != nullptr && t->tp_base != &PyBaseObject_Type)
+ str << '(' << t->tp_base->tp_name << ')';
+}
+
+static void dumpSbkConverter(std::ostream &str, const SbkConverter *c)
+{
+ str << "SbkConverter " << static_cast<const void *>(c) << ": ";
+ if (c->pointerToPython != nullptr)
+ str << ", C++ pointer->Python";
+ if (c->copyToPython != nullptr)
+ str << ", copy->Python";
+ if (c->toCppPointerConversion.second != nullptr)
+ str << ", Python->C++ pointer";
+ if (!c->toCppConversions.empty())
+ str << ", " << c->toCppConversions.size() << " Python->C++ conversions";
+}
+
+// Less than operator for a PyTypeObject for dumping the converter map
+static bool pyTypeObjectLessThan(const PyTypeObject *t1, const PyTypeObject *t2)
+{
+ const bool isNull1 = t1 == nullptr;
+ const bool isNull2 = t2 == nullptr;
+ if (isNull1 || isNull2)
+ return isNull1 && !isNull2;
+ // Internal types (lower case) first
+ const bool isInternal1 = std::islower(t1->tp_name[0]);
+ const bool isInternal2 = std::islower(t2->tp_name[0]);
+ if (isInternal1 != isInternal2)
+ return !isInternal2;
+ return std::strcmp(t1->tp_name, t2->tp_name) < 0;
+}
+
+void dumpConverters()
+{
+ struct PyTypeObjectLess {
+
+ bool operator()(const PyTypeObject *t1, const PyTypeObject *t2) const {
+ return pyTypeObjectLessThan(t1, t2);
+ }
+ };
+
+ using StringSet = std::set<std::string>;
+ using SbkConverterNamesMap = std::unordered_map<SbkConverter *, StringSet>;
+ using PyTypeObjectConverterMap = std::map<PyTypeObject *, SbkConverterNamesMap,
+ PyTypeObjectLess>;
+
+ auto &str = std::cerr;
+
+ // Sort the entries by the associated PyTypeObjects and converters
+ PyTypeObjectConverterMap pyTypeObjectConverterMap;
+ for (const auto &converter : converters) {
+ auto *sbkConverter = converter.second;
+ if (sbkConverter == nullptr) {
+ str << "Non-existent: \"" << converter.first << "\"\n";
+ continue;
+ }
+ auto *typeObject = sbkConverter->pythonType;
+ auto typeIt = pyTypeObjectConverterMap.find(typeObject);
+ if (typeIt == pyTypeObjectConverterMap.end())
+ typeIt = pyTypeObjectConverterMap.insert(std::make_pair(typeObject,
+ SbkConverterNamesMap{})).first;
+ SbkConverterNamesMap &sbkConverterMap = typeIt->second;
+ auto convIt = sbkConverterMap.find(sbkConverter);
+ if (convIt == sbkConverterMap.end())
+ convIt = sbkConverterMap.insert(std::make_pair(sbkConverter,
+ StringSet{})).first;
+ convIt->second.insert(converter.first);
+ }
+
+ for (const auto &tc : pyTypeObjectConverterMap) {
+ dumpPyTypeObject(str, tc.first);
+ str << ", " << tc.second.size() << " converter(s):\n";
+ for (const auto &cn : tc.second) {
+ str << " ";
+ dumpSbkConverter(str, cn.first);
+ str << ", " << cn.second.size() << " alias(es):";
+ int i = 0;
+ for (const auto &name : cn.second) {
+ if ((i++ % 5) == 0)
+ str << "\n ";
+ str << " \"" << name << '"';
+ }
+ str << '\n';
+ }
+ }
+
+ str << '\n';
+}
+
SbkConverter *createConverterObject(PyTypeObject *type,
PythonToCppFunc toCppPointerConvFunc,
IsConvertibleToCppFunc toCppPointerCheckFunc,
@@ -147,6 +249,13 @@ void addPythonToCppValueConversion(PyTypeObject *type,
addPythonToCppValueConversion(sotp->converter, pythonToCppFunc, isConvertibleToCppFunc);
}
+void addPythonToCppValueConversion(Shiboken::Module::TypeInitStruct typeStruct,
+ PythonToCppFunc pythonToCppFunc,
+ IsConvertibleToCppFunc isConvertibleToCppFunc)
+{
+ addPythonToCppValueConversion(typeStruct.type, pythonToCppFunc, isConvertibleToCppFunc);
+}
+
PyObject *pointerToPython(PyTypeObject *type, const void *cppIn)
{
auto *sotp = PepType_SOTP(type);
@@ -228,6 +337,11 @@ PythonToCppConversion pythonToCppPointerConversion(PyTypeObject *type, PyObject
return {};
}
+PythonToCppConversion pythonToCppPointerConversion(Module::TypeInitStruct typeStruct, PyObject *pyIn)
+{
+ return pythonToCppPointerConversion(typeStruct.type, pyIn);
+}
+
static inline PythonToCppFunc IsPythonToCppConvertible(const SbkConverter *converter, PyObject *pyIn)
{
assert(pyIn);
@@ -403,19 +517,55 @@ bool isImplicitConversion(PyTypeObject *type, PythonToCppFunc toCppFunc)
return toCppFunc != (*conv).second;
}
-void registerConverterName(SbkConverter *converter , const char *typeName)
+void registerConverterName(SbkConverter *converter, const char *typeName)
{
auto iter = converters.find(typeName);
if (iter == converters.end())
converters.insert(std::make_pair(typeName, converter));
}
-SbkConverter *getConverter(const char *typeName)
+static std::string getRealTypeName(const std::string &typeName)
+{
+ auto size = typeName.size();
+ if (std::isalnum(typeName[size - 1]) == 0)
+ return typeName.substr(0, size - 1);
+ return typeName;
+}
+
+// PYSIDE-2404: Build a negative cache of already failed lookups.
+// The resulting list must be reset after each new import,
+// because that can change results. Also clear the cache after
+// reaching some threashold.
+static std::unordered_set<std::string> nonExistingTypeNames{};
+
+// Arbitrary size limit to prevent random name overflows.
+static constexpr std::size_t negativeCacheLimit = 50;
+
+static void rememberAsNonexistent(const std::string &typeName)
+{
+ if (nonExistingTypeNames.size() > negativeCacheLimit)
+ clearNegativeLazyCache();
+ converters.insert(std::make_pair(typeName, nullptr));
+ nonExistingTypeNames.insert(typeName);
+}
+
+SbkConverter *getConverter(const char *typeNameC)
{
- ConvertersMap::const_iterator it = converters.find(typeName);
+ std::string typeName = typeNameC;
+ auto it = converters.find(typeName);
+ // PYSIDE-2404: This can also contain explicit nullptr as a negative cache.
+ if (it != converters.end())
+ return it->second;
+ // PYSIDE-2404: Did not find the name. Load the lazy classes
+ // which have this name and try again.
+ Shiboken::Module::loadLazyClassesWithName(getRealTypeName(typeName).c_str());
+ it = converters.find(typeName);
if (it != converters.end())
return it->second;
- if (Py_VerboseFlag > 0) {
+ // Cache the negative result. Don't forget to clear the cache for new modules.
+ rememberAsNonexistent(typeName);
+
+ if (Shiboken::pyVerbose() > 0) {
const std::string message =
std::string("Can't find type resolver for type '") + typeName + "'.";
PyErr_WarnEx(PyExc_RuntimeWarning, message.c_str(), 0);
@@ -423,6 +573,15 @@ SbkConverter *getConverter(const char *typeName)
return nullptr;
}
+void clearNegativeLazyCache()
+{
+ for (const auto &typeName : nonExistingTypeNames) {
+ auto it = converters.find(typeName);
+ converters.erase(it);
+ }
+ nonExistingTypeNames.clear();
+}
+
SbkConverter *primitiveTypeConverter(int index)
{
return PrimitiveTypeConverters[index];
@@ -748,4 +907,4 @@ void SpecificConverter::toCpp(PyObject *pyIn, void *cppOut)
}
}
-} } // namespace Shiboken::Conversions
+} // namespace Shiboken::Conversions
diff --git a/sources/shiboken6/libshiboken/sbkconverter.h b/sources/shiboken6/libshiboken/sbkconverter.h
index 1428b90e2..0d68f3faf 100644
--- a/sources/shiboken6/libshiboken/sbkconverter.h
+++ b/sources/shiboken6/libshiboken/sbkconverter.h
@@ -5,9 +5,9 @@
#define SBK_CONVERTER_H
#include "sbkpython.h"
+#include "sbkmodule.h"
#include "shibokenmacros.h"
#include "sbkenum.h"
-#include "sbkenum_p.h"
#include "basewrapper_p.h"
#include <limits>
@@ -43,7 +43,7 @@ struct SbkArrayConverter;
*
* C++ -> Python
*/
-typedef PyObject *(*CppToPythonFunc)(const void *);
+using CppToPythonFunc = PyObject *(*)(const void *);
/**
* This function converts a Python object to a C++ value, it may be
@@ -56,7 +56,7 @@ typedef PyObject *(*CppToPythonFunc)(const void *);
*
* Python -> C++
*/
-typedef void (*PythonToCppFunc)(PyObject *,void *);
+using PythonToCppFunc = void (*)(PyObject *,void *);
/**
* Checks if the Python object passed in the argument is convertible to a
@@ -67,7 +67,7 @@ typedef void (*PythonToCppFunc)(PyObject *,void *);
*
* Python -> C++ ?
*/
-typedef PythonToCppFunc (*IsConvertibleToCppFunc)(PyObject *);
+using IsConvertibleToCppFunc = PythonToCppFunc (*)(PyObject *);
} // extern "C"
@@ -147,6 +147,9 @@ LIBSHIBOKEN_API void addPythonToCppValueConversion(SbkConverter *converter,
LIBSHIBOKEN_API void addPythonToCppValueConversion(PyTypeObject *type,
PythonToCppFunc pythonToCppFunc,
IsConvertibleToCppFunc isConvertibleToCppFunc);
+LIBSHIBOKEN_API void addPythonToCppValueConversion(Shiboken::Module::TypeInitStruct typeStruct,
+ PythonToCppFunc pythonToCppFunc,
+ IsConvertibleToCppFunc isConvertibleToCppFunc);
// C++ -> Python ---------------------------------------------------------------------------
@@ -204,6 +207,7 @@ struct PythonToCppConversion
*/
LIBSHIBOKEN_API PythonToCppFunc isPythonToCppPointerConvertible(PyTypeObject *type, PyObject *pyIn);
LIBSHIBOKEN_API PythonToCppConversion pythonToCppPointerConversion(PyTypeObject *type, PyObject *pyIn);
+LIBSHIBOKEN_API PythonToCppConversion pythonToCppPointerConversion(Module::TypeInitStruct typeStruct, PyObject *pyIn);
/**
* Returns a Python to C++ conversion function if the Python object is convertible to a C++ value.
@@ -410,7 +414,7 @@ template<> inline PyTypeObject *SbkType<std::nullptr_t>() { return Py_TYPE(&_Py_
#define SbkChar_Check(X) (PyNumber_Check(X) || Shiboken::String::checkChar(X))
struct PySideQFlagsType;
-struct PySideQFlagsTypePrivate
+struct SbkQFlagsTypePrivate
{
SbkConverter *converter;
};
diff --git a/sources/shiboken6/libshiboken/sbkconverter_p.h b/sources/shiboken6/libshiboken/sbkconverter_p.h
index 27126fbb1..08fc4c8e1 100644
--- a/sources/shiboken6/libshiboken/sbkconverter_p.h
+++ b/sources/shiboken6/libshiboken/sbkconverter_p.h
@@ -278,7 +278,7 @@ struct Primitive<PY_LONG_LONG> : OnePrimitive<PY_LONG_LONG>
{
PY_LONG_LONG result = PyLong_AsLongLong(pyIn);
if (OverFlowChecker<PY_LONG_LONG>::check(result, pyIn))
- PyErr_SetObject(PyExc_OverflowError, 0);
+ PyErr_SetObject(PyExc_OverflowError, nullptr);
*reinterpret_cast<PY_LONG_LONG * >(cppOut) = result;
}
static PythonToCppFunc isConvertible(PyObject *pyIn)
@@ -327,7 +327,7 @@ struct FloatPrimitive : TwoPrimitive<FLOAT>
}
static void toCpp(PyObject *pyIn, void *cppOut)
{
- *reinterpret_cast<FLOAT *>(cppOut) = FLOAT(PyLong_AsLong(pyIn));
+ *reinterpret_cast<FLOAT *>(cppOut) = FLOAT(PyLong_AsDouble(pyIn));
}
static PythonToCppFunc isConvertible(PyObject *pyIn)
{
@@ -524,13 +524,19 @@ struct Primitive<std::nullptr_t> : OnePrimitive<std::nullptr_t>
}
};
-namespace Shiboken {
-namespace Conversions {
+namespace Shiboken::Conversions {
+
SbkConverter *createConverterObject(PyTypeObject *type,
PythonToCppFunc toCppPointerConvFunc,
IsConvertibleToCppFunc toCppPointerCheckFunc,
CppToPythonFunc pointerToPythonFunc,
CppToPythonFunc copyToPythonFunc);
-} // namespace Conversions
-} // namespace Shiboken
+
+LIBSHIBOKEN_API void dumpConverters();
+
+/// Interface for sbkmodule which must reset cache when new module is loaded.
+LIBSHIBOKEN_API void clearNegativeLazyCache();
+
+} // namespace Shiboken::Conversions
+
#endif // SBK_CONVERTER_P_H
diff --git a/sources/shiboken6/libshiboken/sbkcppstring.cpp b/sources/shiboken6/libshiboken/sbkcppstring.cpp
index 42b09111c..8e8324f5e 100644
--- a/sources/shiboken6/libshiboken/sbkcppstring.cpp
+++ b/sources/shiboken6/libshiboken/sbkcppstring.cpp
@@ -12,6 +12,11 @@ PyObject *fromCppString(const std::string &value)
return PyUnicode_FromStringAndSize(value.data(), value.size());
}
+PyObject *fromCppStringView(std::string_view value)
+{
+ return PyUnicode_FromStringAndSize(value.data(), value.size());
+}
+
PyObject *fromCppWString(const std::wstring &value)
{
return PyUnicode_FromWideChar(value.data(), value.size());
diff --git a/sources/shiboken6/libshiboken/sbkcppstring.h b/sources/shiboken6/libshiboken/sbkcppstring.h
index f418ea8dd..7ffe11c75 100644
--- a/sources/shiboken6/libshiboken/sbkcppstring.h
+++ b/sources/shiboken6/libshiboken/sbkcppstring.h
@@ -8,10 +8,12 @@
#include "shibokenmacros.h"
#include <string>
+#include <string_view>
namespace Shiboken::String
{
LIBSHIBOKEN_API PyObject *fromCppString(const std::string &value);
+ LIBSHIBOKEN_API PyObject *fromCppStringView(std::string_view value);
LIBSHIBOKEN_API PyObject *fromCppWString(const std::wstring &value);
LIBSHIBOKEN_API void toCppString(PyObject *str, std::string *value);
LIBSHIBOKEN_API void toCppWString(PyObject *str, std::wstring *value);
diff --git a/sources/shiboken6/libshiboken/sbkcpptonumpy.cpp b/sources/shiboken6/libshiboken/sbkcpptonumpy.cpp
index 44e900f01..7637efa70 100644
--- a/sources/shiboken6/libshiboken/sbkcpptonumpy.cpp
+++ b/sources/shiboken6/libshiboken/sbkcpptonumpy.cpp
@@ -49,17 +49,17 @@ PyObject *createByteArray1(Py_ssize_t, const uint8_t *)
PyObject *createDoubleArray1(Py_ssize_t, const double *)
{
- return Py_None;
+ Py_RETURN_NONE;
}
PyObject *createFloatArray1(Py_ssize_t, const float *)
{
- return Py_None;
+ Py_RETURN_NONE;
}
PyObject *createIntArray1(Py_ssize_t, const int *)
{
- return Py_None;
+ Py_RETURN_NONE;
}
#endif // !HAVE_NUMPY
diff --git a/sources/shiboken6/libshiboken/sbkenum.cpp b/sources/shiboken6/libshiboken/sbkenum.cpp
index c5eae2fbb..d39369979 100644
--- a/sources/shiboken6/libshiboken/sbkenum.cpp
+++ b/sources/shiboken6/libshiboken/sbkenum.cpp
@@ -2,7 +2,6 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "sbkenum.h"
-#include "sbkenum_p.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
#include "sbkstaticstrings_p.h"
@@ -11,393 +10,28 @@
#include "autodecref.h"
#include "sbkpython.h"
#include "signature.h"
-#include "helper.h"
#include <cstring>
#include <vector>
#include <sstream>
-#include <iostream>
-
-#define SbkEnumType_Check(o) (Py_TYPE(Py_TYPE(o)) == SbkEnumType_TypeF())
-using enum_func = PyObject *(*)(PyObject *, PyObject *);
using namespace Shiboken;
extern "C"
{
-// forward
-struct lastEnumCreated;
-
-// forward
-static PyTypeObject *recordCurrentEnum(PyObject *scopeOrModule,
- const char *name,
- PyTypeObject *enumType,
- PyTypeObject *flagsType);
-
struct SbkEnumType
{
PyTypeObject type;
};
-static void cleanupEnumTypes();
-
-struct SbkEnumObject
-{
- PyObject_HEAD
- Enum::EnumValueType ob_value;
- PyObject *ob_name;
-};
-
-static PyTypeObject *SbkEnum_TypeF(); // forward
-
-static PyObject *SbkEnumObject_repr(PyObject *self)
-{
- const SbkEnumObject *enumObj = reinterpret_cast<SbkEnumObject *>(self);
- auto name = Py_TYPE(self)->tp_name;
- if (enumObj->ob_name) {
- return String::fromFormat("%s.%s", name, PyBytes_AS_STRING(enumObj->ob_name));
- }
- return String::fromFormat("%s(%ld)", name, enumObj->ob_value);
-}
-
-static PyObject *SbkEnumObject_name(PyObject *self, void *)
-{
- auto *enum_self = reinterpret_cast<SbkEnumObject *>(self);
-
- if (enum_self->ob_name == nullptr)
- Py_RETURN_NONE;
-
- Py_INCREF(enum_self->ob_name);
- return enum_self->ob_name;
-}
-
-static PyObject *SbkEnum_tp_new(PyTypeObject *type, PyObject *args, PyObject *)
-{
- long itemValue = 0;
- if (!PyArg_ParseTuple(args, "|l:__new__", &itemValue))
- return nullptr;
-
- if (type == SbkEnum_TypeF()) {
- PyErr_Format(PyExc_TypeError, "You cannot use %s directly", type->tp_name);
- return nullptr;
- }
-
- SbkEnumObject *self = PyObject_New(SbkEnumObject, type);
- if (!self)
- return nullptr;
- self->ob_value = itemValue;
- AutoDecRef item(Enum::getEnumItemFromValue(type, itemValue));
- self->ob_name = item.object() ? SbkEnumObject_name(item, nullptr) : nullptr;
- return reinterpret_cast<PyObject *>(self);
-}
-
-static const char *SbkEnum_SignatureStrings[] = {
- "Shiboken.Enum(self,itemValue:int=0)",
- nullptr}; // Sentinel
-
-static void enum_object_dealloc(PyObject *ob)
-{
- auto *self = reinterpret_cast<SbkEnumObject *>(ob);
- Py_XDECREF(self->ob_name);
- Sbk_object_dealloc(ob);
-}
-
-static PyObject *_enum_op(enum_func f, PyObject *a, PyObject *b) {
- PyObject *valA = a;
- PyObject *valB = b;
- PyObject *result = nullptr;
- bool enumA = false;
- bool enumB = false;
-
- // We are not allowing floats
- if (!PyFloat_Check(valA) && !PyFloat_Check(valB)) {
- // Check if both variables are SbkEnumObject
- if (SbkEnumType_Check(valA)) {
- valA = PyLong_FromLong(reinterpret_cast<SbkEnumObject *>(valA)->ob_value);
- enumA = true;
- }
- if (SbkEnumType_Check(valB)) {
- valB = PyLong_FromLong(reinterpret_cast<SbkEnumObject *>(valB)->ob_value);
- enumB = true;
- }
- }
-
- // Without an enum we are not supporting the operation
- if (!(enumA || enumB)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
- result = f(valA, valB);
-
- // Decreasing the reference of the used variables a and b.
- if (enumA)
- Py_DECREF(valA);
- if (enumB)
- Py_DECREF(valB);
- return result;
-}
-
-/* Notes:
- * On Py3k land we use long type when using integer numbers. However, on older
- * versions of Python (version 2) we need to convert it to int type,
- * respectively.
- *
- * Thus calling PyLong_FromLong() will result in calling PyLong_FromLong in
- * Py3k.
- */
-static PyObject *enum_int(PyObject *v)
-{
- return PyLong_FromLong(reinterpret_cast<SbkEnumObject *>(v)->ob_value);
-}
-
-static PyObject *enum_and(PyObject *self, PyObject *b)
-{
- return _enum_op(PyNumber_And, self, b);
-}
-
-static PyObject *enum_or(PyObject *self, PyObject *b)
-{
- return _enum_op(PyNumber_Or, self, b);
-}
-
-static PyObject *enum_xor(PyObject *self, PyObject *b)
-{
- return _enum_op(PyNumber_Xor, self, b);
-}
-
-static int enum_bool(PyObject *v)
-{
- return (reinterpret_cast<SbkEnumObject *>(v)->ob_value > 0);
-}
-
-static PyObject *enum_add(PyObject *self, PyObject *v)
-{
- return _enum_op(PyNumber_Add, self, v);
-}
-
-static PyObject *enum_subtract(PyObject *self, PyObject *v)
-{
- return _enum_op(PyNumber_Subtract, self, v);
-}
-
-static PyObject *enum_multiply(PyObject *self, PyObject *v)
-{
- return _enum_op(PyNumber_Multiply, self, v);
-}
-
-static PyObject *enum_richcompare(PyObject *self, PyObject *other, int op)
-{
- PyObject *valA = self;
- PyObject *valB = other;
- PyObject *result = nullptr;
- bool enumA = false;
- bool enumB = false;
-
- // We are not allowing floats
- if (!PyFloat_Check(valA) && !PyFloat_Check(valB)) {
-
- // Check if both variables are SbkEnumObject
- if (SbkEnumType_Check(valA)) {
- valA = PyLong_FromLong(reinterpret_cast<SbkEnumObject *>(valA)->ob_value);
- enumA = true;
- }
- if (SbkEnumType_Check(valB)) {
- valB = PyLong_FromLong(reinterpret_cast<SbkEnumObject *>(valB)->ob_value);
- enumB =true;
- }
- }
-
- // Without an enum we are not supporting the operation
- if (!(enumA || enumB)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
- result = PyObject_RichCompare(valA, valB, op);
-
- // Decreasing the reference of the used variables a and b.
- if (enumA)
- Py_DECREF(valA);
- if (enumB)
- Py_DECREF(valB);
-
- return result;
-}
-
-static Py_hash_t enum_hash(PyObject *pyObj)
-{
- Py_hash_t val = reinterpret_cast<SbkEnumObject *>(pyObj)->ob_value;
- if (val == -1)
- val = -2;
- return val;
-}
-
-static PyGetSetDef SbkEnumGetSetList[] = {
- {const_cast<char *>("name"), SbkEnumObject_name, nullptr, nullptr, nullptr},
- {nullptr, nullptr, nullptr, nullptr, nullptr} // Sentinel
-};
-
-static void SbkEnumTypeDealloc(PyObject *pyObj);
-static PyTypeObject *SbkEnumTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwds);
-
-static PyGetSetDef SbkEnumType_getsetlist[] = {
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(Sbk_TypeGet___signature__),
- nullptr, nullptr, nullptr},
- {nullptr, nullptr, nullptr, nullptr, nullptr} // Sentinel
-};
-
-static PyType_Slot SbkEnumType_Type_slots[] = {
- {Py_tp_dealloc, reinterpret_cast<void *>(SbkEnumTypeDealloc)},
- {Py_tp_base, reinterpret_cast<void *>(&PyType_Type)},
- {Py_tp_alloc, reinterpret_cast<void *>(PyType_GenericAlloc)},
- {Py_tp_new, reinterpret_cast<void *>(SbkEnumTypeTpNew)},
- {Py_tp_free, reinterpret_cast<void *>(PyObject_GC_Del)},
- {Py_tp_getset, reinterpret_cast<void *>(SbkEnumType_getsetlist)},
- {0, nullptr}
-};
-
-// PYSIDE-535: The tp_itemsize field is inherited and does not need to be set.
-// In PyPy, it _must_ not be set, because it would have the meaning that a
-// `__len__` field must be defined. Not doing so creates a hard-to-find crash.
-static PyType_Spec SbkEnumType_Type_spec = {
- "1:Shiboken.EnumMeta",
- 0,
- 0, // sizeof(PyMemberDef), not for PyPy without a __len__ defined
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
- SbkEnumType_Type_slots,
-};
-
-PyTypeObject *SbkEnumType_TypeF(void)
-{
- static auto *type = SbkType_FromSpec(&SbkEnumType_Type_spec);
- return type;
-}
-
-static void SbkEnumTypeDealloc(PyObject *pyObj)
-{
- auto *enumType = reinterpret_cast<SbkEnumType *>(pyObj);
- auto *setp = PepType_SETP(enumType);
-
- PyObject_GC_UnTrack(pyObj);
-#ifndef Py_LIMITED_API
-# if PY_VERSION_HEX >= 0x030A0000
- Py_TRASHCAN_BEGIN(pyObj, 1);
-# else
- Py_TRASHCAN_SAFE_BEGIN(pyObj);
-# endif
-#endif
- if (setp->converter)
- Conversions::deleteConverter(setp->converter);
- PepType_SETP_delete(enumType);
-#ifndef Py_LIMITED_API
-# if PY_VERSION_HEX >= 0x030A0000
- Py_TRASHCAN_END;
-# else
- Py_TRASHCAN_SAFE_END(pyObj);
-# endif
-#endif
- if (PepRuntime_38_flag) {
- // PYSIDE-939: Handling references correctly.
- // This was not needed before Python 3.8 (Python issue 35810)
- Py_DECREF(Py_TYPE(pyObj));
- }
-}
-
-PyTypeObject *SbkEnumTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
-{
- init_enum();
- return PepType_Type_tp_new(metatype, args, kwds);
-}
-
-} // extern "C"
-
-///////////////////////////////////////////////////////////////
-//
-// PYSIDE-15: Pickling Support for Qt Enum objects
-// This works very well and fixes the issue.
-//
-extern "C" {
-
-static PyObject *enum_unpickler = nullptr;
-
-// Pickling: reduce the Qt Enum object
-static PyObject *enum___reduce__(PyObject *obj)
-{
- init_enum();
- return Py_BuildValue("O(Ni)",
- enum_unpickler,
- Py_BuildValue("s", Py_TYPE(obj)->tp_name),
- PyLong_AS_LONG(obj));
-}
-
-} // extern "C"
-
-namespace Shiboken { namespace Enum {
-
-// Unpickling: rebuild the Qt Enum object
-PyObject *unpickleEnum(PyObject *enum_class_name, PyObject *value)
-{
- AutoDecRef parts(PyObject_CallMethod(enum_class_name,
- "split", "s", "."));
- if (parts.isNull())
- return nullptr;
- PyObject *top_name = PyList_GetItem(parts, 0); // borrowed ref
- if (top_name == nullptr)
- return nullptr;
- PyObject *module = PyImport_GetModule(top_name);
- if (module == nullptr) {
- PyErr_Format(PyExc_ImportError, "could not import module %.200s",
- String::toCString(top_name));
- return nullptr;
- }
- AutoDecRef cur_thing(module);
- int len = PyList_Size(parts);
- for (int idx = 1; idx < len; ++idx) {
- PyObject *name = PyList_GetItem(parts, idx); // borrowed ref
- PyObject *thing = PyObject_GetAttr(cur_thing, name);
- if (thing == nullptr) {
- PyErr_Format(PyExc_ImportError, "could not import Qt Enum type %.200s",
- String::toCString(enum_class_name));
- return nullptr;
- }
- cur_thing.reset(thing);
- }
- PyObject *klass = cur_thing;
- return PyObject_CallFunctionObjArgs(klass, value, nullptr);
-}
-
-int enumOption{};
-
-} // namespace Enum
-} // namespace Shiboken
-
-extern "C" {
-
// Initialization
static bool _init_enum()
{
AutoDecRef shibo(PyImport_ImportModule("shiboken6.Shiboken"));
- auto mod = shibo.object();
- // publish Shiboken.Enum so that the signature gets initialized
- if (PyObject_SetAttrString(mod, "Enum", reinterpret_cast<PyObject *>(SbkEnum_TypeF())) < 0)
- return false;
- if (InitSignatureStrings(SbkEnum_TypeF(), SbkEnum_SignatureStrings) < 0)
- return false;
- enum_unpickler = PyObject_GetAttrString(mod, "_unpickle_enum");
- if (enum_unpickler == nullptr)
- return false;
- return true;
+ return !shibo.isNull();
}
-static int useOldEnum = -1;
-
-static PyMethodDef SbkEnumObject_Methods[] = {
- {"__reduce__", reinterpret_cast<PyCFunction>(enum___reduce__),
- METH_NOARGS, nullptr},
- {nullptr, nullptr, 0, nullptr} // Sentinel
-};
-
static PyObject *PyEnumModule{};
static PyObject *PyEnumMeta{};
static PyObject *PyEnum{};
@@ -408,8 +42,7 @@ static PyObject *PyFlag_KEEP{};
bool PyEnumMeta_Check(PyObject *ob)
{
- return Py_TYPE(ob) == (useOldEnum ? SbkEnumType_TypeF()
- : reinterpret_cast<PyTypeObject *>(PyEnumMeta));
+ return Py_TYPE(ob) == reinterpret_cast<PyTypeObject *>(PyEnumMeta);
}
PyTypeObject *getPyEnumMeta()
@@ -445,20 +78,17 @@ void init_enum()
static bool isInitialized = false;
if (isInitialized)
return;
- if (!(isInitialized || enum_unpickler || _init_enum()))
- Py_FatalError("could not load enum pickling helper function");
- Py_AtExit(cleanupEnumTypes);
+ if (!(isInitialized || _init_enum()))
+ Py_FatalError("could not init enum");
// PYSIDE-1735: Determine whether we should use the old or the new enum implementation.
- static PyObject *sysmodule = PyImport_AddModule("sys");
- static PyObject *option = PyObject_GetAttrString(sysmodule, "pyside63_option_python_enum");
+ static PyObject *option = PySys_GetObject("pyside6_option_python_enum");
if (!option || !PyLong_Check(option)) {
PyErr_Clear();
- option = PyLong_FromLong(0);
+ option = PyLong_FromLong(1);
}
int ignoreOver{};
Enum::enumOption = PyLong_AsLongAndOverflow(option, &ignoreOver);
- useOldEnum = Enum::enumOption == Enum::ENOPT_OLD_ENUM;
getPyEnumMeta();
isInitialized = true;
}
@@ -472,8 +102,8 @@ int enumIsFlag(PyObject *ob_type)
if (metatype != reinterpret_cast<PyTypeObject *>(PyEnumMeta))
return -1;
auto *mro = reinterpret_cast<PyTypeObject *>(ob_type)->tp_mro;
- Py_ssize_t idx, n = PyTuple_GET_SIZE(mro);
- for (idx = 0; idx < n; idx++) {
+ const Py_ssize_t n = PyTuple_GET_SIZE(mro);
+ for (Py_ssize_t idx = 0; idx < n; ++idx) {
auto *sub_type = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(mro, idx));
if (sub_type == reinterpret_cast<PyTypeObject *>(PyFlag))
return 1;
@@ -481,519 +111,6 @@ int enumIsFlag(PyObject *ob_type)
return 0;
}
-// PYSIDE-1735: Helper function to ask what enum we are using
-bool usingNewEnum()
-{
- init_enum();
- return !useOldEnum;
-}
-
-} // extern "C"
-
-//
-///////////////////////////////////////////////////////////////
-
-namespace Shiboken {
-
-class DeclaredEnumTypes
-{
-public:
- struct EnumEntry
- {
- char *name; // full name as allocated. type->tp_name might be a substring.
- PyTypeObject *type;
- };
-
- DeclaredEnumTypes(const DeclaredEnumTypes &) = delete;
- DeclaredEnumTypes(DeclaredEnumTypes &&) = delete;
- DeclaredEnumTypes &operator=(const DeclaredEnumTypes &) = delete;
- DeclaredEnumTypes &operator=(DeclaredEnumTypes &&) = delete;
-
- DeclaredEnumTypes();
- ~DeclaredEnumTypes();
- static DeclaredEnumTypes &instance();
- void addEnumType(const EnumEntry &e) { m_enumTypes.push_back(e); }
-
- void cleanup();
-
-private:
- std::vector<EnumEntry> m_enumTypes;
-};
-
-namespace Enum {
-
-// forward
-static PyObject *newItemOld(PyTypeObject *enumType, EnumValueType itemValue,
- const char *itemName);
-
-// forward
-static PyTypeObject * newTypeWithNameOld(const char *name,
- const char *cppName,
- PyTypeObject *numbers_fromFlag);
-
-bool check(PyObject *pyObj)
-{
- init_enum();
-
- // PYSIDE-1735: Decide dynamically if new or old enums will be used.
- if (useOldEnum)
- return Py_TYPE(Py_TYPE(pyObj)) == SbkEnumType_TypeF();
-
- static PyTypeObject *meta = getPyEnumMeta();
- return Py_TYPE(Py_TYPE(pyObj)) == reinterpret_cast<PyTypeObject *>(meta);
-}
-
-static PyObject *getEnumItemFromValueOld(PyTypeObject *enumType,
- EnumValueType itemValue)
-{
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- PyObject *values = PyDict_GetItem(enumType->tp_dict, PyName::values());
- if (values == nullptr)
- return nullptr;
-
- while (PyDict_Next(values, &pos, &key, &value)) {
- auto *obj = reinterpret_cast<SbkEnumObject *>(value);
- if (obj->ob_value == itemValue) {
- Py_INCREF(value);
- return value;
- }
- }
- return nullptr;
-}
-
-PyObject *getEnumItemFromValue(PyTypeObject *enumType, EnumValueType itemValue)
-{
- init_enum();
- // PYSIDE-1735: Decide dynamically if new or old enums will be used.
- if (useOldEnum)
- return getEnumItemFromValueOld(enumType, itemValue);
-
- auto *obEnumType = reinterpret_cast<PyObject *>(enumType);
- AutoDecRef val2members(PyObject_GetAttrString(obEnumType, "_value2member_map_"));
- if (val2members.isNull()) {
- PyErr_Clear();
- return nullptr;
- }
- AutoDecRef ob_value(PyLong_FromLongLong(itemValue));
- auto *result = PyDict_GetItem(val2members, ob_value);
- Py_XINCREF(result);
- return result;
-}
-
-static PyTypeObject *createEnum(const char *fullName, const char *cppName,
- PyTypeObject *flagsType)
-{
- init_enum();
- PyTypeObject *enumType = newTypeWithNameOld(fullName, cppName, flagsType);
- if (PyType_Ready(enumType) < 0) {
- Py_XDECREF(enumType);
- return nullptr;
- }
- return enumType;
-}
-
-PyTypeObject *createGlobalEnum(PyObject *module, const char *name, const char *fullName,
- const char *cppName, PyTypeObject *flagsType)
-{
- PyTypeObject *enumType = createEnum(fullName, cppName, flagsType);
- if (enumType && PyModule_AddObject(module, name, reinterpret_cast<PyObject *>(enumType)) < 0) {
- Py_DECREF(enumType);
- return nullptr;
- }
- flagsType = recordCurrentEnum(module, name, enumType, flagsType);
- if (flagsType && PyModule_AddObject(module, PepType_GetNameStr(flagsType),
- reinterpret_cast<PyObject *>(flagsType)) < 0) {
- Py_DECREF(enumType);
- return nullptr;
- }
- return enumType;
-}
-
-PyTypeObject *createScopedEnum(PyTypeObject *scope, const char *name, const char *fullName,
- const char *cppName, PyTypeObject *flagsType)
-{
- PyTypeObject *enumType = createEnum(fullName, cppName, flagsType);
- if (enumType && PyDict_SetItemString(scope->tp_dict, name,
- reinterpret_cast<PyObject *>(enumType)) < 0) {
- Py_DECREF(enumType);
- return nullptr;
- }
- auto *obScope = reinterpret_cast<PyObject *>(scope);
- flagsType = recordCurrentEnum(obScope, name, enumType, flagsType);
- if (flagsType && PyDict_SetItemString(scope->tp_dict,
- PepType_GetNameStr(flagsType),
- reinterpret_cast<PyObject *>(flagsType)) < 0) {
- Py_DECREF(enumType);
- return nullptr;
- }
- return enumType;
-}
-
-static PyObject *createEnumItem(PyTypeObject *enumType, const char *itemName,
- EnumValueType itemValue)
-{
- init_enum();
- PyObject *enumItem = newItemOld(enumType, itemValue, itemName);
- if (PyDict_SetItemString(enumType->tp_dict, itemName, enumItem) < 0) {
- Py_DECREF(enumItem);
- return nullptr;
- }
- return enumItem;
-}
-
-bool createGlobalEnumItem(PyTypeObject *enumType, PyObject *module,
- const char *itemName, EnumValueType itemValue)
-{
- PyObject *enumItem = createEnumItem(enumType, itemName, itemValue);
- if (!enumItem)
- return false;
- int ok = useOldEnum ? PyModule_AddObject(module, itemName, enumItem) : true;
- Py_DECREF(enumItem);
- return ok >= 0;
-}
-
-bool createScopedEnumItem(PyTypeObject *enumType, PyTypeObject *scope,
- const char *itemName, EnumValueType itemValue)
-{
- PyObject *enumItem = createEnumItem(enumType, itemName, itemValue);
- if (!enumItem)
- return false;
- int ok = useOldEnum ? PyDict_SetItemString(scope->tp_dict, itemName, enumItem) : true;
- Py_DECREF(enumItem);
- return ok >= 0;
-}
-
-// This exists temporary as the old way to create an enum item.
-// For the public interface, we use a new function
-static PyObject *newItemOld(PyTypeObject *enumType,
- EnumValueType itemValue, const char *itemName)
-{
- bool newValue = true;
- SbkEnumObject *enumObj;
- if (!itemName) {
- enumObj = reinterpret_cast<SbkEnumObject *>(
- getEnumItemFromValue(enumType, itemValue));
- if (enumObj)
- return reinterpret_cast<PyObject *>(enumObj);
-
- newValue = false;
- }
-
- enumObj = PyObject_New(SbkEnumObject, enumType);
- if (!enumObj)
- return nullptr;
-
- enumObj->ob_name = itemName ? PyBytes_FromString(itemName) : nullptr;
- enumObj->ob_value = itemValue;
-
- if (newValue) {
- auto dict = enumType->tp_dict; // Note: 'values' is borrowed
- PyObject *values = PyDict_GetItemWithError(dict, PyName::values());
- if (values == nullptr) {
- if (PyErr_Occurred())
- return nullptr;
- AutoDecRef new_values(values = PyDict_New());
- if (values == nullptr)
- return nullptr;
- if (PyDict_SetItem(dict, PyName::values(), values) < 0)
- return nullptr;
- }
- PyDict_SetItemString(values, itemName, reinterpret_cast<PyObject *>(enumObj));
- }
-
- return reinterpret_cast<PyObject *>(enumObj);
-}
-
-PyObject *newItem(PyTypeObject *enumType, EnumValueType itemValue,
- const char *itemName)
-{
- init_enum();
- // PYSIDE-1735: Decide dynamically if new or old enums will be used.
- if (useOldEnum)
- return newItemOld(enumType, itemValue, itemName);
-
- auto *obEnumType = reinterpret_cast<PyObject *>(enumType);
- if (!itemName)
- return PyObject_CallFunction(obEnumType, "L", itemValue);
-
- static PyObject *const _member_map_ = String::createStaticString("_member_map_");
- auto *member_map = PyDict_GetItem(enumType->tp_dict, _member_map_);
- if (!(member_map && PyDict_Check(member_map)))
- return nullptr;
- auto *result = PyDict_GetItemString(member_map, itemName);
- Py_XINCREF(result);
- return result;
-}
-
-} // namespace Shiboken
-} // namespace Enum
-
-static PyType_Slot SbkNewEnum_slots[] = {
- {Py_tp_repr, reinterpret_cast<void *>(SbkEnumObject_repr)},
- {Py_tp_str, reinterpret_cast<void *>(SbkEnumObject_repr)},
- {Py_tp_getset, reinterpret_cast<void *>(SbkEnumGetSetList)},
- {Py_tp_methods, reinterpret_cast<void *>(SbkEnumObject_Methods)},
- {Py_tp_new, reinterpret_cast<void *>(SbkEnum_tp_new)},
- {Py_nb_add, reinterpret_cast<void *>(enum_add)},
- {Py_nb_subtract, reinterpret_cast<void *>(enum_subtract)},
- {Py_nb_multiply, reinterpret_cast<void *>(enum_multiply)},
- {Py_nb_positive, reinterpret_cast<void *>(enum_int)},
- {Py_nb_bool, reinterpret_cast<void *>(enum_bool)},
- {Py_nb_and, reinterpret_cast<void *>(enum_and)},
- {Py_nb_xor, reinterpret_cast<void *>(enum_xor)},
- {Py_nb_or, reinterpret_cast<void *>(enum_or)},
- {Py_nb_int, reinterpret_cast<void *>(enum_int)},
- {Py_nb_index, reinterpret_cast<void *>(enum_int)},
- {Py_tp_richcompare, reinterpret_cast<void *>(enum_richcompare)},
- {Py_tp_hash, reinterpret_cast<void *>(enum_hash)},
- {Py_tp_dealloc, reinterpret_cast<void *>(enum_object_dealloc)},
- {0, nullptr}
-};
-static PyType_Spec SbkNewEnum_spec = {
- "1:Shiboken.Enum",
- sizeof(SbkEnumObject),
- 0,
- Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
- SbkNewEnum_slots,
-};
-
-static PyTypeObject *SbkEnum_TypeF()
-{
- static auto type = SbkType_FromSpecWithMeta(&SbkNewEnum_spec, SbkEnumType_TypeF());
- return type;
-}
-
-namespace Shiboken { namespace Enum {
-
-static void
-copyNumberMethods(PyTypeObject *flagsType,
- PyType_Slot number_slots[],
- int *pidx)
-{
- int idx = *pidx;
-#define PUT_SLOT(name) \
- number_slots[idx].slot = (name); \
- number_slots[idx].pfunc = PyType_GetSlot(flagsType, (name)); \
- ++idx;
-
- PUT_SLOT(Py_nb_absolute);
- PUT_SLOT(Py_nb_add);
- PUT_SLOT(Py_nb_and);
- PUT_SLOT(Py_nb_bool);
- PUT_SLOT(Py_nb_divmod);
- PUT_SLOT(Py_nb_float);
- PUT_SLOT(Py_nb_floor_divide);
- PUT_SLOT(Py_nb_index);
- PUT_SLOT(Py_nb_inplace_add);
- PUT_SLOT(Py_nb_inplace_and);
- PUT_SLOT(Py_nb_inplace_floor_divide);
- PUT_SLOT(Py_nb_inplace_lshift);
- PUT_SLOT(Py_nb_inplace_multiply);
- PUT_SLOT(Py_nb_inplace_or);
- PUT_SLOT(Py_nb_inplace_power);
- PUT_SLOT(Py_nb_inplace_remainder);
- PUT_SLOT(Py_nb_inplace_rshift);
- PUT_SLOT(Py_nb_inplace_subtract);
- PUT_SLOT(Py_nb_inplace_true_divide);
- PUT_SLOT(Py_nb_inplace_xor);
- PUT_SLOT(Py_nb_int);
- PUT_SLOT(Py_nb_invert);
- PUT_SLOT(Py_nb_lshift);
- PUT_SLOT(Py_nb_multiply);
- PUT_SLOT(Py_nb_negative);
- PUT_SLOT(Py_nb_or);
- PUT_SLOT(Py_nb_positive);
- PUT_SLOT(Py_nb_power);
- PUT_SLOT(Py_nb_remainder);
- PUT_SLOT(Py_nb_rshift);
- PUT_SLOT(Py_nb_subtract);
- PUT_SLOT(Py_nb_true_divide);
- PUT_SLOT(Py_nb_xor);
-#undef PUT_SLOT
- *pidx = idx;
-}
-
-static PyTypeObject * newTypeWithNameOld(const char *name,
- const char *cppName,
- PyTypeObject *numbers_fromFlag)
-{
- // Careful: SbkType_FromSpec does not allocate the string.
- PyType_Slot newslots[99] = {}; // enough but not too big for the stack
- PyType_Spec newspec;
- DeclaredEnumTypes::EnumEntry entry{strdup(name), nullptr};
- newspec.name = entry.name; // Note that SbkType_FromSpec might use a substring.
- newspec.basicsize = SbkNewEnum_spec.basicsize;
- newspec.itemsize = SbkNewEnum_spec.itemsize;
- newspec.flags = SbkNewEnum_spec.flags;
- // we must append all the number methods, so rebuild everything:
- int idx = 0;
- while (SbkNewEnum_slots[idx].slot) {
- newslots[idx].slot = SbkNewEnum_slots[idx].slot;
- newslots[idx].pfunc = SbkNewEnum_slots[idx].pfunc;
- ++idx;
- }
- if (numbers_fromFlag)
- copyNumberMethods(numbers_fromFlag, newslots, &idx);
- newspec.slots = newslots;
- AutoDecRef bases(PyTuple_New(1));
- static auto basetype = reinterpret_cast<PyObject *>(SbkEnum_TypeF());
- Py_INCREF(basetype);
- PyTuple_SetItem(bases, 0, basetype);
- auto *type = SbkType_FromSpecBasesMeta(&newspec, bases, SbkEnumType_TypeF());
- entry.type = type;
-
- auto *enumType = reinterpret_cast<SbkEnumType *>(type);
- auto *setp = PepType_SETP(enumType);
- setp->cppName = cppName;
- DeclaredEnumTypes::instance().addEnumType(entry);
- return entry.type;
-}
-
-// PySIDE-1735: This function is in the API and should be removed in 6.4 .
-// Python enums are created differently.
-PyTypeObject *newTypeWithName(const char *name,
- const char *cppName,
- PyTypeObject *numbers_fromFlag)
-{
- if (!useOldEnum)
- PyErr_Format(PyExc_RuntimeError, "function `%s` can no longer be used when the Python "
- "Enum's have been selected", __FUNCTION__);
- return newTypeWithNameOld(name, cppName, numbers_fromFlag);
-}
-
-const char *getCppName(PyTypeObject *enumType)
-{
- assert(Py_TYPE(enumType) == SbkEnumType_TypeF());
- auto *type = reinterpret_cast<SbkEnumType *>(enumType);
- auto *setp = PepType_SETP(type);
- return setp->cppName;
-}
-
-EnumValueType getValue(PyObject *enumItem)
-{
- init_enum();
-
- assert(Enum::check(enumItem));
-
- // PYSIDE-1735: Decide dynamically if new or old enums will be used.
- if (useOldEnum)
- return reinterpret_cast<SbkEnumObject *>(enumItem)->ob_value;
-
- std::cerr << __FUNCTION__ << ' ' << Shiboken::debugPyObject(enumItem)
- << " err=" << Shiboken::debugPyObject(PyErr_Occurred()) << '\n';
-
- AutoDecRef pyValue(PyObject_GetAttrString(enumItem, "value"));
- return PyLong_AsLongLong(pyValue);
-}
-
-void setTypeConverter(PyTypeObject *type, SbkConverter *converter, bool isFlag)
-{
- if (isFlag) {
- auto *flagsType = reinterpret_cast<PySideQFlagsType *>(type);
- PepType_PFTP(flagsType)->converter = converter;
- }
- else {
- auto *enumType = reinterpret_cast<SbkEnumType *>(type);
- PepType_SETP(enumType)->converter = converter;
- }
-}
-
-} // namespace Enum
-
-DeclaredEnumTypes &DeclaredEnumTypes::instance()
-{
- static DeclaredEnumTypes me;
- return me;
-}
-
-DeclaredEnumTypes::DeclaredEnumTypes() = default;
-
-DeclaredEnumTypes::~DeclaredEnumTypes()
-{
- cleanup();
-}
-
-void DeclaredEnumTypes::cleanup()
-{
- static bool was_called = false;
- if (was_called)
- return;
-
- for (const auto &e : m_enumTypes) {
- std::free(e.name);
- }
- m_enumTypes.clear();
- was_called = true;
-}
-
-} // namespace Shiboken
-
-static void cleanupEnumTypes()
-{
- DeclaredEnumTypes::instance().cleanup();
-}
-
-///////////////////////////////////////////////////////////////////////
-//
-// PYSIDE-1735: Re-implementation of Enums using Python
-// ====================================================
-//
-// This is a very simple, first implementation of a replacement
-// for the Qt-like Enums using the Python Enum module.
-//
-// The basic idea:
-// ---------------
-// * We create the Enums as always
-// * After creation of each enum, a special function is called that
-// * grabs the last generated enum
-// * reads all Enum items
-// * generates a class statement for the Python Enum
-// * creates a new Python Enum class
-// * replaces the already inserted Enum with the new one.
-//
-// There are lots of ways to optimize that. Will be added later.
-//
-extern "C" {
-
-struct lastEnumCreated {
- PyObject *scopeOrModule;
- const char *name;
- PyTypeObject *enumType;
- PyTypeObject *flagsType;
-};
-
-static lastEnumCreated lec{};
-
-static PyTypeObject *recordCurrentEnum(PyObject *scopeOrModule,
- const char *name,
- PyTypeObject *enumType,
- PyTypeObject *flagsType)
-{
- lec.scopeOrModule = scopeOrModule;
- lec.name = name;
- lec.enumType = enumType;
- lec.flagsType = flagsType;
-
- // PYSIDE-1735: Decide dynamically if new or old enums will be used.
- if (useOldEnum)
- return flagsType;
-
- // We return nullptr as flagsType to disable flag creation.
- return nullptr;
-}
-
-static bool is_old_version()
-{
- auto *sysmodule = PyImport_AddModule("sys");
- auto *dic = PyModule_GetDict(sysmodule);
- auto *version = PyDict_GetItemString(dic, "version_info");
- auto *major = PyTuple_GetItem(version, 0);
- auto *minor = PyTuple_GetItem(version, 1);
- auto number = PyLong_AsLong(major) * 1000 + PyLong_AsLong(minor);
- return number <= 3008;
-}
-
///////////////////////////////////////////////////////////////////////
//
// Support for Missing Values
@@ -1015,6 +132,7 @@ static bool is_old_version()
// We create each constant only once and keep the result in a dict
// "_sbk_missing_". This is similar to a competitor's "_sip_missing_".
//
+
static PyObject *missing_func(PyObject * /* self */ , PyObject *args)
{
// In order to relax matters to be more compatible with C++, we need
@@ -1030,10 +148,11 @@ static PyObject *missing_func(PyObject * /* self */ , PyObject *args)
if (!PyLong_Check(value))
Py_RETURN_NONE;
auto *type = reinterpret_cast<PyTypeObject *>(klass);
- auto *sbk_missing = PyDict_GetItem(type->tp_dict, _sbk_missing);
+ AutoDecRef tpDict(PepType_GetDict(type));
+ auto *sbk_missing = PyDict_GetItem(tpDict.object(), _sbk_missing);
if (!sbk_missing) {
sbk_missing = PyDict_New();
- PyDict_SetItem(type->tp_dict, _sbk_missing, sbk_missing);
+ PyDict_SetItem(tpDict.object(), _sbk_missing, sbk_missing);
}
// See if the value is already in the dict.
AutoDecRef val_str(PyObject_CallMethod(value, "__str__", nullptr));
@@ -1084,35 +203,99 @@ static PyObject *create_missing_func(PyObject *klass)
static auto *const obType = reinterpret_cast<PyObject *>(type);
static auto *const _missing = Shiboken::String::createStaticString("_missing_");
static auto *const func = PyObject_GetAttr(obType, _missing);
- static auto *const functools = PyImport_ImportModule("_functools"); // builtin
- static auto *const _partial = Shiboken::String::createStaticString("partial");
- static auto *const partial = PyObject_GetAttr(functools, _partial);
+ static auto *const partial = Pep_GetPartialFunction();
return PyObject_CallFunctionObjArgs(partial, func, klass, nullptr);
}
//
////////////////////////////////////////////////////////////////////////
-PyTypeObject *morphLastEnumToPython()
+} // extern "C"
+
+namespace Shiboken::Enum {
+
+int enumOption{};
+
+bool check(PyObject *pyObj)
+{
+ init_enum();
+
+ static PyTypeObject *meta = getPyEnumMeta();
+ return Py_TYPE(Py_TYPE(pyObj)) == reinterpret_cast<PyTypeObject *>(meta);
+}
+
+PyObject *getEnumItemFromValue(PyTypeObject *enumType, EnumValueType itemValue)
+{
+ init_enum();
+
+ auto *obEnumType = reinterpret_cast<PyObject *>(enumType);
+ AutoDecRef val2members(PyObject_GetAttrString(obEnumType, "_value2member_map_"));
+ if (val2members.isNull()) {
+ PyErr_Clear();
+ return nullptr;
+ }
+ AutoDecRef ob_value(PyLong_FromLongLong(itemValue));
+ auto *result = PyDict_GetItem(val2members, ob_value);
+ Py_XINCREF(result);
+ return result;
+}
+
+PyObject *newItem(PyTypeObject *enumType, EnumValueType itemValue,
+ const char *itemName)
+{
+ init_enum();
+
+ auto *obEnumType = reinterpret_cast<PyObject *>(enumType);
+ if (!itemName)
+ return PyObject_CallFunction(obEnumType, "L", itemValue);
+
+ static PyObject *const _member_map_ = String::createStaticString("_member_map_");
+ AutoDecRef tpDict(PepType_GetDict(enumType));
+ auto *member_map = PyDict_GetItem(tpDict.object(), _member_map_);
+ if (!(member_map && PyDict_Check(member_map)))
+ return nullptr;
+ auto *result = PyDict_GetItemString(member_map, itemName);
+ Py_XINCREF(result);
+ return result;
+}
+
+EnumValueType getValue(PyObject *enumItem)
{
- /// The Python Enum internal structure is way too complicated.
- /// It is much easier to generate Python code and execute it.
+ init_enum();
+
+ assert(Enum::check(enumItem));
+
+ AutoDecRef pyValue(PyObject_GetAttrString(enumItem, "value"));
+ return PyLong_AsLongLong(pyValue);
+}
- // Pick up the last generated Enum and convert it into a PyEnum
- auto *enumType = lec.enumType;
- // This is temporary; SbkEnumType will be removed, soon.
+void setTypeConverter(PyTypeObject *type, SbkConverter *converter)
+{
+ auto *enumType = reinterpret_cast<SbkEnumType *>(type);
+ PepType_SETP(enumType)->converter = converter;
+}
- // PYSIDE-1735: Decide dynamically if new or old enums will be used.
- if (useOldEnum)
- return enumType;
+static PyTypeObject *createEnumForPython(PyObject *scopeOrModule,
+ const char *fullName,
+ PyObject *pyEnumItems)
+{
+ const char *colon = strchr(fullName, ':');
+ assert(colon);
+ int package_level = atoi(fullName);
+ const char *mod = colon + 1;
- auto *setp = PepType_SETP(reinterpret_cast<SbkEnumType *>(enumType));
- if (setp->replacementType) {
- // For some (yet to fix) reason, initialization of the enums can happen twice.
- // If that happens, use the existing new type to keep type checks correct.
- return setp->replacementType;
+ const char *qual = mod;
+ for (int idx = package_level; idx > 0; --idx) {
+ const char *dot = strchr(qual, '.');
+ if (!dot)
+ break;
+ qual = dot + 1;
}
+ int mlen = qual - mod - 1;
+ AutoDecRef module(Shiboken::String::fromCString(mod, mlen));
+ AutoDecRef qualname(Shiboken::String::fromCString(qual));
+ const char *dot = strrchr(qual, '.');
+ AutoDecRef name(Shiboken::String::fromCString(dot ? dot + 1 : qual));
- auto *scopeOrModule = lec.scopeOrModule;
static PyObject *enumName = String::createStaticString("IntEnum");
if (PyType_Check(scopeOrModule)) {
// For global objects, we have no good solution, yet where to put the int info.
@@ -1120,15 +303,9 @@ PyTypeObject *morphLastEnumToPython()
auto *sotp = PepType_SOTP(type);
if (!sotp->enumFlagsDict)
initEnumFlagsDict(type);
- enumName = PyDict_GetItem(sotp->enumTypeDict, String::fromCString(lec.name));
+ enumName = PyDict_GetItem(sotp->enumTypeDict, name);
}
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- PyObject *values = PyDict_GetItem(enumType->tp_dict, PyName::values());
- if (!values)
- return nullptr;
-
AutoDecRef PyEnumType(PyObject_GetAttr(PyEnumModule, enumName));
assert(PyEnumType.object());
bool isFlag = PyObject_IsSubclass(PyEnumType, PyFlag);
@@ -1141,24 +318,13 @@ PyTypeObject *morphLastEnumToPython()
PyEnumType.reset(surrogate);
}
- // Walk the values dict and create a Python enum type.
- AutoDecRef name(PyUnicode_FromString(lec.name));
- AutoDecRef args(PyList_New(0));
+ // Walk the enumItemStrings and create a Python enum type.
auto *pyName = name.object();
- auto *pyArgs = args.object();
- while (PyDict_Next(values, &pos, &key, &value)) {
- auto *key_value = PyTuple_New(2);
- PyTuple_SET_ITEM(key_value, 0, key);
- Py_INCREF(key);
- auto *obj = reinterpret_cast<SbkEnumObject *>(value);
- auto *num = PyLong_FromLongLong(obj->ob_value);
- PyTuple_SET_ITEM(key_value, 1, num);
- PyList_Append(pyArgs, key_value);
- }
+
// We now create the new type. Since Python 3.11, we need to pass in
// `boundary=KEEP` because the default STRICT crashes on us.
// See QDir.Filter.Drives | QDir.Filter.Files
- AutoDecRef callArgs(Py_BuildValue("(OO)", pyName, pyArgs));
+ AutoDecRef callArgs(Py_BuildValue("(OO)", pyName, pyEnumItems));
AutoDecRef callDict(PyDict_New());
static PyObject *boundary = String::createStaticString("boundary");
if (PyFlag_KEEP)
@@ -1177,40 +343,110 @@ PyTypeObject *morphLastEnumToPython()
}
auto *newType = reinterpret_cast<PyTypeObject *>(obNewType);
- auto *obEnumType = reinterpret_cast<PyObject *>(enumType);
- AutoDecRef qual_name(PyObject_GetAttr(obEnumType, PyMagicName::qualname()));
- PyObject_SetAttr(obNewType, PyMagicName::qualname(), qual_name);
- AutoDecRef module(PyObject_GetAttr(obEnumType, PyMagicName::module()));
+ PyObject_SetAttr(obNewType, PyMagicName::qualname(), qualname);
PyObject_SetAttr(obNewType, PyMagicName::module(), module);
// See if we should re-introduce shortcuts in the enclosing object.
const bool useGlobalShortcut = (Enum::enumOption & Enum::ENOPT_GLOBAL_SHORTCUT) != 0;
const bool useScopedShortcut = (Enum::enumOption & Enum::ENOPT_SCOPED_SHORTCUT) != 0;
if (useGlobalShortcut || useScopedShortcut) {
+ // We have to use the iterator protokol because the values dict is a mappingproxy.
+ AutoDecRef values(PyObject_GetAttr(obNewType, PyMagicName::members()));
+ AutoDecRef mapIterator(PyObject_GetIter(values));
+ AutoDecRef mapKey{};
bool isModule = PyModule_Check(scopeOrModule);
- pos = 0;
- while (PyDict_Next(values, &pos, &key, &value)) {
- AutoDecRef entry(PyObject_GetAttr(obNewType, key));
- if ((useGlobalShortcut && isModule) || (useScopedShortcut && !isModule))
- if (PyObject_SetAttr(scopeOrModule, key, entry) < 0)
+ while ((mapKey.reset(PyIter_Next(mapIterator))), mapKey.object()) {
+ if ((useGlobalShortcut && isModule) || (useScopedShortcut && !isModule)) {
+ AutoDecRef value(PyObject_GetItem(values, mapKey));
+ if (PyObject_SetAttr(scopeOrModule, mapKey, value) < 0)
return nullptr;
+ }
}
}
- // Protect against double initialization
- setp->replacementType = newType;
-
- // PYSIDE-1735: Old Python versions can't stand the early enum deallocation.
- static bool old_python_version = is_old_version();
- if (old_python_version)
- Py_INCREF(obEnumType);
return newType;
}
-PyTypeObject *mapFlagsToSameEnum(PyTypeObject *FType, PyTypeObject *EType)
+template <typename IntT>
+static PyObject *toPyObject(IntT v)
{
- // this will be switchable...
- return useOldEnum ? FType : EType;
+ if constexpr (sizeof(IntT) == 8) {
+ if constexpr (std::is_unsigned_v<IntT>)
+ return PyLong_FromUnsignedLongLong(v);
+ return PyLong_FromLongLong(v);
+ }
+ if constexpr (std::is_unsigned_v<IntT>)
+ return PyLong_FromUnsignedLong(v);
+ return PyLong_FromLong(v);
}
-} // extern "C"
+template <typename IntT>
+static PyTypeObject *createPythonEnumHelper(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const IntT enumValues[])
+{
+ AutoDecRef args(PyList_New(0));
+ auto *pyEnumItems = args.object();
+ for (size_t idx = 0; enumItemStrings[idx] != nullptr; ++idx) {
+ const char *kv = enumItemStrings[idx];
+ auto *key = PyUnicode_FromString(kv);
+ auto *value = toPyObject(enumValues[idx]);
+ auto *key_value = PyTuple_New(2);
+ PyTuple_SET_ITEM(key_value, 0, key);
+ PyTuple_SET_ITEM(key_value, 1, value);
+ PyList_Append(pyEnumItems, key_value);
+ }
+ return createEnumForPython(module, fullName, pyEnumItems);
+}
+
+// Now we have to concretize these functions explicitly,
+// otherwise templates will not work across modules.
+
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int64_t enumValues[])
+{
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
+}
+
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint64_t enumValues[])
+{
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
+}
+
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int32_t enumValues[])
+{
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
+}
+
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint32_t enumValues[])
+{
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
+}
+
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int16_t enumValues[])
+{
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
+}
+
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint16_t enumValues[])
+{
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
+}
+
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int8_t enumValues[])
+{
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
+}
+
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint8_t enumValues[])
+{
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
+}
+
+} // namespace Shiboken::Enum
diff --git a/sources/shiboken6/libshiboken/sbkenum.h b/sources/shiboken6/libshiboken/sbkenum.h
index a39519189..e19ca4b4c 100644
--- a/sources/shiboken6/libshiboken/sbkenum.h
+++ b/sources/shiboken6/libshiboken/sbkenum.h
@@ -15,81 +15,88 @@ LIBSHIBOKEN_API bool PyEnumMeta_Check(PyObject *ob);
/// exposed for the signature module
LIBSHIBOKEN_API void init_enum();
-extern LIBSHIBOKEN_API PyTypeObject *SbkEnumType_TypeF(void);
struct SbkConverter;
struct SbkEnumType;
-struct SbkEnumTypePrivate;
-} // extern "C"
-
-namespace Shiboken
+struct SbkEnumTypePrivate
{
+ SbkConverter *converter;
+};
+
+/// PYSIDE-1735: Pass on the Python enum/flag information.
+LIBSHIBOKEN_API void initEnumFlagsDict(PyTypeObject *type);
+
+/// PYSIDE-1735: Make sure that we can import the Python enum implementation.
+LIBSHIBOKEN_API PyTypeObject *getPyEnumMeta();
+/// PYSIDE-1735: Helper function supporting QEnum
+LIBSHIBOKEN_API int enumIsFlag(PyObject *ob_enum);
-inline bool isShibokenEnum(PyObject *pyObj)
-{
- return Py_TYPE(Py_TYPE(pyObj)) == SbkEnumType_TypeF();
}
-namespace Enum
+namespace Shiboken::Enum {
+
+enum : int {
+ ENOPT_OLD_ENUM = 0x00, // PySide 6.6: no longer supported
+ ENOPT_NEW_ENUM = 0x01,
+ ENOPT_INHERIT_INT = 0x02,
+ ENOPT_GLOBAL_SHORTCUT = 0x04,
+ ENOPT_SCOPED_SHORTCUT = 0x08,
+ ENOPT_NO_FAKESHORTCUT = 0x10,
+ ENOPT_NO_FAKERENAMES = 0x20,
+ ENOPT_NO_ZERODEFAULT = 0x40,
+ ENOPT_NO_MISSING = 0x80,
+};
+
+LIBSHIBOKEN_API extern int enumOption;
+
+using EnumValueType = long long;
+
+LIBSHIBOKEN_API bool check(PyObject *obj);
+
+LIBSHIBOKEN_API PyObject *newItem(PyTypeObject *enumType, EnumValueType itemValue,
+ const char *itemName = nullptr);
+
+LIBSHIBOKEN_API EnumValueType getValue(PyObject *enumItem);
+LIBSHIBOKEN_API PyObject *getEnumItemFromValue(PyTypeObject *enumType,
+ EnumValueType itemValue);
+
+/// Sets the enum/flag's type converter.
+LIBSHIBOKEN_API void setTypeConverter(PyTypeObject *type, SbkConverter *converter);
+
+/// Creating Python enums for different types.
+LIBSHIBOKEN_API PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int64_t enumValues[]);
+
+LIBSHIBOKEN_API PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint64_t enumValues[]);
+
+LIBSHIBOKEN_API PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int32_t enumValues[]);
+
+LIBSHIBOKEN_API PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint32_t enumValues[]);
+
+LIBSHIBOKEN_API PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int16_t enumValues[]);
+
+LIBSHIBOKEN_API PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint16_t enumValues[]);
+
+LIBSHIBOKEN_API PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int8_t enumValues[]);
+
+LIBSHIBOKEN_API PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint8_t enumValues[]);
+
+/// This template removes duplication by inlining necessary type casts.
+template <typename IntT>
+inline PyTypeObject *createPythonEnum(PyTypeObject *scope,
+ const char *fullName, const char *enumItemStrings[], const IntT enumValues[])
{
- using EnumValueType = long long;
-
- LIBSHIBOKEN_API bool check(PyObject *obj);
- /**
- * Creates a new enum type (and its flags type, if any is given)
- * and registers it to Python and adds it to \p module.
- * \param module Module to where the new enum type will be added.
- * \param name Name of the enum.
- * \param fullName Name of the enum that includes all scope information (e.g.: "module.Enum").
- * \param cppName Full qualified C++ name of the enum.
- * \param flagsType Optional Python type for the flags associated with the enum.
- * \return The new enum type or NULL if it fails.
- */
- LIBSHIBOKEN_API PyTypeObject *createGlobalEnum(PyObject *module,
- const char *name,
- const char *fullName,
- const char *cppName,
- PyTypeObject *flagsType = nullptr);
- /// This function does the same as createGlobalEnum, but adds the enum to a Shiboken type or namespace.
- LIBSHIBOKEN_API PyTypeObject *createScopedEnum(PyTypeObject *scope,
- const char *name,
- const char *fullName,
- const char *cppName,
- PyTypeObject *flagsType = nullptr);
-
- /**
- * Creates a new enum item for a given enum type and adds it to \p module.
- * \param enumType Enum type to where the new enum item will be added.
- * \param module Module to where the enum type of the new enum item belongs.
- * \param itemName Name of the enum item.
- * \param itemValue Numerical value of the enum item.
- * \return true if everything goes fine, false if it fails.
- */
- LIBSHIBOKEN_API bool createGlobalEnumItem(PyTypeObject *enumType, PyObject *module,
- const char *itemName,
- EnumValueType itemValue);
- /// This function does the same as createGlobalEnumItem, but adds the enum to a Shiboken type or namespace.
- LIBSHIBOKEN_API bool createScopedEnumItem(PyTypeObject *enumType, PyTypeObject *scope,
- const char *itemName, EnumValueType itemValue);
-
- LIBSHIBOKEN_API PyObject *newItem(PyTypeObject *enumType, EnumValueType itemValue,
- const char *itemName = nullptr);
-
- LIBSHIBOKEN_API PyTypeObject *newTypeWithName(const char *name, const char *cppName,
- PyTypeObject *numbers_fromFlag=nullptr);
- LIBSHIBOKEN_API const char *getCppName(PyTypeObject *type);
- LIBSHIBOKEN_API PyObject *getCppNameNew(PyTypeObject *type);
-
- LIBSHIBOKEN_API EnumValueType getValue(PyObject *enumItem);
- LIBSHIBOKEN_API PyObject *getEnumItemFromValue(PyTypeObject *enumType,
- EnumValueType itemValue);
-
- /// Sets the enum/flag's type converter.
- LIBSHIBOKEN_API void setTypeConverter(PyTypeObject *type, SbkConverter *converter, bool isFlag);
-
- LIBSHIBOKEN_API PyObject *unpickleEnum(PyObject *, PyObject *);
+ auto *obScope = reinterpret_cast<PyObject *>(scope);
+ return createPythonEnum(obScope, fullName, enumItemStrings, enumValues);
}
-} // namespace Shiboken
+} // namespace Shiboken::Enum
#endif // SKB_PYENUM_H
diff --git a/sources/shiboken6/libshiboken/sbkenum_p.h b/sources/shiboken6/libshiboken/sbkenum_p.h
deleted file mode 100644
index d8477b4b3..000000000
--- a/sources/shiboken6/libshiboken/sbkenum_p.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (C) 2021 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef SBKENUM_P_H
-#define SBKENUM_P_H
-
-#include "sbkpython.h"
-#include "shibokenmacros.h"
-
-struct SbkEnumTypePrivate
-{
- SbkConverter *converter;
- const char *cppName;
- PyTypeObject *replacementType;
-};
-
-extern "C" {
-
-/// PYSIDE-1735: Pass on the Python enum/flag information.
-LIBSHIBOKEN_API void initEnumFlagsDict(PyTypeObject *type);
-
-/// PYSIDE-1735: Patching the Enum / Flags implementation. Remove in 6.4
-LIBSHIBOKEN_API PyTypeObject *morphLastEnumToPython();
-LIBSHIBOKEN_API PyTypeObject *mapFlagsToSameEnum(PyTypeObject *FType, PyTypeObject *EType);
-
-/// PYSIDE-1735: Make sure that we can import the Python enum implementation.
-LIBSHIBOKEN_API PyTypeObject *getPyEnumMeta();
-/// PYSIDE-1735: Helper function supporting QEnum
-LIBSHIBOKEN_API int enumIsFlag(PyObject *ob_enum);
-/// PYSIDE-1735: Helper function to ask what enum we are using
-LIBSHIBOKEN_API bool usingNewEnum();
-
-}
-
-namespace Shiboken { namespace Enum {
-
-enum : int {
- ENOPT_OLD_ENUM = 0x00,
- ENOPT_NEW_ENUM = 0x01,
- ENOPT_INHERIT_INT = 0x02,
- ENOPT_GLOBAL_SHORTCUT = 0x04,
- ENOPT_SCOPED_SHORTCUT = 0x08,
- ENOPT_NO_FAKESHORTCUT = 0x10,
- ENOPT_NO_FAKERENAMES = 0x20,
- ENOPT_NO_ZERODEFAULT = 0x40,
- ENOPT_NO_MISSING = 0x80,
-};
-
-LIBSHIBOKEN_API extern int enumOption;
-
-}}
-
-#endif // SBKENUM_P_H
diff --git a/sources/shiboken6/libshiboken/sbkerrors.cpp b/sources/shiboken6/libshiboken/sbkerrors.cpp
index c8f8a989f..84c080f8d 100644
--- a/sources/shiboken6/libshiboken/sbkerrors.cpp
+++ b/sources/shiboken6/libshiboken/sbkerrors.cpp
@@ -2,10 +2,42 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "sbkerrors.h"
+#include "sbkstring.h"
#include "helper.h"
+#include "gilstate.h"
+
+#include <cstdio>
+#include <string>
+
+using namespace std::literals::string_literals;
namespace Shiboken
{
+
+// PYSIDE-2335: Track down if we can reach a Python error handler.
+// _pythonContextStack has always the current state of handler status
+// in its lowest bit.
+// Blocking calls like exec or run need to use `setBlocking`.
+static thread_local std::size_t _pythonContextStack{};
+
+PythonContextMarker::PythonContextMarker()
+{
+ // Shift history up and set lowest bit.
+ _pythonContextStack = (_pythonContextStack * 2) + 1;
+}
+
+PythonContextMarker::~PythonContextMarker()
+{
+ // Shift history down.
+ _pythonContextStack /= 2;
+}
+
+void PythonContextMarker::setBlocking()
+{
+ // Clear lowest bit.
+ _pythonContextStack = _pythonContextStack / 2 * 2;
+}
+
namespace Errors
{
@@ -66,6 +98,74 @@ void setWrongContainerType()
PyErr_SetString(PyExc_TypeError, "Wrong type passed to container conversion.");
}
+// Prepend something to an exception message provided it is a single string
+// argument.
+static bool prependToExceptionMessage(PyObject *exc, const char *context)
+{
+ Shiboken::AutoDecRef args(PepException_GetArgs(exc));
+ if (args.isNull() || PyTuple_Check(args.object()) == 0 || PyTuple_Size(args) != 1)
+ return false;
+ auto *oldMessage = PyTuple_GetItem(args, 0);
+ if (oldMessage == nullptr || PyUnicode_CheckExact(oldMessage) == 0)
+ return false;
+ auto *newMessage = PyUnicode_FromFormat("%s%U", context, oldMessage);
+ PepException_SetArgs(exc, PyTuple_Pack(1, newMessage));
+ return true;
+}
+
+struct ErrorStore {
+ PyObject *type;
+ PyObject *exc;
+ PyObject *traceback;
+};
+
+static thread_local ErrorStore savedError{};
+
+static bool hasPythonContext()
+{
+ return _pythonContextStack & 1;
+}
+
+void storeErrorOrPrint()
+{
+ // This error happened in a function with no way to return an error state.
+ // Therefore, we handle the error when we are error checking, anyway.
+ // But we do that only when we know that an error handler can pick it up.
+ if (hasPythonContext())
+ PyErr_Fetch(&savedError.type, &savedError.exc, &savedError.traceback);
+ else
+ PyErr_Print();
+}
+
+// Like storeErrorOrPrint() with additional context info that is prepended
+// to the exception message or printed.
+static void storeErrorOrPrintWithContext(const char *context)
+{
+ if (hasPythonContext()) {
+ PyErr_Fetch(&savedError.type, &savedError.exc, &savedError.traceback);
+ prependToExceptionMessage(savedError.exc, context);
+ } else {
+ std::fputs(context, stderr);
+ PyErr_Print();
+ }
+}
+
+void storePythonOverrideErrorOrPrint(const char *className, const char *funcName)
+{
+ const std::string context = "Error calling Python override of "s
+ + className + "::"s + funcName + "(): "s;
+ storeErrorOrPrintWithContext(context.c_str());
+}
+
+PyObject *occurred()
+{
+ if (savedError.type) {
+ PyErr_Restore(savedError.type, savedError.exc, savedError.traceback);
+ savedError.type = nullptr;
+ }
+ return PyErr_Occurred();
+}
+
} // namespace Errors
namespace Warnings
diff --git a/sources/shiboken6/libshiboken/sbkerrors.h b/sources/shiboken6/libshiboken/sbkerrors.h
index d894d8e7a..18ce701e7 100644
--- a/sources/shiboken6/libshiboken/sbkerrors.h
+++ b/sources/shiboken6/libshiboken/sbkerrors.h
@@ -7,8 +7,31 @@
#include "sbkpython.h"
#include "shibokenmacros.h"
+/// Craving for C++20 and std::source_location::current()
+#if defined(_MSC_VER)
+# define SBK_FUNC_INFO __FUNCSIG__
+#elif defined(__GNUC__)
+# define SBK_FUNC_INFO __PRETTY_FUNCTION__
+#else
+# define SBK_FUNC_INFO __FUNCTION__
+#endif
+
namespace Shiboken
{
+
+struct LIBSHIBOKEN_API PythonContextMarker
+{
+public:
+ PythonContextMarker(const PythonContextMarker &) = delete;
+ PythonContextMarker(PythonContextMarker &&) = delete;
+ PythonContextMarker &operator=(const PythonContextMarker &) = delete;
+ PythonContextMarker &operator=(PythonContextMarker &&) = delete;
+
+ explicit PythonContextMarker();
+ ~PythonContextMarker();
+ void setBlocking();
+};
+
namespace Errors
{
@@ -23,6 +46,20 @@ LIBSHIBOKEN_API void setSequenceTypeError(const char *expectedType);
LIBSHIBOKEN_API void setSetterTypeError(const char *name, const char *expectedType);
LIBSHIBOKEN_API void setWrongContainerType();
+/// Report an error ASAP: Instead of printing, store for later re-raise.
+/// This replaces `PyErr_Print`, which cannot report errors as exception.
+/// To be used in contexts where raising errors is impossible.
+LIBSHIBOKEN_API void storeErrorOrPrint();
+
+/// Call storeErrorOrPrint() and print the context to report
+/// errors when calling Python overrides of virtual functions.
+LIBSHIBOKEN_API void storePythonOverrideErrorOrPrint(const char *className, const char *funcName);
+
+/// Handle an error as in PyErr_Occurred(), but also check for errors which
+/// were captured by `storeErrorOrPrint`.
+/// To be used in normal error checks.
+LIBSHIBOKEN_API PyObject *occurred();
+
} // namespace Errors
namespace Warnings
diff --git a/sources/shiboken6/libshiboken/sbkfeature_base.cpp b/sources/shiboken6/libshiboken/sbkfeature_base.cpp
index 2931a8abd..f31b8f4f7 100644
--- a/sources/shiboken6/libshiboken/sbkfeature_base.cpp
+++ b/sources/shiboken6/libshiboken/sbkfeature_base.cpp
@@ -4,7 +4,8 @@
#include "basewrapper.h"
#include "basewrapper_p.h"
#include "autodecref.h"
-#include "sbkenum_p.h"
+#include "pep384ext.h"
+#include "sbkenum.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
#include "sbkstaticstrings_p.h"
@@ -12,6 +13,8 @@
#include "sbkfeature_base.h"
#include "gilstate.h"
+#include <cctype>
+
using namespace Shiboken;
extern "C"
@@ -23,7 +26,8 @@ extern "C"
//
int currentSelectId(PyTypeObject *type)
{
- PyObject *PyId = PyObject_GetAttr(type->tp_dict, PyName::select_id());
+ AutoDecRef tpDict(PepType_GetDict(type));
+ PyObject *PyId = PyObject_GetAttr(tpDict.object(), PyName::select_id());
if (PyId == nullptr) {
PyErr_Clear();
return 0x00;
@@ -34,11 +38,19 @@ int currentSelectId(PyTypeObject *type)
}
static SelectableFeatureHook SelectFeatureSet = nullptr;
+static SelectableFeatureCallback featureCb = nullptr;
+
+void setSelectableFeatureCallback(SelectableFeatureCallback func)
+{
+ featureCb = func;
+}
SelectableFeatureHook initSelectableFeature(SelectableFeatureHook func)
{
auto ret = SelectFeatureSet;
SelectFeatureSet = func;
+ if (featureCb)
+ featureCb(SelectFeatureSet != nullptr);
return ret;
}
//
@@ -53,47 +65,62 @@ void disassembleFrame(const char *marker)
static PyObject *dismodule = PyImport_ImportModule("dis");
static PyObject *disco = PyObject_GetAttrString(dismodule, "disco");
static PyObject *const _f_lasti = Shiboken::String::createStaticString("f_lasti");
+ static PyObject *const _f_lineno = Shiboken::String::createStaticString("f_lineno");
static PyObject *const _f_code = Shiboken::String::createStaticString("f_code");
+ static PyObject *const _co_filename = Shiboken::String::createStaticString("co_filename");
+ AutoDecRef ignore{};
auto *frame = reinterpret_cast<PyObject *>(PyEval_GetFrame());
- AutoDecRef f_lasti(PyObject_GetAttr(frame, _f_lasti));
- AutoDecRef f_code(PyObject_GetAttr(frame, _f_code));
- fprintf(stdout, "\n%s BEGIN\n", marker);
- PyObject_CallFunctionObjArgs(disco, f_code.object(), f_lasti.object(), nullptr);
- fprintf(stdout, "%s END\n\n", marker);
- static PyObject *sysmodule = PyImport_ImportModule("sys");
- static PyObject *stdout_file = PyObject_GetAttrString(sysmodule, "stdout");
- PyObject_CallMethod(stdout_file, "flush", nullptr);
+ if (frame == nullptr) {
+ fprintf(stdout, "\n%s BEGIN no frame END\n\n", marker);
+ } else {
+ AutoDecRef f_lasti(PyObject_GetAttr(frame, _f_lasti));
+ AutoDecRef f_lineno(PyObject_GetAttr(frame, _f_lineno));
+ AutoDecRef f_code(PyObject_GetAttr(frame, _f_code));
+ AutoDecRef co_filename(PyObject_GetAttr(f_code, _co_filename));
+ long line = PyLong_AsLong(f_lineno);
+ const char *fname = String::toCString(co_filename);
+ fprintf(stdout, "\n%s BEGIN line=%ld %s\n", marker, line, fname);
+ ignore.reset(PyObject_CallFunctionObjArgs(disco, f_code.object(), f_lasti.object(), nullptr));
+ fprintf(stdout, "%s END line=%ld %s\n\n", marker, line, fname);
+ }
+#if PY_VERSION_HEX >= 0x030C0000 && !Py_LIMITED_API
+ if (error_type)
+ PyErr_DisplayException(error_value);
+#endif
+ static PyObject *stdout_file = PySys_GetObject("stdout");
+ ignore.reset(PyObject_CallMethod(stdout_file, "flush", nullptr));
PyErr_Restore(error_type, error_value, error_traceback);
}
+// python 3.12
+static int const CALL = 171;
// Python 3.11
static int const PRECALL = 166;
// we have "big instructions" with gaps after them
-static int const LOAD_ATTR_GAP = 4 * 2;
-static int const LOAD_METHOD_GAP = 10 * 2;
+static int const LOAD_METHOD_GAP_311 = 10 * 2;
+static int const LOAD_ATTR_GAP_311 = 4 * 2;
+static int const LOAD_ATTR_GAP = 9 * 2;
// Python 3.7 - 3.10
static int const LOAD_METHOD = 160;
static int const CALL_METHOD = 161;
// Python 3.6
static int const CALL_FUNCTION = 131;
static int const LOAD_ATTR = 106;
-
-static int _getVersion()
-{
- static PyObject *const sysmodule = PyImport_AddModule("sys");
- static PyObject *const version = PyObject_GetAttrString(sysmodule, "version_info");
- static PyObject *const major = PyTuple_GetItem(version, 0);
- static PyObject *const minor = PyTuple_GetItem(version, 1);
- static auto number = PyLong_AsLong(major) * 1000 + PyLong_AsLong(minor);
- return number;
-}
+// NoGil (how long will this exist in this form?)
+static int const LOAD_METHOD_NOGIL = 55;
+static int const CALL_METHOD_NOGIL = 72;
static bool currentOpcode_Is_CallMethNoArgs()
{
+ // PYSIDE-2221: Special case for the NoGil version:
+ // Find out if we have such a version.
+ // We could also ask the variable `Py_NOGIL`.
+ static PyObject *flags = PySys_GetObject("flags");
+ static bool isNoGil = PyObject_HasAttrString(flags, "nogil");
// We look into the currently active operation if we are going to call
// a method with zero arguments.
auto *frame = PyEval_GetFrame();
-#if PY_VERSION_HEX >= 0x03090000 && !Py_LIMITED_API && !defined(PYPY_VERSION)
+#if !Py_LIMITED_API && !defined(PYPY_VERSION)
auto *f_code = PyFrame_GetCode(frame);
#else
static PyObject *const _f_code = Shiboken::String::createStaticString("f_code");
@@ -114,20 +141,37 @@ static bool currentOpcode_Is_CallMethNoArgs()
char *co_code{};
PyBytes_AsStringAndSize(dec_co_code, &co_code, &code_len);
uint8_t opcode1 = co_code[f_lasti];
+ if (isNoGil) {
+ uint8_t opcode2 = co_code[f_lasti + 4];
+ uint8_t oparg2 = co_code[f_lasti + 6];
+ return opcode1 == LOAD_METHOD_NOGIL && opcode2 == CALL_METHOD_NOGIL && oparg2 == 1;
+ }
uint8_t opcode2 = co_code[f_lasti + 2];
uint8_t oparg2 = co_code[f_lasti + 3];
- static auto number = _getVersion();
- if (number < 3007)
- return opcode1 == LOAD_ATTR && opcode2 == CALL_FUNCTION && oparg2 == 0;
- if (number < 3011)
+ static auto number = _PepRuntimeVersion();
+ if (number < 0x030B00)
return opcode1 == LOAD_METHOD && opcode2 == CALL_METHOD && oparg2 == 0;
- // With Python 3.11, the opcodes get bigger and change a bit.
+ if (number < 0x030C00) {
+ // With Python 3.11, the opcodes get bigger and change a bit.
+ // Note: The new adaptive opcodes are elegantly hidden and we
+ // don't need to take care of them.
+ if (opcode1 == LOAD_METHOD)
+ f_lasti += LOAD_METHOD_GAP_311;
+ else if (opcode1 == LOAD_ATTR)
+ f_lasti += LOAD_ATTR_GAP_311;
+ else
+ return false;
+
+ opcode2 = co_code[f_lasti + 2];
+ oparg2 = co_code[f_lasti + 3];
+
+ return opcode2 == PRECALL && oparg2 == 0;
+ }
+ // With Python 3.12, the opcodes get again bigger and change a bit.
// Note: The new adaptive opcodes are elegantly hidden and we
// don't need to take care of them.
- if (opcode1 == LOAD_METHOD)
- f_lasti += LOAD_METHOD_GAP;
- else if (opcode1 == LOAD_ATTR)
+ if (opcode1 == LOAD_ATTR)
f_lasti += LOAD_ATTR_GAP;
else
return false;
@@ -135,7 +179,7 @@ static bool currentOpcode_Is_CallMethNoArgs()
opcode2 = co_code[f_lasti + 2];
oparg2 = co_code[f_lasti + 3];
- return opcode2 == PRECALL && oparg2 == 0;
+ return opcode2 == CALL && oparg2 == 0;
}
void initEnumFlagsDict(PyTypeObject *type)
@@ -166,12 +210,107 @@ void initEnumFlagsDict(PyTypeObject *type)
static PyObject *replaceNoArgWithZero(PyObject *callable)
{
- static auto *functools = PyImport_ImportModule("_functools"); // builtin
- static auto *partial = PyObject_GetAttrString(functools, "partial");
+ static auto *partial = Pep_GetPartialFunction();
static auto *zero = PyLong_FromLong(0);
return PyObject_CallFunctionObjArgs(partial, callable, zero, nullptr);
}
+static PyObject *lookupUnqualifiedOrOldEnum(PyTypeObject *type, PyObject *name)
+{
+ // MRO has been observed to be 0 in case of errors with QML decorators
+ if (type == nullptr || type->tp_mro == nullptr)
+ return nullptr;
+ // Quick Check: Avoid "__..", "_slots", etc.
+ if (std::isalpha(Shiboken::String::toCString(name)[0]) == 0)
+ return nullptr;
+ static PyTypeObject *const EnumMeta = getPyEnumMeta();
+ static PyObject *const _member_map_ = String::createStaticString("_member_map_");
+ // This is similar to `find_name_in_mro`, but instead of looking directly into
+ // tp_dict, we also search for the attribute in local classes of that dict (Part 2).
+ PyObject *mro = type->tp_mro;
+ PyObject *result{};
+ assert(PyTuple_Check(mro));
+ Py_ssize_t idx, n = PyTuple_GET_SIZE(mro);
+ for (idx = 0; idx < n; ++idx) {
+ auto *base = PyTuple_GET_ITEM(mro, idx);
+ auto *type_base = reinterpret_cast<PyTypeObject *>(base);
+ if (!SbkObjectType_Check(type_base))
+ continue;
+ auto sotp = PepType_SOTP(type_base);
+ // The EnumFlagInfo structure tells us if there are Enums at all.
+ const char **enumFlagInfo = sotp->enumFlagInfo;
+ if (!(enumFlagInfo))
+ continue;
+ if (!sotp->enumFlagsDict)
+ initEnumFlagsDict(type_base);
+ bool useFakeRenames = !(Enum::enumOption & Enum::ENOPT_NO_FAKERENAMES);
+ if (useFakeRenames) {
+ auto *rename = PyDict_GetItem(sotp->enumFlagsDict, name);
+ if (rename) {
+ /*
+ * Part 1: Look into the enumFlagsDict if we have an old flags name.
+ * -------------------------------------------------------------
+ * We need to replace the parameterless
+
+ QtCore.Qt.Alignment()
+
+ * by the one-parameter call
+
+ QtCore.Qt.AlignmentFlag(0)
+
+ * That means: We need to bind the zero as default into a wrapper and
+ * return that to be called.
+ *
+ * Addendum:
+ * ---------
+ * We first need to look into the current opcode of the bytecode to find
+ * out if we have a call like above or just a type lookup.
+ */
+ AutoDecRef tpDict(PepType_GetDict(type_base));
+ auto *flagType = PyDict_GetItem(tpDict.object(), rename);
+ if (currentOpcode_Is_CallMethNoArgs())
+ return replaceNoArgWithZero(flagType);
+ Py_INCREF(flagType);
+ return flagType;
+ }
+ }
+ bool useFakeShortcuts = !(Enum::enumOption & Enum::ENOPT_NO_FAKESHORTCUT);
+ if (useFakeShortcuts) {
+ AutoDecRef tpDict(PepType_GetDict(type_base));
+ auto *dict = tpDict.object();
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+ while (PyDict_Next(dict, &pos, &key, &value)) {
+ /*
+ * Part 2: Check for a duplication into outer scope.
+ * -------------------------------------------------
+ * We need to replace the shortcut
+
+ QtCore.Qt.AlignLeft
+
+ * by the correct call
+
+ QtCore.Qt.AlignmentFlag.AlignLeft
+
+ * That means: We need to search all Enums of the class.
+ */
+ if (Py_TYPE(value) == EnumMeta) {
+ auto *valtype = reinterpret_cast<PyTypeObject *>(value);
+ AutoDecRef valtypeDict(PepType_GetDict(valtype));
+ auto *member_map = PyDict_GetItem(valtypeDict.object(), _member_map_);
+ if (member_map && PyDict_Check(member_map)) {
+ result = PyDict_GetItem(member_map, name);
+ Py_XINCREF(result);
+ if (result)
+ return result;
+ }
+ }
+ }
+ }
+ }
+ return nullptr;
+}
+
PyObject *mangled_type_getattro(PyTypeObject *type, PyObject *name)
{
/*
@@ -180,11 +319,10 @@ PyObject *mangled_type_getattro(PyTypeObject *type, PyObject *name)
* with the complex `tp_getattro` of `QObject` and other instances.
* What we change here is the meta class of `QObject`.
*/
- static getattrofunc const type_getattro = PyType_Type.tp_getattro;
+ static getattrofunc const type_getattro = PepExt_Type_GetGetAttroSlot(&PyType_Type);
static PyObject *const ignAttr1 = PyName::qtStaticMetaObject();
static PyObject *const ignAttr2 = PyMagicName::get();
static PyTypeObject *const EnumMeta = getPyEnumMeta();
- static PyObject *const _member_map_ = String::createStaticString("_member_map_");
if (SelectFeatureSet != nullptr)
SelectFeatureSet(type);
@@ -194,7 +332,7 @@ PyObject *mangled_type_getattro(PyTypeObject *type, PyObject *name)
// The PYI files now look correct, but the old duplication is
// emulated here. This should be removed in Qt 7, see `parser.py`.
//
- // FIXME PYSIDE7 should remove this forgivingness:
+ // FIXME PYSIDE7 should remove this forgiveness:
//
// The duplication of enum values into the enclosing scope, allowing to write
// Qt.AlignLeft instead of Qt.Alignment.AlignLeft, is still implemented but
@@ -211,88 +349,16 @@ PyObject *mangled_type_getattro(PyTypeObject *type, PyObject *name)
}
if (!ret && name != ignAttr1 && name != ignAttr2) {
- PyObject *error_type, *error_value, *error_traceback;
+ PyObject *error_type{}, *error_value{}, *error_traceback{};
PyErr_Fetch(&error_type, &error_value, &error_traceback);
-
- // This is similar to `find_name_in_mro`, but instead of looking directly into
- // tp_dict, we also search for the attribute in local classes of that dict (Part 2).
- PyObject *mro = type->tp_mro;
- assert(PyTuple_Check(mro));
- size_t idx, n = PyTuple_GET_SIZE(mro);
- for (idx = 0; idx < n; ++idx) {
- auto *base = PyTuple_GET_ITEM(mro, idx);
- auto *type_base = reinterpret_cast<PyTypeObject *>(base);
- auto sotp = PepType_SOTP(type_base);
- // The EnumFlagInfo structure tells us if there are Enums at all.
- const char **enumFlagInfo = sotp->enumFlagInfo;
- if (!(enumFlagInfo))
- continue;
- if (!sotp->enumFlagsDict)
- initEnumFlagsDict(type_base);
- bool useFakeRenames = !(Enum::enumOption & Enum::ENOPT_NO_FAKERENAMES);
- if (useFakeRenames) {
- auto *rename = PyDict_GetItem(sotp->enumFlagsDict, name);
- if (rename) {
- /*
- * Part 1: Look into the enumFlagsDict if we have an old flags name.
- * -------------------------------------------------------------
- * We need to replace the parameterless
-
- QtCore.Qt.Alignment()
-
- * by the one-parameter call
-
- QtCore.Qt.AlignmentFlag(0)
-
- * That means: We need to bind the zero as default into a wrapper and
- * return that to be called.
- *
- * Addendum:
- * ---------
- * We first need to look into the current opcode of the bytecode to find
- * out if we have a call like above or just a type lookup.
- */
- auto *flagType = PyDict_GetItem(type_base->tp_dict, rename);
- if (currentOpcode_Is_CallMethNoArgs())
- return replaceNoArgWithZero(flagType);
- Py_INCREF(flagType);
- return flagType;
- }
- }
- bool useFakeShortcuts = !(Enum::enumOption & Enum::ENOPT_NO_FAKESHORTCUT);
- if (useFakeShortcuts) {
- auto *dict = type_base->tp_dict;
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(dict, &pos, &key, &value)) {
- /*
- * Part 2: Check for a duplication into outer scope.
- * -------------------------------------------------
- * We need to replace the shortcut
-
- QtCore.Qt.AlignLeft
-
- * by the correct call
-
- QtCore.Qt.AlignmentFlag.AlignLeft
-
- * That means: We need to search all Enums of the class.
- */
- if (Py_TYPE(value) == EnumMeta) {
- auto *valtype = reinterpret_cast<PyTypeObject *>(value);
- auto *member_map = PyDict_GetItem(valtype->tp_dict, _member_map_);
- if (member_map && PyDict_Check(member_map)) {
- auto *result = PyDict_GetItem(member_map, name);
- if (result) {
- Py_INCREF(result);
- return result;
- }
- }
- }
- }
- }
+ ret = lookupUnqualifiedOrOldEnum(type, name);
+ if (ret) {
+ Py_DECREF(error_type);
+ Py_XDECREF(error_value);
+ Py_XDECREF(error_traceback);
+ } else {
+ PyErr_Restore(error_type, error_value, error_traceback);
}
- PyErr_Restore(error_type, error_value, error_traceback);
}
return ret;
}
@@ -302,12 +368,14 @@ PyObject *Sbk_TypeGet___dict__(PyTypeObject *type, void * /* context */)
/*
* This is the override for getting a dict.
*/
- auto dict = type->tp_dict;
+ AutoDecRef tpDict(PepType_GetDict(type));
+ auto *dict = tpDict.object();;
if (dict == nullptr)
Py_RETURN_NONE;
if (SelectFeatureSet != nullptr) {
SelectFeatureSet(type);
- dict = type->tp_dict;
+ tpDict.reset(PepType_GetDict(type));
+ dict = tpDict.object();
}
return PyDictProxy_New(dict);
}
diff --git a/sources/shiboken6/libshiboken/sbkmodule.cpp b/sources/shiboken6/libshiboken/sbkmodule.cpp
index aeae34a36..76087fbb5 100644
--- a/sources/shiboken6/libshiboken/sbkmodule.cpp
+++ b/sources/shiboken6/libshiboken/sbkmodule.cpp
@@ -2,54 +2,499 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "sbkmodule.h"
+#include "autodecref.h"
#include "basewrapper.h"
#include "bindingmanager.h"
+#include "sbkstring.h"
+#include "sbkcppstring.h"
+#include "sbkconverter_p.h"
+
#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+#include <cstring>
+
+/// This hash maps module objects to arrays of converters.
+using ModuleConvertersMap = std::unordered_map<PyObject *, SbkConverter **> ;
/// This hash maps module objects to arrays of Python types.
-using ModuleTypesMap = std::unordered_map<PyObject *, PyTypeObject **> ;
+using ModuleTypesMap = std::unordered_map<PyObject *, Shiboken::Module::TypeInitStruct *> ;
-/// This hash maps module objects to arrays of converters.
-using ModuleConvertersMap = std::unordered_map<PyObject *, SbkConverter **>;
+struct TypeCreationStruct
+{
+ Shiboken::Module::TypeCreationFunction func;
+ std::vector<std::string> subtypeNames;
+};
+
+/// This hash maps type names to type creation structs.
+using NameToTypeFunctionMap = std::unordered_map<std::string, TypeCreationStruct> ;
+
+/// This hash maps module objects to maps of names to functions.
+using ModuleToFuncsMap = std::unordered_map<PyObject *, NameToTypeFunctionMap> ;
/// All types produced in imported modules are mapped here.
static ModuleTypesMap moduleTypes;
static ModuleConvertersMap moduleConverters;
+static ModuleToFuncsMap moduleToFuncs;
namespace Shiboken
{
namespace Module
{
+// PYSIDE-2404: Replacing the arguments generated by cpythonTypeNameExt
+// by a function call.
+LIBSHIBOKEN_API PyTypeObject *get(TypeInitStruct &typeStruct)
+{
+ if (typeStruct.type != nullptr)
+ return typeStruct.type;
+
+ static PyObject *sysModules = PyImport_GetModuleDict();
+
+ // The slow path for initialization.
+ // We get the type by following the chain from the module.
+ // As soon as types[index] gets filled, we can stop.
+
+ std::string_view names(typeStruct.fullName);
+ const bool usePySide = names.compare(0, 8, "PySide6.") == 0;
+ auto dotPos = usePySide ? names.find('.', 8) : names.find('.');
+ auto startPos = dotPos + 1;
+ AutoDecRef modName(String::fromCppStringView(names.substr(0, dotPos)));
+ auto *modOrType = PyDict_GetItem(sysModules, modName);
+ if (modOrType == nullptr) {
+ PyErr_Format(PyExc_SystemError, "Module \"%U\" should already be in sys.modules",
+ modName.object());
+ return nullptr;
+ }
+
+ do {
+ dotPos = names.find('.', startPos);
+ auto typeName = dotPos != std::string::npos
+ ? names.substr(startPos, dotPos - startPos)
+ : names.substr(startPos);
+ startPos = dotPos + 1;
+ AutoDecRef obTypeName(String::fromCppStringView(typeName));
+ modOrType = PyObject_GetAttr(modOrType, obTypeName);
+ } while (typeStruct.type == nullptr && dotPos != std::string::npos);
+
+ return typeStruct.type;
+}
+
+static void incarnateHelper(PyObject *module, const std::string_view names,
+ const NameToTypeFunctionMap &nameToFunc)
+{
+ auto dotPos = names.find('.');
+ std::string::size_type startPos = 0;
+ auto *modOrType{module};
+ while (dotPos != std::string::npos) {
+ auto typeName = names.substr(startPos, dotPos - startPos);
+ AutoDecRef obTypeName(String::fromCppStringView(typeName));
+ modOrType = PyObject_GetAttr(modOrType, obTypeName);
+ startPos = dotPos + 1;
+ dotPos = names.find('.', startPos);
+ }
+ // now we have the type to create.
+ auto funcIter = nameToFunc.find(std::string(names));
+ // - call this function that returns a PyTypeObject
+ auto tcStruct = funcIter->second;
+ auto initFunc = tcStruct.func;
+ PyTypeObject *type = initFunc(modOrType);
+ auto name = names.substr(startPos);
+ PyObject_SetAttrString(modOrType, name.data(), reinterpret_cast<PyObject *>(type));
+}
+
+static void incarnateSubtypes(PyObject *module,
+ const std::vector<std::string> &nameList,
+ NameToTypeFunctionMap &nameToFunc)
+{
+ for (auto const & tableIter : nameList) {
+ std::string_view names(tableIter);
+ incarnateHelper(module, names, nameToFunc);
+ }
+}
+
+static PyTypeObject *incarnateType(PyObject *module, const char *name,
+ NameToTypeFunctionMap &nameToFunc)
+{
+ // - locate the name and retrieve the generating function
+ auto funcIter = nameToFunc.find(name);
+ if (funcIter == nameToFunc.end()) {
+ // attribute does really not exist.
+ PyErr_SetNone(PyExc_AttributeError);
+ return nullptr;
+ }
+ // - call this function that returns a PyTypeObject
+ auto tcStruct = funcIter->second;
+ auto initFunc = tcStruct.func;
+ auto *modOrType{module};
+
+ // PYSIDE-2404: Make sure that no switching happens during type creation.
+ auto saveFeature = initSelectableFeature(nullptr);
+ PyTypeObject *type = initFunc(modOrType);
+ if (!tcStruct.subtypeNames.empty())
+ incarnateSubtypes(module, tcStruct.subtypeNames, nameToFunc);
+ initSelectableFeature(saveFeature);
+
+ // - assign this object to the name in the module
+ auto *res = reinterpret_cast<PyObject *>(type);
+ Py_INCREF(res);
+ PyModule_AddObject(module, name, res); // steals reference
+ // - remove the entry, if not by something cleared.
+ if (!nameToFunc.empty())
+ nameToFunc.erase(funcIter);
+ // - return the PyTypeObject.
+ return type;
+}
+
+// PYSIDE-2404: Make sure that the mentioned classes really exist.
+// Used in `Pyside::typeName`. Because the result will be cached by
+// the creation of the type(s), this is efficient.
+void loadLazyClassesWithName(const char *name)
+{
+ for (auto const & tableIter : moduleToFuncs) {
+ auto nameToFunc = tableIter.second;
+ auto funcIter = nameToFunc.find(name);
+ if (funcIter != nameToFunc.end()) {
+ // attribute exists in the lazy types.
+ auto *module = tableIter.first;
+ incarnateType(module, name, nameToFunc);
+ }
+ }
+}
+
+// PYSIDE-2404: Completely load all not yet loaded classes.
+// This is needed to resolve a star import.
+void resolveLazyClasses(PyObject *module)
+{
+ // - locate the module in the moduleTofuncs mapping
+ auto tableIter = moduleToFuncs.find(module);
+ if (tableIter == moduleToFuncs.end())
+ return;
+
+ // - see if there are still unloaded elements
+ auto &nameToFunc = tableIter->second;
+
+ // - incarnate all types.
+ while (!nameToFunc.empty()) {
+ auto it = nameToFunc.begin();
+ auto attrNameStr = it->first;
+ incarnateType(module, attrNameStr.c_str(), nameToFunc);
+ }
+}
+
+// PYSIDE-2404: Override the gettattr function of modules.
+static getattrofunc origModuleGetattro{};
+
+// PYSIDE-2404: Use the patched module getattr to do on-demand initialization.
+// This modifies _all_ modules but should have no impact.
+static PyObject *PyModule_lazyGetAttro(PyObject *module, PyObject *name)
+{
+ // - check if the attribute is present and return it.
+ auto *attr = PyObject_GenericGetAttr(module, name);
+ // - we handle AttributeError, only.
+ if (!(attr == nullptr && PyErr_ExceptionMatches(PyExc_AttributeError)))
+ return attr;
+
+ PyErr_Clear();
+ // - locate the module in the moduleTofuncs mapping
+ auto tableIter = moduleToFuncs.find(module);
+ // - if this is not our module, use the original
+ if (tableIter == moduleToFuncs.end())
+ return origModuleGetattro(module, name);
+
+ // - locate the name and retrieve the generating function
+ const char *attrNameStr = Shiboken::String::toCString(name);
+ auto &nameToFunc = tableIter->second;
+ // - create the real type and handle subtypes
+ auto *type = incarnateType(module, attrNameStr, nameToFunc);
+ auto *ret = reinterpret_cast<PyObject *>(type);
+ // - if attribute does really not exist use the original
+ if (ret == nullptr && PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Clear();
+ return origModuleGetattro(module, name);
+ }
+ return ret;
+}
+
+// PYSIDE-2404: Supply a new module dir for not yet visible entries.
+// This modification is only for "our" modules.
+static PyObject *_module_dir_template(PyObject * /* self */, PyObject *args)
+{
+ static PyObject *const _dict = Shiboken::String::createStaticString("__dict__");
+ // The dir function must replace all of the builtin function.
+ PyObject *module{};
+ if (!PyArg_ParseTuple(args, "O", &module))
+ return nullptr;
+
+ auto tableIter = moduleToFuncs.find(module);
+ assert(tableIter != moduleToFuncs.end());
+ Shiboken::AutoDecRef dict(PyObject_GetAttr(module, _dict));
+ auto *ret = PyDict_Keys(dict);
+ // Now add all elements that were not yet in the dict.
+ auto &nameToFunc = tableIter->second;
+ for (const auto &funcIter : nameToFunc) {
+ const char *name = funcIter.first.c_str();
+ Shiboken::AutoDecRef pyName(PyUnicode_FromString(name));
+ PyList_Append(ret, pyName);
+ }
+ return ret;
+}
+
+static PyMethodDef module_methods[] = {
+ {"__dir__", (PyCFunction)_module_dir_template, METH_VARARGS, nullptr},
+ {nullptr, nullptr, 0, nullptr}
+};
+
+// Python 3.8 - 3.12
+static int const LOAD_CONST_312 = 100;
+static int const IMPORT_NAME_312 = 108;
+
+static bool isImportStar(PyObject *module)
+{
+ // Find out whether we have a star import. This must work even
+ // when we have no import support from feature.
+ static PyObject *const _f_code = Shiboken::String::createStaticString("f_code");
+ static PyObject *const _f_lasti = Shiboken::String::createStaticString("f_lasti");
+ static PyObject *const _f_back = Shiboken::String::createStaticString("f_back");
+ static PyObject *const _co_code = Shiboken::String::createStaticString("co_code");
+ static PyObject *const _co_consts = Shiboken::String::createStaticString("co_consts");
+ static PyObject *const _co_names = Shiboken::String::createStaticString("co_names");
+
+ auto *obFrame = reinterpret_cast<PyObject *>(PyEval_GetFrame());
+ if (obFrame == nullptr)
+ return true; // better assume worst-case.
+
+ Py_INCREF(obFrame);
+ AutoDecRef dec_frame(obFrame);
+
+ // Calculate the offset of the running import_name opcode on the stack.
+ // Right before that there must be a load_const with the tuple `("*",)`.
+ while (dec_frame.object() != Py_None) {
+ AutoDecRef dec_f_code(PyObject_GetAttr(dec_frame, _f_code));
+ AutoDecRef dec_co_code(PyObject_GetAttr(dec_f_code, _co_code));
+ AutoDecRef dec_f_lasti(PyObject_GetAttr(dec_frame, _f_lasti));
+ Py_ssize_t f_lasti = PyLong_AsSsize_t(dec_f_lasti);
+ Py_ssize_t code_len;
+ char *co_code{};
+ PyBytes_AsStringAndSize(dec_co_code, &co_code, &code_len);
+ uint8_t opcode2 = co_code[f_lasti];
+ uint8_t opcode1 = co_code[f_lasti - 2];
+ if (opcode1 == LOAD_CONST_312 && opcode2 == IMPORT_NAME_312) {
+ uint8_t oparg1 = co_code[f_lasti - 1];
+ uint8_t oparg2 = co_code[f_lasti + 1];
+ AutoDecRef dec_co_consts(PyObject_GetAttr(dec_f_code, _co_consts));
+ auto *fromlist = PyTuple_GetItem(dec_co_consts, oparg1);
+ if (PyTuple_Check(fromlist) && PyTuple_Size(fromlist) == 1
+ && Shiboken::String::toCString(PyTuple_GetItem(fromlist, 0))[0] == '*') {
+ AutoDecRef dec_co_names(PyObject_GetAttr(dec_f_code, _co_names));
+ const char *name = String::toCString(PyTuple_GetItem(dec_co_names, oparg2));
+ const char *modName = PyModule_GetName(module);
+ if (std::strcmp(name, modName) == 0)
+ return true;
+ }
+ }
+ dec_frame.reset(PyObject_GetAttr(dec_frame, _f_back));
+ }
+ return false;
+}
+
+// PYSIDE-2404: These modules produce ambiguous names which we cannot handle, yet.
+static std::unordered_set<std::string> dontLazyLoad{
+ "sample",
+ "smart",
+ "testbinding"
+};
+
+static const std::unordered_set<std::string> knownModules{
+ "shiboken6.Shiboken",
+ "minimal",
+ "other",
+ "sample",
+ "smart",
+ "scriptableapplication",
+ "testbinding"
+};
+
+static bool canNotLazyLoad(PyObject *module)
+{
+ const char *modName = PyModule_GetName(module);
+
+ // There are no more things that must be disabled :-D
+ return dontLazyLoad.find(modName) != dontLazyLoad.end();
+}
+
+static bool shouldLazyLoad(PyObject *module)
+{
+ const char *modName = PyModule_GetName(module);
+
+ if (knownModules.find(modName) != knownModules.end())
+ return true;
+ return std::strncmp(modName, "PySide6.", 8) == 0;
+}
+
+void checkIfShouldLoadImmediately(PyObject *module, const std::string &name,
+ const NameToTypeFunctionMap &nameToFunc)
+{
+ static const char *flag = getenv("PYSIDE6_OPTION_LAZY");
+ static const int value = flag != nullptr ? std::atoi(flag) : 1;
+
+ // PYSIDE-2404: Lazy Loading
+ //
+ // Options:
+ // 0 - switch lazy loading off.
+ // 1 - lazy loading for all known modules.
+ // 3 - lazy loading for any module.
+ //
+ // By default we lazy load all known modules (option = 1).
+ if (value == 0 // completely disabled
+ || canNotLazyLoad(module) // for some reason we cannot lazy load
+ || (value == 1 && !shouldLazyLoad(module)) // not a known module
+ ) {
+ incarnateHelper(module, name, nameToFunc);
+ }
+}
+
+void AddTypeCreationFunction(PyObject *module,
+ const char *name,
+ TypeCreationFunction func)
+{
+ // - locate the module in the moduleTofuncs mapping
+ auto tableIter = moduleToFuncs.find(module);
+ assert(tableIter != moduleToFuncs.end());
+ // - Assign the name/generating function tcStruct.
+ auto &nameToFunc = tableIter->second;
+ TypeCreationStruct tcStruct{func, {}};
+ auto nit = nameToFunc.find(name);
+ if (nit == nameToFunc.end())
+ nameToFunc.insert(std::make_pair(name, tcStruct));
+ else
+ nit->second = tcStruct;
+
+ checkIfShouldLoadImmediately(module, name, nameToFunc);
+}
+
+void AddTypeCreationFunction(PyObject *module,
+ const char *containerName,
+ TypeCreationFunction func,
+ const char *namePath)
+{
+ // - locate the module in the moduleTofuncs mapping
+ auto tableIter = moduleToFuncs.find(module);
+ assert(tableIter != moduleToFuncs.end());
+ // - Assign the name/generating function tcStruct.
+ auto &nameToFunc = tableIter->second;
+ auto nit = nameToFunc.find(containerName);
+
+ // - insert namePath into the subtype vector of the main type.
+ nit->second.subtypeNames.push_back(namePath);
+ // - insert it also as its own entry.
+ nit = nameToFunc.find(namePath);
+ TypeCreationStruct tcStruct{func, {}};
+ if (nit == nameToFunc.end())
+ nameToFunc.insert(std::make_pair(namePath, tcStruct));
+ else
+ nit->second = tcStruct;
+
+ checkIfShouldLoadImmediately(module, namePath, nameToFunc);
+}
+
PyObject *import(const char *moduleName)
{
PyObject *sysModules = PyImport_GetModuleDict();
PyObject *module = PyDict_GetItemString(sysModules, moduleName);
- if (module)
+ if (module != nullptr)
Py_INCREF(module);
else
module = PyImport_ImportModule(moduleName);
- if (!module)
- PyErr_Format(PyExc_ImportError,"could not import module '%s'", moduleName);
+ if (module == nullptr)
+ PyErr_Format(PyExc_ImportError, "could not import module '%s'", moduleName);
return module;
}
-PyObject *create(const char * /* moduleName */, void *moduleData)
+// PYSIDE-2404: Redirecting import for "import *" support.
+//
+// The first import will be handled by the isImportStar function.
+// But the same module might be imported twice, which would give no
+// introspection due to module caching.
+
+static PyObject *origImportFunc{};
+
+static PyObject *lazy_import(PyObject * /* self */, PyObject *args, PyObject *kwds)
+{
+ auto *ret = PyObject_Call(origImportFunc, args, kwds);
+ if (ret != nullptr) {
+ // PYSIDE-2404: Support star import when lazy loading.
+ if (PyTuple_Size(args) >= 4) {
+ auto *fromlist = PyTuple_GetItem(args, 3);
+ if (PyTuple_Check(fromlist) && PyTuple_Size(fromlist) == 1
+ && Shiboken::String::toCString(PyTuple_GetItem(fromlist, 0))[0] == '*')
+ Shiboken::Module::resolveLazyClasses(ret);
+ }
+ }
+ return ret;
+}
+
+static PyMethodDef lazy_methods[] = {
+ {"__lazy_import__", (PyCFunction)lazy_import, METH_VARARGS | METH_KEYWORDS, nullptr},
+ {nullptr, nullptr, 0, nullptr}
+};
+
+PyObject *create(const char * /* modName */, void *moduleData)
{
+ static auto *sysModules = PyImport_GetModuleDict();
+ static auto *builtins = PyEval_GetBuiltins();
+ static auto *partial = Pep_GetPartialFunction();
+ static bool lazy_init{};
+
Shiboken::init();
- return PyModule_Create(reinterpret_cast<PyModuleDef *>(moduleData));
+ auto *module = PyModule_Create(reinterpret_cast<PyModuleDef *>(moduleData));
+
+ // Setup of a dir function for "missing" classes.
+ auto *moduleDirTemplate = PyCFunction_NewEx(module_methods, nullptr, nullptr);
+ // Turn this function into a bound object, so we have access to the module.
+ auto *moduleDir = PyObject_CallFunctionObjArgs(partial, moduleDirTemplate, module, nullptr);
+ PyModule_AddObject(module, module_methods->ml_name, moduleDir); // steals reference
+ // Insert an initial empty table for the module.
+ NameToTypeFunctionMap empty;
+ moduleToFuncs.insert(std::make_pair(module, empty));
+
+ // A star import must be done unconditionally. Use the complete name.
+ if (isImportStar(module))
+ dontLazyLoad.insert(PyModule_GetName(module));
+
+ if (!lazy_init) {
+ // Install the getattr patch.
+ origModuleGetattro = PyModule_Type.tp_getattro;
+ PyModule_Type.tp_getattro = PyModule_lazyGetAttro;
+ // Add the lazy import redirection.
+ origImportFunc = PyDict_GetItemString(builtins, "__import__");
+ auto *func = PyCFunction_NewEx(lazy_methods, nullptr, nullptr);
+ PyDict_SetItemString(builtins, "__import__", func);
+ // Everything is set.
+ lazy_init = true;
+ }
+ // PYSIDE-2404: Nuitka inserts some additional code in standalone mode
+ // in an invisible virtual module (i.e. `QtCore-postLoad`)
+ // that gets imported before the running import can call
+ // `_PyImport_FixupExtensionObject` which does the insertion
+ // into `sys.modules`. This can cause a race condition.
+ // Insert the module early into the module dict to prevend recursion.
+ PyDict_SetItemString(sysModules, PyModule_GetName(module), module);
+ // Clear the non-existing name cache because we have a new module.
+ Shiboken::Conversions::clearNegativeLazyCache();
+ return module;
}
-void registerTypes(PyObject *module, PyTypeObject **types)
+void registerTypes(PyObject *module, TypeInitStruct *types)
{
auto iter = moduleTypes.find(module);
if (iter == moduleTypes.end())
moduleTypes.insert(std::make_pair(module, types));
}
-PyTypeObject **getTypes(PyObject *module)
+TypeInitStruct *getTypes(PyObject *module)
{
auto iter = moduleTypes.find(module);
return (iter == moduleTypes.end()) ? 0 : iter->second;
diff --git a/sources/shiboken6/libshiboken/sbkmodule.h b/sources/shiboken6/libshiboken/sbkmodule.h
index a4f7837f5..2c407e09d 100644
--- a/sources/shiboken6/libshiboken/sbkmodule.h
+++ b/sources/shiboken6/libshiboken/sbkmodule.h
@@ -12,8 +12,22 @@ extern "C"
struct SbkConverter;
}
-namespace Shiboken {
-namespace Module {
+namespace Shiboken::Module {
+
+struct TypeInitStruct
+{
+ PyTypeObject *type;
+ const char *fullName;
+};
+
+/// PYSIDE-2404: Replacing the arguments in cpythonTypeNameExt by a function.
+LIBSHIBOKEN_API PyTypeObject *get(TypeInitStruct &typeStruct);
+
+/// PYSIDE-2404: Make sure that mentioned classes really exist.
+LIBSHIBOKEN_API void loadLazyClassesWithName(const char *name);
+
+/// PYSIDE-2404: incarnate all classes for star imports.
+LIBSHIBOKEN_API void resolveLazyClasses(PyObject *module);
/**
* Imports and returns the module named \p moduleName, or a NULL pointer in case of failure.
@@ -30,19 +44,31 @@ LIBSHIBOKEN_API PyObject *import(const char *moduleName);
*/
LIBSHIBOKEN_API PyObject *create(const char *moduleName, void *moduleData);
+using TypeCreationFunction = PyTypeObject *(*)(PyObject *module);
+
+/// Adds a type creation function to the module.
+LIBSHIBOKEN_API void AddTypeCreationFunction(PyObject *module,
+ const char *name,
+ TypeCreationFunction func);
+
+LIBSHIBOKEN_API void AddTypeCreationFunction(PyObject *module,
+ const char *name,
+ TypeCreationFunction func,
+ const char *containerName);
+
/**
* Registers the list of types created by \p module.
* \param module Module where the types were created.
* \param types Array of PyTypeObject *objects representing the types created on \p module.
*/
-LIBSHIBOKEN_API void registerTypes(PyObject *module, PyTypeObject **types);
+LIBSHIBOKEN_API void registerTypes(PyObject *module, TypeInitStruct *types);
/**
* Retrieves the array of types.
* \param module Module where the types were created.
* \returns A pointer to the PyTypeObject *array of types.
*/
-LIBSHIBOKEN_API PyTypeObject **getTypes(PyObject *module);
+LIBSHIBOKEN_API TypeInitStruct *getTypes(PyObject *module);
/**
* Registers the list of converters created by \p module for non-wrapper types.
@@ -58,6 +84,6 @@ LIBSHIBOKEN_API void registerTypeConverters(PyObject *module, SbkConverter **con
*/
LIBSHIBOKEN_API SbkConverter **getTypeConverters(PyObject *module);
-} } // namespace Shiboken::Module
+} // namespace Shiboken::Module
#endif // SBK_MODULE_H
diff --git a/sources/shiboken6/libshiboken/sbknumpy.cpp b/sources/shiboken6/libshiboken/sbknumpy.cpp
index 060a2b6f4..b6422e73f 100644
--- a/sources/shiboken6/libshiboken/sbknumpy.cpp
+++ b/sources/shiboken6/libshiboken/sbknumpy.cpp
@@ -17,9 +17,27 @@
namespace Shiboken::Numpy
{
+#ifdef HAVE_NUMPY
+static void initNumPy()
+{
+ // PYSIDE-2404: Delay-initialize numpy from check() as it causes a
+ // significant startup delay (~770 allocations in memray)
+ static bool initialized = false;
+ if (initialized)
+ return;
+ initialized = true;
+ // Expanded from macro "import_array" in __multiarray_api.h
+ // Make sure to read about the magic defines PY_ARRAY_UNIQUE_SYMBOL etc.,
+ // when changing this or spreading the code over several source files.
+ if (_import_array() < 0)
+ PyErr_Print();
+}
+#endif // HAVE_NUMPY
+
bool check(PyObject *pyIn)
{
#ifdef HAVE_NUMPY
+ initNumPy();
return PyArray_Check(pyIn);
#else
SBK_UNUSED(pyIn);
diff --git a/sources/shiboken6/libshiboken/sbknumpyarrayconverter.cpp b/sources/shiboken6/libshiboken/sbknumpyarrayconverter.cpp
index c8541adf5..835a97524 100644
--- a/sources/shiboken6/libshiboken/sbknumpyarrayconverter.cpp
+++ b/sources/shiboken6/libshiboken/sbknumpyarrayconverter.cpp
@@ -94,8 +94,7 @@ std::ostream &operator<<(std::ostream &str, PyArrayObject *o)
return str;
}
-namespace Shiboken {
-namespace Conversions {
+namespace Shiboken::Conversions {
// Internals from sbkarrayconverter.cpp
SbkArrayConverter *createArrayConverter(IsArrayConvertibleToCppFunc toCppCheckFunc);
@@ -105,6 +104,7 @@ SbkArrayConverter *unimplementedArrayConverter();
template <int dimension>
static bool isPrimitiveArray(PyObject *pyIn, int expectedNpType)
{
+ Shiboken::Numpy::initNumPy();
if (!PyArray_Check(pyIn))
return false;
auto *pya = reinterpret_cast<PyArrayObject *>(pyIn);
@@ -210,6 +210,9 @@ static PythonToCppFunc checkArray2(PyObject *pyIn, int dim1, int dim2)
template <class T>
static void setOrExtendArrayConverter(int dimension, IsArrayConvertibleToCppFunc toCppCheckFunc)
{
+ // PYSIDE-2404/FIXME: When adding a C++ -> Python conversion, be sure
+ // to delay-initialize numpy in the converter (similar to the
+ // initialization in check() for the Python -> C++ conversion).
SbkArrayConverter *arrayConverter = ArrayTypeConverter<T>(dimension);
if (arrayConverter == unimplementedArrayConverter()) {
arrayConverter = createArrayConverter(toCppCheckFunc);
@@ -235,15 +238,6 @@ static inline void extendArrayConverter2()
void initNumPyArrayConverters()
{
- // Expanded from macro "import_array" in __multiarray_api.h
- // Make sure to read about the magic defines PY_ARRAY_UNIQUE_SYMBOL etc.,
- // when changing this or spreading the code over several source files.
- if (_import_array() < 0) {
- if (debugNumPy)
- PyErr_Print();
- PyErr_Clear();
- return;
- }
// Extend the converters for primitive types by NumPy ones.
extendArrayConverter1<short, NPY_SHORT>();
extendArrayConverter2<short, NPY_SHORT>();
@@ -273,5 +267,4 @@ void initNumPyArrayConverters()
extendArrayConverter2<double, NPY_DOUBLE>();
}
-} // namespace Conversions
-} // namespace Shiboken
+} // namespace Shiboken::Conversions
diff --git a/sources/shiboken6/libshiboken/sbknumpyview.cpp b/sources/shiboken6/libshiboken/sbknumpyview.cpp
index 44a4b5587..bafbf8038 100644
--- a/sources/shiboken6/libshiboken/sbknumpyview.cpp
+++ b/sources/shiboken6/libshiboken/sbknumpyview.cpp
@@ -6,12 +6,54 @@
#include "helper.h"
#include <iostream>
#include <iomanip>
+#include <optional>
#ifdef HAVE_NUMPY
namespace Shiboken {
namespace Numpy {
+static std::optional<View::Type> viewTypeFromNumPy(int npt)
+{
+ switch (npt) {
+ case NPY_SHORT:
+ return View::Int16;
+ case NPY_USHORT:
+ return View::Unsigned16;
+ case NPY_INT:
+ return View::Int;
+ case NPY_UINT:
+ return View::Unsigned;
+ case NPY_LONG:
+ if constexpr (sizeof(long) == sizeof(int))
+ return View::Int;
+ if constexpr (sizeof(long) == sizeof(int64_t))
+ return View::Int64;
+ break;
+ case NPY_ULONG:
+ if constexpr (sizeof(long) == sizeof(int))
+ return View::Unsigned;
+ if constexpr (sizeof(long) == sizeof(int64_t))
+ return View::Unsigned64;
+ break;
+ case NPY_LONGLONG:
+ if constexpr (sizeof(long long) == 8)
+ return View::Int64;
+ break;
+ case NPY_ULONGLONG:
+ if constexpr (sizeof(long long) == 8)
+ return View::Unsigned64;
+ break;
+ case NPY_FLOAT:
+ return View::Float;
+ case NPY_DOUBLE:
+ return View::Double;
+ default:
+ break;
+ }
+ return {};
+}
+
View View::fromPyObject(PyObject *pyIn)
{
if (pyIn == nullptr || PyArray_Check(pyIn) == 0)
@@ -23,27 +65,13 @@ View View::fromPyObject(PyObject *pyIn)
if (ndim > 2)
return {};
- View::Type type;
- switch (PyArray_TYPE(ar)) {
- case NPY_INT:
- type = View::Int;
- break;
- case NPY_UINT:
- type = View::Unsigned;
- break;
- case NPY_FLOAT:
- type = View::Float;
- break;
- case NPY_DOUBLE:
- type = View::Double;
- break;
- default:
+ const auto typeO = viewTypeFromNumPy(PyArray_TYPE(ar));
+ if (!typeO.has_value())
return {};
- }
View result;
result.ndim = ndim;
- result.type = type;
+ result.type = typeO.value();
result.data = PyArray_DATA(ar);
result.dimensions[0] = PyArray_DIMS(ar)[0];
result.stride[0] = PyArray_STRIDES(ar)[0];
@@ -91,11 +119,29 @@ std::ostream &operator<<(std::ostream &str, const debugPyArrayObject &a)
}
str << "], type=";
switch (type) {
+ case NPY_SHORT:
+ str << "short";
+ break;
+ case NPY_USHORT:
+ str << "ushort";
+ break;
case NPY_INT:
- str << "int";
+ str << "int32";
break;
case NPY_UINT:
- str << "uint";
+ str << "uint32";
+ break;
+ case NPY_LONG:
+ str << "long";
+ break;
+ case NPY_ULONG:
+ str << "ulong";
+ break;
+ case NPY_LONGLONG:
+ str << "long long";
+ break;
+ case NPY_ULONGLONG:
+ str << "ulong long";
break;
case NPY_FLOAT:
str << "float";
@@ -122,12 +168,30 @@ std::ostream &operator<<(std::ostream &str, const debugPyArrayObject &a)
if (const int dim0 = PyArray_DIMS(ar)[0]) {
auto *data = PyArray_DATA(ar);
switch (type) {
+ case NPY_SHORT:
+ debugArray(str, reinterpret_cast<const short *>(data), dim0);
+ break;
+ case NPY_USHORT:
+ debugArray(str, reinterpret_cast<const unsigned short *>(data), dim0);
+ break;
case NPY_INT:
debugArray(str, reinterpret_cast<const int *>(data), dim0);
break;
case NPY_UINT:
debugArray(str, reinterpret_cast<const unsigned *>(data), dim0);
break;
+ case NPY_LONG:
+ debugArray(str, reinterpret_cast<const long *>(data), dim0);
+ break;
+ case NPY_ULONG:
+ debugArray(str, reinterpret_cast<const unsigned long*>(data), dim0);
+ break;
+ case NPY_LONGLONG:
+ debugArray(str, reinterpret_cast<const long long *>(data), dim0);
+ break;
+ case NPY_ULONGLONG:
+ debugArray(str, reinterpret_cast<const unsigned long long *>(data), dim0);
+ break;
case NPY_FLOAT:
debugArray(str, reinterpret_cast<const float *>(data), dim0);
break;
diff --git a/sources/shiboken6/libshiboken/sbknumpyview.h b/sources/shiboken6/libshiboken/sbknumpyview.h
index d41e2c716..918913b78 100644
--- a/sources/shiboken6/libshiboken/sbknumpyview.h
+++ b/sources/shiboken6/libshiboken/sbknumpyview.h
@@ -22,7 +22,7 @@ LIBSHIBOKEN_API bool check(PyObject *pyIn);
/// numpy headers.
struct LIBSHIBOKEN_API View
{
- enum Type { Int, Unsigned, Float, Double};
+ enum Type { Int, Unsigned, Float, Double, Int16, Unsigned16, Int64, Unsigned64 };
static View fromPyObject(PyObject *pyIn);
diff --git a/sources/shiboken6/libshiboken/sbksmartpointer.cpp b/sources/shiboken6/libshiboken/sbksmartpointer.cpp
new file mode 100644
index 000000000..ee28f7db8
--- /dev/null
+++ b/sources/shiboken6/libshiboken/sbksmartpointer.cpp
@@ -0,0 +1,58 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#include "sbksmartpointer.h"
+#include "sbkstring.h"
+#include "autodecref.h"
+
+#include <unordered_set>
+
+namespace Shiboken::SmartPointer
+{
+
+PyObject *repr(PyObject *pointer, PyObject *pointee)
+{
+ Shiboken::AutoDecRef pointerRepr(Shiboken::String::repr(pointer));
+ if (pointer == nullptr)
+ return pointerRepr.release();
+
+ Shiboken::AutoDecRef pointeeRepr(pointee != nullptr
+ ? PyObject_Repr(pointee)
+ : Shiboken::String::repr(pointee));
+
+ return PyUnicode_FromFormat("%U (%U)", pointerRepr.object(), pointeeRepr.object());
+}
+
+// __dir__ for a smart pointer. Add the __dir__ entries of the pointee to the list.
+PyObject *dir(PyObject *pointer, PyObject *pointee)
+{
+ if (pointer == nullptr)
+ return PyList_New(0);
+ // Get the pointer's dir entries. Note: PyObject_Dir() cannot be called on
+ // self, will crash. Work around by using the type dict keys.
+ AutoDecRef tpDict(PepType_GetDict(Py_TYPE(pointer)));
+ auto *result = PyMapping_Keys(tpDict);
+
+ if (pointee != nullptr && pointee != Py_None) {
+ // Add the entries of the pointee that do not exist in the pointer's list.
+ // Since Python internally caches strings; we can use a set of PyObject *.
+ std::unordered_set<PyObject *> knownStrings;
+ for (Py_ssize_t i = 0, size = PySequence_Size(result); i < size; ++i) {
+ Shiboken::AutoDecRef item(PySequence_GetItem(result, i));
+ knownStrings.insert(item.object());
+ }
+ const auto knownEnd = knownStrings.end();
+
+ Shiboken::AutoDecRef pointeeDir(PyObject_Dir(pointee));
+ for (Py_ssize_t i = 0, size = PySequence_Size(pointeeDir.object()); i < size; ++i) {
+ Shiboken::AutoDecRef item(PySequence_GetItem(pointeeDir, i));
+ if (knownStrings.find(item.object()) == knownEnd)
+ PyList_Append(result, item.object());
+ }
+ }
+
+ PyList_Sort(result);
+ return result;
+}
+
+} // namespace Shiboken::SmartPointer
diff --git a/sources/shiboken6/libshiboken/sbksmartpointer.h b/sources/shiboken6/libshiboken/sbksmartpointer.h
new file mode 100644
index 000000000..5e2022722
--- /dev/null
+++ b/sources/shiboken6/libshiboken/sbksmartpointer.h
@@ -0,0 +1,18 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef SBK_SBKSMARTPOINTER_H
+#define SBK_SBKSMARTPOINTER_H
+
+#include "sbkpython.h"
+#include "shibokenmacros.h"
+
+namespace Shiboken::SmartPointer
+{
+
+LIBSHIBOKEN_API PyObject *repr(PyObject *pointer, PyObject *pointee);
+LIBSHIBOKEN_API PyObject *dir(PyObject *pointer, PyObject *pointee);
+
+} // namespace Shiboken::SmartPointer
+
+#endif // SBK_SBKSMARTPOINTER_H
diff --git a/sources/shiboken6/libshiboken/sbkstaticstrings.cpp b/sources/shiboken6/libshiboken/sbkstaticstrings.cpp
index 0c8beaabb..023de0ea4 100644
--- a/sources/shiboken6/libshiboken/sbkstaticstrings.cpp
+++ b/sources/shiboken6/libshiboken/sbkstaticstrings.cpp
@@ -24,6 +24,7 @@ STATIC_STRING_IMPL(im_self, "im_self")
STATIC_STRING_IMPL(loads, "loads")
STATIC_STRING_IMPL(multi, "multi")
STATIC_STRING_IMPL(name, "name")
+STATIC_STRING_IMPL(orig_dict, "orig_dict")
STATIC_STRING_IMPL(qApp, "qApp")
STATIC_STRING_IMPL(result, "result")
STATIC_STRING_IMPL(select_id, "select_id")
@@ -75,7 +76,6 @@ STATIC_STRING_IMPL(iter, "__iter__")
STATIC_STRING_IMPL(mro, "__mro__")
STATIC_STRING_IMPL(new_, "__new__")
STATIC_STRING_IMPL(objclass, "__objclass__")
-STATIC_STRING_IMPL(signature, "__signature__")
STATIC_STRING_IMPL(weakrefoffset, "__weakrefoffset__")
STATIC_STRING_IMPL(opaque_container, "__opaque_container__")
} // namespace PyMagicName
diff --git a/sources/shiboken6/libshiboken/sbkstaticstrings.h b/sources/shiboken6/libshiboken/sbkstaticstrings.h
index 02cc8a7f6..017790ee3 100644
--- a/sources/shiboken6/libshiboken/sbkstaticstrings.h
+++ b/sources/shiboken6/libshiboken/sbkstaticstrings.h
@@ -23,6 +23,7 @@ LIBSHIBOKEN_API PyObject *im_self();
LIBSHIBOKEN_API PyObject *loads();
LIBSHIBOKEN_API PyObject *multi();
LIBSHIBOKEN_API PyObject *name();
+LIBSHIBOKEN_API PyObject *orig_dict();
LIBSHIBOKEN_API PyObject *result();
LIBSHIBOKEN_API PyObject *select_id();
LIBSHIBOKEN_API PyObject *value();
diff --git a/sources/shiboken6/libshiboken/sbkstring.cpp b/sources/shiboken6/libshiboken/sbkstring.cpp
index 8f2dc6d52..b5e87ca5a 100644
--- a/sources/shiboken6/libshiboken/sbkstring.cpp
+++ b/sources/shiboken6/libshiboken/sbkstring.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "sbkstring.h"
+#include "sbkenum.h"
#include "sbkstaticstrings_p.h"
#include "autodecref.h"
@@ -14,6 +15,11 @@ bool checkIterable(PyObject *obj)
return PyObject_HasAttr(obj, Shiboken::PyMagicName::iter());
}
+bool checkIterableArgument(PyObject *obj)
+{
+ return checkIterable(obj) && !Shiboken::Enum::check(obj);
+}
+
static PyObject *initPathLike()
{
PyObject *PathLike{};
@@ -233,4 +239,16 @@ PyObject *getSnakeCaseName(PyObject *name, bool lower)
return name;
}
+// Return a generic representation of a PyObject as does PyObject_Repr().
+// Note: PyObject_Repr() may not be called on self from __repr__() as this
+// causes a recursion.
+PyObject *repr(PyObject *o)
+{
+ if (o == nullptr)
+ return PyUnicode_FromString("<NULL>");
+ if (o == Py_None)
+ return PyUnicode_FromString("None");
+ return PyUnicode_FromFormat("<%s object at %p>", Py_TYPE(o)->tp_name, o);
+}
+
} // namespace Shiboken::String
diff --git a/sources/shiboken6/libshiboken/sbkstring.h b/sources/shiboken6/libshiboken/sbkstring.h
index a24c01def..ebc5428c7 100644
--- a/sources/shiboken6/libshiboken/sbkstring.h
+++ b/sources/shiboken6/libshiboken/sbkstring.h
@@ -13,6 +13,8 @@ namespace String
{
LIBSHIBOKEN_API bool check(PyObject *obj);
LIBSHIBOKEN_API bool checkIterable(PyObject *obj);
+ /// Check for iterable function arguments (excluding enumerations)
+ LIBSHIBOKEN_API bool checkIterableArgument(PyObject *obj);
LIBSHIBOKEN_API bool checkPath(PyObject *path);
LIBSHIBOKEN_API bool checkType(PyTypeObject *obj);
LIBSHIBOKEN_API bool checkChar(PyObject *obj);
@@ -29,6 +31,7 @@ namespace String
LIBSHIBOKEN_API PyObject *createStaticString(const char *str);
LIBSHIBOKEN_API PyObject *getSnakeCaseName(const char *name, bool lower);
LIBSHIBOKEN_API PyObject *getSnakeCaseName(PyObject *name, bool lower);
+ LIBSHIBOKEN_API PyObject *repr(PyObject *o);
} // namespace String
} // namespace Shiboken
diff --git a/sources/shiboken6/libshiboken/sbktypefactory.cpp b/sources/shiboken6/libshiboken/sbktypefactory.cpp
index 0da1a8e23..079548eed 100644
--- a/sources/shiboken6/libshiboken/sbktypefactory.cpp
+++ b/sources/shiboken6/libshiboken/sbktypefactory.cpp
@@ -7,6 +7,8 @@
extern "C"
{
+using Shiboken::AutoDecRef;
+
PyTypeObject *SbkType_FromSpec(PyType_Spec *spec)
{
return SbkType_FromSpec_BMDWB(spec, nullptr, nullptr, 0, 0, nullptr);
@@ -37,6 +39,60 @@ static PyObject *_PyType_FromSpecWithBases(PyType_Spec *, PyObject *);
#endif // PYPY_VERSION
+// PYSIDE-2230: Not so temporary fix for Python 3.12.
+// A tp_new is no longer allowed in a meta class.
+// Hopefully, the Python devs will supply the missing support.
+// It turned out that they will not fix that, as expected.
+// Note: Python 3.12 is the first version that grabs the metaclass from base classes.
+static PyObject *_PyType_FromSpecWithBasesHack(PyType_Spec *spec,
+ PyObject *bases,
+ PyTypeObject *meta)
+{
+ PyTypeObject *keepMeta{};
+ newfunc keepNew{};
+ AutoDecRef basesPatch{};
+
+ if (bases) {
+ if (bases == Py_None) {
+ // PYSIDE-2230: This is the SbkObject entry which has no base to provide
+ // the metaclass. We patch it in by modifying `object`s class.
+ assert(meta);
+ auto *base = reinterpret_cast<PyObject *>(&PyBaseObject_Type);
+ base->ob_type = meta;
+ basesPatch.reset(Py_BuildValue("(O)", &PyBaseObject_Type));
+ bases = basesPatch.object();
+ }
+
+ Py_ssize_t n = PyTuple_GET_SIZE(bases);
+ for (auto idx = 0; idx < n; ++idx) {
+ PyTypeObject *base = reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(bases, idx));
+ PyTypeObject *meta = Py_TYPE(base);
+ if (meta->tp_new != PyType_Type.tp_new) {
+ // make sure there is no second meta class
+ assert(keepMeta == nullptr);
+ keepMeta = meta;
+ keepNew = meta->tp_new;
+ meta->tp_new = PyType_Type.tp_new;
+ }
+ }
+ }
+
+#if !defined(Py_LIMITED_API) && PY_VERSION_HEX >= 0x030C0000
+ auto *ret = PyType_FromMetaclass(meta, nullptr /*module*/, spec, bases);
+#else
+ auto *ret = _PyType_FromSpecWithBases(spec, bases);
+#endif
+
+ if (keepMeta)
+ keepMeta->tp_new = keepNew;
+ if (basesPatch.object()) {
+ // undo the metaclass patch.
+ auto *base = PyTuple_GET_ITEM(basesPatch.object(), 0);
+ base->ob_type = &PyType_Type;
+ }
+ return ret;
+}
+
PyTypeObject *SbkType_FromSpec_BMDWB(PyType_Spec *spec,
PyObject *bases,
PyTypeObject *meta,
@@ -61,7 +117,7 @@ PyTypeObject *SbkType_FromSpec_BMDWB(PyType_Spec *spec,
int package_level = atoi(spec->name);
const char *mod = new_spec.name = colon + 1;
- PyObject *obType = _PyType_FromSpecWithBases(&new_spec, bases);
+ PyObject *obType = _PyType_FromSpecWithBasesHack(&new_spec, bases, meta);
if (obType == nullptr)
return nullptr;
@@ -73,8 +129,8 @@ PyTypeObject *SbkType_FromSpec_BMDWB(PyType_Spec *spec,
qual = dot + 1;
}
int mlen = qual - mod - 1;
- Shiboken::AutoDecRef module(Shiboken::String::fromCString(mod, mlen));
- Shiboken::AutoDecRef qualname(Shiboken::String::fromCString(qual));
+ AutoDecRef module(Shiboken::String::fromCString(mod, mlen));
+ AutoDecRef qualname(Shiboken::String::fromCString(qual));
auto *type = reinterpret_cast<PyTypeObject *>(obType);
@@ -98,9 +154,10 @@ PyTypeObject *SbkType_FromSpec_BMDWB(PyType_Spec *spec,
// PyType_Ready too early. (at least in PyPy, which caused pretty long debugging.)
auto *ht = reinterpret_cast<PyHeapTypeObject *>(type);
ht->ht_qualname = qualname;
- if (PyDict_SetItem(type->tp_dict, Shiboken::PyMagicName::qualname(), qualname))
+ AutoDecRef tpDict(PepType_GetDict(type));
+ if (PyDict_SetItem(tpDict.object(), Shiboken::PyMagicName::qualname(), qualname))
return nullptr;
- if (PyDict_SetItem(type->tp_dict, Shiboken::PyMagicName::module(), module))
+ if (PyDict_SetItem(tpDict.object(), Shiboken::PyMagicName::module(), module))
return nullptr;
PyType_Ready(type);
#else
@@ -329,7 +386,7 @@ _PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
/// Here is the only change needed: Do not finalize type creation.
// if (PyType_Ready(type) < 0)
// goto fail;
- type->tp_dict = PyDict_New();
+ PepType_SetDict(type, PyDict_New());
/// This is not found in PyPy:
// if (type->tp_dictoffset) {
// res->ht_cached_keys = _PyDict_NewKeysForClass();
diff --git a/sources/shiboken6/libshiboken/sbkversion.h.in b/sources/shiboken6/libshiboken/sbkversion.h.in
index 7f99abc3e..5c0b38fdb 100644
--- a/sources/shiboken6/libshiboken/sbkversion.h.in
+++ b/sources/shiboken6/libshiboken/sbkversion.h.in
@@ -10,8 +10,8 @@
#define SHIBOKEN_MICRO_VERSION @shiboken_MICRO_VERSION@
#define SHIBOKEN_RELEASE_LEVEL "final"
#define SHIBOKEN_SERIAL 0
-#define PYTHON_VERSION_MAJOR @PYTHON_VERSION_MAJOR@
-#define PYTHON_VERSION_MINOR @PYTHON_VERSION_MINOR@
-#define PYTHON_VERSION_PATCH @PYTHON_VERSION_PATCH@
+#define PYTHON_VERSION_MAJOR @Python_VERSION_MAJOR@
+#define PYTHON_VERSION_MINOR @Python_VERSION_MINOR@
+#define PYTHON_VERSION_PATCH @Python_VERSION_PATCH@
#endif
diff --git a/sources/shiboken6/libshiboken/sbkwindows.h b/sources/shiboken6/libshiboken/sbkwindows.h
new file mode 100644
index 000000000..9e753fa5e
--- /dev/null
+++ b/sources/shiboken6/libshiboken/sbkwindows.h
@@ -0,0 +1,17 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef SBKWINDOWS_H
+#define SBKWINDOWS_H
+
+#ifdef _WIN32
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+#endif
+
+#endif // SBKWINDOWS_H
diff --git a/sources/shiboken6/libshiboken/shiboken.h b/sources/shiboken6/libshiboken/shiboken.h
index 13a15e1f4..fcf777ae0 100644
--- a/sources/shiboken6/libshiboken/shiboken.h
+++ b/sources/shiboken6/libshiboken/shiboken.h
@@ -11,10 +11,10 @@
#include "gilstate.h"
#include "threadstatesaver.h"
#include "helper.h"
+#include "pyobjectholder.h"
#include "sbkarrayconverter.h"
#include "sbkconverter.h"
#include "sbkenum.h"
-#include "sbkenum_p.h" // PYSIDE-1735: This is during the migration, only.
#include "sbkerrors.h"
#include "sbkmodule.h"
#include "sbkstring.h"
diff --git a/sources/shiboken6/libshiboken/signature.h b/sources/shiboken6/libshiboken/signature.h
index 1cc100f3d..e0130b5a6 100644
--- a/sources/shiboken6/libshiboken/signature.h
+++ b/sources/shiboken6/libshiboken/signature.h
@@ -13,7 +13,6 @@ extern "C"
LIBSHIBOKEN_API int InitSignatureStrings(PyTypeObject *, const char *[]);
LIBSHIBOKEN_API void FinishSignatureInitialization(PyObject *, const char *[]);
LIBSHIBOKEN_API void SetError_Argument(PyObject *, const char *, PyObject *);
-LIBSHIBOKEN_API PyObject *Sbk_TypeGet___signature__(PyObject *, PyObject *);
LIBSHIBOKEN_API PyObject *Sbk_TypeGet___doc__(PyObject *);
LIBSHIBOKEN_API PyObject *GetFeatureDict();
diff --git a/sources/shiboken6/libshiboken/signature/signature.cpp b/sources/shiboken6/libshiboken/signature/signature.cpp
index f83618779..3255cb56d 100644
--- a/sources/shiboken6/libshiboken/signature/signature.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature.cpp
@@ -197,7 +197,7 @@ PyObject *GetSignature_Wrapper(PyObject *ob, PyObject *modifier)
PyObject *props = PyDict_GetItem(dict, func_name);
if (props == nullptr) {
// handle `__init__` like the class itself
- if (strcmp(String::toCString(func_name), "__init__") == 0)
+ if (PyUnicode_CompareWithASCIIString(func_name, "__init__") == 0)
return GetSignature_TypeMod(objclass, modifier);
Py_RETURN_NONE;
}
@@ -227,6 +227,8 @@ PyObject *GetSignature_TypeMod(PyObject *ob, PyObject *modifier)
// The `modifier` argument is a string that is passed in from `loader.py`.
// Configuration what the modifiers mean is completely in Python.
//
+// PYSIDE-2101: The __signature__ attribute is gone due to rlcompleter.
+//
PyObject *get_signature_intern(PyObject *ob, PyObject *modifier)
{
@@ -246,6 +248,9 @@ PyObject *get_signature_intern(PyObject *ob, PyObject *modifier)
return pyside_tp_get___signature__(ob, modifier);
if (Py_TYPE(ob) == &PyWrapperDescr_Type)
return pyside_wd_get___signature__(ob, modifier);
+ // For classmethods we use the simple wrapper description implementation.
+ if (Py_TYPE(ob) == &PyClassMethodDescr_Type)
+ return pyside_wd_get___signature__(ob, modifier);
return nullptr;
}
@@ -302,7 +307,7 @@ static PyObject *feature_import(PyObject * /* self */, PyObject *args, PyObject
PyMethodDef signature_methods[] = {
{"__feature_import__", (PyCFunction)feature_import, METH_VARARGS | METH_KEYWORDS, nullptr},
{"get_signature", (PyCFunction)get_signature, METH_VARARGS,
- "get the __signature__, but pass an optional string parameter"},
+ "get the signature, passing an optional string parameter"},
{nullptr, nullptr, 0, nullptr}
};
@@ -385,9 +390,7 @@ PyObject *PySide_BuildSignatureProps(PyObject *type_key)
#ifdef PYPY_VERSION
static bool get_lldebug_flag()
{
- PyObject *sysmodule = PyImport_AddModule("sys");
- auto *dic = PyModule_GetDict(sysmodule);
- dic = PyDict_GetItemString(dic, "pypy_translation_info");
+ auto *dic = PySys_GetObject("pypy_translation_info");
int lldebug = PyObject_IsTrue(PyDict_GetItemString(dic, "translation.lldebug"));
int lldebug0 = PyObject_IsTrue(PyDict_GetItemString(dic, "translation.lldebug0"));
return lldebug || lldebug0;
@@ -428,8 +431,6 @@ static int PySide_FinishSignatures(PyObject *module, const char *signatures[])
if (PyCFunction_Check(func))
if (PyDict_SetItem(pyside_globals->map_dict, func, module) < 0)
return -1;
- if (_finish_nested_classes(obdict) < 0)
- return -1;
// The finish_import function will not work the first time since phase 2
// was not yet run. But that is ok, because the first import is always for
// the shiboken module (or a test module).
@@ -451,10 +452,12 @@ static int PySide_FinishSignatures(PyObject *module, const char *signatures[])
int InitSignatureStrings(PyTypeObject *type, const char *signatures[])
{
+ // PYSIDE-2404: This function now also builds the mapping for static methods.
+ // It was one missing spot to let Lazy import work.
init_shibokensupport_module();
auto *ob_type = reinterpret_cast<PyObject *>(type);
int ret = PySide_BuildSignatureArgs(ob_type, signatures);
- if (ret < 0) {
+ if (ret < 0 || _build_func_to_type(ob_type) < 0) {
PyErr_Print();
PyErr_SetNone(PyExc_ImportError);
}
@@ -471,6 +474,8 @@ void FinishSignatureInitialization(PyObject *module, const char *signatures[])
* Still, it is not possible to call init phase 2 from here,
* because the import is still running. Do it from Python!
*/
+ init_shibokensupport_module();
+
#ifndef PYPY_VERSION
static const bool patch_types = true;
#else
@@ -534,7 +539,7 @@ static PyObject *adjustFuncName(const char *func_name)
// Find the feature flags
auto type = reinterpret_cast<PyTypeObject *>(obtype.object());
- auto dict = type->tp_dict;
+ AutoDecRef dict(PepType_GetDict(type));
int id = currentSelectId(type);
id = id < 0 ? 0 : id; // if undefined, set to zero
auto lower = id & 0x01;
@@ -583,7 +588,9 @@ void SetError_Argument(PyObject *args, const char *func_name, PyObject *info)
PyObject *e, *v, *t;
// Note: These references are all borrowed.
PyErr_Fetch(&e, &v, &t);
+ Py_DECREF(e);
info = v;
+ Py_XDECREF(t);
}
// PYSIDE-1019: Modify the function name expression according to feature.
AutoDecRef new_func_name(adjustFuncName(func_name));
@@ -614,14 +621,10 @@ void SetError_Argument(PyObject *args, const char *func_name, PyObject *info)
* But the __doc__ attribute existed already by inheritance, and calling
* PyType_Modified() is not supported. So we added the getsets explicitly
* to the metatype.
+ *
+ * PYSIDE-2101: The __signature__ attribute is gone due to rlcompleter.
*/
-PyObject *Sbk_TypeGet___signature__(PyObject *ob, PyObject *modifier)
-{
- init_shibokensupport_module();
- return pyside_tp_get___signature__(ob, modifier);
-}
-
PyObject *Sbk_TypeGet___doc__(PyObject *ob)
{
init_shibokensupport_module();
diff --git a/sources/shiboken6/libshiboken/signature/signature_extend.cpp b/sources/shiboken6/libshiboken/signature/signature_extend.cpp
index d571f90f3..7292f8216 100644
--- a/sources/shiboken6/libshiboken/signature/signature_extend.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature_extend.cpp
@@ -70,8 +70,6 @@ PyObject *pyside_cf_get___signature__(PyObject *func, PyObject *modifier)
PyObject *pyside_sm_get___signature__(PyObject *sm, PyObject *modifier)
{
AutoDecRef func(PyObject_GetAttr(sm, PyMagicName::func()));
- if (Py_TYPE(func) == PepFunction_TypePtr)
- return PyObject_GetAttr(func, PyMagicName::signature());
return _get_written_signature(GetSignature_Function, func, modifier);
}
@@ -79,7 +77,7 @@ PyObject *pyside_md_get___signature__(PyObject *ob_md, PyObject *modifier)
{
AutoDecRef func(name_key_to_func(ob_md));
if (func.object() == Py_None)
- return Py_None;
+ Py_RETURN_NONE;
if (func.isNull())
Py_FatalError("missing mapping in MethodDescriptor");
return pyside_cf_get___signature__(func, modifier);
@@ -123,13 +121,15 @@ static PyObject *handle_doc(PyObject *ob, PyObject *old_descr)
{
AutoDecRef ob_type_mod(GetClassOrModOf(ob));
const char *name;
- if (PyModule_Check(ob_type_mod.object()))
+ bool isModule = PyModule_Check(ob_type_mod.object());
+ if (isModule)
name = PyModule_GetName(ob_type_mod.object());
else
name = reinterpret_cast<PyTypeObject *>(ob_type_mod.object())->tp_name;
PyObject *res{};
- if (handle_doc_in_progress || name == nullptr || strncmp(name, "PySide6.", 8) != 0) {
+ if (handle_doc_in_progress || name == nullptr
+ || (isModule && strncmp(name, "PySide6.", 8) != 0)) {
res = PyObject_CallMethodObjArgs(old_descr, PyMagicName::get(), ob, nullptr);
} else {
handle_doc_in_progress++;
@@ -169,59 +169,29 @@ static PyObject *pyside_wd_get___doc__(PyObject *wd)
return handle_doc(wd, old_wd_doc_descr);
}
-// the default setter for all objects
-static int pyside_set___signature__(PyObject *op, PyObject *value)
-{
- // By this additional check, this function refuses write access.
- // We consider both nullptr and Py_None as not been written.
- AutoDecRef has_val(get_signature_intern(op, nullptr));
- if (!(has_val.isNull() || has_val == Py_None)) {
- PyErr_Format(PyExc_AttributeError,
- "Attribute '__signature__' of '%.50s' object is not writable",
- Py_TYPE(op)->tp_name);
- return -1;
- }
- int ret = value == nullptr ? PyDict_DelItem(pyside_globals->value_dict, op)
- : PyDict_SetItem(pyside_globals->value_dict, op, value);
- Py_XINCREF(value);
- return ret;
-}
-
// PYSIDE-535: We cannot patch types easily in PyPy.
// Let's use the `get_signature` function, instead.
static PyGetSetDef new_PyCFunction_getsets[] = {
{const_cast<char *>("__doc__"), reinterpret_cast<getter>(pyside_cf_get___doc__),
nullptr, nullptr, nullptr},
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(pyside_cf_get___signature__),
- reinterpret_cast<setter>(pyside_set___signature__),
- nullptr, nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr}
};
static PyGetSetDef new_PyStaticMethod_getsets[] = {
{const_cast<char *>("__doc__"), reinterpret_cast<getter>(pyside_sm_get___doc__),
nullptr, nullptr, nullptr},
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(pyside_sm_get___signature__),
- reinterpret_cast<setter>(pyside_set___signature__),
- nullptr, nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr}
};
static PyGetSetDef new_PyMethodDescr_getsets[] = {
{const_cast<char *>("__doc__"), reinterpret_cast<getter>(pyside_md_get___doc__),
nullptr, nullptr, nullptr},
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(pyside_md_get___signature__),
- reinterpret_cast<setter>(pyside_set___signature__),
- nullptr, nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr}
};
static PyGetSetDef new_PyWrapperDescr_getsets[] = {
{const_cast<char *>("__doc__"), reinterpret_cast<getter>(pyside_wd_get___doc__),
nullptr, nullptr, nullptr},
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(pyside_wd_get___signature__),
- reinterpret_cast<setter>(pyside_set___signature__),
- nullptr, nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr}
};
diff --git a/sources/shiboken6/libshiboken/signature/signature_globals.cpp b/sources/shiboken6/libshiboken/signature/signature_globals.cpp
index d0ea86fc6..3a79a12d5 100644
--- a/sources/shiboken6/libshiboken/signature/signature_globals.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature_globals.cpp
@@ -88,11 +88,9 @@ static safe_globals_struc *init_phase_1()
* Due to MSVC's limitation to 64k strings, we needed to assemble pieces.
*/
auto **block_ptr = reinterpret_cast<const char **>(PySide_CompressedSignaturePackage);
- int npieces = 0;
PyObject *piece{};
AutoDecRef zipped_string_sequence(PyList_New(0));
for (; **block_ptr != 0; ++block_ptr) {
- npieces++;
// we avoid the string/unicode dilemma by not using PyString_XXX:
piece = Py_BuildValue("s", *block_ptr);
if (piece == nullptr || PyList_Append(zipped_string_sequence, piece) < 0)
@@ -189,6 +187,16 @@ static int init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
p->feature_imported_func = PyObject_GetAttrString(loader, "feature_imported");
if (p->feature_imported_func == nullptr)
break;
+
+ // We call stuff like the feature initialization late,
+ // after all the function pointers are in place.
+ PyObject *post_init_func = PyObject_GetAttrString(loader, "post_init");
+ if (post_init_func == nullptr)
+ break;
+ PyObject *ret = PyObject_CallFunctionObjArgs(post_init_func, nullptr);
+ if (ret == nullptr)
+ break;
+
return 0;
} while (0);
@@ -201,12 +209,12 @@ static int init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
#ifndef _WIN32
////////////////////////////////////////////////////////////////////////////
// a stack trace for linux-like platforms
-#include <stdio.h>
+#include <cstdio>
#if defined(__GLIBC__)
# include <execinfo.h>
#endif
#include <signal.h>
-#include <stdlib.h>
+#include <cstdlib>
#include <unistd.h>
static void handler(int sig) {
@@ -219,7 +227,7 @@ static void handler(int sig) {
// print out all the frames to stderr
#endif
- fprintf(stderr, "Error: signal %d:\n", sig);
+ std::fprintf(stderr, "Error: signal %d:\n", sig);
#if defined(__GLIBC__)
backtrace_symbols_fd(array, size, STDERR_FILENO);
#endif
@@ -229,7 +237,7 @@ static void handler(int sig) {
////////////////////////////////////////////////////////////////////////////
#endif // _WIN32
-safe_globals pyside_globals = nullptr;
+safe_globals_struc *pyside_globals = nullptr;
void init_shibokensupport_module(void)
{
diff --git a/sources/shiboken6/libshiboken/signature/signature_helper.cpp b/sources/shiboken6/libshiboken/signature/signature_helper.cpp
index ef0c021d5..cf84cfa13 100644
--- a/sources/shiboken6/libshiboken/signature/signature_helper.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature_helper.cpp
@@ -51,10 +51,13 @@ int add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **doc_descr)
/*
* This function is used to assign a new `__signature__` attribute,
* and also to override a `__doc__` or `__name__` attribute.
+ *
+ * PYSIDE-2101: The __signature__ attribute is gone due to rlcompleter.
*/
assert(PyType_Check(type));
PyType_Ready(type);
- PyObject *dict = type->tp_dict;
+ AutoDecRef tpDict(PepType_GetDict(type));
+ auto *dict = tpDict.object();
for (; gsp->name != nullptr; gsp++) {
PyObject *have_descr = PyDict_GetItemString(dict, gsp->name);
if (have_descr != nullptr) {
@@ -291,7 +294,7 @@ PyObject *_address_to_stringlist(PyObject *numkey)
return res_list;
}
-static int _build_func_to_type(PyObject *obtype)
+int _build_func_to_type(PyObject *obtype)
{
/*
* There is no general way to directly get the type of a static method.
@@ -307,7 +310,17 @@ static int _build_func_to_type(PyObject *obtype)
* We also check for hidden methods, see below.
*/
auto *type = reinterpret_cast<PyTypeObject *>(obtype);
- PyObject *dict = type->tp_dict;
+ AutoDecRef tpDict(PepType_GetDict(type));
+ auto *dict = tpDict.object();
+
+ // PYSIDE-2404: Get the original dict for late initialization.
+ // The dict might have been switched before signature init.
+ static const auto *pyTypeType_tp_dict = PepType_GetDict(&PyType_Type);
+ if (Py_TYPE(dict) != Py_TYPE(pyTypeType_tp_dict)) {
+ tpDict.reset(PyObject_GetAttr(dict, PyName::orig_dict()));
+ dict = tpDict.object();
+ }
+
PyMethodDef *meth = type->tp_methods;
if (meth == nullptr)
@@ -373,26 +386,4 @@ static int _build_func_to_type(PyObject *obtype)
return 0;
}
-int _finish_nested_classes(PyObject *obdict)
-{
- PyObject *key, *value, *obtype;
- PyTypeObject *subtype;
- Py_ssize_t pos = 0;
-
- if (obdict == nullptr)
- return -1;
- while (PyDict_Next(obdict, &pos, &key, &value)) {
- if (PyType_Check(value)) {
- obtype = value;
- if (_build_func_to_type(obtype) < 0)
- return -1;
- // now continue with nested cases
- subtype = reinterpret_cast<PyTypeObject *>(obtype);
- if (_finish_nested_classes(subtype->tp_dict) < 0)
- return -1;
- }
- }
- return 0;
-}
-
} // extern "C"
diff --git a/sources/shiboken6/libshiboken/signature_p.h b/sources/shiboken6/libshiboken/signature_p.h
index 7ea03877a..d0c4ee537 100644
--- a/sources/shiboken6/libshiboken/signature_p.h
+++ b/sources/shiboken6/libshiboken/signature_p.h
@@ -10,7 +10,7 @@ extern "C" {
// signature_globals.cpp
-typedef struct safe_globals_struc {
+struct safe_globals_struc {
// init part 1: get arg_dict
PyObject *helper_module;
PyObject *arg_dict;
@@ -25,9 +25,9 @@ typedef struct safe_globals_struc {
PyObject *finish_import_func;
PyObject *feature_import_func;
PyObject *feature_imported_func;
-} safe_globals_struc, *safe_globals;
+};
-extern safe_globals pyside_globals;
+extern safe_globals_struc *pyside_globals;
extern PyMethodDef signature_methods[];
void init_shibokensupport_module(void);
@@ -63,6 +63,7 @@ PyObject *_get_class_of_cf(PyObject *ob_cf);
PyObject *_get_class_of_sm(PyObject *ob_sm);
PyObject *_get_class_of_descr(PyObject *ob);
PyObject *_address_to_stringlist(PyObject *numkey);
+int _build_func_to_type(PyObject *obtype);
int _finish_nested_classes(PyObject *dict);
#ifdef PYPY_VERSION
diff --git a/sources/shiboken6/libshiboken/voidptr.cpp b/sources/shiboken6/libshiboken/voidptr.cpp
index e768ff608..8bb3f6ac8 100644
--- a/sources/shiboken6/libshiboken/voidptr.cpp
+++ b/sources/shiboken6/libshiboken/voidptr.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "voidptr.h"
+#include "pep384ext.h"
#include "sbkconverter.h"
#include "basewrapper.h"
#include "basewrapper_p.h"
@@ -10,12 +11,12 @@ extern "C"
{
// Void pointer object definition.
-typedef struct {
+struct SbkVoidPtrObject {
PyObject_HEAD
void *cptr;
Py_ssize_t size;
bool isWritable;
-} SbkVoidPtrObject;
+};
PyObject *SbkVoidPtrObject_new(PyTypeObject *type, PyObject * /* args */, PyObject * /* kwds */)
{
@@ -24,8 +25,7 @@ PyObject *SbkVoidPtrObject_new(PyTypeObject *type, PyObject * /* args */, PyObje
// like this, actual call forgotten:
// SbkVoidPtrObject *self =
// reinterpret_cast<SbkVoidPtrObject *>(type->tp_alloc);
- PyObject *ob = type->tp_alloc(type, 0);
- auto *self = reinterpret_cast<SbkVoidPtrObject *>(ob);
+ auto *self = PepExt_TypeCallAlloc<SbkVoidPtrObject>(type, 0);
if (self != nullptr) {
self->cptr = nullptr;
@@ -156,10 +156,9 @@ PyObject *SbkVoidPtrObject_int(PyObject *v)
PyObject *toBytes(PyObject *self, PyObject * /* args */)
{
auto *sbkObject = reinterpret_cast<SbkVoidPtrObject *>(self);
- if (sbkObject->size < 0) {
- PyErr_SetString(PyExc_IndexError, "VoidPtr does not have a size set.");
- return nullptr;
- }
+ if (sbkObject->size < 0)
+ return PyErr_Format(PyExc_IndexError, "VoidPtr does not have a size set.");
+
PyObject *bytes = PyBytes_FromStringAndSize(reinterpret_cast<const char *>(sbkObject->cptr),
sbkObject->size);
Py_XINCREF(bytes);
@@ -256,38 +255,42 @@ static PyBufferProcs SbkVoidPtrObjectBufferProc = {
(releasebufferproc)nullptr // bf_releasebuffer
};
-// Void pointer type definition.
-static PyType_Slot SbkVoidPtrType_slots[] = {
- {Py_tp_repr, reinterpret_cast<void *>(SbkVoidPtrObject_repr)},
- {Py_nb_int, reinterpret_cast<void *>(SbkVoidPtrObject_int)},
- {Py_sq_length, reinterpret_cast<void *>(SbkVoidPtrObject_length)},
- {Py_tp_str, reinterpret_cast<void *>(SbkVoidPtrObject_str)},
- {Py_tp_richcompare, reinterpret_cast<void *>(SbkVoidPtrObject_richcmp)},
- {Py_tp_init, reinterpret_cast<void *>(SbkVoidPtrObject_init)},
- {Py_tp_new, reinterpret_cast<void *>(SbkVoidPtrObject_new)},
- {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)},
- {Py_tp_methods, reinterpret_cast<void *>(SbkVoidPtrObject_methods)},
- {0, nullptr}
-};
-static PyType_Spec SbkVoidPtrType_spec = {
- "2:shiboken6.Shiboken.VoidPtr",
- sizeof(SbkVoidPtrObject),
- 0,
- Py_TPFLAGS_DEFAULT,
- SbkVoidPtrType_slots,
-};
-
-
+static PyTypeObject *createVoidPtrType()
+{
+ PyType_Slot SbkVoidPtrType_slots[] = {
+ {Py_tp_repr, reinterpret_cast<void *>(SbkVoidPtrObject_repr)},
+ {Py_nb_int, reinterpret_cast<void *>(SbkVoidPtrObject_int)},
+ {Py_sq_length, reinterpret_cast<void *>(SbkVoidPtrObject_length)},
+ {Py_tp_str, reinterpret_cast<void *>(SbkVoidPtrObject_str)},
+ {Py_tp_richcompare, reinterpret_cast<void *>(SbkVoidPtrObject_richcmp)},
+ {Py_tp_init, reinterpret_cast<void *>(SbkVoidPtrObject_init)},
+ {Py_tp_new, reinterpret_cast<void *>(SbkVoidPtrObject_new)},
+ {Py_tp_dealloc, reinterpret_cast<void *>(Sbk_object_dealloc)},
+ {Py_tp_methods, reinterpret_cast<void *>(SbkVoidPtrObject_methods)},
+ {0, nullptr}
+ };
+
+ PyType_Spec SbkVoidPtrType_spec = {
+ "2:shiboken6.Shiboken.VoidPtr",
+ sizeof(SbkVoidPtrObject),
+ 0,
+ Py_TPFLAGS_DEFAULT,
+ SbkVoidPtrType_slots,
+ };
+
+ return SbkType_FromSpec_BMDWB(&SbkVoidPtrType_spec,
+ nullptr, nullptr, 0, 0,
+ &SbkVoidPtrObjectBufferProc);
}
PyTypeObject *SbkVoidPtr_TypeF(void)
{
- static PyTypeObject *type = SbkType_FromSpec_BMDWB(&SbkVoidPtrType_spec,
- nullptr, nullptr, 0, 0,
- &SbkVoidPtrObjectBufferProc);
+ static auto *type = createVoidPtrType();
return type;
}
+} // extern "C"
+
namespace VoidPtr {
static int voidPointerInitialized = false;
diff --git a/sources/shiboken6/shibokenmodule/CMakeLists.txt b/sources/shiboken6/shibokenmodule/CMakeLists.txt
index 1a3d42a1b..702750450 100644
--- a/sources/shiboken6/shibokenmodule/CMakeLists.txt
+++ b/sources/shiboken6/shibokenmodule/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(shibokenmodule)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/shibokenmodule.txt.in"
@@ -25,9 +28,12 @@ add_custom_command(
add_library(shibokenmodule MODULE ${sample_SRC})
target_include_directories(shibokenmodule PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR})
-set_property(TARGET shibokenmodule PROPERTY PREFIX "")
-# PYSIDE-1497: This `..` is the crucial trick to unify the path location of `Shiboken`.
-set_property(TARGET shibokenmodule PROPERTY OUTPUT_NAME "../Shiboken${PYTHON_EXTENSION_SUFFIX}")
+
+set_target_properties(shibokenmodule PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "Shiboken${PYTHON_EXTENSION_SUFFIX}"
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.."
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/..")
if(WIN32)
set_property(TARGET shibokenmodule PROPERTY SUFFIX ".pyd")
diff --git a/sources/shiboken6/shibokenmodule/Shiboken.pyi b/sources/shiboken6/shibokenmodule/Shiboken.pyi
index a708e3871..6a1a63217 100644
--- a/sources/shiboken6/shibokenmodule/Shiboken.pyi
+++ b/sources/shiboken6/shibokenmodule/Shiboken.pyi
@@ -18,7 +18,8 @@ class Object(object):
def __init__(self) -> None: ...
-class VoidPtr(object): ...
+class VoidPtr(object):
+ def __init__(self, value: int) -> None: ...
def _unpickle_enum(arg__1: object, arg__2: object) -> object: ...
diff --git a/sources/shiboken6/shibokenmodule/_config.py.in b/sources/shiboken6/shibokenmodule/_config.py.in
index 92b3cd23c..600c431c9 100644
--- a/sources/shiboken6/shibokenmodule/_config.py.in
+++ b/sources/shiboken6/shibokenmodule/_config.py.in
@@ -9,3 +9,4 @@ version_info = (@shiboken_MAJOR_VERSION@, @shiboken_MINOR_VERSION@, @shiboken_MI
@PACKAGE_BUILD_COMMIT_HASH_DESCRIBED@
@PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT@
@PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT@
+@QT_MACOS_DEPLOYMENT_TARGET@
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/feature.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/feature.py
index 5171d59e9..7a0871ee7 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/feature.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/feature.py
@@ -1,6 +1,9 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+# flake8: noqa F:821
+# flake8: noqa F:401
+
"""
__feature__.py (renamed to feature.py)
@@ -15,7 +18,7 @@ The normal usage is like
Alternatively, there is the `set_selection` function which uses select_id's
and takes an optional `mod_name` parameter.
-The select id `-1` has the spectial meaning "ignore this module".
+The select id `-1` has the special meaning "ignore this module".
"""
import inspect
@@ -80,6 +83,7 @@ None to indicate that a normal import should be performed, and
All these variables are transparently kept in module `builtins`.
"""
+
def feature_import(name, *args, **kwargs):
# PYSIDE-1368: The `__name__` attribute does not need to exist in all modules.
# PYSIDE-1398: sys._getframe(1) may not exist when embedding.
@@ -110,8 +114,10 @@ def feature_import(name, *args, **kwargs):
# Redirect to the original import
return None
+
_is_initialized = False
+
def __init__():
global _is_initialized
if not _is_initialized:
@@ -132,9 +138,12 @@ def feature_imported(module):
A module that uses PySide has a switching default of 0 = "no feature".
Otherwise the default is -1 = "ignore this module".
"""
- name = module.__name__
- if name not in pyside_feature_dict:
- pyside_feature_dict[name] = 0 if _mod_uses_pyside(module) else -1
+
+ # PYSIDE-1368: The `__name__` attribute does not need to exist in all modules.
+ if hasattr(module, "__name__"):
+ name = module.__name__
+ if name not in pyside_feature_dict:
+ pyside_feature_dict[name] = 0 if _mod_uses_pyside(module) else -1
def _mod_uses_pyside(module):
@@ -152,6 +161,15 @@ def _mod_uses_pyside(module):
except OSError:
# this is a module withot source file
return False
+ except SyntaxError:
+ # PYSIDE-2189: A UnicodeError happens in tokenize.py in find_cookie
+ # which is then creating a SyntaxError in inspect.
+ # This is undocumented and a Python error, seen in Python 3.10.2 on Windows,
+ # importing `pythoncom` of the win32 package.
+ return False
+ except Exception:
+ # PYSIDE-2393: pytest behaves weird when allowing any other error.
+ return False
return "PySide6" in source
@@ -170,6 +188,7 @@ def set_selection(select_id, mod_name=None):
sys.modules["PySide6.QtCore"].__init_feature__()
return _current_selection(flag)
+
# The set_section(0) case seems to be unsafe. We will migrate to
# use the opaque feature.reset() call in all test cases.
def reset():
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/fix-complaints.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/fix-complaints.py
index 3e1d49328..f7190b12f 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/fix-complaints.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/fix-complaints.py
@@ -9,7 +9,6 @@ Run it once after copying a new version. It is idem-potent, unless
you are changing messages (what I did, of course :-) .
"""
-import os
import glob
from pathlib import Path
@@ -24,6 +23,7 @@ offending_words = {
utf8_line = "# This Python file uses the following encoding: utf-8\n"
marker_line = f"# It has been edited by {Path(__file__).name} .\n"
+
def patch_file(fname):
with fname.open() as f:
lines = f.readlines()
@@ -41,6 +41,7 @@ def patch_file(fname):
with open(fname, "w") as f:
f.write("".join(lines))
+
def doit():
dirname = Path(__file__).parent
patched_files = []
@@ -51,6 +52,7 @@ def doit():
print("Working on", fname)
patch_file(fname)
+
if __name__ == "__main__":
doit()
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
index 6b428e613..c2a19efef 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
@@ -1,6 +1,8 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+# flake8: noqa E:721
+
"""
errorhandler.py
@@ -19,12 +21,10 @@ This matter will be improved in a later version.
"""
import collections.abc
-import inspect
-import sys
import typing
from shibokensupport.signature import get_signature
-from shibokensupport.signature.mapping import update_mapping, namespace
+from shibokensupport.signature.mapping import namespace
from textwrap import dedent
@@ -77,8 +77,8 @@ def seterror_argument(args, func_name, info):
if info == "<":
msg = f"{func_name}(): not enough arguments"
elif info == "0":
- msg = (f"{func_name}(): not enough arguments. "
- "Note: keyword arguments are only supported for optional parameters.")
+ msg = (f"{func_name}(): not enough arguments. "
+ "Note: keyword arguments are only supported for optional parameters.")
elif info == ">":
msg = f"{func_name}(): too many arguments"
elif info.isalnum():
@@ -87,6 +87,12 @@ def seterror_argument(args, func_name, info):
msg = f"{func_name}(): {info}"
err = AttributeError
return err, msg
+ if isinstance(info, Exception):
+ # PYSIDE-2230: Python 3.12 seems to always do normalization.
+ err = type(info)
+ info = info.args[0]
+ msg = f"{func_name}(): {info}"
+ return err, msg
if info and type(info) is dict:
msg = f"{func_name}(): unsupported keyword '{tuple(info)[0]}'"
return AttributeError, msg
@@ -126,6 +132,8 @@ def check_string_type(s):
def make_helptext(func):
existing_doc = func.__doc__
+ if existing_doc is None and hasattr(func, "__dict__"):
+ existing_doc = func.__dict__.get("__doc__")
sigs = get_signature(func)
if not sigs:
return existing_doc
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py
index dbde18f18..bae264294 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py
@@ -34,9 +34,10 @@ def finish_import(module):
except Exception as e:
name = e.__class__.__qualname__
print(72 * "*")
- print(f"Error in deprecated.py, ignored:")
+ print("Error in deprecated.py, ignored:")
print(f" {name}: {e}")
+
"""
A note for people who might think this could be written in pure Python:
@@ -62,4 +63,3 @@ module, it is *perhaps* possible to solve that. I tried for a day and then
gave up, since the solution is anyway not too nice when __import__ must
be overridden.
"""
-#eof
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py
index c271be7f7..0e781cbcb 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py
@@ -79,6 +79,7 @@ class SignatureLayout(SimpleNamespace):
The only allowed values are '{allowed_values}'.
"""))
+
# The following names are used literally in this module.
# This way, we avoid the dict hashing problem.
signature = SignatureLayout()
@@ -115,7 +116,7 @@ def define_nameless_parameter():
P = inspect.Parameter
newname = "NamelessParameter"
bases = P.__bases__
- body = dict(P.__dict__) # get rid of mappingproxy
+ body = dict(P.__dict__) # get rid of mappingproxy
if "__slots__" in body:
# __slots__ would create duplicates
for name in body["__slots__"]:
@@ -167,12 +168,13 @@ def make_signature_nameless(signature):
signature.parameters[key].__class__ = NamelessParameter
-_POSITIONAL_ONLY = inspect._POSITIONAL_ONLY
-_POSITIONAL_OR_KEYWORD = inspect._POSITIONAL_OR_KEYWORD
-_VAR_POSITIONAL = inspect._VAR_POSITIONAL
-_KEYWORD_ONLY = inspect._KEYWORD_ONLY
-_VAR_KEYWORD = inspect._VAR_KEYWORD
-_empty = inspect._empty
+_POSITIONAL_ONLY = inspect._POSITIONAL_ONLY # noqa E:201
+_POSITIONAL_OR_KEYWORD = inspect._POSITIONAL_OR_KEYWORD # noqa E:201
+_VAR_POSITIONAL = inspect._VAR_POSITIONAL # noqa E:201
+_KEYWORD_ONLY = inspect._KEYWORD_ONLY # noqa E:201
+_VAR_KEYWORD = inspect._VAR_KEYWORD # noqa E:201
+_empty = inspect._empty # noqa E:201
+
def create_signature(props, key):
if not props:
@@ -183,9 +185,9 @@ def create_signature(props, key):
return list(create_signature(elem, key)
for elem in props["multi"])
if type(key) is tuple:
- sig_kind, modifier = key
+ _, modifier = key
else:
- sig_kind, modifier = key, "signature"
+ _, modifier = key, "signature"
layout = globals()[modifier] # lookup of the modifier in this module
if not isinstance(layout, SignatureLayout):
@@ -234,8 +236,8 @@ def create_signature(props, key):
if kind == _VAR_POSITIONAL:
kind = _KEYWORD_ONLY
sig = inspect.Signature(params,
- return_annotation=annotations.get('return', _empty),
- __validate_parameters__=False)
+ return_annotation=annotations.get('return', _empty),
+ __validate_parameters__=False)
# the special case of nameless parameters
if not layout.parameter_names:
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
index 947537a0f..5650e2bc1 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py
@@ -14,9 +14,7 @@ by producing a lot of clarity.
import inspect
import sys
import types
-import typing
from shibokensupport.signature import get_signature as get_sig
-from shibokensupport.signature.layout import create_signature
"""
@@ -106,7 +104,7 @@ class ExactEnumerator(object):
return ret
if "<" in class_name:
# This is happening in QtQuick for some reason:
- ## class QSharedPointer<QQuickItemGrabResult >:
+ # class std::shared_ptr<QQuickItemGrabResult >:
# We simply skip over this class.
return ret
bases_list = []
@@ -125,11 +123,18 @@ class ExactEnumerator(object):
enums = []
properties = []
signals = []
+ attributes = {}
for thing_name, thing in class_members:
if signal_check(thing):
signals.append((thing_name, thing))
elif inspect.isclass(thing):
+ # If this is the only member of the class, it causes the stub
+ # to be printed empty without ..., as self.fmt.have_body will
+ # then be True. (Example: QtCore.QCborTag). Skip it to avoid
+ # this problem.
+ if thing_name == "_member_type_":
+ continue
subclass_name = ".".join((class_name, thing_name))
subclasses.append((subclass_name, thing))
elif inspect.isroutine(thing):
@@ -141,21 +146,28 @@ class ExactEnumerator(object):
enums.append((thing_name, type(thing).__qualname__, thing))
elif isinstance(thing, property):
properties.append((thing_name, thing))
+ # Support attributes that have PySide types as values,
+ # but we skip the 'staticMetaObject' that needs
+ # to be defined at a QObject level.
+ elif "PySide" in str(type(thing)) and "QMetaObject" not in str(type(thing)):
+ if class_name not in attributes:
+ attributes[class_name] = {}
+ attributes[class_name][thing_name] = thing
if thing_name in self.collision_candidates:
self.collision_track.add(thing_name)
init_signature = getattr(klass, "__signature__", None)
- new_enum = sys.pyside63_option_python_enum
# sort by class then enum value
- enums.sort(key=lambda tup: (tup[1], tup[2].value if new_enum else tup[2]))
+ enums.sort(key=lambda tup: (tup[1], tup[2].value))
# We want to handle functions and properties together.
func_prop = sorted(functions + properties, key=lambda tup: tup[0])
# find out how many functions create a signature
sigs = list(_ for _ in functions if get_sig(_[1]))
- self.fmt.have_body = bool(subclasses or sigs or properties or enums or init_signature)
+ self.fmt.have_body = bool(subclasses or sigs or properties or enums or # noqa W:504
+ init_signature or signals or attributes)
with self.fmt.klass(class_name, class_str):
self.fmt.level += 1
@@ -165,8 +177,7 @@ class ExactEnumerator(object):
if len(enums):
self.section()
for enum_name, enum_class_name, value in enums:
- with self.fmt.enum(enum_class_name, enum_name,
- value.value if new_enum else value):
+ with self.fmt.enum(enum_class_name, enum_name, value.value):
pass
if hasattr(self.fmt, "signal"):
# this is an optional feature
@@ -178,6 +189,13 @@ class ExactEnumerator(object):
sig_str = str(signal)
with self.fmt.signal(sig_class_name, signal_name, sig_str):
pass
+ if hasattr(self.fmt, "attribute"):
+ if len(attributes):
+ self.section()
+ for class_name, attrs in attributes.items():
+ for attr_name, attr_value in attrs.items():
+ with self.fmt.attribute(attr_name, attr_value):
+ pass
if len(subclasses):
self.section()
for subclass_name, subclass in subclasses:
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py
index bbca35fbd..ce12dd6c8 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py
@@ -3,6 +3,8 @@ LICENSE_TEXT = """
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
"""
+# flake8: noqa E:402
+
"""
pyi_generator.py
@@ -21,7 +23,6 @@ from pathlib import Path
from contextlib import contextmanager
from textwrap import dedent
-from shiboken6 import Shiboken
from shibokensupport.signature.lib.enum_sig import HintingEnumerator
from shibokensupport.signature.lib.tool import build_brace_pattern
@@ -59,6 +60,7 @@ class Formatter(Writer):
unrelated tasks of enumeration and formatting apart.
"""
def __init__(self, outfile, options, *args):
+ # XXX Find out which of these patches is still necessary!
self.options = options
Writer.__init__(self, outfile, *args)
# patching __repr__ to disable the __repr__ of typing.TypeVar:
@@ -74,8 +76,12 @@ class Formatter(Writer):
"""
def _typevar__repr__(self):
return f"typing.{self.__name__}"
- typing.TypeVar.__repr__ = _typevar__repr__
-
+ # This is no longer necessary for modern typing versions.
+ # Ignore therefore if the repr is read-only and cannot be changed.
+ try:
+ typing.TypeVar.__repr__ = _typevar__repr__
+ except TypeError:
+ pass
# Adding a pattern to substitute "Union[T, NoneType]" by "Optional[T]"
# I tried hard to replace typing.Optional by a simple override, but
# this became _way_ too much.
@@ -84,6 +90,7 @@ class Formatter(Writer):
pattern = fr"\b Union \s* \[ \s* {brace_pat} \s*, \s* NoneType \s* \]"
replace = r"Optional[\1]"
optional_searcher = re.compile(pattern, flags=re.VERBOSE)
+
def optional_replacer(source):
return optional_searcher.sub(replace, str(source))
self.optional_replacer = optional_replacer
@@ -152,6 +159,12 @@ class Formatter(Writer):
yield
@contextmanager
+ def attribute(self, attr_name, attr_value):
+ spaces = indent * self.level
+ self.print(f"{spaces}{attr_name:25} = ... # type: {type(attr_value).__qualname__}")
+ yield
+
+ @contextmanager
def signal(self, class_name, sig_name, sig_str):
spaces = indent * self.level
self.print(f"{spaces}{sig_name:25}: ClassVar[{class_name}] = ... # {sig_str}")
@@ -165,12 +178,14 @@ def find_imports(text):
FROM_IMPORTS = [
(None, ["builtins"]),
(None, ["os"]),
- (None, ["enum"] if sys.pyside63_option_python_enum else []),
+ (None, ["enum"]),
+ ("collections.abc", ["Iterable"]),
("typing", sorted(typing.__all__)),
("PySide6.QtCore", ["PyClassProperty", "Signal", "SignalInstance"]),
("shiboken6", ["Shiboken"]),
]
+
def filter_from_imports(from_struct, text):
"""
Build a reduced new `from` structure (nfs) with found entries, only
@@ -180,8 +195,15 @@ def filter_from_imports(from_struct, text):
lis = []
nfs.append((mod, lis))
for each in imports:
- if re.search(rf"(\b|@){each}\b([^\s\(:]|\n)", text):
- lis.append(each)
+ # PYSIDE-1603: We search text that is a usage of the class `each`,
+ # but only if the class is not also defined here.
+ if (f"class {each}(") not in text:
+ if re.search(rf"(\b|@){each}\b([^\s\(:]|\n)", text):
+ lis.append(each)
+ # Search if a type is present in the return statement
+ # of function declarations: '... -> here:'
+ if re.search(rf"->.*{each}.*:", text):
+ lis.append(each)
if not lis:
nfs.pop()
return nfs
@@ -220,12 +242,10 @@ def generate_pyi(import_name, outpath, options):
obj = getattr(top, plainname) if import_name != plainname else top
if not getattr(obj, "__file__", None) or Path(obj.__file__).is_dir():
raise ModuleNotFoundError(f"We do not accept a namespace as module `{plainname}`")
- module = sys.modules[import_name]
outfile = io.StringIO()
fmt = Formatter(outfile, options)
fmt.print(LICENSE_TEXT.strip())
- need_imports = options._pyside_call and not USE_PEP563
if USE_PEP563:
fmt.print("from __future__ import annotations")
fmt.print()
@@ -267,13 +287,12 @@ def generate_pyi(import_name, outpath, options):
wr.print(f"from {mod} import {import_args}")
wr.print()
wr.print()
+ wr.print("NoneType: TypeAlias = type[None]")
+ wr.print()
else:
wr.print(line)
if not options.quiet:
options.logger.info(f"Generated: {outfilepath}")
- # PYSIDE-1735: .pyi files are no longer compatible with Python, because
- # enum classes contain ellipsis which a Python enum forbids.
- # We will implement tests with Mypy, instead.
def main():
@@ -288,11 +307,10 @@ def main():
pyi_generator will try to generate an interface "<module>.pyi".
"""))
parser.add_argument("module",
- help="The full path name of an importable module binary (.pyd, .so)")
+ help="The full path name of an importable module binary (.pyd, .so)") # noqa E:128
parser.add_argument("--quiet", action="store_true", help="Run quietly")
- parser.add_argument("--check", action="store_true", help="Test the output")
parser.add_argument("--outpath",
- help="the output directory (default = location of module binary)")
+ help="the output directory (default = location of module binary)") # noqa E:128
options = parser.parse_args()
module = options.module
outpath = options.outpath
@@ -310,6 +328,7 @@ def main():
options.logger = logger
generate_pyi(module, outpath, options=options)
+
if __name__ == "__main__":
main()
# eof
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
index a7900e6b2..979dcf4ce 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
@@ -44,8 +44,8 @@ def build_brace_pattern(level, separators):
ro, rc = round_ = "()"
so, sc = square = "[]"
- co, cc = curly = "CD" # we insert "{}", later...
- ao, ac = angle = "<>"
+ co, cc = curly = "CD" # noqa E:201 we insert "{}", later...
+ ao, ac = angle = "<>" # noqa E:201
q2, bs, q1 = '"', "\\", "'"
allpat = round_ + square + curly + angle
__ = " "
@@ -79,8 +79,8 @@ def build_brace_pattern(level, separators):
{indent} )*
""")
for idx in range(level):
- pattern = pattern.format(replacer = repeated if idx < level-1 else no_braces_q,
- indent = idx * " ", **locals())
+ pattern = pattern.format(replacer=repeated if idx < level - 1 else no_braces_q,
+ indent=idx * " ", **locals())
return pattern.replace("C", "{").replace("D", "}")
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/loader.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/loader.py
index b6a432ba9..fb4c9eeca 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/loader.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/loader.py
@@ -1,6 +1,9 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+# flake8: noqa E:402
+# flake8: noqa F:401
+
"""
loader.py
@@ -30,22 +33,27 @@ import types
def pyside_type_init(type_key, sig_strings):
return parser.pyside_type_init(type_key, sig_strings)
+
# name used in signature.cpp
def create_signature(props, key):
return layout.create_signature(props, key)
+
# name used in signature.cpp
def seterror_argument(args, func_name, info):
return errorhandler.seterror_argument(args, func_name, info)
+
# name used in signature.cpp
def make_helptext(func):
return errorhandler.make_helptext(func)
+
# name used in signature.cpp
def finish_import(module):
return importhandler.finish_import(module)
+
# name used in signature.cpp
def feature_import(*args, **kwds):
# don't spend a stack level here for speed and compatibility
@@ -53,6 +61,7 @@ def feature_import(*args, **kwds):
feature_import = feature.feature_import
return feature_import(*args, **kwds)
+
# name used in signature.cpp
def feature_imported(*args, **kwds):
# don't spend a stack level here for speed and compatibility
@@ -107,6 +116,7 @@ def move_into_pyside_package():
put_into_package(PySide6.support.signature.lib, pyi_generator)
put_into_package(PySide6.support.signature.lib, tool)
+
from shibokensupport.signature import mapping
from shibokensupport.signature import errorhandler
from shibokensupport.signature import layout
@@ -119,23 +129,30 @@ from shibokensupport.signature.lib import tool
import enum
+post_init = lambda: None # noqa E:731 default
+
if "PySide6" in sys.modules:
# We publish everything under "PySide6.support", again.
move_into_pyside_package()
# PYSIDE-1502: Make sure that support can be imported.
try:
import PySide6.support
- except ModuleNotFoundError as e:
+ except ModuleNotFoundError:
print("PySide6.support could not be imported. "
"This is a serious configuration error.", file=sys.stderr)
raise
- # PYSIDE-1019: Modify `__import__` to be `__feature__` aware.
- # __feature__ is already in sys.modules as feature, so this is actually no import
- if not is_pypy:
- # PYSIDE-535: Cannot enable __feature__ for various reasons.
- import PySide6.support.feature
- sys.modules["__feature__"] = PySide6.support.feature
- builtins.__orig_import__ = builtins.__import__
- builtins.__import__ = builtins.__feature_import__
+
+ def post_init():
+ """
+ This function needs to be called explicitly when all function pointers are set.
+ Doing this during import has bad side-effects when preloading the loader.
+ """
+ # PYSIDE-1019: Modify `__import__` to be `__feature__` aware.
+ if not is_pypy:
+ # PYSIDE-535: Cannot enable __feature__ for various reasons.
+ import PySide6.support.feature
+ sys.modules["__feature__"] = PySide6.support.feature
+ builtins.__orig_import__ = builtins.__import__
+ builtins.__import__ = builtins.__feature_import__
# end of file
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
index dbc4596a2..944a928e6 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -1,6 +1,8 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+# flake8: noqa E:203
+
"""
mapping.py
@@ -20,10 +22,12 @@ from pathlib import Path
from typing import TypeVar, Generic
from _imp import is_builtin
+
class ellipsis(object):
def __repr__(self):
return "..."
+
ellipsis = ellipsis()
Point = typing.Tuple[int, int]
Variant = typing.Any
@@ -38,7 +42,7 @@ _S = TypeVar("_S")
MultiMap = typing.DefaultDict[str, typing.List[str]]
# ulong_max is only 32 bit on windows.
-ulong_max = 2*sys.maxsize+1 if len(struct.pack("L", 1)) != 4 else 0xffffffff
+ulong_max = 2 * sys.maxsize + 1 if len(struct.pack("L", 1)) != 4 else 0xffffffff
ushort_max = 0xffff
GL_COLOR_BUFFER_BIT = 0x00004000
@@ -74,6 +78,7 @@ class _NotCalled(str):
text = self if self.endswith(")") else self + "()"
return eval(text, namespace)
+
USE_PEP563 = False
# Note: we cannot know if this feature has been imported.
# Otherwise it would be "sys.version_info[:2] >= (3, 7)".
@@ -86,6 +91,7 @@ USE_PEP563 = False
class Virtual(_NotCalled):
pass
+
# Other types I simply could not find.
class Missing(_NotCalled):
# The string must be quoted, because the object does not exist.
@@ -98,6 +104,7 @@ class Missing(_NotCalled):
class Invalid(_NotCalled):
pass
+
# Helper types
class Default(_NotCalled):
pass
@@ -106,6 +113,7 @@ class Default(_NotCalled):
class Instance(_NotCalled):
pass
+
# Parameterized primitive variables
class _Parameterized(object):
def __init__(self, type):
@@ -115,15 +123,18 @@ class _Parameterized(object):
def __repr__(self):
return f"{type(self).__name__}({self.type.__name__})"
+
# Mark the primitive variables to be moved into the result.
class ResultVariable(_Parameterized):
pass
+
# Mark the primitive variables to become Sequence, Iterable or List
# (decided in the parser).
class ArrayLikeVariable(_Parameterized):
pass
+
StringList = ArrayLikeVariable(str)
@@ -142,7 +153,7 @@ class Reloader(object):
if getattr(mod, "__file__", None) and not Path(mod.__file__).is_dir():
ending = Path(mod.__file__).suffix
return ending not in (".py", ".pyc", ".pyo", ".pyi")
- return bool(is_builtin(mod.__name__))
+ return bool(hasattr(mod, "__name__") and is_builtin(mod.__name__))
def update(self):
"""
@@ -180,12 +191,14 @@ def check_module(mod):
mod_name = mod.__name__
raise ImportError(f"Module '{mod_name}' is not a binary module!")
+
update_mapping = Reloader().update
type_map = {}
namespace = globals() # our module's __dict__
type_map.update({
"...": ellipsis,
+ "Any": typing.Any,
"bool": bool,
"char": int,
"double": float,
@@ -200,7 +213,7 @@ type_map.update({
"PyObject": object,
"PyObject*": object,
"PyArrayObject": ArrayLikeVariable, # numpy
- "PyPathLike": typing.Union[str, bytes, os.PathLike],
+ "PyPathLike": typing.Union[str, bytes, os.PathLike[str]],
"PySequence": typing.Iterable, # important for numpy
"PyTypeObject": type,
"QChar": str,
@@ -217,6 +230,7 @@ type_map.update({
"uintptr_t": int,
"qintptr": int,
"qsizetype": int,
+ "QFunctionPointer": int,
"QList": ArrayLikeVariable,
"qlonglong": int,
"QMap": typing.Dict,
@@ -227,6 +241,7 @@ type_map.update({
"qreal": float,
"QSet": typing.Set,
"QString": str,
+ "QLatin1String": str,
"QStringView": str,
"QStringList": StringList,
"quint16": int,
@@ -264,16 +279,16 @@ type_map.update({
"ulong": int,
"ULONG_MAX": ulong_max,
"UINT64_MAX": 0xffffffff,
- "unsigned char": int, # 5.9
+ "unsigned char": int, # 5.9
"unsigned char*": str,
"unsigned int": int,
- "unsigned long int": int, # 5.6, RHEL 6.6
+ "unsigned long int": int, # 5.6, RHEL 6.6
"unsigned long long": int,
"unsigned long": int,
- "unsigned short int": int, # 5.6, RHEL 6.6
+ "unsigned short int": int, # 5.6, RHEL 6.6
"unsigned short": int,
"ushort": int,
- "void": int, # be more specific?
+ "void": int, # be more specific?
"WId": WId,
"zero(bytes)": b"",
"zero(Char)": 0,
@@ -285,7 +300,9 @@ type_map.update({
"zero(Any)": None,
# This can be refined by importing numpy.typing optionally, but better than nothing.
"numpy.ndarray": typing.List[typing.Any],
- })
+ "std.array[int, 4]": typing.List[int],
+ "std.array[float, 4]": typing.List[float]
+})
type_map.update({
# Handling variables declared as array:
@@ -297,8 +314,8 @@ type_map.update({
"array long long*" : ArrayLikeVariable(int),
"array long*" : ArrayLikeVariable(int),
"array short*" : ArrayLikeVariable(int),
- "array signed char*" : bytes,
- "array unsigned char*" : bytes,
+ "array signed char*" : typing.Union[bytes, bytearray, memoryview],
+ "array unsigned char*" : typing.Union[bytes, bytearray, memoryview],
"array unsigned int*" : ArrayLikeVariable(int),
"array unsigned short*" : ArrayLikeVariable(int),
# PYSIDE-1646: New macOS primitive types
@@ -309,17 +326,17 @@ type_map.update({
"array int32_t*" : ArrayLikeVariable(int),
"array uint32_t*" : ArrayLikeVariable(int),
"array intptr_t*" : ArrayLikeVariable(int),
- })
+})
type_map.update({
# Special cases:
- "char*" : bytes,
- "QChar*" : bytes,
+ "char*" : typing.Union[bytes, bytearray, memoryview],
+ "QChar*" : typing.Union[bytes, bytearray, memoryview],
"quint32*" : int, # only for QRandomGenerator
"quint8*" : bytearray, # only for QCborStreamReader and QCborValue
- "uchar*" : bytes,
- "unsigned char*": bytes,
- })
+ "uchar*" : typing.Union[bytes, bytearray, memoryview],
+ "unsigned char*": typing.Union[bytes, bytearray, memoryview],
+})
type_map.update({
# Handling variables that are returned, eventually as Tuples:
@@ -341,7 +358,7 @@ type_map.update({
"uint*" : ResultVariable(int),
"unsigned int*" : ResultVariable(int),
"QStringList*" : ResultVariable(StringList),
- })
+})
type_map.update({
@@ -349,20 +366,21 @@ type_map.update({
"[typing.Any]" : [typing.Any],
"[typing.Any,typing.Any]" : [typing.Any, typing.Any],
"None" : None,
- })
+})
# PYSIDE-1328: We need to handle "self" explicitly.
type_map.update({
"self" : "self",
"cls" : "cls",
- })
+})
# PYSIDE-1538: We need to treat "std::optional" accordingly.
type_map.update({
"std.optional": typing.Optional,
})
+
# The Shiboken Part
def init_Shiboken():
type_map.update({
@@ -372,6 +390,7 @@ def init_Shiboken():
})
return locals()
+
def init_minimal():
type_map.update({
"MinBool": bool,
@@ -387,7 +406,7 @@ def init_sample():
"const char*": str,
"Complex": complex,
"double": float,
- "ByteArray&": bytes,
+ "ByteArray&": typing.Union[bytes, bytearray, memoryview],
"Foo.HANDLE": int,
"HANDLE": int,
"Null": None,
@@ -395,7 +414,7 @@ def init_sample():
"OddBool": bool,
"PStr": str,
"PyDate": datetime.date,
- "PyBuffer": bytes,
+ "PyBuffer": typing.Union[bytes, bytearray, memoryview],
"sample.bool": bool,
"sample.char": int,
"sample.double": float,
@@ -431,6 +450,7 @@ def init_smart():
# This missing type should be defined in module smart. We cannot set it to Missing()
# because it is a container type. Therefore, we supply a surrogate:
global SharedPtr
+
class SharedPtr(Generic[_S]):
__module__ = "smart"
smart.SharedPtr = SharedPtr
@@ -444,7 +464,7 @@ def init_smart():
def init_PySide6_QtCore():
from PySide6.QtCore import Qt, QUrl, QDir, QKeyCombination
from PySide6.QtCore import QRect, QRectF, QSize, QPoint, QLocale, QByteArray
- from PySide6.QtCore import QMarginsF # 5.9
+ from PySide6.QtCore import QMarginsF # 5.9
from PySide6.QtCore import SignalInstance
try:
# seems to be not generated by 5.9 ATM.
@@ -455,40 +475,41 @@ def init_PySide6_QtCore():
"' '": " ",
"'%'": "%",
"'g'": "g",
- "4294967295UL": 4294967295, # 5.6, RHEL 6.6
+ "4294967295UL": 4294967295, # 5.6, RHEL 6.6
"CheckIndexOption.NoOption": Instance(
- "PySide6.QtCore.QAbstractItemModel.CheckIndexOptions.NoOption"), # 5.11
+ "PySide6.QtCore.QAbstractItemModel.CheckIndexOptions.NoOption"), # 5.11
"DescriptorType(-1)": int, # Native handle of QSocketDescriptor
"false": False,
"list of QAbstractAnimation": typing.List[PySide6.QtCore.QAbstractAnimation],
"long long": int,
"size_t": int,
- "NULL": None, # 5.6, MSVC
- "nullptr": None, # 5.9
- "PyBuffer": bytes,
+ "NULL": None, # 5.6, MSVC
+ "nullptr": None, # 5.9
+ "PyBuffer": typing.Union[bytes, bytearray, memoryview],
"PyByteArray": bytearray,
- "PyBytes": bytes,
+ "PyBytes": typing.Union[bytes, bytearray, memoryview],
"PyTuple": typing.Tuple,
"QDeadlineTimer(QDeadlineTimer.Forever)": Instance("PySide6.QtCore.QDeadlineTimer"),
"PySide6.QtCore.QUrl.ComponentFormattingOptions":
- PySide6.QtCore.QUrl.ComponentFormattingOption, # mismatch option/enum, why???
+ PySide6.QtCore.QUrl.ComponentFormattingOption, # mismatch option/enum, why???
"PyUnicode": typing.Text,
"QByteArrayView": QByteArray,
"Q_NULLPTR": None,
"QCalendar.Unspecified": PySide6.QtCore.QCalendar.Unspecified,
+ "QCborTag(-1)": ulong_max,
"QDir.Filters(AllEntries | NoDotAndDotDot)": Instance(
"QDir.Filters(QDir.AllEntries | QDir.NoDotAndDotDot)"),
"QDir.SortFlags(Name | IgnoreCase)": Instance(
"QDir.SortFlags(QDir.Name | QDir.IgnoreCase)"),
- "QEvent.Type.None" : None,
- "QGenericArgument((0))": ellipsis, # 5.6, RHEL 6.6. Is that ok?
+ "QEvent.Type.None": None,
+ "QGenericArgument((0))": ellipsis, # 5.6, RHEL 6.6. Is that ok?
"QGenericArgument()": ellipsis,
"QGenericArgument(0)": ellipsis,
- "QGenericArgument(NULL)": ellipsis, # 5.6, MSVC
- "QGenericArgument(nullptr)": ellipsis, # 5.10
+ "QGenericArgument(NULL)": ellipsis, # 5.6, MSVC
+ "QGenericArgument(nullptr)": ellipsis, # 5.10
"QGenericArgument(Q_NULLPTR)": ellipsis,
"QJsonObject": typing.Dict[str, PySide6.QtCore.QJsonValue],
- "QModelIndex()": Invalid("PySide6.QtCore.QModelIndex"), # repr is btw. very wrong, fix it?!
+ "QModelIndex()": Invalid("PySide6.QtCore.QModelIndex"), # repr is btw. very wrong, fix it?!
"QModelIndexList": typing.List[PySide6.QtCore.QModelIndex],
"PySideSignalInstance": SignalInstance,
"QString()": "",
@@ -496,17 +517,17 @@ def init_PySide6_QtCore():
"QStringList()": [],
"QStringRef": str,
"QStringRef": str,
- "Qt.HANDLE": int, # be more explicit with some constants?
+ "Qt.HANDLE": int, # be more explicit with some constants?
"QUrl.FormattingOptions(PrettyDecoded)": Instance(
"QUrl.FormattingOptions(QUrl.PrettyDecoded)"),
"QVariant()": Invalid(Variant),
- "QVariant.Type": type, # not so sure here...
- "QVariantMap": typing.Dict[str, Variant],
+ "QVariant.Type": type, # not so sure here...
"QVariantMap": typing.Dict[str, Variant],
+ "std.chrono.seconds{5}" : ellipsis,
})
try:
type_map.update({
- "PySide6.QtCore.QMetaObject.Connection": PySide6.QtCore.Connection, # wrong!
+ "PySide6.QtCore.QMetaObject.Connection": PySide6.QtCore.Connection, # wrong!
})
except AttributeError:
# this does not exist on 5.9 ATM.
@@ -531,7 +552,7 @@ def init_PySide6_QtConcurrent():
def init_PySide6_QtGui():
- from PySide6.QtGui import QPageLayout, QPageSize # 5.12 macOS
+ from PySide6.QtGui import QPageLayout, QPageSize # 5.12 macOS
type_map.update({
"0.0f": 0.0,
"1.0f": 1.0,
@@ -540,10 +561,11 @@ def init_PySide6_QtGui():
"int32_t": int,
"HBITMAP": int,
"HICON": int,
+ "HMONITOR": int,
"HRGN": int,
- "QPixmap()": Default("PySide6.QtGui.QPixmap"), # can't create without qApp
- "QPlatformSurface*": int, # a handle
- "QVector< QTextLayout.FormatRange >()": [], # do we need more structure?
+ "QPixmap()": Default("PySide6.QtGui.QPixmap"), # can't create without qApp
+ "QPlatformSurface*": int, # a handle
+ "QVector< QTextLayout.FormatRange >()": [], # do we need more structure?
"uint32_t": int,
"uint8_t": int,
"USHRT_MAX": ushort_max,
@@ -557,8 +579,9 @@ def init_PySide6_QtGui():
def init_PySide6_QtWidgets():
- from PySide6.QtWidgets import QWidget, QMessageBox, QStyleOption, QStyleHintReturn, QStyleOptionComplex
- from PySide6.QtWidgets import QGraphicsItem, QStyleOptionGraphicsItem # 5.9
+ from PySide6.QtWidgets import (QWidget, QMessageBox, QStyleOption,
+ QStyleHintReturn, QStyleOptionComplex,
+ QGraphicsItem, QStyleOptionGraphicsItem)
type_map.update({
"QMessageBox.StandardButtons(Yes | No)": Instance(
"QMessageBox.StandardButtons(QMessageBox.Yes | QMessageBox.No)"),
@@ -579,7 +602,7 @@ def init_PySide6_QtSql():
from PySide6.QtSql import QSqlDatabase
type_map.update({
"QLatin1StringView(QSqlDatabase.defaultConnection)": QSqlDatabase.defaultConnection,
- "QVariant.Invalid": Invalid("Variant"), # not sure what I should create, here...
+ "QVariant.Invalid": Invalid("Variant"), # not sure what I should create, here...
})
return locals()
@@ -603,7 +626,7 @@ def init_PySide6_QtOpenGL():
type_map.update({
"GLbitfield": int,
"GLenum": int,
- "GLfloat": float, # 5.6, MSVC 15
+ "GLfloat": float, # 5.6, MSVC 15
"GLint": int,
"GLuint": int,
})
@@ -660,6 +683,22 @@ def init_PySide6_QtBluetooth():
return locals()
+def init_PySide6_QtGraphs():
+ from PySide6.QtGraphs import (QBarDataItem, QSurfaceDataItem)
+ QBarDataRow = typing.List[QBarDataItem]
+ QBarDataArray = typing.List[QBarDataRow]
+ QSurfaceDataRow = typing.List[QSurfaceDataItem]
+ QSurfaceDataArray = typing.List[QSurfaceDataRow]
+ type_map.update({
+ "100.0f": 100.0,
+ "QBarDataArray": QBarDataArray,
+ "QBarDataArray*": QBarDataArray,
+ "QSurfaceDataArray": QSurfaceDataArray,
+ "QSurfaceDataArray*": QSurfaceDataArray,
+ })
+ return locals()
+
+
def init_PySide6_QtHttpServer():
type_map.update({
"qMakePair(1u, 1u)": (1, 1),
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 5d86b93a5..9b48ab442 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -3,20 +3,17 @@
import ast
import enum
-import functools
import keyword
import os
import re
import sys
-import types
import typing
import warnings
from types import SimpleNamespace
from shibokensupport.signature.mapping import (type_map, update_mapping,
- namespace, _NotCalled, ResultVariable, ArrayLikeVariable)
+ namespace, _NotCalled, ResultVariable, ArrayLikeVariable) # noqa E:128
from shibokensupport.signature.lib.tool import build_brace_pattern
-from shibokensupport import feature
_DEBUG = False
LIST_KEYWORDS = False
@@ -41,8 +38,9 @@ guesses, we provide an entry in 'type_map' that resolves it.
In effect, 'type_map' maps text to real Python objects.
"""
+
def _get_flag_enum_option():
- from shiboken6 import (__version_info__ as ver,
+ from shiboken6 import (__version_info__ as ver, # noqa F:401
__minimum_python_version__ as pyminver,
__maximum_python_version__ as pymaxver)
@@ -50,7 +48,7 @@ def _get_flag_enum_option():
# This decides between delivered vs. dev versions.
# When 6.4 is out, the switching mode will be gone.
flag = ver[:2] >= (6, 4)
- envname = "PYSIDE63_OPTION_PYTHON_ENUM"
+ envname = "PYSIDE6_OPTION_PYTHON_ENUM"
sysname = envname.lower()
opt = os.environ.get(envname)
if opt:
@@ -64,27 +62,30 @@ def _get_flag_enum_option():
try:
flag = ast.literal_eval(opt)
except Exception:
- flag = True
+ flag = False # turn a forbidden option into an error
elif hasattr(sys, sysname):
- flag = getattr(sys, sysname)
+ opt2 = flag = getattr(sys, sysname)
if not isinstance(flag, int):
- flag = True
+ flag = False # turn a forbidden option into an error
p = f"\n *** Python is at version {'.'.join(map(str, pyminver or (0,)))} now."
- # PYSIDE-1797: Emit a warning when we may remove pep384_issue33738.cpp
- if pyminver and pyminver >= (3, 8):
- warnings.warn(f"{p} The file pep384_issue33738.cpp should be removed ASAP! ***")
+ q = f"\n *** PySide is at version {'.'.join(map(str, ver[:2]))} now."
# _PepUnicode_AsString: Fix a broken promise
if pyminver and pyminver >= (3, 10):
warnings.warn(f"{p} _PepUnicode_AsString can now be replaced by PyUnicode_AsUTF8! ***")
- # PYSIDE-1960: Emit a warning when we may remove pep384_issue33738.cpp
+ # PYSIDE-1960: Emit a warning when we may remove bufferprocs_py37.(cpp|h)
if pyminver and pyminver >= (3, 11):
warnings.warn(f"{p} The files bufferprocs_py37.(cpp|h) should be removed ASAP! ***")
# PYSIDE-1735: Emit a warning when we should maybe evict forgiveness mode
if ver[:2] >= (7, 0):
- warnings.warn(f"{p} Please drop Enum forgiveness mode in `mangled_type_getattro` ***")
+ warnings.warn(f"{q} Please drop Enum forgiveness mode in `mangled_type_getattro` ***")
+ # PYSIDE-2404: Emit a warning when we should drop uppercase offset constants
+ if ver[:2] >= (7, 0):
+ warnings.warn(f"{q} Please drop uppercase type offsets in `copyOffsetEnumStream` ***")
# normalize the sys attribute
setattr(sys, sysname, flag)
os.environ[envname] = str(flag)
+ if int(flag) == 0:
+ raise RuntimeError(f"Old Enums are no longer supported. int({opt or opt2}) evaluates to 0)")
return flag
@@ -106,6 +107,7 @@ def dprint(*args, **kw):
_cache = {}
+
def _parse_arglist(argstr):
# The following is a split re. The string is broken into pieces which are
# between the recognized strings. Because the re has groups, both the
@@ -187,7 +189,7 @@ def _handle_instance_fixup(thing):
if not match:
return thing
start, stop = match.start(), match.end() - 1
- pre, func, args = thing[:start], thing[start : stop], thing[stop:]
+ pre, func, args = thing[:start], thing[start:stop], thing[stop:]
if func[0].isupper() or func.startswith("gl") and func[2:3].isupper():
return thing
# Now convert this string to snake case.
@@ -196,7 +198,7 @@ def _handle_instance_fixup(thing):
if char.isupper():
if idx and func[idx - 1].isupper():
# two upper chars are forbidden
- return things
+ return thing
snake_func += f"_{char.lower()}"
else:
snake_func += char
@@ -239,12 +241,14 @@ def try_to_guess(thing, valtype):
return ret
return None
+
def get_name(thing):
if isinstance(thing, type):
return getattr(thing, "__qualname__", thing.__name__)
else:
return thing.__name__
+
def _resolve_value(thing, valtype, line):
if thing in ("0", "None") and valtype:
if valtype.startswith("PySide6.") or valtype.startswith("typing."):
@@ -297,7 +301,7 @@ def to_string(thing):
dot = "." in str(thing) or m not in (thing.__qualname__, "builtins")
name = get_name(thing)
ret = m + "." + name if dot else name
- assert(eval(ret, globals(), namespace))
+ assert (eval(ret, globals(), namespace))
return ret
# Note: This captures things from the typing module:
return str(thing)
@@ -305,8 +309,9 @@ def to_string(thing):
matrix_pattern = "PySide6.QtGui.QGenericMatrix"
+
def handle_matrix(arg):
- n, m, typstr = tuple(map(lambda x:x.strip(), arg.split(",")))
+ n, m, typstr = tuple(map(lambda x: x.strip(), arg.split(",")))
assert typstr == "float"
result = f"PySide6.QtGui.QMatrix{n}x{m}"
return eval(result, globals(), namespace)
@@ -334,13 +339,13 @@ def _resolve_type(thing, line, level, var_handler, func_name=None):
# Special case: Handle the generic matrices.
if contr == matrix_pattern:
return handle_matrix(thing)
- contr = var_handler(_resolve_type(contr, line, level+1, var_handler))
+ contr = var_handler(_resolve_type(contr, line, level + 1, var_handler))
if isinstance(contr, _NotCalled):
raise SystemError("Container types must exist:", repr(contr))
contr = to_string(contr)
pieces = []
for part in _parse_arglist(thing):
- part = var_handler(_resolve_type(part, line, level+1, var_handler))
+ part = var_handler(_resolve_type(part, line, level + 1, var_handler))
if isinstance(part, _NotCalled):
# fix the tag (i.e. "Missing") by repr
part = repr(part)
@@ -350,7 +355,7 @@ def _resolve_type(thing, line, level, var_handler, func_name=None):
# PYSIDE-1538: Make sure that the eval does not crash.
try:
return eval(result, globals(), namespace)
- except Exception as e:
+ except Exception:
warnings.warn(f"""pyside_type_init:_resolve_type
UNRECOGNIZED: {result!r}
@@ -429,9 +434,9 @@ def calculate_props(line):
props.defaults = defaults
props.kwdefaults = {}
props.annotations = annotations
- props.varnames = varnames = tuple(tup[0] for tup in arglist)
+ props.varnames = tuple(tup[0] for tup in arglist)
funcname = parsed.funcname
- shortname = funcname[funcname.rindex(".")+1:]
+ shortname = funcname[funcname.rindex(".") + 1:]
props.name = shortname
props.multi = parsed.multi
fix_variables(props, line)
@@ -477,7 +482,6 @@ def fix_variables(props, line):
else:
diff -= 1
if retvars:
- rvs = []
retvars = list(handle_retvar(rv) if isinstance(rv, ArrayLikeVariable) else rv
for rv in retvars)
if len(retvars) == 1:
diff --git a/sources/shiboken6/shibokenmodule/shibokenmodule.cpp b/sources/shiboken6/shibokenmodule/shibokenmodule.cpp
new file mode 100644
index 000000000..5c6219885
--- /dev/null
+++ b/sources/shiboken6/shibokenmodule/shibokenmodule.cpp
@@ -0,0 +1,119 @@
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+// @snippet isvalid
+bool isValid = Shiboken::Object::isValid(%1, false);
+%PYARG_0 = %CONVERTTOPYTHON[bool](isValid);
+// @snippet isvalid
+
+// @snippet wrapinstance
+auto *pyType = reinterpret_cast<PyTypeObject *>(%2);
+if (Shiboken::ObjectType::checkType(pyType)) {
+ auto *ptr = reinterpret_cast<void *>(%1);
+ if (auto *wrapper = Shiboken::BindingManager::instance().retrieveWrapper(ptr)) {
+ Py_INCREF(wrapper);
+ %PYARG_0 = reinterpret_cast<PyObject *>(wrapper);
+ } else {
+ %PYARG_0 = Shiboken::Object::newObject(pyType, ptr, false, true);
+ }
+} else {
+ PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type.");
+}
+// @snippet wrapinstance
+
+// @snippet getcpppointer
+if (Shiboken::Object::checkType(%1)) {
+ std::vector<void*> ptrs = Shiboken::Object::cppPointers(reinterpret_cast<SbkObject *>(%1));
+ %PYARG_0 = PyTuple_New(ptrs.size());
+ for (std::size_t i = 0; i < ptrs.size(); ++i)
+ PyTuple_SET_ITEM(%PYARG_0, i, PyLong_FromVoidPtr(ptrs[i]));
+} else {
+ PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type.");
+}
+// @snippet getcpppointer
+
+// @snippet delete
+if (Shiboken::Object::checkType(%1)) {
+ Shiboken::Object::callCppDestructors(reinterpret_cast<SbkObject *>(%1));
+} else {
+ PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type.");
+}
+// @snippet delete
+
+// @snippet ownedbypython
+if (Shiboken::Object::checkType(%1)) {
+ bool hasOwnership = Shiboken::Object::hasOwnership(reinterpret_cast<SbkObject *>(%1));
+ %PYARG_0 = %CONVERTTOPYTHON[bool](hasOwnership);
+} else {
+ PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type.");
+}
+// @snippet ownedbypython
+
+// @snippet createdbypython
+if (Shiboken::Object::checkType(%1)) {
+ bool wasCreatedByPython = Shiboken::Object::wasCreatedByPython(reinterpret_cast<SbkObject *>(%1));
+ %PYARG_0 = %CONVERTTOPYTHON[bool](wasCreatedByPython);
+} else {
+ PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type.");
+}
+// @snippet createdbypython
+
+// @snippet disassembleframe
+Shiboken::AutoDecRef label(PyObject_Str(%1));
+const char *marker = Shiboken::String::toCString(label);
+disassembleFrame(marker);
+Py_INCREF(Py_None);
+%PYARG_0 = Py_None;
+// @snippet disassembleframe
+
+// @snippet dump
+if (!Shiboken::Object::checkType(%1)) {
+ %PYARG_0 = Shiboken::String::fromCString("Ordinary Python type.");
+} else {
+ std::string str = Shiboken::Object::info(reinterpret_cast<SbkObject *>(%1));
+ %PYARG_0 = Shiboken::String::fromCString(str.c_str());
+}
+// @snippet dump
+
+// @snippet getallvalidwrappers
+const auto setAll = Shiboken::BindingManager::instance().getAllPyObjects();
+PyObject* listAll = PyList_New(0);
+if (listAll == nullptr)
+ return nullptr;
+for (auto *o : setAll) {
+ if (o != nullptr) {
+ if (PyList_Append(listAll, o) != 0) {
+ Py_DECREF(listAll);
+ return nullptr;
+ }
+ }
+}
+return listAll;
+// @snippet getallvalidwrappers
+
+// @snippet dumptypegraph
+const bool ok = Shiboken::BindingManager::instance().dumpTypeGraph(%1);
+%PYARG_0 = %CONVERTTOPYTHON[bool](ok);
+// @snippet dumptypegraph
+
+// @snippet dumpwrappermap
+Shiboken::BindingManager::instance().dumpWrapperMap();
+// @snippet dumpwrappermap
+
+// @snippet dumpconverters
+Shiboken::Conversions::dumpConverters();
+// @snippet dumpconverters
+
+// @snippet init
+// Add __version__ and __version_info__ attributes to the module
+PyObject* version = PyTuple_New(5);
+PyTuple_SET_ITEM(version, 0, PyLong_FromLong(SHIBOKEN_MAJOR_VERSION));
+PyTuple_SET_ITEM(version, 1, PyLong_FromLong(SHIBOKEN_MINOR_VERSION));
+PyTuple_SET_ITEM(version, 2, PyLong_FromLong(SHIBOKEN_MICRO_VERSION));
+PyTuple_SET_ITEM(version, 3, Shiboken::String::fromCString(SHIBOKEN_RELEASE_LEVEL));
+PyTuple_SET_ITEM(version, 4, PyLong_FromLong(SHIBOKEN_SERIAL));
+PyModule_AddObject(module, "__version_info__", version);
+PyModule_AddStringConstant(module, "__version__", SHIBOKEN_VERSION);
+VoidPtr::addVoidPtrToModule(module);
+Shiboken::initShibokenSupport(module);
+// @snippet init
diff --git a/sources/shiboken6/shibokenmodule/typesystem_shiboken.xml b/sources/shiboken6/shibokenmodule/typesystem_shiboken.xml
index 81919d6c3..acb522ecc 100644
--- a/sources/shiboken6/shibokenmodule/typesystem_shiboken.xml
+++ b/sources/shiboken6/shibokenmodule/typesystem_shiboken.xml
@@ -1,13 +1,14 @@
<?xml version="1.0" ?>
+<!--
+// Copyright (C) 2024 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+-->
<typesystem package="Shiboken">
<primitive-type name="bool" />
<primitive-type name="unsigned long" />
<primitive-type name="size_t" />
<add-function signature="isValid(PyObject*)" return-type="bool">
- <inject-code>
- bool isValid = Shiboken::Object::isValid(%1, false);
- %PYARG_0 = %CONVERTTOPYTHON[bool](isValid);
- </inject-code>
+ <inject-code file="shibokenmodule.cpp" snippet="isvalid"/>
</add-function>
<add-function signature="invalidate(PyObject*)">
@@ -17,125 +18,53 @@
</add-function>
<add-function signature="wrapInstance(size_t, PyTypeObject)" return-type="PyObject*">
- <inject-code>
- auto *pyType = reinterpret_cast&lt;PyTypeObject *&gt;(%2);
- if (Shiboken::ObjectType::checkType(pyType)) {
- %PYARG_0 = Shiboken::Object::newObject(pyType,
- reinterpret_cast&lt;void *&gt;(%1),
- false, true);
- } else {
- PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type.");
- }
- </inject-code>
+ <inject-code file="shibokenmodule.cpp" snippet="wrapinstance"/>
</add-function>
<add-function signature="getCppPointer(PyObject*)" return-type="PySequence*">
- <inject-code>
- if (Shiboken::Object::checkType(%1)) {
- std::vector&lt;void*> ptrs = Shiboken::Object::cppPointers(reinterpret_cast&lt;SbkObject *&gt;(%1));
- %PYARG_0 = PyTuple_New(ptrs.size());
- for (std::size_t i = 0; i &lt; ptrs.size(); ++i)
- PyTuple_SET_ITEM(%PYARG_0, i, PyLong_FromVoidPtr(ptrs[i]));
- } else {
- PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type.");
- }
- </inject-code>
+ <inject-code file="shibokenmodule.cpp" snippet="getcpppointer"/>
</add-function>
<add-function signature="delete(PyObject*)">
- <inject-code>
- if (Shiboken::Object::checkType(%1)) {
- Shiboken::Object::callCppDestructors(reinterpret_cast&lt;SbkObject *&gt;(%1));
- } else {
- PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type.");
- }
- </inject-code>
+ <inject-code file="shibokenmodule.cpp" snippet="delete"/>
</add-function>
<add-function signature="ownedByPython(PyObject*)" return-type="bool">
- <inject-code>
- if (Shiboken::Object::checkType(%1)) {
- bool hasOwnership = Shiboken::Object::hasOwnership(reinterpret_cast&lt;SbkObject *&gt;(%1));
- %PYARG_0 = %CONVERTTOPYTHON[bool](hasOwnership);
- } else {
- PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type.");
- }
- </inject-code>
+ <inject-code file="shibokenmodule.cpp" snippet="ownedbypython"/>
</add-function>
<add-function signature="createdByPython(PyObject*)" return-type="bool">
- <inject-code>
- if (Shiboken::Object::checkType(%1)) {
- bool wasCreatedByPython = Shiboken::Object::wasCreatedByPython(reinterpret_cast&lt;SbkObject *&gt;(%1));
- %PYARG_0 = %CONVERTTOPYTHON[bool](wasCreatedByPython);
- } else {
- PyErr_SetString(PyExc_TypeError, "You need a shiboken-based type.");
- }
- </inject-code>
+ <inject-code file="shibokenmodule.cpp" snippet="createdbypython"/>
</add-function>
<add-function signature="disassembleFrame(PyObject*)" return-type="PyObject">
- <inject-code>
- Shiboken::AutoDecRef label(PyObject_Str(%1));
- const char *marker = Shiboken::String::toCString(label);
- disassembleFrame(marker);
- Py_INCREF(Py_None);
- %PYARG_0 = Py_None;
- </inject-code>
+ <inject-code file="shibokenmodule.cpp" snippet="disassembleframe"/>
</add-function>
<add-function signature="dump(PyObject*)" return-type="const char *">
- <inject-code>
- if (!Shiboken::Object::checkType(%1)) {
- %PYARG_0 = Shiboken::String::fromCString("Ordinary Python type.");
- } else {
- std::string str = Shiboken::Object::info(reinterpret_cast&lt;SbkObject *&gt;(%1));
- %PYARG_0 = Shiboken::String::fromCString(str.c_str());
- }
- </inject-code>
+ <inject-code file="shibokenmodule.cpp" snippet="dump"/>
</add-function>
<add-function signature="getAllValidWrappers(void)" return-type="PySequence*">
- <inject-code>
- const auto setAll = Shiboken::BindingManager::instance().getAllPyObjects();
- PyObject* listAll = PyList_New(0);
- if (listAll == nullptr)
- return nullptr;
+ <inject-code file="shibokenmodule.cpp" snippet="getallvalidwrappers"/>
+ </add-function>
- for (auto *o : setAll) {
- if (o != nullptr) {
- if (PyList_Append(listAll, o) != 0) {
- Py_DECREF(listAll);
- return nullptr;
- }
- }
- }
- return listAll;
- </inject-code>
+ <add-function signature="dumpTypeGraph(const char *@fileName@)" return-type="bool">
+ <inject-code file="shibokenmodule.cpp" snippet="dumptypegraph"/>
</add-function>
- <add-function signature="_unpickle_enum(PyObject*, PyObject*)" return-type="PyObject*">
- <inject-code>
- %PYARG_0 = Shiboken::Enum::unpickleEnum(%1, %2);
- </inject-code>
+ <add-function signature="dumpWrapperMap()">
+ <inject-code file="shibokenmodule.cpp" snippet="dumpwrappermap"/>
+ </add-function>
+
+ <add-function signature="dumpConverters()">
+ <inject-code file="shibokenmodule.cpp" snippet="dumpconverters"/>
</add-function>
<extra-includes>
<include file-name="sbkversion.h" location="local"/>
<include file-name="voidptr.h" location="local"/>
+ <include file-name="sbkconverter_p.h" location="local"/>
</extra-includes>
- <inject-code position="end">
- // Add __version__ and __version_info__ attributes to the module
- PyObject* version = PyTuple_New(5);
- PyTuple_SET_ITEM(version, 0, PyLong_FromLong(SHIBOKEN_MAJOR_VERSION));
- PyTuple_SET_ITEM(version, 1, PyLong_FromLong(SHIBOKEN_MINOR_VERSION));
- PyTuple_SET_ITEM(version, 2, PyLong_FromLong(SHIBOKEN_MICRO_VERSION));
- PyTuple_SET_ITEM(version, 3, Shiboken::String::fromCString(SHIBOKEN_RELEASE_LEVEL));
- PyTuple_SET_ITEM(version, 4, PyLong_FromLong(SHIBOKEN_SERIAL));
- PyModule_AddObject(module, "__version_info__", version);
- PyModule_AddStringConstant(module, "__version__", SHIBOKEN_VERSION);
- VoidPtr::addVoidPtrToModule(module);
-
- Shiboken::initShibokenSupport(module);
- </inject-code>
+ <inject-code position="end" file="shibokenmodule.cpp" snippet="init"/>
</typesystem>
diff --git a/sources/shiboken6/tests/CMakeLists.txt b/sources/shiboken6/tests/CMakeLists.txt
index c1fca5134..05f6e9e60 100644
--- a/sources/shiboken6/tests/CMakeLists.txt
+++ b/sources/shiboken6/tests/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
if(BUILD_TESTS)
@@ -11,6 +14,8 @@ if(NOT DEFINED MINIMAL_TESTS)
add_subdirectory(libother)
endif()
+shiboken_get_debug_level(debug_level)
+
if(WIN32 OR DEFINED AVOID_PROTECTED_HACK)
message(STATUS "Tests will be generated avoiding the protected hack!")
set(GENERATOR_EXTRA_FLAGS --avoid-protected-hack)
@@ -18,6 +23,7 @@ else()
message(STATUS "Tests will be generated using the protected hack!")
set(GENERATOR_EXTRA_FLAGS )
endif()
+list(APPEND GENERATOR_EXTRA_FLAGS ${SHIBOKEN_GENERATOR_EXTRA_FLAGS} ${debug_level})
add_subdirectory(minimalbinding)
if(NOT DEFINED MINIMAL_TESTS)
@@ -40,13 +46,18 @@ list(SORT TEST_FILES)
set(test_blacklist "")
if(SHIBOKEN_IS_CROSS_BUILD)
- # PYTHON_EXECUTABLE will be empty when cross-building.
+ # Python_EXECUTABLE will be empty when cross-building.
message(WARNING
"Running tests when cross-compiling is not supported because it would require running "
"a target python interpreter which might have a different architecture than the host."
)
else()
- find_package(PythonInterp REQUIRED)
+ find_package(
+ Python
+ ${USE_PYTHON_VERSION}
+ REQUIRED
+ COMPONENTS Interpreter Development
+ )
endif()
if(NOT CTEST_TESTING_TIMEOUT)
@@ -60,7 +71,7 @@ foreach(test_file ${TEST_FILES})
string(REGEX MATCH "/([^/]+)(binding|module)/([^/]+)_test.py" tmp ${test_file})
set(test_name "${CMAKE_MATCH_1}_${CMAKE_MATCH_3}")
list(FIND test_blacklist ${test_name} expect_fail)
- add_test(${test_name} ${PYTHON_EXECUTABLE} ${test_file})
+ add_test(${test_name} ${Python_EXECUTABLE} ${test_file})
set_tests_properties(${test_name} PROPERTIES ENVIRONMENT "BUILD_DIR=${BUILD_DIR}")
set_tests_properties(${test_name} PROPERTIES TIMEOUT ${CTEST_TESTING_TIMEOUT})
if (${expect_fail} GREATER -1)
diff --git a/sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt b/sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt
index 3568b228d..e7dbef961 100644
--- a/sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt
+++ b/sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_executable(dumpcodemodel main.cpp)
target_include_directories(dumpcodemodel
diff --git a/sources/shiboken6/tests/dumpcodemodel/main.cpp b/sources/shiboken6/tests/dumpcodemodel/main.cpp
index 1befca260..eb876634c 100644
--- a/sources/shiboken6/tests/dumpcodemodel/main.cpp
+++ b/sources/shiboken6/tests/dumpcodemodel/main.cpp
@@ -38,7 +38,7 @@ static void formatDebugOutput(const FileModelItem &dom, bool verbose)
QDebug debug(&output);
if (verbose)
debug.setVerbosity(3);
- debug << dom.data();
+ debug << dom.get();
}
std::cout << qPrintable(output) << '\n';
}
@@ -48,14 +48,14 @@ static const char *primitiveTypes[] = {
"float", "double"
};
-static inline QString nameAttribute() { return QStringLiteral("name"); }
+constexpr auto nameAttribute = "name"_L1;
static void formatXmlClass(QXmlStreamWriter &writer, const ClassModelItem &klass);
static void formatXmlEnum(QXmlStreamWriter &writer, const EnumModelItem &en)
{
writer.writeStartElement(u"enum-type"_s);
- writer.writeAttribute(nameAttribute(), en->name());
+ writer.writeAttribute(nameAttribute, en->name());
writer.writeEndElement();
}
@@ -97,7 +97,7 @@ static void formatXmlClass(QXmlStreamWriter &writer, const ClassModelItem &klass
formatXmlLocationComment(writer, klass);
writer.writeStartElement(isValueType ? u"value-type"_s
: u"object-type"_s);
- writer.writeAttribute(nameAttribute(), klass->name());
+ writer.writeAttribute(nameAttribute, klass->name());
formatXmlScopeMembers(writer, klass);
writer.writeEndElement();
}
@@ -118,7 +118,7 @@ static void startXmlNamespace(QXmlStreamWriter &writer, const NamespaceModelItem
{
formatXmlLocationComment(writer, nsp);
writer.writeStartElement(u"namespace-type"_s);
- writer.writeAttribute(nameAttribute(), nsp->name());
+ writer.writeAttribute(nameAttribute, nsp->name());
}
static void formatXmlNamespaceMembers(QXmlStreamWriter &writer, const NamespaceModelItem &nsp)
@@ -170,7 +170,7 @@ static void formatXmlOutput(const FileModelItem &dom)
QDateTime::currentDateTime().toString(Qt::ISODate));
for (auto p : primitiveTypes) {
writer.writeStartElement(u"primitive-type"_s);
- writer.writeAttribute(nameAttribute(), QLatin1StringView(p));
+ writer.writeAttribute(nameAttribute, QLatin1StringView(p));
writer.writeEndElement();
}
formatXmlNamespaceMembers(writer, dom);
@@ -245,7 +245,7 @@ int main(int argc, char **argv)
optJoinNamespaces = parser.isSet(joinNamespacesOption);
const FileModelItem dom = AbstractMetaBuilderPrivate::buildDom(arguments, true, level, 0);
- if (dom.isNull()) {
+ if (!dom) {
QString message = u"Unable to parse "_s + positionalArguments.join(u' ');
std::cerr << qPrintable(message) << '\n';
return -2;
diff --git a/sources/shiboken6/tests/libminimal/CMakeLists.txt b/sources/shiboken6/tests/libminimal/CMakeLists.txt
index f906bdb84..4a10f96bf 100644
--- a/sources/shiboken6/tests/libminimal/CMakeLists.txt
+++ b/sources/shiboken6/tests/libminimal/CMakeLists.txt
@@ -1,9 +1,17 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(libminimal)
set(libminimal_SRC
-obj.cpp
-listuser.cpp
-typedef.cpp
+containeruser.cpp containeruser.h
+libminimalmacros.h
+listuser.cpp listuser.h
+minbool.h
+obj.cpp obj.h
+spanuser.cpp spanuser.h
+typedef.cpp typedef.h
+val.h
)
add_library(libminimal SHARED ${libminimal_SRC})
diff --git a/sources/shiboken6/tests/libminimal/containeruser.cpp b/sources/shiboken6/tests/libminimal/containeruser.cpp
new file mode 100644
index 000000000..29af52aef
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/containeruser.cpp
@@ -0,0 +1,55 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "containeruser.h"
+
+#include <algorithm>
+#include <numeric>
+
+ContainerUser::ContainerUser() : m_intVector{1, 2, 3}, m_intArray{1, 2, 3}
+{
+}
+
+ContainerUser::~ContainerUser() = default;
+
+std::vector<int> ContainerUser::createIntVector(int num)
+{
+ std::vector<int> retval(num);
+ std::iota(retval.begin(), retval.end(), 0);
+ return retval;
+}
+
+int ContainerUser::sumIntVector(const std::vector<int> &intVector)
+{
+ return std::accumulate(intVector.cbegin(), intVector.cend(), 0);
+}
+
+std::vector<int> &ContainerUser::intVector()
+{
+ return m_intVector;
+}
+
+void ContainerUser::setIntVector(const std::vector<int> &v)
+{
+ m_intVector = v;
+}
+
+std::array<int, 3> ContainerUser::createIntArray()
+{
+ return {1, 2, 3};
+}
+
+int ContainerUser::sumIntArray(const std::array<int, 3> &intArray)
+{
+ return std::accumulate(intArray.cbegin(), intArray.cend(), 0);
+}
+
+std::array<int, 3> &ContainerUser::intArray()
+{
+ return m_intArray;
+}
+
+void ContainerUser::setIntArray(const std::array<int, 3> &a)
+{
+ m_intArray = a;
+}
diff --git a/sources/shiboken6/tests/libminimal/containeruser.h b/sources/shiboken6/tests/libminimal/containeruser.h
new file mode 100644
index 000000000..55e4020ec
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/containeruser.h
@@ -0,0 +1,36 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef CONTAINERUSER_H
+#define CONTAINERUSER_H
+
+#include "libminimalmacros.h"
+
+#include <array>
+#include <vector>
+
+/// Exercise simple, sequential containers. More advanced tests are in ListUser
+class LIBMINIMAL_API ContainerUser
+{
+public:
+ ContainerUser();
+ ~ContainerUser();
+
+ static std::vector<int> createIntVector(int num);
+ static int sumIntVector(const std::vector<int> &intVector);
+
+ std::vector<int> &intVector();
+ void setIntVector(const std::vector<int> &);
+
+ static std::array<int, 3> createIntArray();
+ static int sumIntArray(const std::array<int, 3> &intArray);
+
+ std::array<int, 3> &intArray();
+ void setIntArray(const std::array<int, 3> &);
+
+private:
+ std::vector<int> m_intVector;
+ std::array<int, 3> m_intArray;
+};
+
+#endif // CONTAINERUSER_H
diff --git a/sources/shiboken6/tests/libminimal/libminimalmacros.h b/sources/shiboken6/tests/libminimal/libminimalmacros.h
index e0dfdd196..099c1f1de 100644
--- a/sources/shiboken6/tests/libminimal/libminimalmacros.h
+++ b/sources/shiboken6/tests/libminimal/libminimalmacros.h
@@ -22,4 +22,28 @@
# define LIBMINIMAL_API LIBMINIMAL_IMPORT
#endif
+#define LIBMINIMAL_DEFAULT_COPY(Class) \
+ Class(const Class &) noexcept = default; \
+ Class &operator=(const Class &) noexcept = default;
+
+#define LIBMINIMAL_DISABLE_COPY(Class) \
+ Class(const Class &) = delete;\
+ Class &operator=(const Class &) = delete;
+
+#define LIBMINIMAL_DEFAULT_MOVE(Class) \
+ Class(Class &&) noexcept = default; \
+ Class &operator=(Class &&) noexcept = default;
+
+#define LIBMINIMAL_DEFAULT_COPY_MOVE(Class) \
+ LIBMINIMAL_DEFAULT_COPY(Class) \
+ LIBMINIMAL_DEFAULT_MOVE(Class)
+
+#define LIBMINIMAL_DISABLE_MOVE(Class) \
+ Class(Class &&) = delete; \
+ Class &operator=(Class &&) = delete;
+
+#define LIBMINIMAL_DISABLE_COPY_MOVE(Class) \
+ LIBMINIMAL_DISABLE_COPY(Class) \
+ LIBMINIMAL_DISABLE_MOVE(Class)
+
#endif // LIBMINIMALMACROS_H
diff --git a/sources/shiboken6/tests/libminimal/listuser.cpp b/sources/shiboken6/tests/libminimal/listuser.cpp
index 14ac1c7ee..93c399542 100644
--- a/sources/shiboken6/tests/libminimal/listuser.cpp
+++ b/sources/shiboken6/tests/libminimal/listuser.cpp
@@ -1,29 +1,35 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <numeric>
-#include <cstdlib>
#include "listuser.h"
#include <algorithm>
+#include <cstdlib>
#include <numeric>
-std::list<int>
-ListUser::createIntList(int num)
+std::list<int> ListUser::createIntList(int num)
{
std::list<int> retval(num);
std::iota(retval.begin(), retval.end(), 0);
return retval;
}
-int
-ListUser::sumIntList(std::list<int> intList)
+int ListUser::sumIntList(std::list<int> intList)
{
return std::accumulate(intList.begin(), intList.end(), 0);
}
-std::list<MinBool>
-ListUser::createMinBoolList(MinBool mb1, MinBool mb2)
+int ListUser::sumIntListDefaultParamConstRef(const std::list<int> &intList)
+{
+ return sumIntList(intList);
+}
+
+int ListUser::sumIntListDefaultParam(std::list<int> intList)
+{
+ return sumIntList(intList);
+}
+
+std::list<MinBool> ListUser::createMinBoolList(MinBool mb1, MinBool mb2)
{
std::list<MinBool> retval;
retval.push_back(mb1);
@@ -31,8 +37,7 @@ ListUser::createMinBoolList(MinBool mb1, MinBool mb2)
return retval;
}
-MinBool
-ListUser::oredMinBoolList(std::list<MinBool> minBoolList)
+MinBool ListUser::oredMinBoolList(std::list<MinBool> minBoolList)
{
MinBool result(false);
for (const auto &m : minBoolList)
@@ -40,8 +45,7 @@ ListUser::oredMinBoolList(std::list<MinBool> minBoolList)
return result;
}
-std::list<Val>
-ListUser::createValList(int num)
+std::list<Val> ListUser::createValList(int num)
{
std::list<Val> retval;
for (int i = 0; i < num; ++i)
@@ -49,17 +53,14 @@ ListUser::createValList(int num)
return retval;
}
-int
-ListUser::sumValList(std::list<Val> valList)
+int ListUser::sumValList(std::list<Val> valList)
{
int total = 0;
for (const auto &v : valList)
total += v.valId();
return total;
}
-
-std::list<Obj*>
-ListUser::createObjList(Obj* o1, Obj* o2)
+std::list<Obj*> ListUser::createObjList(Obj* o1, Obj* o2)
{
std::list<Obj*> retval;
retval.push_back(o1);
@@ -67,8 +68,7 @@ ListUser::createObjList(Obj* o1, Obj* o2)
return retval;
}
-int
-ListUser::sumObjList(std::list<Obj*> objList)
+int ListUser::sumObjList(std::list<Obj*> objList)
{
int total = 0;
for (const auto *obj : objList)
@@ -76,8 +76,7 @@ ListUser::sumObjList(std::list<Obj*> objList)
return total;
}
-std::list<std::list<int> >
-ListUser::createListOfIntLists(int num)
+std::list<std::list<int> > ListUser::createListOfIntLists(int num)
{
std::list<std::list<int> > retval;
for (int i = 0; i < num; ++i)
@@ -85,8 +84,7 @@ ListUser::createListOfIntLists(int num)
return retval;
}
-int
-ListUser::sumListOfIntLists(std::list<std::list<int> > intListList)
+int ListUser::sumListOfIntLists(std::list<std::list<int> > intListList)
{
int total = 0;
for (const auto &list : intListList)
diff --git a/sources/shiboken6/tests/libminimal/listuser.h b/sources/shiboken6/tests/libminimal/listuser.h
index 2254cb138..9904ef27d 100644
--- a/sources/shiboken6/tests/libminimal/listuser.h
+++ b/sources/shiboken6/tests/libminimal/listuser.h
@@ -4,16 +4,21 @@
#ifndef LISTUSER_H
#define LISTUSER_H
-#include <list>
#include "obj.h"
#include "val.h"
#include "minbool.h"
#include "libminimalmacros.h"
+#include <list>
+
struct LIBMINIMAL_API ListUser
{
- virtual ~ListUser() {}
+ LIBMINIMAL_DEFAULT_COPY(ListUser)
+ LIBMINIMAL_DISABLE_MOVE(ListUser)
+
+ ListUser() noexcept = default;
+ virtual ~ListUser() = default;
// List of C++ primitive type items
virtual std::list<int> createIntList(int num);
@@ -21,6 +26,9 @@ struct LIBMINIMAL_API ListUser
virtual int sumIntList(std::list<int> intList);
int callSumIntList(std::list<int> intList) { return sumIntList(intList); }
+ int sumIntListDefaultParamConstRef(const std::list<int> &intList = {1, 2, 3});
+ int sumIntListDefaultParam(std::list<int> intList = {1, 2, 3});
+
// List of C++ MinBool objects used as primitives in Python
virtual std::list<MinBool> createMinBoolList(MinBool mb1, MinBool mb2);
std::list<MinBool> callCreateMinBoolList(MinBool mb1, MinBool mb2) { return createMinBoolList(mb1, mb2); }
diff --git a/sources/shiboken6/tests/libminimal/minbool.h b/sources/shiboken6/tests/libminimal/minbool.h
index f75e458da..e460f466b 100644
--- a/sources/shiboken6/tests/libminimal/minbool.h
+++ b/sources/shiboken6/tests/libminimal/minbool.h
@@ -13,9 +13,10 @@ public:
bool value() const { return m_value; }
inline MinBool operator!() const { return MinBool(!m_value); }
inline MinBool& operator|=(const MinBool& other) {
- m_value = m_value | other.m_value;
+ m_value |= other.m_value;
return *this;
}
+
private:
bool m_value;
};
@@ -30,12 +31,16 @@ inline bool operator!=(MinBool b1, MinBool b2) { return (!b1).value() != (!b2).v
class LIBMINIMAL_API MinBoolUser
{
public:
- MinBoolUser() : m_minbool(MinBool(false)) {}
- virtual ~MinBoolUser() {}
+ LIBMINIMAL_DEFAULT_COPY(MinBoolUser)
+ LIBMINIMAL_DISABLE_MOVE(MinBoolUser)
+
+ MinBoolUser() noexcept : m_minbool(MinBool(false)) {}
+ virtual ~MinBoolUser() = default;
inline MinBool minBool() { return m_minbool; }
inline void setMinBool(MinBool minBool) { m_minbool = minBool; }
virtual MinBool invertedMinBool() { return !m_minbool; }
inline MinBool callInvertedMinBool() { return invertedMinBool(); }
+
private:
MinBool m_minbool;
};
diff --git a/sources/shiboken6/tests/libminimal/obj.cpp b/sources/shiboken6/tests/libminimal/obj.cpp
index 0e49fee8b..a63a9c3c9 100644
--- a/sources/shiboken6/tests/libminimal/obj.cpp
+++ b/sources/shiboken6/tests/libminimal/obj.cpp
@@ -3,14 +3,13 @@
#include "obj.h"
-Obj::Obj(int objId) : m_objId(objId)
+Obj::Obj(int objId) noexcept : m_objId(objId)
{
}
Obj::~Obj() = default;
-bool
-Obj::virtualMethod(int val)
+bool Obj::virtualMethod(int val)
{
return !bool(val%2);
}
diff --git a/sources/shiboken6/tests/libminimal/obj.h b/sources/shiboken6/tests/libminimal/obj.h
index 55a798c02..be0bfb52b 100644
--- a/sources/shiboken6/tests/libminimal/obj.h
+++ b/sources/shiboken6/tests/libminimal/obj.h
@@ -9,7 +9,9 @@
class LIBMINIMAL_API Obj
{
public:
- explicit Obj(int objId);
+ LIBMINIMAL_DISABLE_COPY_MOVE(Obj)
+
+ explicit Obj(int objId) noexcept;
virtual ~Obj();
int objId() const { return m_objId; }
@@ -25,8 +27,6 @@ public:
Obj* callPassObjectTypeReference(Obj& obj) { return passObjectTypeReference(obj); }
private:
- Obj(const Obj&);
- Obj& operator=(const Obj&);
int m_objId;
};
diff --git a/sources/shiboken6/tests/libminimal/spanuser.cpp b/sources/shiboken6/tests/libminimal/spanuser.cpp
new file mode 100644
index 000000000..fea9cd68e
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/spanuser.cpp
@@ -0,0 +1,58 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "spanuser.h"
+
+#include <numeric>
+
+SpanUser::SpanUser() = default;
+
+bool SpanUser::enabled()
+{
+#if __cplusplus >= 202002L
+ return true;
+#else
+ return false;
+#endif
+}
+
+#if __cplusplus >= 202002L
+IntSpan3 SpanUser::getIntSpan3()
+{
+ static int iv[] = {1, 2, 3};
+ return IntSpan3(iv);
+}
+
+IntSpan SpanUser::getIntSpan()
+{
+ static int iv[] = {1, 2, 3};
+ return IntSpan(iv);
+}
+
+ConstIntSpan3 SpanUser::getConstIntSpan3()
+{
+ static const int civ[] = {1, 2, 3};
+ return ConstIntSpan3(civ);
+}
+
+IntSpan3 SpanUser::getIntSpan3_OpaqueContainer()
+{
+ static int iv[] = {1, 2, 3};
+ return IntSpan3(iv);
+}
+
+int SpanUser::sumIntSpan3(IntSpan3 isp3)
+{
+ return std::accumulate(isp3.begin(), isp3.end(), 0);
+}
+
+int SpanUser::sumIntSpan(IntSpan isp)
+{
+ return std::accumulate(isp.begin(), isp.end(), 0);
+}
+
+int SpanUser::sumConstIntSpan3(ConstIntSpan3 ispc3)
+{
+ return std::accumulate(ispc3.begin(), ispc3.end(), 0);
+}
+#endif // C++ 20
diff --git a/sources/shiboken6/tests/libminimal/spanuser.h b/sources/shiboken6/tests/libminimal/spanuser.h
new file mode 100644
index 000000000..c78ba35e7
--- /dev/null
+++ b/sources/shiboken6/tests/libminimal/spanuser.h
@@ -0,0 +1,35 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef SPANUSER_H
+#define SPANUSER_H
+
+#include "libminimalmacros.h"
+
+#if __cplusplus >= 202002L
+# include <span>
+
+using IntSpan3 = std::span<int, 3>;
+using IntSpan = std::span<int>;
+using ConstIntSpan3 = std::span<const int, 3>;
+#endif
+
+struct LIBMINIMAL_API SpanUser
+{
+ SpanUser();
+
+ static bool enabled();
+
+#if __cplusplus >= 202002L
+ static IntSpan3 getIntSpan3();
+ static IntSpan getIntSpan();
+ static ConstIntSpan3 getConstIntSpan3();
+ static IntSpan3 getIntSpan3_OpaqueContainer();
+
+ static int sumIntSpan3(IntSpan3 isp3);
+ static int sumIntSpan(IntSpan isp);
+ static int sumConstIntSpan3(ConstIntSpan3 ispc3);
+#endif // C++ 20
+};
+
+#endif // SPANUSER_H
diff --git a/sources/shiboken6/tests/libminimal/val.h b/sources/shiboken6/tests/libminimal/val.h
index af53263bd..50f090a7d 100644
--- a/sources/shiboken6/tests/libminimal/val.h
+++ b/sources/shiboken6/tests/libminimal/val.h
@@ -9,8 +9,10 @@
class LIBMINIMAL_API Val
{
public:
- explicit Val(int valId) : m_valId(valId) {}
- virtual ~Val() {}
+ explicit Val(int valId) noexcept : m_valId(valId) {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Val)
+
+ virtual ~Val() = default;
int valId() const { return m_valId; }
void setValId(int valId) { m_valId = valId; }
diff --git a/sources/shiboken6/tests/libother/CMakeLists.txt b/sources/shiboken6/tests/libother/CMakeLists.txt
index c078d3546..0379d740b 100644
--- a/sources/shiboken6/tests/libother/CMakeLists.txt
+++ b/sources/shiboken6/tests/libother/CMakeLists.txt
@@ -1,12 +1,17 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(libother)
set(libother_SRC
-number.cpp
-otherderived.cpp
-otherobjecttype.cpp
-othermultiplederived.cpp
-smartptrtester.cpp
-othertypesystypedef.cpp
+extendsnoimplicitconversion.h
+libothermacros.h
+number.cpp number.h
+otherderived.cpp otherderived.h
+othermultiplederived.cpp othermultiplederived.h
+otherobjecttype.cpp otherobjecttype.h
+othertypesystypedef.cpp othertypesystypedef.h
+smartptrtester.cpp smartptrtester.h
)
add_library(libother SHARED ${libother_SRC})
diff --git a/sources/shiboken6/tests/libother/extendsnoimplicitconversion.h b/sources/shiboken6/tests/libother/extendsnoimplicitconversion.h
index bf6cd736c..36d503fe8 100644
--- a/sources/shiboken6/tests/libother/extendsnoimplicitconversion.h
+++ b/sources/shiboken6/tests/libother/extendsnoimplicitconversion.h
@@ -13,8 +13,9 @@ public:
explicit ExtendsNoImplicitConversion(int objId) : m_objId(objId) {};
inline int objId() const { return m_objId; }
inline operator NoImplicitConversion() const { return NoImplicitConversion(m_objId); }
+
private:
int m_objId;
};
-#endif // EXTENDSNOIMPLICITCONVERSION_H
+#endif // EXTENDSNOIMPLICITCONVERSION_H
diff --git a/sources/shiboken6/tests/libother/number.cpp b/sources/shiboken6/tests/libother/number.cpp
index c21c7c086..fbf50dc4a 100644
--- a/sources/shiboken6/tests/libother/number.cpp
+++ b/sources/shiboken6/tests/libother/number.cpp
@@ -2,33 +2,27 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "number.h"
-#include <cstring>
-#include <sstream>
-using namespace std;
+#include <sstream>
-Str
-Number::toStr() const
+Str Number::toStr() const
{
- ostringstream in;
+ std::ostringstream in;
in << m_value;
return in.str().c_str();
}
-Point
-operator*(const Point& p, const Number& n)
+Point operator*(const Point &p, const Number &n)
{
- return Point(p.x() * n.value(), p.y() * n.value());
+ return {p.x() * n.value(), p.y() * n.value()};
}
-Complex
-Number::toComplex() const
+Complex Number::toComplex() const
{
return Complex(m_value);
}
-Number
-Number::fromComplex(Complex cpx)
+Number Number::fromComplex(Complex cpx)
{
return Number(cpx.real());
}
diff --git a/sources/shiboken6/tests/libother/number.h b/sources/shiboken6/tests/libother/number.h
index 85f888d82..2c480e7f2 100644
--- a/sources/shiboken6/tests/libother/number.h
+++ b/sources/shiboken6/tests/libother/number.h
@@ -18,7 +18,7 @@ public:
Str toStr() const;
inline operator Str() const { return toStr(); }
- friend LIBOTHER_API Point operator*(const Point&, const Number&);
+ friend LIBOTHER_API Point operator*(const Point &, const Number &);
Complex toComplex() const;
static Number fromComplex(Complex cpx);
@@ -27,6 +27,6 @@ private:
int m_value;
};
-LIBOTHER_API Point operator*(const Point&, const Number&);
+LIBOTHER_API Point operator*(const Point &, const Number &);
#endif // NUMBER_H
diff --git a/sources/shiboken6/tests/libother/otherderived.cpp b/sources/shiboken6/tests/libother/otherderived.cpp
index 12521b73c..93a18876e 100644
--- a/sources/shiboken6/tests/libother/otherderived.cpp
+++ b/sources/shiboken6/tests/libother/otherderived.cpp
@@ -7,30 +7,24 @@ OtherDerived::OtherDerived(int id) : Abstract(id)
{
}
-OtherDerived::~OtherDerived()
-{
-}
+OtherDerived::~OtherDerived() = default;
-Abstract*
-OtherDerived::createObject()
+Abstract *OtherDerived::createObject()
{
static int id = 100;
return new OtherDerived(id++);
}
-void
-OtherDerived::pureVirtual()
+void OtherDerived::pureVirtual()
{
}
-void*
-OtherDerived::pureVirtualReturningVoidPtr()
+void *OtherDerived::pureVirtualReturningVoidPtr()
{
return nullptr;
}
-void
-OtherDerived::unpureVirtual()
+void OtherDerived::unpureVirtual()
{
}
diff --git a/sources/shiboken6/tests/libother/otherderived.h b/sources/shiboken6/tests/libother/otherderived.h
index cefb4dc11..d6bde8808 100644
--- a/sources/shiboken6/tests/libother/otherderived.h
+++ b/sources/shiboken6/tests/libother/otherderived.h
@@ -18,26 +18,26 @@ public:
OtherDerived(int id = -1);
~OtherDerived() override;
void pureVirtual() override;
- void* pureVirtualReturningVoidPtr() override;
+ void *pureVirtualReturningVoidPtr() override;
void unpureVirtual() override;
PrintFormat returnAnEnum() override { return Short; }
- inline void useObjectTypeFromOtherModule(ObjectType*) {}
- inline Event useValueTypeFromOtherModule(const Event& e) { return e; }
- inline Complex useValueTypeFromOtherModule(const Complex& c) { return c; }
+ inline void useObjectTypeFromOtherModule(ObjectType *) {}
+ inline Event useValueTypeFromOtherModule(const Event &e) { return e; }
+ inline Complex useValueTypeFromOtherModule(const Complex &c) { return c; }
inline void useEnumTypeFromOtherModule(OverloadedFuncEnum) {}
// factory method
- static Abstract* createObject();
+ static Abstract *createObject();
void hideFunction(HideType*) override {}
protected:
- inline const char* getClassName() { return className(); }
- virtual const char* className() override { return "OtherDerived"; }
+ inline const char *getClassName() { return className(); }
+ const char *className() const override { return "OtherDerived"; }
private:
void pureVirtualPrivate() override;
};
-#endif // OTHERDERIVED_H
+#endif // OTHERDERIVED_H
diff --git a/sources/shiboken6/tests/libother/othermultiplederived.cpp b/sources/shiboken6/tests/libother/othermultiplederived.cpp
index 41718fc49..cfbbfb2c2 100644
--- a/sources/shiboken6/tests/libother/othermultiplederived.cpp
+++ b/sources/shiboken6/tests/libother/othermultiplederived.cpp
@@ -8,18 +8,17 @@ VirtualMethods OtherMultipleDerived::returnUselessClass()
return VirtualMethods();
}
-Base1* OtherMultipleDerived::createObject(const std::string& objName)
+Base1 *OtherMultipleDerived::createObject(const std::string &objName)
{
if (objName == "Base1")
return new Base1;
- else if (objName == "MDerived1")
+ if (objName == "MDerived1")
return new MDerived1;
- else if (objName == "SonOfMDerived1")
+ if (objName == "SonOfMDerived1")
return new SonOfMDerived1;
- else if (objName == "MDerived3")
+ if (objName == "MDerived3")
return new MDerived3;
- else if (objName == "OtherMultipleDerived")
+ if (objName == "OtherMultipleDerived")
return new OtherMultipleDerived;
return nullptr;
}
-
diff --git a/sources/shiboken6/tests/libother/othermultiplederived.h b/sources/shiboken6/tests/libother/othermultiplederived.h
index c209c72ac..cd9910687 100644
--- a/sources/shiboken6/tests/libother/othermultiplederived.h
+++ b/sources/shiboken6/tests/libother/othermultiplederived.h
@@ -10,12 +10,12 @@
class ObjectType;
-class LIBOTHER_API OtherMultipleDerived : public MDerived1
+class LIBOTHER_API OtherMultipleDerived : public OtherBase, public MDerived1
{
public:
// this will use CppCopier from other module (bug#142)
VirtualMethods returnUselessClass();
- static Base1* createObject(const std::string& objName);
+ static Base1 *createObject(const std::string &objName);
};
-#endif
+#endif // OTHERMULTIPLEDERIVED_H
diff --git a/sources/shiboken6/tests/libother/otherobjecttype.cpp b/sources/shiboken6/tests/libother/otherobjecttype.cpp
index fee6f5bfa..eaaa231be 100644
--- a/sources/shiboken6/tests/libother/otherobjecttype.cpp
+++ b/sources/shiboken6/tests/libother/otherobjecttype.cpp
@@ -3,10 +3,9 @@
#include "otherobjecttype.h"
-Collector&
-operator<<(Collector& collector, const OtherObjectType& obj)
+Collector &operator<<(Collector &collector, const OtherObjectType &obj)
{
- collector << obj.identifier()*2;
+ collector << obj.identifier() * 2;
return collector;
}
diff --git a/sources/shiboken6/tests/libother/otherobjecttype.h b/sources/shiboken6/tests/libother/otherobjecttype.h
index b301ce22b..844795118 100644
--- a/sources/shiboken6/tests/libother/otherobjecttype.h
+++ b/sources/shiboken6/tests/libother/otherobjecttype.h
@@ -4,16 +4,12 @@
#ifndef OTHEROBJECTTYPE_H
#define OTHEROBJECTTYPE_H
-#include <list>
-#include "str.h"
-
#include "libothermacros.h"
#include "objecttype.h"
#include "collector.h"
#include "samplenamespace.h"
#include "removednamespaces.h"
-
class LIBOTHER_API OtherObjectType : public ObjectType
{
public:
@@ -21,8 +17,6 @@ public:
static int enumAsIntForInvisibleNamespace(RemovedNamespace1::RemovedNamespace1_Enum value);
};
-
-LIBOTHER_API Collector& operator<<(Collector&, const OtherObjectType&);
+LIBOTHER_API Collector &operator<<(Collector &, const OtherObjectType &);
#endif // OTHEROBJECTTYPE_H
-
diff --git a/sources/shiboken6/tests/libother/smartptrtester.cpp b/sources/shiboken6/tests/libother/smartptrtester.cpp
index 25b6a406e..1c6496b1a 100644
--- a/sources/shiboken6/tests/libother/smartptrtester.cpp
+++ b/sources/shiboken6/tests/libother/smartptrtester.cpp
@@ -5,7 +5,7 @@
SharedPtr<Str> SmartPtrTester::createSharedPtrStr(const char *what)
{
- return SharedPtr<Str>(new Str(what));
+ return {new Str(what)};
}
std::string SmartPtrTester::valueOfSharedPtrStr(const SharedPtr<Str> &str)
diff --git a/sources/shiboken6/tests/libsample/CMakeLists.txt b/sources/shiboken6/tests/libsample/CMakeLists.txt
index 6e436ee1f..926972340 100644
--- a/sources/shiboken6/tests/libsample/CMakeLists.txt
+++ b/sources/shiboken6/tests/libsample/CMakeLists.txt
@@ -1,63 +1,93 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(libsample)
set(libsample_SRC
-abstract.cpp
-blackbox.cpp
-bytearray.cpp
-bucket.cpp
-collector.cpp
-complex.cpp
-ctparam.cpp
-onlycopy.cpp
-derived.cpp
-derivedusingct.cpp
-echo.cpp
-exceptiontest.cpp
-functions.cpp
-handle.cpp
-implicitconv.cpp
-intwrapper.cpp
-injectcode.cpp
-listuser.cpp
-modifications.cpp
-mapuser.cpp
-modified_constructor.cpp
-multiple_derived.cpp
-oddbool.cpp
-objectmodel.cpp
-objecttype.cpp
-objecttypeholder.cpp
-objecttypelayout.cpp
-objecttypeoperators.cpp
-objectview.cpp
-overload.cpp
-overloadsort.cpp
-pairuser.cpp
-pen.cpp
-photon.cpp
-point.cpp
-pointf.cpp
-polygon.cpp
-protected.cpp
-reference.cpp
-renaming.cpp
-sample.cpp
-samplenamespace.cpp
-sbkdate.cpp
-simplefile.cpp
-size.cpp
-snakecasetest.cpp
-sometime.cpp
-str.cpp
-strlist.cpp
-templateptr.cpp
-transform.cpp
-typesystypedef.cpp
-virtualmethods.cpp
-expression.cpp
-filter.cpp
+abstract.cpp abstract.h
+blackbox.cpp blackbox.h
+bucket.cpp bucket.h
+bytearray.cpp bytearray.h
+collector.cpp collector.h
+complex.cpp complex.h
+ctorconvrule.h
+ctparam.cpp ctparam.h
+cvlist.h
+derived.cpp derived.h
+derivedusingct.cpp derivedusingct.h
+echo.cpp echo.h
+exceptiontest.cpp exceptiontest.h
+expression.cpp expression.h
+filter.cpp filter.h
+functions.cpp functions.h
+handle.cpp handle.h
+implicitconv.cpp implicitconv.h
+injectcode.cpp injectcode.h
+intwrapper.cpp intwrapper.h
+libsamplemacros.h
+list.h
+listuser.cpp listuser.h
+mapuser.cpp mapuser.h
+modelindex.h
+modifications.cpp modifications.h
+modified_constructor.cpp modified_constructor.h
+multiple_derived.cpp multiple_derived.h
+noimplicitconversion.h
+nondefaultctor.h
+nontypetemplate.h
+null.h
+objectmodel.cpp objectmodel.h
+objecttype.cpp objecttype.h
+objecttypebyvalue.h
+objecttypeholder.cpp objecttypeholder.h
+objecttypelayout.cpp objecttypelayout.h
+objecttypeoperators.cpp objecttypeoperators.h
+objectview.cpp objectview.h
+oddbool.cpp oddbool.h
+onlycopy.cpp onlycopy.h
+overload.cpp overload.h
+overloadsort.cpp overloadsort.h
+pairuser.cpp pairuser.h
+pen.cpp pen.h
+photon.cpp photon.h
+point.cpp point.h
+pointerholder.h
+pointf.cpp pointf.h
+polygon.cpp polygon.h
+privatector.h
+privatedtor.h
+protected.cpp protected.h
+rect.h
+reference.cpp reference.h
+removednamespaces.h
+renaming.cpp renaming.h
+sample.cpp sample.h
+samplenamespace.cpp samplenamespace.h
+sbkdate.cpp sbkdate.h
+stdcomplex.cpp stdcomplex.h
+simplefile.cpp simplefile.h
+size.cpp size.h
+snakecasetest.cpp snakecasetest.h
+sometime.cpp sometime.h
+str.cpp str.h
+strlist.cpp strlist.h
+templateptr.cpp templateptr.h
+transform.cpp transform.h
+typesystypedef.cpp typesystypedef.h
+valueandvirtual.h
+virtualmethods.cpp virtualmethods.h
+voidholder.h
)
+# Includes windows.h which is causing clashes between class Polygon and
+# wingdi.h's Polygon() function.
+
+if(WIN32)
+ set_source_files_properties(
+ bucket.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON
+ )
+endif()
+
add_library(libsample SHARED ${libsample_SRC})
target_include_directories(libsample PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(libsample PRIVATE LIBSAMPLE_BUILD)
diff --git a/sources/shiboken6/tests/libsample/abstract.cpp b/sources/shiboken6/tests/libsample/abstract.cpp
index 7d4a21ceb..0d67d8630 100644
--- a/sources/shiboken6/tests/libsample/abstract.cpp
+++ b/sources/shiboken6/tests/libsample/abstract.cpp
@@ -1,64 +1,64 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
#include "abstract.h"
-#include "objecttype.h"
-using namespace std;
+#include <iostream>
const int Abstract::staticPrimitiveField = 0;
-Abstract::Abstract(int id) : m_id(id)
+Abstract::Abstract(int id) noexcept : m_id(id)
{
- toBeRenamedField = readOnlyField = primitiveField = 123;
- valueTypeField = Point(12, 34);
- objectTypeField = nullptr;
bitField = 0;
}
-Abstract::~Abstract()
-{
-}
+Abstract::~Abstract() = default;
-void
-Abstract::unpureVirtual()
+void Abstract::unpureVirtual()
{
}
-void
-Abstract::callUnpureVirtual()
+void Abstract::callUnpureVirtual()
{
this->unpureVirtual();
}
-
-void
-Abstract::callPureVirtual()
+void Abstract::callPureVirtual()
{
this->pureVirtual();
}
-void
-Abstract::show(PrintFormat format)
+void Abstract::show(PrintFormat format) const
{
- cout << '<';
+ std::cout << '<';
switch(format) {
- case Short:
- cout << this;
- break;
- case Verbose:
- cout << "class " << className() << " | cptr: " << this;
- cout << ", id: " << m_id;
- break;
- case OnlyId:
- cout << "id: " << m_id;
- break;
- case ClassNameAndId:
- cout << className() << " - id: " << m_id;
- break;
+ case Short:
+ std::cout << this;
+ break;
+ case Verbose:
+ std::cout << "class " << className() << " | cptr: " << this
+ << ", id: " << m_id;
+ break;
+ case OnlyId:
+ std::cout << "id: " << m_id;
+ break;
+ case ClassNameAndId:
+ std::cout << className() << " - id: " << m_id;
+ break;
}
- cout << '>';
+ std::cout << '>';
+}
+
+void Abstract::virtualWithOutParameter(int &x) const
+{
+ x = 42;
+}
+
+int Abstract::callVirtualWithOutParameter() const
+{
+ int x;
+ virtualWithOutParameter(x);
+ return x;
}
void Abstract::callVirtualGettingEnum(PrintFormat p)
@@ -69,4 +69,3 @@ void Abstract::callVirtualGettingEnum(PrintFormat p)
void Abstract::virtualGettingAEnum(Abstract::PrintFormat)
{
}
-
diff --git a/sources/shiboken6/tests/libsample/abstract.h b/sources/shiboken6/tests/libsample/abstract.h
index 0e66ad0e1..4c1b98d90 100644
--- a/sources/shiboken6/tests/libsample/abstract.h
+++ b/sources/shiboken6/tests/libsample/abstract.h
@@ -24,6 +24,8 @@ private:
PrivValue2 = PrivValue1 + 2
};
public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Abstract)
+
enum PrintFormat {
Short,
Verbose,
@@ -38,26 +40,26 @@ public:
};
static const int staticPrimitiveField;
- int primitiveField;
+ int primitiveField = 123;
Complex userPrimitiveField;
- Point valueTypeField;
- ObjectType* objectTypeField;
- int toBeRenamedField;
- int readOnlyField;
+ Point valueTypeField{12, 34};
+ ObjectType *objectTypeField = nullptr;
+ int toBeRenamedField = 123;
+ int readOnlyField = 123;
- Abstract(int id = -1);
+ explicit Abstract(int id = -1) noexcept;
virtual ~Abstract();
- inline int id() { return m_id; }
+ inline int id() const { return m_id; }
// factory method
- inline static Abstract* createObject() { return nullptr; }
+ inline static Abstract *createObject() { return nullptr; }
// method that receives an Object Type
- inline static int getObjectId(Abstract* obj) { return obj->id(); }
+ inline static int getObjectId(Abstract *obj) { return obj->id(); }
virtual void pureVirtual() = 0;
- virtual void* pureVirtualReturningVoidPtr() = 0;
+ virtual void *pureVirtualReturningVoidPtr() = 0;
virtual void unpureVirtual();
virtual PrintFormat returnAnEnum() = 0;
@@ -67,13 +69,16 @@ public:
void callPureVirtual();
void callUnpureVirtual();
- void show(PrintFormat format = Verbose);
+ void show(PrintFormat format = Verbose) const;
virtual Type type() const { return TpAbstract; }
- virtual void hideFunction(HideType* arg) = 0;
+ virtual void hideFunction(HideType *arg) = 0;
+
+ virtual void virtualWithOutParameter(int &x) const;
+ int callVirtualWithOutParameter() const;
protected:
- virtual const char* className() { return "Abstract"; }
+ virtual const char *className() const { return "Abstract"; }
// Protected bit-field structure member.
unsigned int bitField: 1;
@@ -82,4 +87,5 @@ private:
virtual void pureVirtualPrivate() = 0;
int m_id;
};
+
#endif // ABSTRACT_H
diff --git a/sources/shiboken6/tests/libsample/blackbox.cpp b/sources/shiboken6/tests/libsample/blackbox.cpp
index f648a3770..2ac435d3d 100644
--- a/sources/shiboken6/tests/libsample/blackbox.cpp
+++ b/sources/shiboken6/tests/libsample/blackbox.cpp
@@ -3,102 +3,79 @@
#include "blackbox.h"
-using namespace std;
-
BlackBox::~BlackBox()
{
// Free all maps.
- while (!m_objects.empty()) {
- delete (*m_objects.begin()).second;
- m_objects.erase(m_objects.begin());
- }
- while (!m_points.empty()) {
- delete (*m_points.begin()).second;
- m_points.erase(m_points.begin());
- }
+ for (const auto &p :m_objects)
+ delete p.second;
+ for (const auto &p : m_points)
+ delete p.second;
}
-int
-BlackBox::keepObjectType(ObjectType* object)
+int BlackBox::keepObjectType(ObjectType *object)
{
- m_ticket++;
- std::pair<int, ObjectType*> item(m_ticket, object);
- m_objects.insert(item);
+ ++m_ticket;
+ m_objects.insert({m_ticket, object});
object->setParent(nullptr);
return m_ticket;
}
-ObjectType*
-BlackBox::retrieveObjectType(int ticket)
+ObjectType *BlackBox::retrieveObjectType(int ticket)
{
const auto it = m_objects.find(ticket);
if (it != m_objects.end()) {
- ObjectType* second = it->second;
+ ObjectType *second = it->second;
m_objects.erase(it);
return second;
}
return nullptr;
}
-void
-BlackBox::disposeObjectType(int ticket)
+void BlackBox::disposeObjectType(int ticket)
{
- ObjectType* object = retrieveObjectType(ticket);
- if (object)
- delete object;
+ delete retrieveObjectType(ticket);
}
-int
-BlackBox::keepPoint(Point* point)
+int BlackBox::keepPoint(Point *point)
{
- m_ticket++;
- std::pair<int, Point*> item(m_ticket, point);
- m_points.insert(item);
-
+ ++m_ticket;
+ m_points.insert({m_ticket, point});
return m_ticket;
}
-Point*
-BlackBox::retrievePoint(int ticket)
+Point *BlackBox::retrievePoint(int ticket)
{
const auto it = m_points.find(ticket);
if (it != m_points.end()) {
- Point* second = it->second;
+ Point *second = it->second;
m_points.erase(it);
return second;
}
return nullptr;
}
-void
-BlackBox::disposePoint(int ticket)
+void BlackBox::disposePoint(int ticket)
{
- Point* point = retrievePoint(ticket);
- if (point)
- delete point;
+ delete retrievePoint(ticket);
}
-
-std::list<ObjectType*>
-BlackBox::objects()
+std::list<ObjectType*> BlackBox::objects()
{
std::list<ObjectType*> l;
- for (auto it = m_objects.begin(), end = m_objects.end(); it != end; ++it)
- l.push_back((*it).second);
+ for (const auto &p : m_objects)
+ l.push_back(p.second);
return l;
}
-std::list<Point*>
-BlackBox::points()
+std::list<Point*> BlackBox::points()
{
std::list<Point*> l;
- for (auto it = m_points.begin(), end = m_points.end(); it != end; ++it)
- l.push_back((*it).second);
+ for (const auto &p : m_points)
+ l.push_back(p.second);
return l;
}
-
diff --git a/sources/shiboken6/tests/libsample/blackbox.h b/sources/shiboken6/tests/libsample/blackbox.h
index bfcbd2128..9d32670dd 100644
--- a/sources/shiboken6/tests/libsample/blackbox.h
+++ b/sources/shiboken6/tests/libsample/blackbox.h
@@ -5,25 +5,28 @@
#define BLACKBOX_H
#include "libsamplemacros.h"
-#include <map>
#include "objecttype.h"
#include "point.h"
+#include <list>
+#include <map>
+
class LIBSAMPLE_API BlackBox
{
public:
- typedef std::map<int, ObjectType*> ObjectTypeMap;
- typedef std::map<int, Point*> PointMap;
+ using ObjectTypeMap = std::map<int, ObjectType*>;
+ using PointMap = std::map<int, Point*>;
- BlackBox() { m_ticket = -1;}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(BlackBox)
+ BlackBox() noexcept = default;
~BlackBox();
- int keepObjectType(ObjectType* object);
- ObjectType* retrieveObjectType(int ticket);
+ int keepObjectType(ObjectType *object);
+ ObjectType *retrieveObjectType(int ticket);
void disposeObjectType(int ticket);
- int keepPoint(Point* point);
- Point* retrievePoint(int ticket);
+ int keepPoint(Point *point);
+ Point *retrievePoint(int ticket);
void disposePoint(int ticket);
std::list<ObjectType*> objects();
@@ -35,8 +38,7 @@ public:
private:
ObjectTypeMap m_objects;
PointMap m_points;
- int m_ticket;
+ int m_ticket = -1;
};
#endif // BLACKBOX_H
-
diff --git a/sources/shiboken6/tests/libsample/bucket.cpp b/sources/shiboken6/tests/libsample/bucket.cpp
index 01a1f591e..cafd382a9 100644
--- a/sources/shiboken6/tests/libsample/bucket.cpp
+++ b/sources/shiboken6/tests/libsample/bucket.cpp
@@ -2,23 +2,20 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "bucket.h"
+
#include <iostream>
#ifdef _WIN32 // _WIN32 is defined by all Windows 32 and 64 bit compilers, but not by others.
-#include <windows.h>
-#define SLEEP(x) Sleep(x)
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# define SLEEP(x) Sleep(x)
#else
-#include <unistd.h>
-#define SLEEP(x) usleep(x)
+# include <unistd.h>
+# define SLEEP(x) usleep(x)
#endif
-
-using namespace std;
-
-Bucket::Bucket() : m_locked(false)
-{
-}
-
void Bucket::push(int x)
{
m_data.push_back(x);
@@ -28,7 +25,7 @@ int Bucket::pop(void)
{
int x = 0;
- if (m_data.size() > 0) {
+ if (!m_data.empty()) {
x = m_data.front();
m_data.pop_front();
}
@@ -44,7 +41,9 @@ bool Bucket::empty()
void Bucket::lock()
{
m_locked = true;
- while (m_locked) { SLEEP(300); }
+ while (m_locked) {
+ SLEEP(300);
+ }
}
void Bucket::unlock()
@@ -58,4 +57,3 @@ bool Bucket::virtualBlockerMethod()
// The return value was added just for diversity sake.
return true;
}
-
diff --git a/sources/shiboken6/tests/libsample/bucket.h b/sources/shiboken6/tests/libsample/bucket.h
index 4a45802a4..73e8edd78 100644
--- a/sources/shiboken6/tests/libsample/bucket.h
+++ b/sources/shiboken6/tests/libsample/bucket.h
@@ -6,6 +6,7 @@
#include "libsamplemacros.h"
#include "objecttype.h"
+
#include <list>
class ObjectType;
@@ -13,7 +14,7 @@ class ObjectType;
class LIBSAMPLE_API Bucket : public ObjectType
{
public:
- Bucket();
+ Bucket() = default;
void push(int);
int pop();
bool empty();
@@ -27,8 +28,7 @@ public:
private:
std::list<int> m_data;
- volatile bool m_locked;
+ volatile bool m_locked = false;
};
#endif // BUCKET_H
-
diff --git a/sources/shiboken6/tests/libsample/bytearray.cpp b/sources/shiboken6/tests/libsample/bytearray.cpp
index 2ed80bf51..78d5162b0 100644
--- a/sources/shiboken6/tests/libsample/bytearray.cpp
+++ b/sources/shiboken6/tests/libsample/bytearray.cpp
@@ -1,13 +1,14 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <cstring>
#include "bytearray.h"
-ByteArray::ByteArray()
+#include <algorithm>
+#include <iterator>
+#include <cstring>
+
+ByteArray::ByteArray() : m_data(1, '\0')
{
- m_data = std::vector<char>(1);
- m_data[0] = '\0';
}
ByteArray::ByteArray(char c)
@@ -17,41 +18,37 @@ ByteArray::ByteArray(char c)
m_data[1] = '\0';
}
-ByteArray::ByteArray(const char* data)
+ByteArray::ByteArray(const char *data)
{
- size_t len = strlen(data);
+ size_t len = std::strlen(data);
m_data = std::vector<char>(len + 1);
memcpy(&m_data[0], data, len);
m_data[len] = '\0';
}
-ByteArray::ByteArray(const char* data, int len)
+ByteArray::ByteArray(const char *data, int len)
{
m_data = std::vector<char>(len + 1);
memcpy(&m_data[0], data, len);
m_data[len] = '\0';
}
-int
-ByteArray::size() const
+int ByteArray::size() const
{
return m_data.size() - 1;
}
-char
-ByteArray::at(int pos) const
+char ByteArray::at(int pos) const
{
return m_data[pos];
}
-const char*
-ByteArray::data() const
+const char *ByteArray::data() const
{
return &(m_data[0]);
}
-ByteArray&
-ByteArray::append(char c)
+ByteArray &ByteArray::append(char c)
{
m_data.pop_back();
m_data.push_back(c);
@@ -59,37 +56,30 @@ ByteArray::append(char c)
return *this;
}
-ByteArray&
-ByteArray::append(const char* data)
+ByteArray &ByteArray::append(const char *data)
{
m_data.pop_back();
- for (int i = 0; i < (int)strlen(data); ++i)
- m_data.push_back(data[i]);
+ std::copy(data, data + strlen(data), std::back_inserter(m_data));
m_data.push_back('\0');
return *this;
}
-ByteArray&
-ByteArray::append(const char* data, int len)
+ByteArray &ByteArray::append(const char *data, int len)
{
m_data.pop_back();
- for (int i = 0; i < len; ++i)
- m_data.push_back(data[i]);
+ std::copy(data, data + len, std::back_inserter(m_data));
m_data.push_back('\0');
return *this;
}
-ByteArray&
-ByteArray::append(const ByteArray& other)
+ByteArray &ByteArray::append(const ByteArray &other)
{
m_data.pop_back();
- for (int i = 0; i < (int)other.m_data.size(); ++i)
- m_data.push_back(other.m_data[i]);
- m_data.push_back('\0');
+ std::copy(other.m_data.begin(), other.m_data.end(), std::back_inserter(m_data));
return *this;
}
-static bool compare(const std::vector<char>& mine, const char* other)
+static bool compare(const std::vector<char> &mine, const char *other)
{
for (int i = 0; i < (int)mine.size() - 1; ++i) {
if (mine[i] != other[i])
@@ -98,85 +88,79 @@ static bool compare(const std::vector<char>& mine, const char* other)
return true;
}
-bool
-ByteArray::operator==(const ByteArray& other) const
+bool ByteArray::operator==(const ByteArray &other) const
{
- return compare(m_data, &other.m_data[0]);
+ return m_data == other.m_data;
}
-bool
-operator==(const ByteArray& ba1, const char* ba2)
+bool operator==(const ByteArray &ba1, const char *ba2)
{
return compare(ba1.m_data, ba2);
}
-bool
-operator==(const char* ba1, const ByteArray& ba2)
+
+bool operator==(const char *ba1, const ByteArray &ba2)
{
return compare(ba2.m_data, ba1);
}
-bool
-ByteArray::operator!=(const ByteArray& other) const
+bool ByteArray::operator!=(const ByteArray &other) const
{
- return !(m_data == other.m_data);
+ return m_data != other.m_data;
}
-bool
-operator!=(const ByteArray& ba1, const char* ba2)
+
+bool operator!=(const ByteArray &ba1, const char *ba2)
{
return !(ba1 == ba2);
}
-bool
-operator!=(const char* ba1, const ByteArray& ba2)
+
+bool operator!=(const char *ba1, const ByteArray &ba2)
{
return !(ba1 == ba2);
}
-ByteArray&
-ByteArray::operator+=(char c)
+ByteArray &ByteArray::operator+=(char c)
{
return append(c);
}
-ByteArray&
-ByteArray::operator+=(const char* data)
+
+ByteArray &ByteArray::operator+=(const char *data)
{
return append(data);
}
-ByteArray&
-ByteArray::operator+=(const ByteArray& other)
+
+ByteArray &ByteArray::operator+=(const ByteArray &other)
{
return append(other);
}
-ByteArray
-operator+(const ByteArray& ba1, const ByteArray& ba2)
+ByteArray operator+(const ByteArray &ba1, const ByteArray &ba2)
{
return ByteArray(ba1) += ba2;
}
-ByteArray
-operator+(const ByteArray& ba1, const char* ba2)
+
+ByteArray operator+(const ByteArray &ba1, const char *ba2)
{
return ByteArray(ba1) += ByteArray(ba2);
}
-ByteArray
-operator+(const char* ba1, const ByteArray& ba2)
+
+ByteArray operator+(const char *ba1, const ByteArray &ba2)
{
return ByteArray(ba1) += ba2;
}
-ByteArray
-operator+(const ByteArray& ba1, char ba2)
+
+ByteArray operator+(const ByteArray &ba1, char ba2)
{
return ByteArray(ba1) += ByteArray(ba2);
}
-ByteArray
-operator+(char ba1, const ByteArray& ba2)
+
+ByteArray operator+(char ba1, const ByteArray &ba2)
{
return ByteArray(ba1) += ba2;
}
-unsigned int
-ByteArray::hash(const ByteArray& byteArray)
+unsigned int ByteArray::hash(const ByteArray &byteArray)
{
unsigned int result = 0;
- for (int i = 0; i < (int)byteArray.m_data.size(); ++i)
- result = 5 * result + byteArray.m_data[i];
+ for (char c : byteArray.m_data)
+ result = 5U * result + unsigned(c);
return result;
}
diff --git a/sources/shiboken6/tests/libsample/bytearray.h b/sources/shiboken6/tests/libsample/bytearray.h
index e4504d755..35ff22367 100644
--- a/sources/shiboken6/tests/libsample/bytearray.h
+++ b/sources/shiboken6/tests/libsample/bytearray.h
@@ -6,58 +6,59 @@
#include "str.h"
#include "libsamplemacros.h"
+
#include <vector>
class LIBSAMPLE_API ByteArray
{
public:
ByteArray();
- ByteArray(char data);
- ByteArray(const char* data);
- ByteArray(const char* data, int len);
+ explicit ByteArray(char data);
+ explicit ByteArray(const char *data);
+ explicit ByteArray(const char *data, int len);
int size() const;
char at(int i) const;
char operator[](int i) const;
- const char* data() const;
+ const char *data() const;
- ByteArray& append(char c);
- ByteArray& append(const char* data);
- ByteArray& append(const char* data, int len);
- ByteArray& append(const ByteArray& other);
+ ByteArray &append(char c);
+ ByteArray &append(const char *data);
+ ByteArray &append(const char *data, int len);
+ ByteArray &append(const ByteArray &other);
- bool operator==(const ByteArray& other) const;
- bool operator!=(const ByteArray& other) const;
+ bool operator==(const ByteArray &other) const;
+ bool operator!=(const ByteArray &other) const;
- ByteArray& operator+=(char c);
- ByteArray& operator+=(const char* data);
- ByteArray& operator+=(const ByteArray& other);
+ ByteArray &operator+=(char c);
+ ByteArray &operator+=(const char *data);
+ ByteArray &operator+=(const ByteArray &other);
- static unsigned int hash(const ByteArray& byteArray);
+ static unsigned int hash(const ByteArray &byteArray);
private:
std::vector<char> m_data;
- friend LIBSAMPLE_API bool operator==(const ByteArray& ba1, const char* ba2);
- friend LIBSAMPLE_API bool operator==(const char* ba1, const ByteArray& ba2);
- friend LIBSAMPLE_API bool operator!=(const ByteArray& ba1, const char* ba2);
- friend LIBSAMPLE_API bool operator!=(const char* ba1, const ByteArray& ba2);
-
- friend LIBSAMPLE_API ByteArray operator+(const ByteArray& ba1, const ByteArray& ba2);
- friend LIBSAMPLE_API ByteArray operator+(const ByteArray& ba1, const char* ba2);
- friend LIBSAMPLE_API ByteArray operator+(const char* ba1, const ByteArray& ba2);
- friend LIBSAMPLE_API ByteArray operator+(const ByteArray& ba1, char ba2);
- friend LIBSAMPLE_API ByteArray operator+(char ba1, const ByteArray& ba2);
+ friend LIBSAMPLE_API bool operator==(const ByteArray &ba1, const char *ba2);
+ friend LIBSAMPLE_API bool operator==(const char *ba1, const ByteArray &ba2);
+ friend LIBSAMPLE_API bool operator!=(const ByteArray &ba1, const char *ba2);
+ friend LIBSAMPLE_API bool operator!=(const char *ba1, const ByteArray &ba2);
+
+ friend LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, const ByteArray &ba2);
+ friend LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, const char *ba2);
+ friend LIBSAMPLE_API ByteArray operator+(const char *ba1, const ByteArray &ba2);
+ friend LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, char ba2);
+ friend LIBSAMPLE_API ByteArray operator+(char ba1, const ByteArray &ba2);
};
-LIBSAMPLE_API bool operator==(const ByteArray& ba1, const char* ba2);
-LIBSAMPLE_API bool operator==(const char* ba1, const ByteArray& ba2);
-LIBSAMPLE_API bool operator!=(const ByteArray& ba1, const char* ba2);
-LIBSAMPLE_API bool operator!=(const char* ba1, const ByteArray& ba2);
+LIBSAMPLE_API bool operator==(const ByteArray &ba1, const char *ba2);
+LIBSAMPLE_API bool operator==(const char *ba1, const ByteArray &ba2);
+LIBSAMPLE_API bool operator!=(const ByteArray &ba1, const char *ba2);
+LIBSAMPLE_API bool operator!=(const char *ba1, const ByteArray &ba2);
-LIBSAMPLE_API ByteArray operator+(const ByteArray& ba1, const ByteArray& ba2);
-LIBSAMPLE_API ByteArray operator+(const ByteArray& ba1, const char* ba2);
-LIBSAMPLE_API ByteArray operator+(const char* ba1, const ByteArray& ba2);
-LIBSAMPLE_API ByteArray operator+(const ByteArray& ba1, char ba2);
-LIBSAMPLE_API ByteArray operator+(char ba1, const ByteArray& ba2);
+LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, const ByteArray &ba2);
+LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, const char *ba2);
+LIBSAMPLE_API ByteArray operator+(const char *ba1, const ByteArray &ba2);
+LIBSAMPLE_API ByteArray operator+(const ByteArray &ba1, char ba2);
+LIBSAMPLE_API ByteArray operator+(char ba1, const ByteArray &ba2);
#endif // BYTEARRAY_H
diff --git a/sources/shiboken6/tests/libsample/collector.cpp b/sources/shiboken6/tests/libsample/collector.cpp
index 2adff6628..579239bcb 100644
--- a/sources/shiboken6/tests/libsample/collector.cpp
+++ b/sources/shiboken6/tests/libsample/collector.cpp
@@ -8,13 +8,13 @@ void Collector::clear()
m_items.clear();
}
-Collector& Collector::operator<<(ObjectType::Identifier item)
+Collector &Collector::operator<<(ObjectType::Identifier item)
{
m_items.push_back(item);
return *this;
}
-Collector& Collector::operator<<(const ObjectType *obj)
+Collector &Collector::operator<<(const ObjectType *obj)
{
m_items.push_back(obj->identifier());
return *this;
@@ -25,9 +25,9 @@ std::list<ObjectType::Identifier> Collector::items()
return m_items;
}
-int Collector::size()
+int Collector::size() const
{
- return (int) m_items.size();
+ return int(m_items.size());
}
Collector &operator<<(Collector &s, const IntWrapper &w)
diff --git a/sources/shiboken6/tests/libsample/collector.h b/sources/shiboken6/tests/libsample/collector.h
index 1ef3281e5..26766847a 100644
--- a/sources/shiboken6/tests/libsample/collector.h
+++ b/sources/shiboken6/tests/libsample/collector.h
@@ -4,36 +4,34 @@
#ifndef COLLECTOR_H
#define COLLECTOR_H
-#include <list>
#include "libsamplemacros.h"
-
#include "intwrapper.h"
#include "objecttype.h"
+#include <list>
+
class LIBSAMPLE_API Collector
{
public:
- Collector() {}
- virtual ~Collector() {}
+ Collector() noexcept = default;
+ virtual ~Collector() = default;
+ LIBMINIMAL_DISABLE_COPY_MOVE(Collector)
void clear();
- Collector& operator<<(ObjectType::Identifier item);
+ Collector &operator<<(ObjectType::Identifier item);
- Collector& operator<<(const ObjectType *);
+ Collector &operator<<(const ObjectType *);
std::list<ObjectType::Identifier> items();
- int size();
+ int size() const;
private:
std::list<ObjectType::Identifier> m_items;
-
- Collector(const Collector&);
- Collector& operator=(const Collector&);
};
/* Helper for testing external operators */
-LIBSAMPLE_API Collector &operator<<(Collector&, const IntWrapper&);
+LIBSAMPLE_API Collector &operator<<(Collector &, const IntWrapper &);
#endif // COLLECTOR_H
diff --git a/sources/shiboken6/tests/libsample/complex.cpp b/sources/shiboken6/tests/libsample/complex.cpp
index ce2c2b7de..e3bec9aae 100644
--- a/sources/shiboken6/tests/libsample/complex.cpp
+++ b/sources/shiboken6/tests/libsample/complex.cpp
@@ -1,18 +1,16 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
#include "complex.h"
-using namespace std;
+#include <iostream>
-Complex::Complex(double real, double imag)
+Complex::Complex(double real, double imag) noexcept
: m_real(real), m_imag(imag)
{
}
-Complex
-Complex::operator+(Complex& other)
+Complex Complex::operator+(const Complex &other)
{
Complex result;
result.setReal(m_real + other.real());
@@ -20,10 +18,7 @@ Complex::operator+(Complex& other)
return result;
}
-void
-Complex::show()
+void Complex::show() const
{
- cout << "(real: " << m_real << ", imag: " << m_imag << ")";
+ std::cout << "(real: " << m_real << ", imag: " << m_imag << ")";
}
-
-
diff --git a/sources/shiboken6/tests/libsample/complex.h b/sources/shiboken6/tests/libsample/complex.h
index 54fb99ed1..168fe5c44 100644
--- a/sources/shiboken6/tests/libsample/complex.h
+++ b/sources/shiboken6/tests/libsample/complex.h
@@ -9,17 +9,19 @@
class LIBSAMPLE_API Complex
{
public:
- Complex(double real = 0.0, double imag = 0.0);
- ~Complex() {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Complex)
+
+ explicit Complex(double real = 0.0, double imag = 0.0) noexcept;
+ ~Complex() = default;
inline double real() const { return m_real; }
inline void setReal(double real) { m_real = real; }
inline double imag() const { return m_imag; }
inline void setImaginary(double imag) { m_imag = imag; }
- Complex operator+(Complex& other);
+ Complex operator+(const Complex &other);
- void show();
+ void show() const;
private:
double m_real;
diff --git a/sources/shiboken6/tests/libsample/ctorconvrule.h b/sources/shiboken6/tests/libsample/ctorconvrule.h
index cd7d1c669..a5411b749 100644
--- a/sources/shiboken6/tests/libsample/ctorconvrule.h
+++ b/sources/shiboken6/tests/libsample/ctorconvrule.h
@@ -9,8 +9,10 @@
class CtorConvRule
{
public:
- explicit CtorConvRule(long value) : m_value(value) {}
- virtual ~CtorConvRule() {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(CtorConvRule)
+
+ explicit CtorConvRule(long value) noexcept : m_value(value) {}
+ virtual ~CtorConvRule() = default;
virtual void dummyVirtualMethod() {}
long value() { return m_value; }
private:
diff --git a/sources/shiboken6/tests/libsample/cvlist.h b/sources/shiboken6/tests/libsample/cvlist.h
index eb635c83b..e09c7d943 100644
--- a/sources/shiboken6/tests/libsample/cvlist.h
+++ b/sources/shiboken6/tests/libsample/cvlist.h
@@ -12,7 +12,7 @@ class CVValueType
CVValueType();
};
-typedef std::list<const CVValueType*> const_ptr_value_list;
+using const_ptr_value_list = std::list<const CVValueType*>;
// This tests binding generation for a container of a const value type. The
// class doesn't need to do anything; this is just to verify that the generated
@@ -21,8 +21,8 @@ typedef std::list<const CVValueType*> const_ptr_value_list;
class CVListUser
{
public:
- static const_ptr_value_list produce() { return const_ptr_value_list(); }
- static void consume(const const_ptr_value_list& l) { (void)l; }
+ static const_ptr_value_list produce() { return {}; }
+ static void consume(const const_ptr_value_list &l) { (void)l; }
};
#endif // LIST_H
diff --git a/sources/shiboken6/tests/libsample/derived.cpp b/sources/shiboken6/tests/libsample/derived.cpp
index 87a8669ff..d20880431 100644
--- a/sources/shiboken6/tests/libsample/derived.cpp
+++ b/sources/shiboken6/tests/libsample/derived.cpp
@@ -1,44 +1,36 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
#include "derived.h"
-using namespace std;
+#include <iostream>
-Derived::Derived(int id) : Abstract(id)
+Derived::Derived(int id) noexcept : Abstract(id)
{
}
-Derived::~Derived()
-{
-}
+Derived::~Derived() = default;
-Abstract*
-Derived::createObject()
+Abstract *Derived::createObject()
{
static int id = 100;
return new Derived(id++);
}
-void
-Derived::pureVirtual()
+void Derived::pureVirtual()
{
}
-void*
-Derived::pureVirtualReturningVoidPtr()
+void *Derived::pureVirtualReturningVoidPtr()
{
return nullptr;
}
-void
-Derived::unpureVirtual()
+void Derived::unpureVirtual()
{
}
-bool
-Derived::singleArgument(bool b)
+bool Derived::singleArgument(bool b)
{
return !b;
}
@@ -70,15 +62,15 @@ Derived::OtherOverloadedFuncEnum Derived::otherOverloaded(int, double)
}
struct SecretClass : public Abstract {
- virtual void pureVirtual() {}
- virtual void *pureVirtualReturningVoidPtr() { return nullptr; }
- virtual PrintFormat returnAnEnum() { return Short; }
- void hideFunction(HideType*){};
+ void pureVirtual() override {}
+ void *pureVirtualReturningVoidPtr() override { return nullptr; }
+ PrintFormat returnAnEnum() override { return Short; }
+ void hideFunction(HideType*) override {};
private:
- virtual void pureVirtualPrivate() {}
+ void pureVirtualPrivate() override {}
};
-Abstract* Derived::triggerImpossibleTypeDiscovery()
+Abstract *Derived::triggerImpossibleTypeDiscovery()
{
return new SecretClass;
}
@@ -86,7 +78,7 @@ Abstract* Derived::triggerImpossibleTypeDiscovery()
struct AnotherSecretClass : public Derived {
};
-Abstract* Derived::triggerAnotherImpossibleTypeDiscovery()
+Abstract *Derived::triggerAnotherImpossibleTypeDiscovery()
{
return new AnotherSecretClass;
}
diff --git a/sources/shiboken6/tests/libsample/derived.h b/sources/shiboken6/tests/libsample/derived.h
index 35673198b..cf95cb601 100644
--- a/sources/shiboken6/tests/libsample/derived.h
+++ b/sources/shiboken6/tests/libsample/derived.h
@@ -15,6 +15,8 @@ enum OverloadedFuncEnum {
class LIBSAMPLE_API Derived : public Abstract
{
public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Derived)
+
enum OtherOverloadedFuncEnum {
OtherOverloadedFunc_iibd,
OtherOverloadedFunc_id
@@ -23,21 +25,21 @@ public:
class SomeInnerClass {
public:
void uselessMethod() {}
- SomeInnerClass operator+(const SomeInnerClass& other) { return other; }
- bool operator==(const SomeInnerClass &) { return true; }
+ SomeInnerClass operator+(const SomeInnerClass &other) { return other; }
+ bool operator==(const SomeInnerClass &) const { return true; }
};
- Derived(int id = -1);
+ explicit Derived(int id = -1) noexcept;
~Derived() override;
void pureVirtual() override;
- void* pureVirtualReturningVoidPtr() override;
+ void *pureVirtualReturningVoidPtr() override;
void unpureVirtual() override;
PrintFormat returnAnEnum() override { return Short; }
Type type() const override { return TpDerived; }
// factory method
- static Abstract* createObject();
+ static Abstract *createObject();
// single argument
bool singleArgument(bool b);
@@ -53,15 +55,15 @@ public:
OtherOverloadedFuncEnum otherOverloaded(int a, int b, bool c, double d);
OtherOverloadedFuncEnum otherOverloaded(int a, double b);
- inline SomeInnerClass returnMyParameter(const SomeInnerClass& s) { return s; }
+ inline SomeInnerClass returnMyParameter(const SomeInnerClass &s) { return s; }
- static Abstract* triggerImpossibleTypeDiscovery();
- static Abstract* triggerAnotherImpossibleTypeDiscovery();
+ static Abstract *triggerImpossibleTypeDiscovery();
+ static Abstract *triggerAnotherImpossibleTypeDiscovery();
void hideFunction(HideType*) override {}
protected:
- const char* getClassName() { return className(); }
- virtual const char* className() override { return "Derived"; }
+ const char *getClassName() { return className(); }
+ virtual const char *className() const override { return "Derived"; }
private:
void pureVirtualPrivate() override;
diff --git a/sources/shiboken6/tests/libsample/echo.h b/sources/shiboken6/tests/libsample/echo.h
index 54db3e9bd..01b11a4a6 100644
--- a/sources/shiboken6/tests/libsample/echo.h
+++ b/sources/shiboken6/tests/libsample/echo.h
@@ -12,19 +12,21 @@ class ObjectType;
class Echo
{
public:
- Echo(){}
- ~Echo(){}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Echo)
+
+ Echo() noexcept = default;
+ ~Echo() = default;
void doNothingWithConstBool(const bool hi);
- void methodWithNamedArg(const Str& string = Str(""));
+ void methodWithNamedArg(const Str &string = Str{});
- Str operator()(const Str& s, const int i) { return s + i; }
+ Str operator()(const Str &s, const int i) { return s + i; }
// These method are here just for compilation test purposes
- Echo& operator<<(unsigned int item);
- Echo& operator<<(signed int item);
- Echo& operator<<(const ObjectType *item);
- Echo& operator<<(Str str);
+ Echo &operator<<(unsigned int item);
+ Echo &operator<<(signed int item);
+ Echo &operator<<(const ObjectType *item);
+ Echo &operator<<(Str str);
};
inline void Echo::doNothingWithConstBool(const bool)
diff --git a/sources/shiboken6/tests/libsample/expression.cpp b/sources/shiboken6/tests/libsample/expression.cpp
index 21a51a288..6f3c5fdc5 100644
--- a/sources/shiboken6/tests/libsample/expression.cpp
+++ b/sources/shiboken6/tests/libsample/expression.cpp
@@ -3,112 +3,77 @@
#include "expression.h"
-#include <sstream>
-
-Expression::Expression() : m_value(0), m_operation(None), m_operand1(nullptr), m_operand2(nullptr)
-{
-}
-
-Expression::Expression(int number) : m_value(number), m_operation(None), m_operand1(nullptr), m_operand2(nullptr)
-{
-}
-Expression::Expression(const Expression& other)
-{
- m_operand1 = other.m_operand1 ? new Expression(*other.m_operand1) : nullptr;
- m_operand2 = other.m_operand2 ? new Expression(*other.m_operand2) : nullptr;
- m_value = other.m_value;
- m_operation = other.m_operation;
-}
+#include <sstream>
-Expression& Expression::operator=(const Expression& other)
-{
- if (&other == this)
- return *this;
- delete m_operand1;
- delete m_operand2;
- m_operand1 = other.m_operand1 ? new Expression(*other.m_operand1) : nullptr;
- m_operand2 = other.m_operand2 ? new Expression(*other.m_operand2) : nullptr;
- m_operation = other.m_operation;
- m_value = other.m_value;
- return *this;
-}
+Expression::Expression() noexcept = default;
-Expression::~Expression()
+Expression::Expression(int number) noexcept : m_value(number)
{
- delete m_operand1;
- delete m_operand2;
}
-Expression Expression::operator+(const Expression& other)
+Expression Expression::operator+(const Expression &other)
{
Expression expr;
expr.m_operation = Add;
- expr.m_operand1 = new Expression(*this);
- expr.m_operand2 = new Expression(other);
+ expr.m_operand1 = std::make_shared<Expression>(*this);
+ expr.m_operand2 = std::make_shared<Expression>(other);
return expr;
}
-Expression Expression::operator-(const Expression& other)
+Expression Expression::operator-(const Expression &other)
{
Expression expr;
expr.m_operation = Add;
- expr.m_operand1 = new Expression(*this);
- expr.m_operand2 = new Expression(other);
+ expr.m_operand1 = std::make_shared<Expression>(*this);
+ expr.m_operand2 = std::make_shared<Expression>(other);
return expr;
}
-Expression Expression::operator<(const Expression& other)
+Expression Expression::operator<(const Expression &other)
{
Expression expr;
expr.m_operation = LessThan;
- expr.m_operand1 = new Expression(*this);
- expr.m_operand2 = new Expression(other);
+ expr.m_operand1 = std::make_shared<Expression>(*this);
+ expr.m_operand2 = std::make_shared<Expression>(other);
return expr;
}
-Expression Expression::operator>(const Expression& other)
+Expression Expression::operator>(const Expression &other)
{
Expression expr;
expr.m_operation = GreaterThan;
- expr.m_operand1 = new Expression(*this);
- expr.m_operand2 = new Expression(other);
+ expr.m_operand1 = std::make_shared<Expression>(*this);
+ expr.m_operand2 = std::make_shared<Expression>(other);
return expr;
}
std::string Expression::toString() const
{
+ std::ostringstream s;
if (m_operation == None) {
- std::ostringstream s;
s << m_value;
return s.str();
}
- std::string result;
- result += '(';
- result += m_operand1->toString();
- char op;
+ s << '(' << m_operand1->toString();
switch (m_operation) {
case Add:
- op = '+';
+ s << '+';
break;
case Sub:
- op = '-';
+ s << '-';
break;
case LessThan:
- op = '<';
+ s << '<';
break;
case GreaterThan:
- op = '<';
+ s << '<';
break;
- case None: // just to avoid the compiler warning
default:
- op = '?';
+ s << '?';
break;
}
- result += op;
- result += m_operand2->toString();
- result += ')';
- return result;
+ s << m_operand2->toString() << ')';
+ return s.str();
}
-
diff --git a/sources/shiboken6/tests/libsample/expression.h b/sources/shiboken6/tests/libsample/expression.h
index cf41cb620..e7c5b7306 100644
--- a/sources/shiboken6/tests/libsample/expression.h
+++ b/sources/shiboken6/tests/libsample/expression.h
@@ -6,34 +6,35 @@
#define EXPRESSION_H
#include "libsamplemacros.h"
+
+#include <memory>
#include <string>
class LIBSAMPLE_API Expression
{
public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Expression)
+
enum Operation {
None, Add, Sub, LessThan, GreaterThan
};
- Expression(int number);
- Expression(const Expression& other);
- Expression& operator=(const Expression& other);
-
- ~Expression();
+ explicit Expression(int number) noexcept;
+ ~Expression() = default;
- Expression operator>(const Expression& other);
- Expression operator<(const Expression& other);
- Expression operator+(const Expression& other);
- Expression operator-(const Expression& other);
+ Expression operator>(const Expression &other);
+ Expression operator<(const Expression &other);
+ Expression operator+(const Expression &other);
+ Expression operator-(const Expression &other);
std::string toString() const;
private:
- int m_value;
- Operation m_operation;
- Expression* m_operand1;
- Expression* m_operand2;
+ int m_value = 0;
+ Operation m_operation = None;
+ std::shared_ptr<Expression> m_operand1;
+ std::shared_ptr<Expression> m_operand2;
- Expression();
+ Expression() noexcept;
};
#endif // EXPRESSION_H
diff --git a/sources/shiboken6/tests/libsample/filter.cpp b/sources/shiboken6/tests/libsample/filter.cpp
index 09c8c89ed..950847985 100644
--- a/sources/shiboken6/tests/libsample/filter.cpp
+++ b/sources/shiboken6/tests/libsample/filter.cpp
@@ -1,34 +1,34 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <string>
#include "filter.h"
+
Data::Data(Field field, std::string value)
: m_field(field), m_value(value)
{
}
-Union::Union(const Data& filter)
+Union::Union(const Data &filter)
{
m_filters.push_back(filter);
}
-Union::Union(const Intersection& filter)
+Union::Union(const Intersection &filter)
{
m_filters.push_back(filter);
}
-Intersection::Intersection(const Data& filter)
+Intersection::Intersection(const Data &filter)
{
m_filters.push_back(filter);
}
-Intersection::Intersection(const Union& filter)
+Intersection::Intersection(const Union &filter)
{
m_filters.push_back(filter);
}
-Intersection operator&(const Intersection& a, const Intersection& b)
+Intersection operator&(const Intersection &a, const Intersection &b)
{
Intersection filter;
filter.addFilter(a);
diff --git a/sources/shiboken6/tests/libsample/filter.h b/sources/shiboken6/tests/libsample/filter.h
index d778342ff..d82d38eb8 100644
--- a/sources/shiboken6/tests/libsample/filter.h
+++ b/sources/shiboken6/tests/libsample/filter.h
@@ -4,11 +4,11 @@
#ifndef FILTER_H
#define FILTER_H
+#include "libsamplemacros.h"
+
#include <string>
#include <list>
-#include "libsamplemacros.h"
-
class Intersection;
class LIBSAMPLE_API Filter
@@ -17,7 +17,6 @@ class LIBSAMPLE_API Filter
class LIBSAMPLE_API Data : public Filter
{
-
public:
enum Field {
Name,
@@ -25,7 +24,7 @@ public:
Year
};
- Data(Field field, std::string value);
+ explicit Data(Field field, std::string value);
Field field() const { return m_field; }
std::string value() const { return m_value; }
@@ -39,12 +38,12 @@ class LIBSAMPLE_API Union : public Filter
{
public:
- Union(const Data&);
- Union(const Intersection&);
+ Union(const Data &);
+ Union(const Intersection &);
Union() = default;
std::list<Filter> filters() const { return m_filters; }
- void addFilter(const Filter& data) { m_filters.push_back(data); }
+ void addFilter(const Filter &data) { m_filters.push_back(data); }
private:
std::list<Filter> m_filters;
@@ -53,19 +52,18 @@ private:
class LIBSAMPLE_API Intersection : public Filter
{
public:
-
- Intersection(const Data&);
- Intersection(const Union&);
+ Intersection(const Data &);
+ Intersection(const Union &);
Intersection() = default;
std::list<Filter> filters() const { return m_filters; }
- void addFilter(const Filter& data) { m_filters.push_back(data); }
+ void addFilter(const Filter &data) { m_filters.push_back(data); }
private:
std::list<Filter> m_filters;
};
-LIBSAMPLE_API Intersection operator&(const Intersection& a, const Intersection& b);
+LIBSAMPLE_API Intersection operator&(const Intersection &a, const Intersection &b);
#endif // FILTER_H
diff --git a/sources/shiboken6/tests/libsample/functions.cpp b/sources/shiboken6/tests/libsample/functions.cpp
index d96a58abd..ad2f4dd5a 100644
--- a/sources/shiboken6/tests/libsample/functions.cpp
+++ b/sources/shiboken6/tests/libsample/functions.cpp
@@ -2,37 +2,33 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "functions.h"
-#include <string.h>
+#include "polygon.h"
+
+#include <cstring>
#include <algorithm>
#include <iostream>
#include <numeric>
-using namespace std;
-
-void
-printSomething()
+void printSomething()
{
- cout << __FUNCTION__ << endl;
+ std::cout << __FUNCTION__ << std::endl;
}
-int
-gimmeInt()
+int gimmeInt()
{
static int val = 2;
val = val * 1.3;
return val;
}
-double
-gimmeDouble()
+double gimmeDouble()
{
static double val = 7.77;
val = val * 1.3;
return val;
}
-std::list<Complex>
-gimmeComplexList()
+std::list<Complex> gimmeComplexList()
{
std::list<Complex> lst;
lst.push_back(Complex());
@@ -41,39 +37,29 @@ gimmeComplexList()
return lst;
}
-Complex
-sumComplexPair(std::pair<Complex, Complex> cpx_pair)
+Complex sumComplexPair(std::pair<Complex, Complex> cpx_pair)
{
return cpx_pair.first + cpx_pair.second;
}
-double
-multiplyPair(std::pair<double, double> pair)
+double multiplyPair(std::pair<double, double> pair)
{
return pair.first * pair.second;
}
-int
-countCharacters(const char* text)
+int countCharacters(const char *text)
{
- if (!text)
- return -1;
- int count;
- for(count = 0; text[count] != '\0'; count++)
- ;
- return count;
+ return text != nullptr ? int(std::strlen(text)) : -1;
}
-char*
-makeCString()
+char *makeCString()
{
- char* string = new char[strlen(__FUNCTION__) + 1];
- strcpy(string, __FUNCTION__);
+ char *string = new char[std::strlen(__FUNCTION__) + 1];
+ std::strcpy(string, __FUNCTION__);
return string;
}
-const char*
-returnCString()
+const char *returnCString()
{
return __FUNCTION__;
}
@@ -88,86 +74,77 @@ GlobalOverloadFuncEnum overloadedFunc(double)
return GlobalOverloadFunc_d;
}
-char*
-returnNullPrimitivePointer()
+char *returnNullPrimitivePointer()
{
return nullptr;
}
-ObjectType*
-returnNullObjectTypePointer()
+ObjectType *returnNullObjectTypePointer()
{
return nullptr;
}
-Event*
-returnNullValueTypePointer()
+Event *returnNullValueTypePointer()
{
return nullptr;
}
-unsigned int
-doubleUnsignedInt(unsigned int value)
+unsigned int doubleUnsignedInt(unsigned int value)
{
return value * 2;
}
-long long
-doubleLongLong(long long value)
+long long doubleLongLong(long long value)
{
return value * 2;
}
-unsigned long long
-doubleUnsignedLongLong(unsigned long long value)
+unsigned long long doubleUnsignedLongLong(unsigned long long value)
{
return value * 2;
}
-short
-doubleShort(short value)
+short doubleShort(short value)
{
return value * 2;
}
-int
-acceptInt(int x)
+int acceptInt(int x)
{
return x;
}
-unsigned int
-acceptUInt(unsigned int x)
+const int *acceptIntReturnPtr(int x)
+{
+ return new int(x);
+}
+
+unsigned int acceptUInt(unsigned int x)
{
return x;
}
-long
-acceptLong(long x)
+long acceptLong(long x)
{
return x;
}
-unsigned long
-acceptULong(unsigned long x)
+unsigned long acceptULong(unsigned long x)
{
return x;
}
-double
-acceptDouble(double x)
+double acceptDouble(double x)
{
return x;
}
-int
-acceptIntReference(int& x)
+int acceptIntReference(int &x)
{
return x;
}
-OddBool
-acceptOddBoolReference(OddBool& x)
+OddBool acceptOddBoolReference(OddBool &x)
{
return x;
}
@@ -202,9 +179,7 @@ double sumDoubleMatrix(double m[2][3])
return result;
}
-ArrayModifyTest::ArrayModifyTest()
-{
-}
+ArrayModifyTest::ArrayModifyTest() = default;
int ArrayModifyTest::sumIntArray(int n, int *array)
{
@@ -227,7 +202,7 @@ void ClassWithFunctionPointer::doNothing(void *operand)
(void) operand;
}
-string addStdStrings(const std::string &s1, const std::string &s2)
+std::string addStdStrings(const std::string &s1, const std::string &s2)
{
return s1 + s2;
}
@@ -239,5 +214,19 @@ std::wstring addStdWStrings(const std::wstring &s1, const std::wstring &s2)
void testNullPtrT(std::nullptr_t)
{
- cout << __FUNCTION__ << '\n';
+ std::cout << __FUNCTION__ << '\n';
+}
+
+int takePolygon(Polygon &&p)
+{
+ auto p2 = std::move(p);
+ std::cout << __FUNCTION__ << ' ' << p2.points().size() << " points\n";
+ return int(p2.points().size());
+}
+
+int takeObjectType(ObjectType &&o)
+{
+ auto o2 = std::move(o);
+ std::cout << __FUNCTION__ << ' ' << o2.objectName().cstring() << '\n';
+ return o2.objectName().size();
}
diff --git a/sources/shiboken6/tests/libsample/functions.h b/sources/shiboken6/tests/libsample/functions.h
index 7492ec4c2..b745aed6b 100644
--- a/sources/shiboken6/tests/libsample/functions.h
+++ b/sources/shiboken6/tests/libsample/functions.h
@@ -5,12 +5,15 @@
#define FUNCTIONS_H
#include "libsamplemacros.h"
-#include <list>
-#include <utility>
#include "oddbool.h"
#include "complex.h"
#include "objecttype.h"
+#include <list>
+#include <utility>
+
+class Polygon;
+
enum GlobalEnum {
NoThing,
FirstThing,
@@ -30,13 +33,13 @@ LIBSAMPLE_API double multiplyPair(std::pair<double, double> pair);
LIBSAMPLE_API std::list<Complex> gimmeComplexList();
LIBSAMPLE_API Complex sumComplexPair(std::pair<Complex, Complex> cpx_pair);
-LIBSAMPLE_API int countCharacters(const char* text);
-LIBSAMPLE_API char* makeCString();
-LIBSAMPLE_API const char* returnCString();
+LIBSAMPLE_API int countCharacters(const char *text);
+LIBSAMPLE_API char *makeCString();
+LIBSAMPLE_API const char *returnCString();
-LIBSAMPLE_API char* returnNullPrimitivePointer();
-LIBSAMPLE_API ObjectType* returnNullObjectTypePointer();
-LIBSAMPLE_API Event* returnNullValueTypePointer();
+LIBSAMPLE_API char *returnNullPrimitivePointer();
+LIBSAMPLE_API ObjectType *returnNullObjectTypePointer();
+LIBSAMPLE_API Event *returnNullValueTypePointer();
// Tests overloading on functions (!methods)
LIBSAMPLE_API GlobalOverloadFuncEnum overloadedFunc(int val);
@@ -48,13 +51,14 @@ LIBSAMPLE_API unsigned long long doubleUnsignedLongLong(unsigned long long value
LIBSAMPLE_API short doubleShort(short value);
LIBSAMPLE_API int acceptInt(int x);
+LIBSAMPLE_API const int *acceptIntReturnPtr(int x);
LIBSAMPLE_API unsigned int acceptUInt(unsigned int x);
LIBSAMPLE_API long acceptLong(long x);
LIBSAMPLE_API unsigned long acceptULong(unsigned long x);
LIBSAMPLE_API double acceptDouble(double x);
-LIBSAMPLE_API int acceptIntReference(int& x);
-LIBSAMPLE_API OddBool acceptOddBoolReference(OddBool& x);
+LIBSAMPLE_API int acceptIntReference(int &x);
+LIBSAMPLE_API OddBool acceptOddBoolReference(OddBool &x);
LIBSAMPLE_API int sumIntArray(int array[4]);
LIBSAMPLE_API double sumDoubleArray(double array[4]);
@@ -66,6 +70,9 @@ LIBSAMPLE_API std::wstring addStdWStrings(const std::wstring &s1, const std::wst
LIBSAMPLE_API void testNullPtrT(std::nullptr_t);
+LIBSAMPLE_API int takePolygon(Polygon &&p);
+LIBSAMPLE_API int takeObjectType(ObjectType &&o);
+
class LIBSAMPLE_API ArrayModifyTest
{
public:
diff --git a/sources/shiboken6/tests/libsample/handle.cpp b/sources/shiboken6/tests/libsample/handle.cpp
index e92c24c89..93c2abe47 100644
--- a/sources/shiboken6/tests/libsample/handle.cpp
+++ b/sources/shiboken6/tests/libsample/handle.cpp
@@ -3,17 +3,17 @@
#include "handle.h"
-HANDLE HandleHolder::createHandle()
+SAMPLE_HANDLE HandleHolder::createHandle()
{
- return (HANDLE) new OBJ;
+ return (SAMPLE_HANDLE) new OBJ;
}
-bool HandleHolder::compare(HandleHolder* other)
+bool HandleHolder::compare(HandleHolder *other)
{
return other->m_handle == m_handle;
}
-bool HandleHolder::compare2(HandleHolder* other)
+bool HandleHolder::compare2(HandleHolder *other)
{
return other->m_handle2 == m_handle2;
}
diff --git a/sources/shiboken6/tests/libsample/handle.h b/sources/shiboken6/tests/libsample/handle.h
index 1ef80689d..07fc89d15 100644
--- a/sources/shiboken6/tests/libsample/handle.h
+++ b/sources/shiboken6/tests/libsample/handle.h
@@ -8,38 +8,38 @@
/* See http://bugs.pyside.org/show_bug.cgi?id=1105. */
namespace Foo {
- using HANDLE = unsigned long;
+ using SAMPLE_HANDLE = unsigned long;
}
class LIBSAMPLE_API OBJ
{
};
-using HANDLE = OBJ *;
+using SAMPLE_HANDLE = OBJ *;
class LIBSAMPLE_API HandleHolder
{
public:
- explicit HandleHolder(HANDLE ptr = nullptr) : m_handle(ptr) {}
- explicit HandleHolder(Foo::HANDLE val): m_handle2(val) {}
+ explicit HandleHolder(SAMPLE_HANDLE ptr = nullptr) : m_handle(ptr) {}
+ explicit HandleHolder(Foo::SAMPLE_HANDLE val): m_handle2(val) {}
- void set(HANDLE ptr);
- inline void set(const Foo::HANDLE& val) { m_handle2 = val; }
- inline HANDLE handle() { return m_handle; }
- inline Foo::HANDLE handle2() { return m_handle2; }
+ void set(SAMPLE_HANDLE ptr);
+ inline void set(const Foo::SAMPLE_HANDLE &val) { m_handle2 = val; }
+ inline SAMPLE_HANDLE handle() const { return m_handle; }
+ inline Foo::SAMPLE_HANDLE handle2() const { return m_handle2; }
- static HANDLE createHandle();
- bool compare(HandleHolder* other);
- bool compare2(HandleHolder* other);
+ static SAMPLE_HANDLE createHandle();
+ bool compare(HandleHolder *other);
+ bool compare2(HandleHolder *other);
private:
- HANDLE m_handle;
- Foo::HANDLE m_handle2;
+ SAMPLE_HANDLE m_handle = nullptr;
+ Foo::SAMPLE_HANDLE m_handle2 = 0;
};
-inline void HandleHolder::set(HANDLE)
+inline void HandleHolder::set(SAMPLE_HANDLE)
{
- HANDLE tmp = m_handle;
+ SAMPLE_HANDLE tmp = m_handle;
m_handle = tmp;
}
diff --git a/sources/shiboken6/tests/libsample/implicitconv.cpp b/sources/shiboken6/tests/libsample/implicitconv.cpp
index fad17e879..887fa6b1c 100644
--- a/sources/shiboken6/tests/libsample/implicitconv.cpp
+++ b/sources/shiboken6/tests/libsample/implicitconv.cpp
@@ -8,40 +8,32 @@ ImplicitConv::ImplicitConv(const Null &) :
{
}
-ImplicitConv
-ImplicitConv::implicitConvCommon(ImplicitConv implicit)
+ImplicitConv ImplicitConv::implicitConvCommon(ImplicitConv implicit)
{
return implicit;
}
-ImplicitConv
-ImplicitConv::implicitConvDefault(ImplicitConv implicit)
+ImplicitConv ImplicitConv::implicitConvDefault(ImplicitConv implicit)
{
return implicit;
}
-ImplicitConv::ICOverloadedFuncEnum
-ImplicitConv::implicitConvOverloading(ImplicitConv, int)
+ImplicitConv::ICOverloadedFuncEnum ImplicitConv::implicitConvOverloading(ImplicitConv, int)
{
return ImplicitConv::OverFunc_Ii;
}
-ImplicitConv::ICOverloadedFuncEnum
-ImplicitConv::implicitConvOverloading(ImplicitConv, bool)
+ImplicitConv::ICOverloadedFuncEnum ImplicitConv::implicitConvOverloading(ImplicitConv, bool)
{
return ImplicitConv::OverFunc_Ib;
}
-ImplicitConv::ICOverloadedFuncEnum
-ImplicitConv::implicitConvOverloading(int)
+ImplicitConv::ICOverloadedFuncEnum ImplicitConv::implicitConvOverloading(int)
{
return ImplicitConv::OverFunc_i;
}
-ImplicitConv::ICOverloadedFuncEnum
-ImplicitConv::implicitConvOverloading(CtorEnum)
+ImplicitConv::ICOverloadedFuncEnum ImplicitConv::implicitConvOverloading(CtorEnum)
{
return ImplicitConv::OverFunc_C;
}
-
-
diff --git a/sources/shiboken6/tests/libsample/implicitconv.h b/sources/shiboken6/tests/libsample/implicitconv.h
index bd390b15c..5d69eb487 100644
--- a/sources/shiboken6/tests/libsample/implicitconv.h
+++ b/sources/shiboken6/tests/libsample/implicitconv.h
@@ -12,6 +12,8 @@ class ObjectType;
class LIBSAMPLE_API ImplicitConv
{
public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ImplicitConv)
+
enum CtorEnum {
CtorNone,
CtorOne,
@@ -28,17 +30,17 @@ public:
OverFunc_C
};
- ImplicitConv() : m_ctorEnum(CtorNone), m_objId(-1), m_value(-1.0) {}
- ImplicitConv(int objId) : m_ctorEnum(CtorOne), m_objId(objId), m_value(-1.0) {}
- ImplicitConv(CtorEnum ctorEnum) : m_ctorEnum(ctorEnum), m_objId(-1), m_value(-1.0) {}
- ImplicitConv(ObjectType&) : m_ctorEnum(CtorObjectTypeReference), m_objId(-1), m_value(-1.0) {}
+ ImplicitConv() noexcept = default;
+ ImplicitConv(int objId) noexcept : m_ctorEnum(CtorOne), m_objId(objId) {}
+ ImplicitConv(CtorEnum ctorEnum) : m_ctorEnum(ctorEnum) {}
+ ImplicitConv(ObjectType&) : m_ctorEnum(CtorObjectTypeReference) {}
ImplicitConv(double value, bool=true) : m_ctorEnum(CtorNone), m_value(value) {}
ImplicitConv(const Null &null);
- ~ImplicitConv() {}
+ ~ImplicitConv() = default;
- inline CtorEnum ctorEnum() { return m_ctorEnum; }
- inline int objId() { return m_objId; }
- inline double value() { return m_value; }
+ inline CtorEnum ctorEnum() const { return m_ctorEnum; }
+ inline int objId() const { return m_objId; }
+ inline double value() const { return m_value; }
static ImplicitConv implicitConvCommon(ImplicitConv implicit);
@@ -50,9 +52,9 @@ public:
static ICOverloadedFuncEnum implicitConvOverloading(CtorEnum dummyArg);
private:
- CtorEnum m_ctorEnum;
- int m_objId;
- double m_value;
+ CtorEnum m_ctorEnum = CtorNone;
+ int m_objId = -1;
+ double m_value = -1.0;
};
#endif // IMPLICITCONV_H
diff --git a/sources/shiboken6/tests/libsample/injectcode.cpp b/sources/shiboken6/tests/libsample/injectcode.cpp
index 488f7faae..707d14ed8 100644
--- a/sources/shiboken6/tests/libsample/injectcode.cpp
+++ b/sources/shiboken6/tests/libsample/injectcode.cpp
@@ -2,20 +2,15 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "injectcode.h"
-#include <sstream>
-using namespace std;
+#include <sstream>
-InjectCode::InjectCode()
-{
-}
+InjectCode::InjectCode() noexcept = default;
-InjectCode::~InjectCode()
-{
-}
+InjectCode::~InjectCode() = default;
template<typename T>
-const char* InjectCode::toStr(const T& value)
+const char *InjectCode::toStr(const T &value)
{
std::ostringstream s;
s << value;
@@ -23,41 +18,41 @@ const char* InjectCode::toStr(const T& value)
return m_valueHolder.c_str();
}
-const char* InjectCode::simpleMethod1(int arg0, int arg1)
+const char *InjectCode::simpleMethod1(int arg0, int arg1)
{
return toStr(arg0 + arg1);
}
-const char* InjectCode::simpleMethod2()
+const char *InjectCode::simpleMethod2()
{
return "_";
}
-const char* InjectCode::simpleMethod3(int argc, char** argv)
+const char *InjectCode::simpleMethod3(int argc, char **argv)
{
for (int i = 0; i < argc; ++i)
m_valueHolder += argv[i];
return m_valueHolder.c_str();
}
-const char* InjectCode::overloadedMethod(int arg0, bool arg1)
+const char *InjectCode::overloadedMethod(int arg0, bool arg1)
{
toStr(arg0);
m_valueHolder += arg1 ? "true" : "false";
return m_valueHolder.c_str();
}
-const char* InjectCode::overloadedMethod(int arg0, double arg1)
+const char *InjectCode::overloadedMethod(int arg0, double arg1)
{
return toStr(arg0 + arg1);
}
-const char* InjectCode::overloadedMethod(int argc, char** argv)
+const char *InjectCode::overloadedMethod(int argc, char **argv)
{
return simpleMethod3(argc, argv);
}
-const char* InjectCode::virtualMethod(int arg)
+const char *InjectCode::virtualMethod(int arg)
{
return toStr(arg);
}
@@ -70,13 +65,13 @@ int InjectCode::arrayMethod(int count, int *values) const
return ret;
}
-int InjectCode::sumArrayAndLength(int* values) const
+int InjectCode::sumArrayAndLength(int *values) const
{
int sum = 0;
- while(*values) {
+ while (*values) {
sum = sum + *values + 1;
- values++;
+ ++values;
}
return sum;
diff --git a/sources/shiboken6/tests/libsample/injectcode.h b/sources/shiboken6/tests/libsample/injectcode.h
index 43a3e8468..74046dad5 100644
--- a/sources/shiboken6/tests/libsample/injectcode.h
+++ b/sources/shiboken6/tests/libsample/injectcode.h
@@ -5,27 +5,31 @@
#define INJECTCODE_H
#include "libsamplemacros.h"
+
#include <utility>
#include <string>
class LIBSAMPLE_API InjectCode
{
public:
- InjectCode();
+ LIBMINIMAL_DEFAULT_COPY_MOVE(InjectCode)
+
+ InjectCode() noexcept;
virtual ~InjectCode();
- const char* simpleMethod1(int arg0, int arg1);
- const char* simpleMethod2();
- const char* simpleMethod3(int argc, char** argv);
+ const char *simpleMethod1(int arg0, int arg1);
+ const char *simpleMethod2();
+ const char *simpleMethod3(int argc, char **argv);
- const char* overloadedMethod(int argc, char** argv);
- const char* overloadedMethod(int arg0, double arg1);
- const char* overloadedMethod(int arg0, bool arg1);
+ const char *overloadedMethod(int argc, char **argv);
+ const char *overloadedMethod(int arg0, double arg1);
+ const char *overloadedMethod(int arg0, bool arg1);
- virtual int arrayMethod(int count, int* values) const;
+ virtual int arrayMethod(int count, int *values) const;
inline int callArrayMethod(int count, int *values) const { return arrayMethod(count, values); }
- virtual const char* virtualMethod(int arg);
- int sumArrayAndLength(int* values) const;
+ virtual const char *virtualMethod(int arg);
+ int sumArrayAndLength(int *values) const;
+
private:
// This attr is just to retain the memory pointed by all return values,
// So, the memory returned by all methods will be valid until someone call
@@ -33,7 +37,7 @@ private:
std::string m_valueHolder;
template<typename T>
- const char* toStr(const T& value);
+ const char *toStr(const T &value);
};
#endif // INJECTCODE_H
diff --git a/sources/shiboken6/tests/libsample/list.h b/sources/shiboken6/tests/libsample/list.h
index 5b0eabb02..5e06d2a66 100644
--- a/sources/shiboken6/tests/libsample/list.h
+++ b/sources/shiboken6/tests/libsample/list.h
@@ -18,6 +18,8 @@ class List : public std::list<T>
class IntList : public List<int>
{
public:
+ LIBMINIMAL_DEFAULT_MOVE(IntList)
+
enum CtorEnum {
NoParamsCtor,
IntCtor,
@@ -25,14 +27,13 @@ public:
ListOfIntCtor
};
- inline IntList() : m_ctorUsed(NoParamsCtor) {}
+ inline IntList() noexcept : m_ctorUsed(NoParamsCtor) {}
inline explicit IntList(int val) : m_ctorUsed(IntCtor) { push_back(val); }
- inline IntList(const List<int>& lst) : List<int>(lst), m_ctorUsed(ListOfIntCtor) {}
+ inline IntList(const List<int> &lst) : List<int>(lst), m_ctorUsed(ListOfIntCtor) {}
+ ~IntList() = default;
- inline IntList(const IntList& lst) : List<int>(lst), m_ctorUsed(CopyCtor) {}
- IntList(IntList &&) = default;
+ inline IntList(const IntList &lst) : List<int>(lst), m_ctorUsed(CopyCtor) {}
IntList &operator=(const IntList &) = default;
- IntList &operator=(IntList &&) = default;
inline void append(int v) { insert(end(), v); }
CtorEnum constructorUsed() { return m_ctorUsed; }
@@ -43,6 +44,8 @@ private:
class PointValueList : public List<Point>
{
public:
+ LIBMINIMAL_DEFAULT_MOVE(PointValueList)
+
enum CtorEnum {
NoParamsCtor,
PointCtor,
@@ -50,14 +53,13 @@ public:
ListOfPointValuesCtor
};
- inline PointValueList() : m_ctorUsed(NoParamsCtor) {}
+ inline PointValueList() noexcept : m_ctorUsed(NoParamsCtor) {}
inline explicit PointValueList(Point val) : m_ctorUsed(PointCtor) { push_back(val); }
- inline PointValueList(const List<Point>& lst) : List<Point>(lst), m_ctorUsed(ListOfPointValuesCtor) {}
+ inline PointValueList(const List<Point> &lst) : List<Point>(lst), m_ctorUsed(ListOfPointValuesCtor) {}
- inline PointValueList(const PointValueList& lst) : List<Point>(lst), m_ctorUsed(CopyCtor) {}
- PointValueList(PointValueList &&) = default;
+ inline PointValueList(const PointValueList &lst) : List<Point>(lst), m_ctorUsed(CopyCtor) {}
PointValueList &operator=(const PointValueList &) = default;
- PointValueList &operator=(PointValueList &&) = default;
+ ~PointValueList() = default;
inline void append(Point v) { insert(end(), v); }
CtorEnum constructorUsed() { return m_ctorUsed; }
@@ -68,6 +70,8 @@ private:
class ObjectTypePtrList : public List<ObjectType*>
{
public:
+ LIBMINIMAL_DEFAULT_MOVE(ObjectTypePtrList)
+
enum CtorEnum {
NoParamsCtor,
ObjectTypeCtor,
@@ -75,19 +79,21 @@ public:
ListOfObjectTypePtrCtor
};
- inline ObjectTypePtrList() : m_ctorUsed(NoParamsCtor) {}
- inline explicit ObjectTypePtrList(ObjectType* val) : m_ctorUsed(ObjectTypeCtor) { push_back(val); }
- inline ObjectTypePtrList(const List<ObjectType*>& lst) : List<ObjectType*>(lst), m_ctorUsed(ListOfObjectTypePtrCtor) {}
+ inline ObjectTypePtrList() = default;
+ inline ObjectTypePtrList(const ObjectTypePtrList &lst) :
+ List<ObjectType*>(lst), m_ctorUsed(CopyCtor) {}
+ inline explicit ObjectTypePtrList(ObjectType *val) :
+ m_ctorUsed(ObjectTypeCtor) { push_back(val); }
+ inline ObjectTypePtrList(const List<ObjectType*> &lst) :
+ List<ObjectType*>(lst), m_ctorUsed(ListOfObjectTypePtrCtor) {}
+ ~ObjectTypePtrList() = default;
- inline ObjectTypePtrList(const ObjectTypePtrList& lst) : List<ObjectType*>(lst), m_ctorUsed(CopyCtor) {}
- ObjectTypePtrList(ObjectTypePtrList &&) = default;
ObjectTypePtrList &operator=(const ObjectTypePtrList &) = default;
- ObjectTypePtrList &operator=(ObjectTypePtrList &&) = default;
- inline void append(ObjectType* v) { insert(end(), v); }
+ inline void append(ObjectType *v) { insert(end(), v); }
CtorEnum constructorUsed() { return m_ctorUsed; }
private:
- CtorEnum m_ctorUsed;
+ CtorEnum m_ctorUsed = NoParamsCtor;
};
#endif // LIST_H
diff --git a/sources/shiboken6/tests/libsample/listuser.cpp b/sources/shiboken6/tests/libsample/listuser.cpp
index 6801bfdf3..9bb7f7798 100644
--- a/sources/shiboken6/tests/libsample/listuser.cpp
+++ b/sources/shiboken6/tests/libsample/listuser.cpp
@@ -1,27 +1,24 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <numeric>
-#include <cstdlib>
#include "listuser.h"
-using namespace std;
+#include <numeric>
+#include <cstdlib>
-std::list<int>
-ListUser::callCreateList()
+std::list<int> ListUser::callCreateList()
{
return createList();
}
ListUser::ListUser() = default;
ListUser::ListUser(const ListUser &other) = default;
-ListUser::ListUser(ListUser &&other) = default;
+ListUser::ListUser(ListUser &&other) noexcept = default;
ListUser &ListUser::operator=(const ListUser &other) = default;
-ListUser &ListUser::operator=(ListUser &&other) = default;
+ListUser &ListUser::operator=(ListUser &&other) noexcept = default;
ListUser::~ListUser() = default;
-std::list<int>
-ListUser::createList()
+std::list<int> ListUser::createList()
{
std::list<int> retval;
for (int i = 0; i < 4; i++)
@@ -29,8 +26,7 @@ ListUser::createList()
return retval;
}
-std::list<Complex>
-ListUser::createComplexList(Complex cpx0, Complex cpx1)
+std::list<Complex> ListUser::createComplexList(Complex cpx0, Complex cpx1)
{
std::list<Complex> retval;
retval.push_back(cpx0);
@@ -38,14 +34,12 @@ ListUser::createComplexList(Complex cpx0, Complex cpx1)
return retval;
}
-double
-ListUser::sumList(std::list<int> vallist)
+double ListUser::sumList(std::list<int> vallist)
{
return std::accumulate(vallist.begin(), vallist.end(), 0.0);
}
-double
-ListUser::sumList(std::list<double> vallist)
+double ListUser::sumList(std::list<double> vallist)
{
return std::accumulate(vallist.begin(), vallist.end(), 0.0);
}
@@ -60,12 +54,10 @@ ListUser::ListOfSomething ListUser::listOfPoints(const std::list<PointF> &)
return ListOfPointF;
}
-void
-ListUser::multiplyPointList(PointList& points, double multiplier)
+void ListUser::multiplyPointList(PointList &points, double multiplier)
{
for (auto *point : points) {
point->setX(point->x() * multiplier);
point->setY(point->y() * multiplier);
}
}
-
diff --git a/sources/shiboken6/tests/libsample/listuser.h b/sources/shiboken6/tests/libsample/listuser.h
index 9351ffb7a..96781ed16 100644
--- a/sources/shiboken6/tests/libsample/listuser.h
+++ b/sources/shiboken6/tests/libsample/listuser.h
@@ -4,13 +4,14 @@
#ifndef LISTUSER_H
#define LISTUSER_H
-#include <list>
#include "complex.h"
#include "point.h"
#include "pointf.h"
#include "libsamplemacros.h"
+#include <list>
+
class LIBSAMPLE_API ListUser
{
public:
@@ -23,9 +24,9 @@ public:
ListUser();
ListUser(const ListUser &other);
- ListUser(ListUser &&other);
+ ListUser(ListUser &&other) noexcept;
ListUser &operator=(const ListUser &other);
- ListUser &operator=(ListUser &&other);
+ ListUser &operator=(ListUser &&other) noexcept;
virtual ~ListUser();
virtual std::list<int> createList();
@@ -36,13 +37,13 @@ public:
double sumList(std::list<int> vallist);
double sumList(std::list<double> vallist);
- static ListOfSomething listOfPoints(const std::list<Point>& pointlist);
- static ListOfSomething listOfPoints(const std::list<PointF>& pointlist);
+ static ListOfSomething listOfPoints(const std::list<Point> &pointlist);
+ static ListOfSomething listOfPoints(const std::list<PointF> &pointlist);
- static void multiplyPointList(PointList& points, double multiplier);
+ static void multiplyPointList(PointList &points, double multiplier);
inline void setList(std::list<int> lst) { m_lst = lst; }
- inline std::list<int> getList() { return m_lst; }
+ inline std::list<int> getList() const { return m_lst; }
private:
std::list<int> m_lst;
diff --git a/sources/shiboken6/tests/libsample/main.cpp b/sources/shiboken6/tests/libsample/main.cpp
index 9d62e753b..1b44642ae 100644
--- a/sources/shiboken6/tests/libsample/main.cpp
+++ b/sources/shiboken6/tests/libsample/main.cpp
@@ -12,207 +12,197 @@
#include "listuser.h"
#include "samplenamespace.h"
-using namespace std;
-
int
main(int argv, char **argc)
{
- cout << endl;
+ std::cout << std::endl;
Derived derived;
- cout << endl;
+ std::cout << std::endl;
derived.unpureVirtual();
derived.pureVirtual();
derived.callPureVirtual();
- cout << endl;
- Abstract* abs;
- abs = Abstract::createObject();
- cout << "Abstract::createObject(): " << abs << endl << endl;
+ std::cout << std::endl;
+ auto *abs = Abstract::createObject();
+ std::cout << "Abstract::createObject(): " << abs << std::endl << std::endl;
delete abs;
abs = Derived::createObject();
- cout << "Derived::createObject() : ";
+ std::cout << "Derived::createObject() : ";
abs->show();
- cout << endl;
+ std::cout << std::endl;
delete abs;
- cout << endl;
+ std::cout << std::endl;
abs = Derived::createObject();
- cout << "Derived::createObject() : ";
+ std::cout << "Derived::createObject() : ";
abs->show();
- cout << endl;
+ std::cout << std::endl;
delete abs;
- cout << endl;
+ std::cout << std::endl;
- cout << endl << "-----------------------------------------" << endl;
+ std::cout << "\n-----------------------------------------\n";
KinderGarten kg;
- Derived* d[] = { 0, 0, 0 };
+ Derived *d[] = { 0, 0, 0 };
for (int i = 0; i < 3; i++) {
d[i] = new Derived(i);
d[i]->show();
- cout << endl;
+ std::cout << std::endl;
kg.addChild(d[i]);
}
kg.show();
- cout << endl;
+ std::cout << std::endl;
- cout << endl << "* kill child ";
+ std::cout << "\n* kill child ";
d[2]->show();
- cout << " ----------------" << endl;
+ std::cout << " ----------------\n";
kg.killChild(d[2]);
kg.show();
- cout << endl;
+ std::cout << std::endl;
- cout << endl << "* release child ";
+ std::cout << "\n* release child ";
d[1]->show();
- cout << " -------------" << endl;
- Abstract* released = kg.releaseChild(d[1]);
- cout << "released: ";
+ std::cout << " -------------\n";
+ Abstract *released = kg.releaseChild(d[1]);
+ std::cout << "released: ";
released->show();
- cout << endl;
+ std::cout << std::endl;
kg.show();
- cout << endl;
-
- cout << endl << "* kill children ------------------------------------" << endl;
+ std::cout << "\n\n* kill children ------------------------------------\n";
kg.killChildren();
kg.show();
- cout << endl << endl;
-
- cout << "-----------------------------------------" << endl;
+ std::cout << "\n\n-----------------------------------------\n";
ListUser lu;
- cout << "ListUser::createList()" << endl;
+ std::cout << "ListUser::createList()\n";
std::list<int> intlist = lu.createList();
- for (std::list<int>::iterator it = intlist.begin(); it != intlist.end(); it++) {
- cout << "* " << *it << endl;
- }
+ for (std::list<int>::iterator it = intlist.begin(); it != intlist.end(); it++)
+ std::cout << "* " << *it << std::endl;
- cout << "ListUser::createComplexList" << endl;
+ std::cout << "ListUser::createComplexList\n";
std::list<Complex> cpxlist = ListUser::createComplexList(Complex(1.1, 2.2), Complex(3.3, 4.4));
for (std::list<Complex>::iterator it = cpxlist.begin(); it != cpxlist.end(); it++) {
- cout << "* ";
+ std::cout << "* ";
(*it).show();
- cout << endl;
+ std::cout << std::endl;
}
- cout << endl;
-
- cout << "-----------------------------------------" << endl;
- cout << "SampleNamespace" << endl;
-
- cout << "SampleNamespace::RandomNumber: ";
- cout << SampleNamespace::getNumber(SampleNamespace::RandomNumber);
- cout << endl;
- cout << "SampleNamespace::UnixTime: ";
- cout << SampleNamespace::getNumber(SampleNamespace::UnixTime);
- cout << endl;
+ std::cout << "\n-----------------------------------------\n"
+ << "SampleNamespace\n";
+
+ std::cout << "SampleNamespace::RandomNumber: ";
+ std::cout << SampleNamespace::getNumber(SampleNamespace::RandomNumber);
+ std::cout << std::endl;
+ std::cout << "SampleNamespace::UnixTime: ";
+ std::cout << SampleNamespace::getNumber(SampleNamespace::UnixTime);
+ std::cout << std::endl;
double val_d = 1.3;
- cout << "SampleNamespace::powerOfTwo(" << val_d << "): ";
- cout << SampleNamespace::powerOfTwo(val_d) << endl;
+ std::cout << "SampleNamespace::powerOfTwo(" << val_d << "): ";
+ std::cout << SampleNamespace::powerOfTwo(val_d) << std::endl;
int val_i = 7;
- cout << "SampleNamespace::powerOfTwo(" << val_i << "): ";
- cout << SampleNamespace::powerOfTwo(val_i) << endl;
- cout << endl;
+ std::cout << "SampleNamespace::powerOfTwo(" << val_i << "): ";
+ std::cout << SampleNamespace::powerOfTwo(val_i) << std::endl;
+ std::cout << std::endl;
- cout << "-----------------------------------------" << endl;
- cout << "Point" << endl;
+ std::cout << "-----------------------------------------" << std::endl;
+ std::cout << "Point" << std::endl;
Point p1(1.1, 2.2);
- cout << "p1: ";
+ std::cout << "p1: ";
p1.show();
- cout << endl;
+ std::cout << std::endl;
Point p2(3.4, 5.6);
- cout << "p2: ";
+ std::cout << "p2: ";
p2.show();
- cout << endl;
+ std::cout << std::endl;
- cout << "p1 + p2 == ";
+ std::cout << "p1 + p2 == ";
(p1 + p2).show();
- cout << endl;
+ std::cout << std::endl;
- cout << "p1 * 2.0 == ";
+ std::cout << "p1 * 2.0 == ";
(p1 * 2.0).show();
- cout << endl;
+ std::cout << std::endl;
- cout << "1.5 * p2 == ";
+ std::cout << "1.5 * p2 == ";
(1.5 * p2).show();
- cout << endl;
+ std::cout << std::endl;
- cout << "p1: ";
+ std::cout << "p1: ";
p1.show();
- cout << endl << "p2: ";
+ std::cout << std::endl << "p2: ";
p2.show();
- cout << endl << "p1 += p2" << endl;
+ std::cout << std::endl << "p1 += p2" << std::endl;
p1 += p2;
- cout << "p1: ";
+ std::cout << "p1: ";
p1.show();
- cout << endl;
+ std::cout << std::endl;
- cout << "p1 == p2 ? " << ((p1 == p2) ? "true" : "false") << endl;
- cout << "p1 == p1 ? " << ((p1 == p1) ? "true" : "false") << endl;
- cout << "p2 == p2 ? " << ((p2 == p2) ? "true" : "false") << endl;
+ std::cout << "p1 == p2 ? " << ((p1 == p2) ? "true" : "false") << std::endl;
+ std::cout << "p1 == p1 ? " << ((p1 == p1) ? "true" : "false") << std::endl;
+ std::cout << "p2 == p2 ? " << ((p2 == p2) ? "true" : "false") << std::endl;
- cout << "-----------------------------------------" << endl;
- cout << "Size" << endl;
+ std::cout << "-----------------------------------------" << std::endl;
+ std::cout << "Size" << std::endl;
Size s1(2, 2);
- cout << "s1: ";
+ std::cout << "s1: ";
s1.show();
- cout << ", area: " << s1.calculateArea();
- cout << endl;
+ std::cout << ", area: " << s1.calculateArea();
+ std::cout << std::endl;
Size s2(3, 5);
- cout << "s2: ";
+ std::cout << "s2: ";
s2.show();
- cout << ", area: " << s2.calculateArea();
- cout << endl;
-
- cout << endl;
-
- cout << "s1 == s2 ? " << ((s1 == s2) ? "true" : "false") << endl;
- cout << "s1 != s2 ? " << ((s1 != s2) ? "true" : "false") << endl;
-
- cout << "s1 < s2 ? " << ((s1 < s2) ? "true" : "false") << endl;
- cout << "s1 <= s2 ? " << ((s1 <= s2) ? "true" : "false") << endl;
- cout << "s1 > s2 ? " << ((s1 > s2) ? "true" : "false") << endl;
- cout << "s1 >= s2 ? " << ((s1 >= s2) ? "true" : "false") << endl;
-
- cout << "s1 < 10 ? " << ((s1 < 10) ? "true" : "false") << endl;
- cout << "s1 <= 10 ? " << ((s1 <= 10) ? "true" : "false") << endl;
- cout << "s1 > 10 ? " << ((s1 > 10) ? "true" : "false") << endl;
- cout << "s1 >= 10 ? " << ((s1 >= 10) ? "true" : "false") << endl;
- cout << "s2 < 10 ? " << ((s2 < 10) ? "true" : "false") << endl;
- cout << "s2 <= 10 ? " << ((s2 <= 10) ? "true" : "false") << endl;
- cout << "s2 > 10 ? " << ((s2 > 10) ? "true" : "false") << endl;
- cout << "s2 >= 10 ? " << ((s2 >= 10) ? "true" : "false") << endl;
- cout << endl;
-
- cout << "s1: ";
+ std::cout << ", area: " << s2.calculateArea();
+ std::cout << std::endl;
+
+ std::cout << std::endl;
+
+ std::cout << "s1 == s2 ? " << ((s1 == s2) ? "true" : "false") << std::endl;
+ std::cout << "s1 != s2 ? " << ((s1 != s2) ? "true" : "false") << std::endl;
+
+ std::cout << "s1 < s2 ? " << ((s1 < s2) ? "true" : "false") << std::endl;
+ std::cout << "s1 <= s2 ? " << ((s1 <= s2) ? "true" : "false") << std::endl;
+ std::cout << "s1 > s2 ? " << ((s1 > s2) ? "true" : "false") << std::endl;
+ std::cout << "s1 >= s2 ? " << ((s1 >= s2) ? "true" : "false") << std::endl;
+
+ std::cout << "s1 < 10 ? " << ((s1 < 10) ? "true" : "false") << std::endl;
+ std::cout << "s1 <= 10 ? " << ((s1 <= 10) ? "true" : "false") << std::endl;
+ std::cout << "s1 > 10 ? " << ((s1 > 10) ? "true" : "false") << std::endl;
+ std::cout << "s1 >= 10 ? " << ((s1 >= 10) ? "true" : "false") << std::endl;
+ std::cout << "s2 < 10 ? " << ((s2 < 10) ? "true" : "false") << std::endl;
+ std::cout << "s2 <= 10 ? " << ((s2 <= 10) ? "true" : "false") << std::endl;
+ std::cout << "s2 > 10 ? " << ((s2 > 10) ? "true" : "false") << std::endl;
+ std::cout << "s2 >= 10 ? " << ((s2 >= 10) ? "true" : "false") << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "s1: ";
s1.show();
- cout << endl << "s2: ";
+ std::cout << std::endl << "s2: ";
s2.show();
- cout << endl << "s1 += s2" << endl;
+ std::cout << std::endl << "s1 += s2" << std::endl;
s1 += s2;
- cout << "s1: ";
+ std::cout << "s1: ";
s1.show();
- cout << endl;
+ std::cout << std::endl;
- cout << endl;
+ std::cout << std::endl;
- cout << "s1: ";
+ std::cout << "s1: ";
s1.show();
- cout << endl << "s1 *= 2.0" << endl;
+ std::cout << std::endl << "s1 *= 2.0" << std::endl;
s1 *= 2.0;
- cout << "s1: ";
+ std::cout << "s1: ";
s1.show();
- cout << endl;
+ std::cout << std::endl;
- cout << endl;
+ std::cout << std::endl;
return 0;
}
diff --git a/sources/shiboken6/tests/libsample/mapuser.cpp b/sources/shiboken6/tests/libsample/mapuser.cpp
index 032d465d8..40059bbcd 100644
--- a/sources/shiboken6/tests/libsample/mapuser.cpp
+++ b/sources/shiboken6/tests/libsample/mapuser.cpp
@@ -1,44 +1,36 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
#include "mapuser.h"
-using namespace std;
+#include <iostream>
-std::map<std::string, std::pair<Complex, int> >
-MapUser::callCreateMap()
+std::map<std::string, std::pair<Complex, int> > MapUser::callCreateMap()
{
return createMap();
}
-
-std::map<std::string, std::pair<Complex, int> >
-MapUser::createMap()
+std::map<std::string, std::pair<Complex, int> > MapUser::createMap()
{
std::map<std::string, std::pair<Complex, int> > retval;
- std::pair<std::string, std::pair<Complex, int> >
- item0("zero", std::pair<Complex, int>(Complex(1.2, 3.4), 2));
- retval.insert(item0);
+ std::pair<Complex, int> value{Complex(1.2, 3.4), 2};
+ retval.insert({"zero", value});
- std::pair<std::string, std::pair<Complex, int> >
- item1("one", std::pair<Complex, int>(Complex(5.6, 7.8), 3));
- retval.insert(item1);
+ value = {Complex(5.6, 7.8), 3};
+ retval.insert({"one", value});
- std::pair<std::string, std::pair<Complex, int> >
- item2("two", std::pair<Complex, int>(Complex(9.1, 2.3), 5));
- retval.insert(item2);
+ value = {Complex(9.1, 2.3), 5};
+ retval.insert({"two", value});
return retval;
}
-void
-MapUser::showMap(std::map<std::string, int> mapping)
+void MapUser::showMap(std::map<std::string, int> mapping)
{
- cout << __FUNCTION__ << endl;
- for (auto it = mapping.begin(), end = mapping.end(); it != end; ++it)
- cout << (*it).first << " => " << (*it).second << endl;
+ std::cout << __FUNCTION__ << std::endl;
+ for (const auto &p : mapping)
+ std::cout << p.first << " => " << p.second << std::endl;
}
void MapUser::pointerToMap(std::map<std::string, std::string> *)
diff --git a/sources/shiboken6/tests/libsample/mapuser.h b/sources/shiboken6/tests/libsample/mapuser.h
index 49318743c..1677a4bfb 100644
--- a/sources/shiboken6/tests/libsample/mapuser.h
+++ b/sources/shiboken6/tests/libsample/mapuser.h
@@ -4,20 +4,23 @@
#ifndef MAPUSER_H
#define MAPUSER_H
+#include "libsamplemacros.h"
+
+#include "complex.h"
+#include "bytearray.h"
+
#include <map>
#include <list>
#include <utility>
#include <string>
-#include "complex.h"
-#include "bytearray.h"
-
-#include "libsamplemacros.h"
class LIBSAMPLE_API MapUser
{
public:
- MapUser() {}
- virtual ~MapUser() {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(MapUser)
+
+ MapUser() noexcept = default;
+ virtual ~MapUser() = default;
virtual std::map<std::string, std::pair<Complex, int> > createMap();
std::map<std::string, std::pair<Complex, int> > callCreateMap();
@@ -31,7 +34,7 @@ public:
static void pointerToMap(std::map<std::string, std::string> *arg);
static void referenceToMap(std::map<std::string, std::string> &arg);
- inline const std::map<int, ByteArray>& passMapIntValueType(const std::map<int, ByteArray>& arg) { return arg; }
+ inline const std::map<int, ByteArray> &passMapIntValueType(const std::map<int, ByteArray>& arg) { return arg; }
std::map<int, std::list<std::list<double> > > foo() const;
diff --git a/sources/shiboken6/tests/libsample/modelindex.h b/sources/shiboken6/tests/libsample/modelindex.h
index 6ed192329..48e1b7de3 100644
--- a/sources/shiboken6/tests/libsample/modelindex.h
+++ b/sources/shiboken6/tests/libsample/modelindex.h
@@ -4,8 +4,6 @@
#ifndef MODELINDEX_H
#define MODELINDEX_H
-#include "libsamplemacros.h"
-
class ModelIndex
{
public:
@@ -13,7 +11,8 @@ public:
inline void setValue(int value) { m_value = value; }
inline int value() const { return m_value; }
- static int getValue(const ModelIndex& index) { return index.value(); }
+ static int getValue(const ModelIndex &index) { return index.value(); }
+
private:
int m_value = 0;
};
@@ -23,11 +22,12 @@ class ReferentModelIndex
public:
ReferentModelIndex() = default;
- explicit ReferentModelIndex(const ModelIndex& index) : m_index(index) {}
+ explicit ReferentModelIndex(const ModelIndex &index) : m_index(index) {}
inline void setValue(int value) { m_index.setValue(value); }
inline int value() const { return m_index.value(); }
operator const ModelIndex&() const { return m_index; }
+
private:
ModelIndex m_index;
};
@@ -37,13 +37,14 @@ class PersistentModelIndex
public:
PersistentModelIndex() = default;
- explicit PersistentModelIndex(const ModelIndex& index) : m_index(index) {}
+ explicit PersistentModelIndex(const ModelIndex &index) : m_index(index) {}
inline void setValue(int value) { m_index.setValue(value); }
inline int value() const { return m_index.value(); }
operator ModelIndex() const { return m_index; }
+
private:
ModelIndex m_index;
};
-#endif
+#endif // MODELINDEX_H
diff --git a/sources/shiboken6/tests/libsample/modifications.cpp b/sources/shiboken6/tests/libsample/modifications.cpp
index 8b1ba07dc..6d627c4c1 100644
--- a/sources/shiboken6/tests/libsample/modifications.cpp
+++ b/sources/shiboken6/tests/libsample/modifications.cpp
@@ -1,15 +1,14 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
#include "modifications.h"
#include "objecttype.h"
-using namespace std;
+#include <iostream>
Modifications::Modifications()
+ : m_object(new ObjectType())
{
- m_object = new ObjectType();
m_object->setObjectName("MyObject");
}
@@ -79,30 +78,26 @@ void Modifications::argRemoval5(int, bool, int, bool)
{
}
-std::pair<double, double>
-Modifications::pointToPair(Point pt, bool* ok)
+std::pair<double, double> Modifications::pointToPair(Point pt, bool *ok)
{
std::pair<double, double> retval(pt.x(), pt.y());
*ok = true;
return retval;
}
-double
-Modifications::multiplyPointCoordsPlusValue(bool* ok, Point pt, double value)
+double Modifications::multiplyPointCoordsPlusValue(bool *ok, Point pt, double value)
{
double retval = (pt.x() * pt.y()) + value;
*ok = true;
return retval;
}
-int
-Modifications::doublePlus(int value, int plus)
+int Modifications::doublePlus(int value, int plus)
{
return (2 * value) + plus;
}
-int
-Modifications::power(int base, int exponent)
+int Modifications::power(int base, int exponent)
{
if (exponent == 0)
return 1;
@@ -112,38 +107,32 @@ Modifications::power(int base, int exponent)
return retval;
}
-int
-Modifications::timesTen(int number)
+int Modifications::timesTen(int number)
{
return number * 10;
}
-int
-Modifications::increment(int number)
+int Modifications::increment(int number)
{
return ++number;
}
-void
-Modifications::exclusiveCppStuff()
+void Modifications::exclusiveCppStuff()
{
- cout << __FUNCTION__ << endl;
+ std::cout << __FUNCTION__ << std::endl;
}
-int
-Modifications::cppMultiply(int a, int b)
+int Modifications::cppMultiply(int a, int b)
{
return a * b;
}
-const char*
-Modifications::className()
+const char *Modifications::className()
{
return "Modifications";
}
-Point
-Modifications::sumPointArray(int arraySize, const Point pointArray[])
+Point Modifications::sumPointArray(int arraySize, const Point pointArray[])
{
Point point;
for (int i = 0; i < arraySize; ++i)
@@ -151,21 +140,18 @@ Modifications::sumPointArray(int arraySize, const Point pointArray[])
return point;
}
-int
-Modifications::getSize(const void* data, int size)
+int Modifications::getSize(const void *data, int size)
{
(void)data;
return size;
}
-int
-Modifications::sumPointCoordinates(const Point* point)
+int Modifications::sumPointCoordinates(const Point *point)
{
return point->x() + point->y();
}
-double
-Modifications::differenceOfPointCoordinates(const Point* pt, bool* ok)
+double Modifications::differenceOfPointCoordinates(const Point *pt, bool *ok)
{
if (!pt) {
*ok = false;
@@ -178,8 +164,7 @@ Modifications::differenceOfPointCoordinates(const Point* pt, bool* ok)
return result;
}
-bool
-Modifications::nonConversionRuleForArgumentWithDefaultValue(ObjectType** object)
+bool Modifications::nonConversionRuleForArgumentWithDefaultValue(ObjectType **object)
{
if (object)
*object = m_object;
diff --git a/sources/shiboken6/tests/libsample/modifications.h b/sources/shiboken6/tests/libsample/modifications.h
index d757d87b9..5bd1bac47 100644
--- a/sources/shiboken6/tests/libsample/modifications.h
+++ b/sources/shiboken6/tests/libsample/modifications.h
@@ -5,15 +5,18 @@
#define MODIFICATIONS_H
#include "libsamplemacros.h"
-#include <utility>
#include "point.h"
#include "oddbool.h"
+#include <utility>
+
class ObjectType;
class LIBSAMPLE_API Modifications
{
public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Modifications)
+
Modifications();
virtual ~Modifications();
@@ -61,10 +64,10 @@ public:
// 'ok' must be removed and the return value will be changed
// to a tuple (PyObject*) containing the expected result plus
// the 'ok' value as a Python boolean
- std::pair<double, double> pointToPair(Point pt, bool* ok);
+ std::pair<double, double> pointToPair(Point pt, bool *ok);
// same as 'pointToPair' except that this time 'ok' is the first argument
- double multiplyPointCoordsPlusValue(bool* ok, Point pt, double value);
+ double multiplyPointCoordsPlusValue(bool *ok, Point pt, double value);
// completely remove 'plus' from the Python side
int doublePlus(int value, int plus = 0);
@@ -85,24 +88,25 @@ public:
int cppMultiply(int a, int b);
// change the name of this virtual method
- virtual const char* className();
+ virtual const char *className();
Point sumPointArray(int arraySize, const Point pointArray[]);
// Replace 'const void*' by 'ByteArray&'.
- int getSize(const void* data, int size);
+ int getSize(const void *data, int size);
// Mark the argument with a <no-null-pointer/> tag;
// the test implementation must expect point never to be null.
- int sumPointCoordinates(const Point* point);
+ int sumPointCoordinates(const Point *point);
// Modify the return value of a virtual method.
- virtual double differenceOfPointCoordinates(const Point* pt, bool* ok);
- double callDifferenceOfPointCoordinates(const Point* pt, bool* ok) { return differenceOfPointCoordinates(pt, ok); }
+ virtual double differenceOfPointCoordinates(const Point *pt, bool *ok);
+ double callDifferenceOfPointCoordinates(const Point *pt, bool *ok)
+ { return differenceOfPointCoordinates(pt, ok); }
// Sets an ObjectType in the argument and returns true.
bool nonConversionRuleForArgumentWithDefaultValue(ObjectType **object = nullptr);
- ObjectType* getObject() const { return m_object; }
+ ObjectType *getObject() const { return m_object; }
// Inject code with a %CONVERTTOPYTHON that receives an user's primitive type.
static inline OddBool passOddBool(OddBool ob) { return ob; }
@@ -118,7 +122,7 @@ public:
void notifySetAttroCalled();
private:
- ObjectType* m_object;
+ ObjectType *m_object;
TestEnum m_enumValue = TestEnumValue1;
bool m_getAttroCalled = false;
bool m_setAttroCalled = false;
@@ -127,8 +131,10 @@ private:
class LIBSAMPLE_API AbstractModifications : public Modifications
{
public:
- AbstractModifications() {}
- virtual ~AbstractModifications() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(AbstractModifications)
+
+ AbstractModifications() noexcept = default;
+ ~AbstractModifications() override = default;
inline bool invert(bool value) { return !value; }
diff --git a/sources/shiboken6/tests/libsample/modified_constructor.cpp b/sources/shiboken6/tests/libsample/modified_constructor.cpp
index d53815243..c39c97738 100644
--- a/sources/shiboken6/tests/libsample/modified_constructor.cpp
+++ b/sources/shiboken6/tests/libsample/modified_constructor.cpp
@@ -8,8 +8,7 @@ ModifiedConstructor::ModifiedConstructor(int first_arg)
m_stored_value = first_arg;
}
-int
-ModifiedConstructor::retrieveValue()
+int ModifiedConstructor::retrieveValue() const
{
return m_stored_value;
}
diff --git a/sources/shiboken6/tests/libsample/modified_constructor.h b/sources/shiboken6/tests/libsample/modified_constructor.h
index 48cb812a6..a27899f3f 100644
--- a/sources/shiboken6/tests/libsample/modified_constructor.h
+++ b/sources/shiboken6/tests/libsample/modified_constructor.h
@@ -10,8 +10,8 @@ class LIBSAMPLE_API ModifiedConstructor
{
public:
- ModifiedConstructor(int first_arg);
- int retrieveValue();
+ explicit ModifiedConstructor(int first_arg);
+ int retrieveValue() const;
private:
int m_stored_value;
diff --git a/sources/shiboken6/tests/libsample/multiple_derived.cpp b/sources/shiboken6/tests/libsample/multiple_derived.cpp
index 9797a397b..be535c62f 100644
--- a/sources/shiboken6/tests/libsample/multiple_derived.cpp
+++ b/sources/shiboken6/tests/libsample/multiple_derived.cpp
@@ -3,37 +3,22 @@
#include "multiple_derived.h"
-MDerived1::MDerived1() : m_value(100)
-{
-}
+MDerived1::MDerived1() noexcept = default;
-MDerived2::MDerived2() : m_value(200)
-{
-}
+MDerived2::MDerived2() noexcept = default;
-MDerived3::MDerived3() : m_value(3000)
-{
-}
+MDerived3::MDerived3() noexcept = default;
-MDerived4::MDerived4()
-{
-}
+MDerived4::MDerived4() noexcept = default;
-MDerived5::MDerived5()
-{
-}
+MDerived5::MDerived5() noexcept = default;
-MDerived1*
-MDerived1::transformFromBase1(Base1* self)
+MDerived1 *MDerived1::transformFromBase1(Base1 *self)
{
- MDerived1* ptr = dynamic_cast<MDerived1*>(self);
- return ptr;
+ return dynamic_cast<MDerived1*>(self);
}
-MDerived1*
-MDerived1::transformFromBase2(Base2* self)
+MDerived1 *MDerived1::transformFromBase2(Base2 *self)
{
- MDerived1* ptr = dynamic_cast<MDerived1*>(self);
- return ptr;
+ return dynamic_cast<MDerived1*>(self);
}
-
diff --git a/sources/shiboken6/tests/libsample/multiple_derived.h b/sources/shiboken6/tests/libsample/multiple_derived.h
index b91fb34cd..8c2143ed6 100644
--- a/sources/shiboken6/tests/libsample/multiple_derived.h
+++ b/sources/shiboken6/tests/libsample/multiple_derived.h
@@ -5,70 +5,86 @@
#define MDERIVED_H
#include "libsamplemacros.h"
+
#include <string>
class Base1
{
public:
- Base1() : m_value(1) {}
- virtual ~Base1() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base1)
+
+ Base1() noexcept = default;
+ virtual ~Base1() = default;
+
virtual int base1Method() { return m_value; }
virtual void publicMethod() {};
+
private:
- int m_value;
+ int m_value = 1;
};
class Base2
{
public:
- Base2() : m_value(2) {}
- virtual ~Base2() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base2)
+
+ Base2() noexcept = default;
+ virtual ~Base2() = default;
virtual int base2Method() { return m_value; }
+
private:
- int m_value;
+ int m_value = 2;
};
class LIBSAMPLE_API MDerived1 : public Base1, public Base2
{
public:
- MDerived1();
- ~MDerived1() override {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(MDerived1)
+
+ MDerived1() noexcept;
+ ~MDerived1() override = default;
int mderived1Method() { return m_value; }
int base1Method () override { return Base1::base1Method() * 10; }
int base2Method() override { return Base2::base2Method() * 10; }
- inline Base1* castToBase1() { return (Base1*) this; }
- inline Base2* castToBase2() { return (Base2*) this; }
+ inline Base1 *castToBase1() { return (Base1*) this; }
+ inline Base2 *castToBase2() { return (Base2*) this; }
- static MDerived1* transformFromBase1(Base1 *self);
- static MDerived1* transformFromBase2(Base2 *self);
+ static MDerived1 *transformFromBase1(Base1 *self);
+ static MDerived1 *transformFromBase2(Base2 *self);
private:
void publicMethod() override {}
- int m_value;
+ int m_value = 100;
};
class SonOfMDerived1 : public MDerived1
{
public:
- SonOfMDerived1() : m_value(0) {}
- ~SonOfMDerived1() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(SonOfMDerived1)
+
+ SonOfMDerived1() noexcept = default;
+ ~SonOfMDerived1() = default;
- inline MDerived1* castToMDerived1() { return (MDerived1*) this; }
+ inline MDerived1 *castToMDerived1() { return this; }
int sonOfMDerived1Method() { return m_value; }
+
private:
- int m_value;
+ int m_value = 0;
};
class Base3
{
public:
- explicit Base3(int val = 3) : m_value(val) {}
- virtual ~Base3() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base3)
+
+ explicit Base3(int val = 3) noexcept : m_value(val) {}
+ virtual ~Base3() = default;
int base3Method() { return m_value; }
+
private:
int m_value;
};
@@ -76,80 +92,95 @@ private:
class Base4
{
public:
- Base4() : m_value(4) {}
- virtual ~Base4() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base4)
+
+ Base4() noexcept = default;
+ virtual ~Base4() = default;
int base4Method() { return m_value; }
+
private:
- int m_value;
+ int m_value = 4;
};
class Base5
{
public:
- Base5() : m_value(5) {}
- virtual ~Base5() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base5)
+
+ Base5() noexcept = default;
+ virtual ~Base5() = default;
virtual int base5Method() { return m_value; }
+
private:
- int m_value;
+ int m_value = 5;
};
class Base6
{
public:
- Base6() : m_value(6) {}
- virtual ~Base6() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(Base6)
+
+ Base6() noexcept = default;
+ virtual ~Base6() = default;
virtual int base6Method() { return m_value; }
+
private:
- int m_value;
+ int m_value = 6;
};
-
class LIBSAMPLE_API MDerived2 : public Base3, public Base4, public Base5, public Base6
{
public:
- MDerived2();
- virtual ~MDerived2() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(MDerived2)
+
+ MDerived2() noexcept;
+ virtual ~MDerived2() = default;
inline int base4Method() { return Base3::base3Method() * 10; }
inline int mderived2Method() { return m_value; }
- inline Base3* castToBase3() { return (Base3*) this; }
- inline Base4* castToBase4() { return (Base4*) this; }
- inline Base5* castToBase5() { return (Base5*) this; }
- inline Base6* castToBase6() { return (Base6*) this; }
+ inline Base3 *castToBase3() { return this; }
+ inline Base4 *castToBase4() { return this; }
+ inline Base5 *castToBase5() { return this; }
+ inline Base6 *castToBase6() { return this; }
private:
- int m_value;
+ int m_value = 200;
};
class LIBSAMPLE_API MDerived3 : public MDerived1, public MDerived2
{
public:
- MDerived3();
- virtual ~MDerived3() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(MDerived3)
+
+ MDerived3() noexcept;
+ virtual ~MDerived3() = default;
inline virtual int mderived3Method() { return m_value; }
- inline MDerived1* castToMDerived1() { return (MDerived1*) this; }
- inline MDerived2* castToMDerived2() { return (MDerived2*) this; }
+ inline MDerived1 *castToMDerived1() { return this; }
+ inline MDerived2 *castToMDerived2() { return this; }
- inline Base3* castToBase3() { return (Base3*) this; }
+ inline Base3 *castToBase3() { return (Base3*) this; }
private:
- int m_value;
+ int m_value = 3000;
};
class LIBSAMPLE_API MDerived4 : public Base3, public Base4
{
public:
- MDerived4();
- ~MDerived4() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(MDerived4)
+
+ MDerived4() noexcept;
+ ~MDerived4() = default;
inline int mderived4Method() { return 0; }
inline int justDummyMethod() { return m_value; }
- inline Base3* castToBase3() { return (Base3*) this; }
- inline Base4* castToBase4() { return (Base4*) this; }
+ inline Base3 *castToBase3() { return this; }
+ inline Base4 *castToBase4() { return this; }
+
private:
int m_value;
};
@@ -157,14 +188,15 @@ private:
class LIBSAMPLE_API MDerived5 : public Base3, public Base4
{
public:
- MDerived5();
- virtual ~MDerived5() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(MDerived5)
+
+ MDerived5() noexcept;
+ virtual ~MDerived5() = default;
virtual int mderived5Method() { return 0; }
- inline Base3* castToBase3() { return (Base3*) this; }
- inline Base4* castToBase4() { return (Base4*) this; }
+ inline Base3 *castToBase3() { return this; }
+ inline Base4 *castToBase4() { return this; }
};
#endif // MDERIVED_H
-
diff --git a/sources/shiboken6/tests/libsample/noimplicitconversion.h b/sources/shiboken6/tests/libsample/noimplicitconversion.h
index e7d738037..a0b91380b 100644
--- a/sources/shiboken6/tests/libsample/noimplicitconversion.h
+++ b/sources/shiboken6/tests/libsample/noimplicitconversion.h
@@ -13,9 +13,12 @@ class NoImplicitConversion
public:
explicit NoImplicitConversion(int objId) : m_objId(objId) {}
inline int objId() const { return m_objId; }
- inline static int receivesNoImplicitConversionByValue(NoImplicitConversion arg) { return arg.m_objId; }
- inline static int receivesNoImplicitConversionByPointer(NoImplicitConversion* arg) { return arg->m_objId; }
- inline static int receivesNoImplicitConversionByReference(NoImplicitConversion& arg) { return arg.m_objId; }
+ inline static int receivesNoImplicitConversionByValue(NoImplicitConversion arg)
+ { return arg.m_objId; }
+ inline static int receivesNoImplicitConversionByPointer(NoImplicitConversion *arg)
+ { return arg->m_objId; }
+ inline static int receivesNoImplicitConversionByReference(NoImplicitConversion &arg)
+ { return arg.m_objId; }
private:
int m_objId;
};
diff --git a/sources/shiboken6/tests/libsample/nondefaultctor.h b/sources/shiboken6/tests/libsample/nondefaultctor.h
index c410515ad..fa97b8859 100644
--- a/sources/shiboken6/tests/libsample/nondefaultctor.h
+++ b/sources/shiboken6/tests/libsample/nondefaultctor.h
@@ -8,13 +8,16 @@
class NonDefaultCtor
{
- int m_value;
public:
- NonDefaultCtor(int value) : m_value(value)
+ LIBMINIMAL_DEFAULT_COPY_MOVE(NonDefaultCtor)
+
+ explicit NonDefaultCtor(int value) noexcept : m_value(value)
{
}
- inline int value()
+ virtual ~NonDefaultCtor() = default;
+
+ inline int value() const
{
return m_value;
}
@@ -44,7 +47,8 @@ public:
return returnMyselfVirtual();
}
- virtual ~NonDefaultCtor() {}
+private:
+ int m_value;
};
-#endif
+#endif // NONDEFAULTCTOR_H
diff --git a/sources/shiboken6/tests/libsample/nontypetemplate.h b/sources/shiboken6/tests/libsample/nontypetemplate.h
index d3bc7fb8a..e41c21604 100644
--- a/sources/shiboken6/tests/libsample/nontypetemplate.h
+++ b/sources/shiboken6/tests/libsample/nontypetemplate.h
@@ -21,7 +21,7 @@ private:
int m_array[Size];
};
-typedef IntArray<2> IntArray2;
-typedef IntArray<3> IntArray3;
+using IntArray2 = IntArray<2>;
+using IntArray3 = IntArray<3>;
#endif // NONTYPETEMPLATE_H
diff --git a/sources/shiboken6/tests/libsample/null.h b/sources/shiboken6/tests/libsample/null.h
index 9a618095c..945a89fa2 100644
--- a/sources/shiboken6/tests/libsample/null.h
+++ b/sources/shiboken6/tests/libsample/null.h
@@ -8,12 +8,12 @@ class Null
{
public:
Null(bool value) : m_isNull(value) {}
- Null() : m_isNull(false) {}
+ Null() = default;
+
void setIsNull(bool flag) { m_isNull = flag; }
private:
- bool m_isNull;
+ bool m_isNull = false;
};
-#endif // STR_H
-
+#endif // NULL_H
diff --git a/sources/shiboken6/tests/libsample/objectmodel.cpp b/sources/shiboken6/tests/libsample/objectmodel.cpp
index a211d2969..56ed86577 100644
--- a/sources/shiboken6/tests/libsample/objectmodel.cpp
+++ b/sources/shiboken6/tests/libsample/objectmodel.cpp
@@ -3,14 +3,12 @@
#include "objectmodel.h"
-void
-ObjectModel::setData(ObjectType* data)
+void ObjectModel::setData(ObjectType *data)
{
m_data = data;
}
-ObjectType*
-ObjectModel::data() const
+ObjectType *ObjectModel::data() const
{
return m_data;
}
diff --git a/sources/shiboken6/tests/libsample/objectmodel.h b/sources/shiboken6/tests/libsample/objectmodel.h
index 063404460..6d2f97aee 100644
--- a/sources/shiboken6/tests/libsample/objectmodel.h
+++ b/sources/shiboken6/tests/libsample/objectmodel.h
@@ -11,11 +11,10 @@ class LIBSAMPLE_API ObjectModel : public ObjectType
{
public:
explicit ObjectModel(ObjectType *parent = nullptr)
- : ObjectType(parent), m_data(nullptr)
- {}
+ : ObjectType(parent) {}
- void setData(ObjectType* data);
- virtual ObjectType* data() const;
+ void setData(ObjectType *data);
+ virtual ObjectType *data() const;
// The MethodCalled enum and related static methods were created to
// test bug #630 [http://bugs.openbossa.org/show_bug.cgi?id=630]
@@ -26,8 +25,7 @@ public:
private:
// The model holds only one piece of data.
// (This is just a test after all.)
- ObjectType* m_data;
+ ObjectType *m_data = nullptr;
};
#endif // OBJECTMODEL_H
-
diff --git a/sources/shiboken6/tests/libsample/objecttype.cpp b/sources/shiboken6/tests/libsample/objecttype.cpp
index 1e3920734..fa3e7357c 100644
--- a/sources/shiboken6/tests/libsample/objecttype.cpp
+++ b/sources/shiboken6/tests/libsample/objecttype.cpp
@@ -3,44 +3,36 @@
#include "objecttype.h"
#include "objecttypelayout.h"
+
#include <algorithm>
#include <iostream>
#include <string>
#include <assert.h>
-#include <algorithm>
-
-using namespace std;
-
-ObjectType::ObjectType(ObjectType* parent) : m_parent(nullptr), m_layout(nullptr), m_call_id(-1)
+ObjectType::ObjectType(ObjectType *parent)
{
setParent(parent);
}
+ObjectType::ObjectType(ObjectType &&) noexcept = default;
+ObjectType &ObjectType::operator=(ObjectType &&) noexcept = default;
+
ObjectType::~ObjectType()
{
for (auto *o : m_children)
delete o;
}
-ObjectType*
-ObjectType::createWithChild()
+ObjectType *ObjectType::createWithChild()
{
- ObjectType* parent = create();
- ObjectType* child = create();
+ ObjectType *parent = create();
+ ObjectType *child = create();
child->setObjectName("child");
child->setParent(parent);
return parent;
}
-const ObjectType *ObjectType::defaultInstance()
-{
- static ObjectType result;
- return &result;
-}
-
-void
-ObjectType::removeChild(ObjectType* child)
+void ObjectType::removeChild(ObjectType *child)
{
if (!child)
return;
@@ -52,8 +44,7 @@ ObjectType::removeChild(ObjectType* child)
}
}
-ObjectType*
-ObjectType::takeChild(ObjectType* child)
+ObjectType *ObjectType::takeChild(ObjectType *child)
{
if (!child)
return nullptr;
@@ -67,8 +58,7 @@ ObjectType::takeChild(ObjectType* child)
return nullptr;
}
-ObjectType*
-ObjectType::takeChild(const Str& name)
+ObjectType *ObjectType::takeChild(const Str &name)
{
return takeChild(findChild(name));
@@ -82,15 +72,13 @@ ObjectTypeList::iterator ObjectType::findChildByName(const Str &name)
});
}
-ObjectType*
-ObjectType::findChild(const Str& name)
+ObjectType *ObjectType::findChild(const Str &name)
{
auto it = findChildByName(name);
return it != m_children.end() ? *it : nullptr;
}
-void
-ObjectType::killChild(const Str& name)
+void ObjectType::killChild(const Str &name)
{
auto it = findChildByName(name);
if (it != m_children.end()) {
@@ -100,8 +88,7 @@ ObjectType::killChild(const Str& name)
}
}
-void
-ObjectType::setParent(ObjectType* parent)
+void ObjectType::setParent(ObjectType *parent)
{
if (m_parent == parent)
return;
@@ -114,20 +101,17 @@ ObjectType::setParent(ObjectType* parent)
m_parent->m_children.push_back(this);
}
-void
-ObjectType::setObjectName(const Str& name)
+void ObjectType::setObjectName(const Str &name)
{
m_objectName = name;
}
-Str
-ObjectType::objectName() const
+Str ObjectType::objectName() const
{
return m_objectName;
}
-bool
-ObjectType::causeEvent(Event::EventType eventType)
+bool ObjectType::causeEvent(Event::EventType eventType)
{
Event e(eventType);
return event(&e);
@@ -138,8 +122,7 @@ bool ObjectType::event(Event *)
return true;
}
-int
-ObjectType::processEvent(ObjectTypeList objects, Event *event)
+int ObjectType::processEvent(ObjectTypeList objects, Event *event)
{
return std::count_if(objects.begin(), objects.end(),
[event] (ObjectType *o) {
@@ -147,8 +130,7 @@ ObjectType::processEvent(ObjectTypeList objects, Event *event)
});
}
-void
-ObjectType::callInvalidateEvent(Event* event)
+void ObjectType::callInvalidateEvent(Event *event)
{
invalidateEvent(event);
}
@@ -157,32 +139,34 @@ void ObjectType::invalidateEvent(Event *)
{
}
-void
-ObjectType::setLayout(ObjectTypeLayout* l)
+void ObjectType::setLayout(ObjectTypeLayout *l)
{
if (!l) {
- cerr << "[WARNING] ObjectType::setLayout: Cannot set layout to 0." << endl;
+ std::cerr << "[WARNING] ObjectType::setLayout: Cannot set layout to 0.\n";
return;
}
if (layout()) {
if (layout() != l) {
- cerr << "[WARNING] ObjectType::setLayout: Attempting to set ObjectTypeLayout '" << l->objectName().cstring();
- cerr << "' on ObjectType '" << objectName().cstring() << "', which already has a layout." << endl;
+ std::cerr << "[WARNING] ObjectType::setLayout: Attempting to set ObjectTypeLayout '"
+ << l->objectName().cstring()
+ << "' on ObjectType '" << objectName().cstring()
+ << "', which already has a layout.\n";
}
return;
}
- ObjectType* oldParent = l->parent();
+ ObjectType *oldParent = l->parent();
if (oldParent && oldParent != this) {
if (oldParent->isLayoutType()) {
- cerr << "[WARNING] ObjectType::setLayout: Attempting to set ObjectTypeLayout '" << l->objectName().cstring();
- cerr << "' on ObjectType '" << objectName().cstring() << "', when the ObjectTypeLayout already has a parent layout." << endl;
+ std::cerr << "[WARNING] ObjectType::setLayout: Attempting to set ObjectTypeLayout '"
+ << l->objectName().cstring()
+ << "' on ObjectType '" << objectName().cstring()
+ << "', when the ObjectTypeLayout already has a parent layout.\n";
return;
- } else {
- // Steal the layout from an ObjectType parent.
- oldParent->takeLayout();
}
+ // Steal the layout from an ObjectType parent.
+ oldParent->takeLayout();
}
m_layout = l;
@@ -192,9 +176,9 @@ ObjectType::setLayout(ObjectTypeLayout* l)
}
}
-ObjectTypeLayout* ObjectType::takeLayout()
+ObjectTypeLayout *ObjectType::takeLayout()
{
- ObjectTypeLayout* l = layout();
+ ObjectTypeLayout *l = layout();
if (!l)
return nullptr;
m_layout = nullptr;
@@ -202,15 +186,14 @@ ObjectTypeLayout* ObjectType::takeLayout()
return l;
}
-unsigned int
-objectTypeHash(const ObjectType* objectType)
+unsigned int objectTypeHash(const ObjectType *objectType)
{
return reinterpret_cast<std::size_t>(objectType);
}
unsigned char ObjectType::callWithEnum(const Str &, Event::EventType, unsigned char value)
{
- return value*value;
+ return value * value;
}
unsigned char ObjectType::callWithEnum(const Str &, unsigned char value)
@@ -218,23 +201,20 @@ unsigned char ObjectType::callWithEnum(const Str &, unsigned char value)
return value;
}
-void
-ObjectType::setObjectSplittedName(const char*, const Str& prefix, const Str& suffix)
+void ObjectType::setObjectSplittedName(const char *, const Str &prefix, const Str &suffix)
{
std::string result(prefix.cstring());
result += suffix.cstring();
m_objectName = result.c_str();
}
-void
-ObjectType::setObjectNameWithSize(const char*, int size, const Str& name)
+void ObjectType::setObjectNameWithSize(const char *, int size, const Str &name)
{
std::string result(name.cstring(), size);
m_objectName = result.c_str();
}
-void
-ObjectType::setObjectNameWithSize(const Str& name, int size)
+void ObjectType::setObjectNameWithSize(const Str &name, int size)
{
setObjectNameWithSize("", size, name);
}
@@ -254,34 +234,29 @@ int ObjectType::callId() const
return m_call_id;
}
-
void ObjectType::callVirtualCreateChild()
{
- ObjectType* fake_parent = new ObjectType();
- ObjectType* fake_child = createChild(fake_parent);
+ auto *fake_parent = new ObjectType();
+ ObjectType *fake_child = createChild(fake_parent);
assert(fake_child->isPython());
(void)fake_child;
delete fake_parent;
}
-ObjectType* ObjectType::createChild(ObjectType* parent)
+ObjectType *ObjectType::createChild(ObjectType *parent)
{
return new ObjectType(parent);
}
std::size_t ObjectType::createObjectType()
{
- void* addr = new ObjectType();
+ void *addr = new ObjectType();
return (std::size_t) addr;
}
-OtherBase::~OtherBase()
-{
-}
+OtherBase::~OtherBase() = default;
-ObjectTypeDerived::~ObjectTypeDerived()
-{
-}
+ObjectTypeDerived::~ObjectTypeDerived() = default;
bool ObjectTypeDerived::event(Event *)
{
diff --git a/sources/shiboken6/tests/libsample/objecttype.h b/sources/shiboken6/tests/libsample/objecttype.h
index 221fb7eea..498556459 100644
--- a/sources/shiboken6/tests/libsample/objecttype.h
+++ b/sources/shiboken6/tests/libsample/objecttype.h
@@ -4,13 +4,12 @@
#ifndef OBJECTTYPE_H
#define OBJECTTYPE_H
-#include <list>
#include "str.h"
#include "null.h"
#include "libsamplemacros.h"
-#include <stddef.h>
+#include <list>
struct Event
{
@@ -26,8 +25,8 @@ struct Event
Value2
};
- Event(EventType eventType) : m_eventType(eventType) {}
- EventType eventType() { return m_eventType; }
+ explicit Event(EventType eventType) : m_eventType(eventType) {}
+ EventType eventType() const { return m_eventType; }
void setEventType(EventType et) { m_eventType = et; }
void setEventTypeByConstRef(const EventType &et) { m_eventType = et; }
@@ -49,67 +48,72 @@ public:
explicit ObjectType(ObjectType *parent = nullptr);
virtual ~ObjectType();
+ ObjectType(const ObjectType &) = delete;
+ ObjectType &operator=(const ObjectType &) = delete;
+ ObjectType(ObjectType &&) noexcept;
+ ObjectType &operator=(ObjectType &&) noexcept;
// factory method
- inline static ObjectType* create() { return new ObjectType(); }
- static ObjectType* createWithChild();
-
- static const ObjectType *defaultInstance();
-
- void setParent(ObjectType* parent);
- inline ObjectType* parent() const { return m_parent; }
- inline const ObjectTypeList& children() const { return m_children; }
- void killChild(const Str& name);
- void removeChild(ObjectType* child);
- ObjectType* takeChild(ObjectType* child);
- virtual ObjectType* takeChild(const Str& name);
- ObjectType* findChild(const Str& name);
+ inline static ObjectType *create() { return new ObjectType(); }
+ static ObjectType *createWithChild();
+
+ void setParent(ObjectType *parent);
+ inline ObjectType *parent() const { return m_parent; }
+ inline const ObjectTypeList &children() const { return m_children; }
+ void killChild(const Str &name);
+ void removeChild(ObjectType *child);
+ ObjectType *takeChild(ObjectType *child);
+ virtual ObjectType *takeChild(const Str &name);
+ ObjectType *findChild(const Str &name);
Str objectName() const;
- void setObjectName(const Str& name);
+ void setObjectName(const Str &name);
inline Identifier identifier() const { return reinterpret_cast<Identifier>(this); }
bool causeEvent(Event::EventType eventType);
// Returns true if the event is processed.
- virtual bool event(Event* event);
+ virtual bool event(Event *event);
static int processEvent(ObjectTypeList objects, Event *event);
- void callInvalidateEvent(Event* event);
+ void callInvalidateEvent(Event *event);
virtual void invalidateEvent(Event *event);
// This nonsense method emulate QWidget.setLayout method
// All layout objects will became children of this object.
- void setLayout(ObjectTypeLayout* layout);
- inline ObjectTypeLayout* layout() const { return m_layout; }
+ void setLayout(ObjectTypeLayout *layout);
+ inline ObjectTypeLayout *layout() const { return m_layout; }
// This method should be reimplemented by ObjectTypeLayout.
virtual bool isLayoutType() { return false; }
- unsigned char callWithEnum(const Str& prefix, Event::EventType type, unsigned char value=80);
- unsigned char callWithEnum(const Str& prefix, unsigned char value=0);
+ unsigned char callWithEnum(const Str &prefix, Event::EventType type,
+ unsigned char value=80);
+ unsigned char callWithEnum(const Str &prefix, unsigned char value=0);
//Functions used in test with named arguments
- void setObjectSplittedName(const char*, const Str& prefix = Str("<unk"), const Str& suffix = Str("nown>"));
- void setObjectNameWithSize(const char*, int size=9, const Str& name = Str("<unknown>"));
- void setObjectNameWithSize(const Str& name = Str("<unknown>"), int size=9);
+ void setObjectSplittedName(const char *, const Str &prefix = Str("<unk"),
+ const Str &suffix = Str("nown>"));
+ void setObjectNameWithSize(const char *, int size=9,
+ const Str &name = Str("<unknown>"));
+ void setObjectNameWithSize(const Str &name = Str("<unknown>"), int size = 9);
//Function used to confuse the generator when two values accept Null as arg
void setObject(ObjectType *);
- void setObject(const Null&);
+ void setObject(const Null &);
int callId() const;
//Function used to create a parent from C++
virtual bool isPython() { return false; }
void callVirtualCreateChild();
- virtual ObjectType* createChild(ObjectType* parent);
+ virtual ObjectType *createChild(ObjectType *parent);
static std::size_t createObjectType();
//return a parent from C++
- ObjectType* getCppParent() {
+ ObjectType *getCppParent() {
if (!m_parent) {
- ObjectType* parent = new ObjectType();
+ ObjectType *parent = new ObjectType();
setParent(parent);
}
return m_parent;
@@ -124,41 +128,39 @@ public:
// nextInFocusChain simply returns the parent to test object cycles; the parent
// may be returned by the QWidget's implementation but isn't always returned
- ObjectType* nextInFocusChain() { return m_parent; }
+ ObjectType *nextInFocusChain() { return m_parent; }
private:
- ObjectType(const ObjectType&);
- ObjectType& operator=(const ObjectType&);
-
- ObjectTypeLayout* takeLayout();
+ ObjectTypeLayout *takeLayout();
ObjectTypeList::iterator findChildByName(const Str &name);
Str m_objectName;
- ObjectType* m_parent;
+ ObjectType *m_parent = nullptr;
ObjectTypeList m_children;
- ObjectTypeLayout* m_layout;
-
-
+ ObjectTypeLayout *m_layout = nullptr;
//used on overload null test
- int m_call_id;
+ int m_call_id = -1;
};
-LIBSAMPLE_API unsigned int objectTypeHash(const ObjectType* objectType);
+LIBSAMPLE_API unsigned int objectTypeHash(const ObjectType *objectType);
class LIBSAMPLE_API OtherBase {
public:
- OtherBase() {};
+ LIBMINIMAL_DISABLE_COPY_MOVE(OtherBase)
+
+ OtherBase() noexcept = default;
virtual ~OtherBase();
};
class LIBSAMPLE_API ObjectTypeDerived: public ObjectType, public OtherBase {
public:
- ObjectTypeDerived(): ObjectType(), OtherBase() {};
+ LIBMINIMAL_DISABLE_COPY_MOVE(ObjectTypeDerived)
- bool event(Event* event) override;
+ ObjectTypeDerived() noexcept = default;
+
+ bool event(Event *event) override;
~ObjectTypeDerived() override;
};
#endif // OBJECTTYPE_H
-
diff --git a/sources/shiboken6/tests/libsample/objecttypebyvalue.h b/sources/shiboken6/tests/libsample/objecttypebyvalue.h
index 0d7ac0160..7b12ff945 100644
--- a/sources/shiboken6/tests/libsample/objecttypebyvalue.h
+++ b/sources/shiboken6/tests/libsample/objecttypebyvalue.h
@@ -3,13 +3,15 @@
#ifndef OBJECTTYPEBYVALUE_H
#define OBJECTTYPEBYVALUE_H
-#include <list>
+
#include "protected.h"
+#include <list>
+
class ObjectTypeByValue
{
public:
- ObjectTypeByValue returnSomeKindOfMe() { return ObjectTypeByValue(); }
+ ObjectTypeByValue returnSomeKindOfMe() { return {}; }
void acceptKindOfMeAsValue(ObjectTypeByValue kindOfMe);
void acceptListOfObjectTypeByValue(std::list<ObjectTypeByValue> listOfMe);
diff --git a/sources/shiboken6/tests/libsample/objecttypeholder.cpp b/sources/shiboken6/tests/libsample/objecttypeholder.cpp
index 076023470..c0950d09c 100644
--- a/sources/shiboken6/tests/libsample/objecttypeholder.cpp
+++ b/sources/shiboken6/tests/libsample/objecttypeholder.cpp
@@ -3,14 +3,14 @@
#include "objecttypeholder.h"
-ObjectTypeHolder::ObjectTypeHolder(const char* objectName)
+ObjectTypeHolder::ObjectTypeHolder(const char *objectName)
{
- auto object = new ObjectType();
+ auto *object = new ObjectType();
object->setObjectName(objectName);
m_objectType = object;
}
-ObjectTypeHolder::ObjectTypeHolder(const ObjectType *object) :
+ObjectTypeHolder::ObjectTypeHolder(const ObjectType *object) noexcept :
m_objectType(object)
{
}
@@ -20,14 +20,12 @@ ObjectTypeHolder::~ObjectTypeHolder()
delete m_objectType;
}
-Str
-ObjectTypeHolder::passObjectTypeAsReference(const ObjectType& objectType)
+Str ObjectTypeHolder::passObjectTypeAsReference(const ObjectType &objectType)
{
return objectType.objectName();
}
-Str
-ObjectTypeHolder::callPassObjectTypeAsReference()
+Str ObjectTypeHolder::callPassObjectTypeAsReference()
{
return passObjectTypeAsReference(*m_objectType);
}
diff --git a/sources/shiboken6/tests/libsample/objecttypeholder.h b/sources/shiboken6/tests/libsample/objecttypeholder.h
index f0ddd97b2..190664608 100644
--- a/sources/shiboken6/tests/libsample/objecttypeholder.h
+++ b/sources/shiboken6/tests/libsample/objecttypeholder.h
@@ -11,17 +11,19 @@
class LIBSAMPLE_API ObjectTypeHolder
{
public:
- explicit ObjectTypeHolder(const char* objectName);
- explicit ObjectTypeHolder(const ObjectType *object = ObjectType::defaultInstance());
+ LIBMINIMAL_DISABLE_COPY_MOVE(ObjectTypeHolder)
+
+ explicit ObjectTypeHolder(const char *objectName);
+ explicit ObjectTypeHolder(const ObjectType *object) noexcept;
virtual ~ObjectTypeHolder();
- const ObjectType* getObjecType() { return m_objectType; }
+ const ObjectType *getObjectType() const { return m_objectType; }
- virtual Str passObjectTypeAsReference(const ObjectType& objectType);
+ virtual Str passObjectTypeAsReference(const ObjectType &objectType);
Str callPassObjectTypeAsReference();
private:
const ObjectType *m_objectType;
};
-#endif
+#endif // OBJECTTYPEHOLDER_H
diff --git a/sources/shiboken6/tests/libsample/objecttypelayout.cpp b/sources/shiboken6/tests/libsample/objecttypelayout.cpp
index 2fbd20ccf..3fa02917c 100644
--- a/sources/shiboken6/tests/libsample/objecttypelayout.cpp
+++ b/sources/shiboken6/tests/libsample/objecttypelayout.cpp
@@ -2,17 +2,16 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "objecttypelayout.h"
-#include <iostream>
-using namespace std;
+#include <iostream>
-void ObjectTypeLayout::addObject(ObjectType* obj)
+void ObjectTypeLayout::addObject(ObjectType *obj)
{
if (obj->isLayoutType()) {
- ObjectTypeLayout* l = reinterpret_cast<ObjectTypeLayout*>(obj);
+ auto *l = reinterpret_cast<ObjectTypeLayout*>(obj);
if (l->parent()) {
- cerr << "[WARNING] ObjectTypeLayout::addObject: layout '" << l->objectName().cstring();
- cerr << "' already has a parent." << endl;
+ std::cerr << "[WARNING] ObjectTypeLayout::addObject: layout '"
+ << l->objectName().cstring() << "' already has a parent.\n";
return;
}
@@ -25,12 +24,12 @@ void ObjectTypeLayout::addObject(ObjectType* obj)
m_objects.push_back(obj);
}
-std::list< ObjectType* > ObjectTypeLayout::objects() const
+std::list<ObjectType*> ObjectTypeLayout::objects() const
{
return m_objects;
}
-void ObjectTypeLayout::reparentChildren(ObjectType* parent)
+void ObjectTypeLayout::reparentChildren(ObjectType *parent)
{
for (auto *o : m_objects) {
if (o->isLayoutType())
@@ -39,4 +38,3 @@ void ObjectTypeLayout::reparentChildren(ObjectType* parent)
o->setParent(parent);
}
}
-
diff --git a/sources/shiboken6/tests/libsample/objecttypelayout.h b/sources/shiboken6/tests/libsample/objecttypelayout.h
index 98eb30946..0aa9fad6e 100644
--- a/sources/shiboken6/tests/libsample/objecttypelayout.h
+++ b/sources/shiboken6/tests/libsample/objecttypelayout.h
@@ -6,6 +6,7 @@
#include "libsamplemacros.h"
#include "objecttype.h"
+
#include <list>
class ObjectType;
@@ -13,19 +14,19 @@ class ObjectType;
class LIBSAMPLE_API ObjectTypeLayout : public ObjectType
{
public:
- void addObject(ObjectType* obj);
+ void addObject(ObjectType *obj);
std::list<ObjectType*> objects() const;
bool isLayoutType() override { return true; }
- inline static ObjectTypeLayout* create() { return new ObjectTypeLayout(); }
+ inline static ObjectTypeLayout *create() { return new ObjectTypeLayout(); }
+
+ ObjectType *takeChild(const Str &name) override { return ObjectType::takeChild(name); }
- ObjectType* takeChild(const Str& name) override { return ObjectType::takeChild(name); }
private:
std::list<ObjectType*> m_objects;
- void reparentChildren(ObjectType* parent);
- friend LIBSAMPLE_API void ObjectType::setLayout(ObjectTypeLayout* l);
+ void reparentChildren(ObjectType *parent);
+ friend LIBSAMPLE_API void ObjectType::setLayout(ObjectTypeLayout *l);
};
#endif // OBJECTTYPELAYOUT_H
-
diff --git a/sources/shiboken6/tests/libsample/objecttypeoperators.cpp b/sources/shiboken6/tests/libsample/objecttypeoperators.cpp
index 05f229a81..c78387a3e 100644
--- a/sources/shiboken6/tests/libsample/objecttypeoperators.cpp
+++ b/sources/shiboken6/tests/libsample/objecttypeoperators.cpp
@@ -7,32 +7,32 @@ ObjectTypeOperators::ObjectTypeOperators(const std::string key) : m_key(key)
{
}
-bool ObjectTypeOperators::operator==(const ObjectTypeOperators& other) const
+bool ObjectTypeOperators::operator==(const ObjectTypeOperators &other) const
{
return m_key == other.m_key;
}
-const ObjectTypeOperators& ObjectTypeOperators::operator<(const ObjectTypeOperators& other) const
+const ObjectTypeOperators &ObjectTypeOperators::operator<(const ObjectTypeOperators &other) const
{
return m_key < other.m_key ? *this : other;
}
-bool operator==(const ObjectTypeOperators* obj, const std::string& str)
+bool operator==(const ObjectTypeOperators *obj, const std::string &str)
{
return obj->key() == str;
}
-bool operator==(const std::string& str, const ObjectTypeOperators* obj)
+bool operator==(const std::string &str, const ObjectTypeOperators *obj)
{
return str == obj->key();
}
-std::string operator+(const ObjectTypeOperators* obj, const std::string& str)
+std::string operator+(const ObjectTypeOperators *obj, const std::string &str)
{
return obj->key() + str;
}
-std::string operator+(const std::string& str, const ObjectTypeOperators* obj)
+std::string operator+(const std::string &str, const ObjectTypeOperators *obj)
{
return str + obj->key();
}
diff --git a/sources/shiboken6/tests/libsample/objecttypeoperators.h b/sources/shiboken6/tests/libsample/objecttypeoperators.h
index b768359a3..6144952ca 100644
--- a/sources/shiboken6/tests/libsample/objecttypeoperators.h
+++ b/sources/shiboken6/tests/libsample/objecttypeoperators.h
@@ -5,32 +5,32 @@
#define OBJECTTYPEOPERATORS_H
#include "libsamplemacros.h"
+
#include <string>
class LIBSAMPLE_API ObjectTypeOperators
{
public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(ObjectTypeOperators)
+
explicit ObjectTypeOperators(const std::string key);
- virtual ~ObjectTypeOperators() {}
+ virtual ~ObjectTypeOperators() = default;
- bool operator==(const ObjectTypeOperators& other) const;
- const ObjectTypeOperators& operator<(const ObjectTypeOperators& other) const;
+ bool operator==(const ObjectTypeOperators &other) const;
+ const ObjectTypeOperators &operator<(const ObjectTypeOperators &other) const;
// chaos!
- virtual void operator>(const ObjectTypeOperators&) { m_key.append("operator>"); }
+ virtual void operator>(const ObjectTypeOperators &) { m_key.append("operator>"); }
std::string key() const { return m_key; }
private:
std::string m_key;
-
- ObjectTypeOperators(ObjectTypeOperators&);
- ObjectTypeOperators& operator=(ObjectTypeOperators&);
};
-LIBSAMPLE_API bool operator==(const ObjectTypeOperators* obj, const std::string& str);
-LIBSAMPLE_API bool operator==(const std::string& str, const ObjectTypeOperators* obj);
-LIBSAMPLE_API std::string operator+(const ObjectTypeOperators* obj, const std::string& str);
-LIBSAMPLE_API std::string operator+(const std::string& str, const ObjectTypeOperators* obj);
+LIBSAMPLE_API bool operator==(const ObjectTypeOperators *obj, const std::string &str);
+LIBSAMPLE_API bool operator==(const std::string &str, const ObjectTypeOperators *obj);
+LIBSAMPLE_API std::string operator+(const ObjectTypeOperators *obj, const std::string &str);
+LIBSAMPLE_API std::string operator+(const std::string &str, const ObjectTypeOperators *obj);
#endif // OBJECTTYPEOPERATORS_H
diff --git a/sources/shiboken6/tests/libsample/objectview.cpp b/sources/shiboken6/tests/libsample/objectview.cpp
index 5717053a7..1b727f88c 100644
--- a/sources/shiboken6/tests/libsample/objectview.cpp
+++ b/sources/shiboken6/tests/libsample/objectview.cpp
@@ -5,25 +5,20 @@
#include "objectmodel.h"
#include "str.h"
-Str
-ObjectView::displayModelData()
+Str ObjectView::displayModelData()
{
if (!m_model)
- return Str("(NULL)");
+ return {"(NULL)"};
return Str("Name: %VAR").arg(m_model->objectName());
}
-void
-ObjectView::modifyModelData(Str& data)
+void ObjectView::modifyModelData(Str &data)
{
if (m_model)
m_model->setObjectName(data);
}
-
-ObjectType*
-ObjectView::getRawModelData()
+ObjectType *ObjectView::getRawModelData()
{
return m_model->data();
}
-
diff --git a/sources/shiboken6/tests/libsample/objectview.h b/sources/shiboken6/tests/libsample/objectview.h
index 1de474ff2..2567deee5 100644
--- a/sources/shiboken6/tests/libsample/objectview.h
+++ b/sources/shiboken6/tests/libsample/objectview.h
@@ -13,21 +13,19 @@ class ObjectModel;
class LIBSAMPLE_API ObjectView : public ObjectType
{
public:
- ObjectView(ObjectModel *model = nullptr, ObjectType *parent = nullptr)
- : ObjectType(parent), m_model(model)
- {}
+ explicit ObjectView(ObjectModel *model = nullptr, ObjectType *parent = nullptr)
+ : ObjectType(parent), m_model(model) {}
- inline void setModel(ObjectModel* model) { m_model = model; }
- inline ObjectModel* model() const { return m_model; }
+ inline void setModel(ObjectModel *model) { m_model = model; }
+ inline ObjectModel *model() const { return m_model; }
Str displayModelData();
- void modifyModelData(Str& data);
+ void modifyModelData(Str &data);
- ObjectType* getRawModelData();
+ ObjectType *getRawModelData();
private:
- ObjectModel* m_model;
+ ObjectModel *m_model;
};
#endif // OBJECTVIEW_H
-
diff --git a/sources/shiboken6/tests/libsample/oddbool.cpp b/sources/shiboken6/tests/libsample/oddbool.cpp
index 06a61f1c2..bc1ee833f 100644
--- a/sources/shiboken6/tests/libsample/oddbool.cpp
+++ b/sources/shiboken6/tests/libsample/oddbool.cpp
@@ -7,7 +7,7 @@ ComparisonTester::ComparisonTester(int v) : m_value(v)
{
}
-ComparisonTester& ComparisonTester::operator=(int v)
+ComparisonTester &ComparisonTester::operator=(int v)
{
m_value = v;
return *this;
diff --git a/sources/shiboken6/tests/libsample/oddbool.h b/sources/shiboken6/tests/libsample/oddbool.h
index a64a05eb3..dd2d32604 100644
--- a/sources/shiboken6/tests/libsample/oddbool.h
+++ b/sources/shiboken6/tests/libsample/oddbool.h
@@ -16,7 +16,7 @@ class OddBool
{
public:
- inline explicit OddBool(bool b) : m_value(b) {}
+ inline explicit OddBool(bool b) noexcept : m_value(b) {}
bool value() const { return m_value; }
inline OddBool operator!() const { return OddBool(!m_value); }
@@ -35,9 +35,11 @@ inline bool operator!=(OddBool b1, OddBool b2) { return (!b1).value() != (!b2).v
class OddBoolUser
{
public:
- OddBoolUser() : m_oddbool(OddBool(false)) {}
- OddBoolUser(const OddBool& oddBool) : m_oddbool(oddBool) {}
- virtual ~OddBoolUser() {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(OddBoolUser)
+
+ OddBoolUser() noexcept : m_oddbool(OddBool(false)) {}
+ OddBoolUser(const OddBool &oddBool) : m_oddbool(oddBool) {}
+ virtual ~OddBoolUser() = default;
inline OddBool oddBool() { return m_oddbool; }
inline void setOddBool(OddBool oddBool) { m_oddbool = oddBool; }
@@ -52,7 +54,7 @@ public:
return invertedOddBool();
}
- static inline OddBool getOddBool(const OddBoolUser& oddBoolUser)
+ static inline OddBool getOddBool(const OddBoolUser &oddBoolUser)
{
return oddBoolUser.m_oddbool;
}
diff --git a/sources/shiboken6/tests/libsample/onlycopy.cpp b/sources/shiboken6/tests/libsample/onlycopy.cpp
index 6fa4ad064..981ea88a4 100644
--- a/sources/shiboken6/tests/libsample/onlycopy.cpp
+++ b/sources/shiboken6/tests/libsample/onlycopy.cpp
@@ -11,45 +11,23 @@ public:
int value;
};
-OnlyCopy::OnlyCopy(int value) : d(new OnlyCopyPrivate(value))
+OnlyCopy::OnlyCopy(int value) : d(std::make_shared<OnlyCopyPrivate>(value))
{
-
}
-OnlyCopy::OnlyCopy(OnlyCopyPrivate *dIn) : d(dIn)
-{
-}
-
-OnlyCopy::~OnlyCopy()
-{
- delete d;
-}
-
-OnlyCopy::OnlyCopy(const OnlyCopy& other) : d(new OnlyCopyPrivate(other.value()))
-{
-}
-
-OnlyCopy&
-OnlyCopy::operator=(const OnlyCopy& other)
-{
- d->value = other.d->value;
- return *this;
-}
+OnlyCopy::~OnlyCopy() = default;
int OnlyCopy::value() const
{
return d->value;
}
-OnlyCopy
-FriendOfOnlyCopy::createOnlyCopy(int value)
+OnlyCopy FriendOfOnlyCopy::createOnlyCopy(int value)
{
-
return OnlyCopy(value);
}
-std::list<OnlyCopy>
-FriendOfOnlyCopy::createListOfOnlyCopy(int quantity)
+std::list<OnlyCopy> FriendOfOnlyCopy::createListOfOnlyCopy(int quantity)
{
std::list<OnlyCopy> list;
for (int i = 0; i < quantity; ++i)
diff --git a/sources/shiboken6/tests/libsample/onlycopy.h b/sources/shiboken6/tests/libsample/onlycopy.h
index e7c411a18..7dc3e0069 100644
--- a/sources/shiboken6/tests/libsample/onlycopy.h
+++ b/sources/shiboken6/tests/libsample/onlycopy.h
@@ -5,7 +5,9 @@
#define ONLYCOPYCLASS_H
#include "libsamplemacros.h"
+
#include <list>
+#include <memory>
// These classes simulate a situation found in QWebEngineHistoryItem.
@@ -14,18 +16,20 @@ class OnlyCopyPrivate;
class LIBSAMPLE_API OnlyCopy
{
public:
- OnlyCopy(const OnlyCopy& other);
- OnlyCopy& operator=(const OnlyCopy& other);
+ LIBMINIMAL_DEFAULT_COPY_MOVE(OnlyCopy)
+
~OnlyCopy();
int value() const;
static int getValue(OnlyCopy onlyCopy) { return onlyCopy.value(); }
- static int getValueFromReference(const OnlyCopy& onlyCopy) { return onlyCopy.value(); }
+ static int getValueFromReference(const OnlyCopy &onlyCopy) { return onlyCopy.value(); }
+
private:
- OnlyCopyPrivate *d;
- explicit OnlyCopy(int value);
- explicit OnlyCopy(OnlyCopyPrivate *d); // rejected due to unknown OnlyCopyPrivate
friend class FriendOfOnlyCopy;
+
+ explicit OnlyCopy(int value);
+
+ std::shared_ptr<OnlyCopyPrivate> d;
};
class LIBSAMPLE_API FriendOfOnlyCopy
@@ -35,4 +39,4 @@ public:
static std::list<OnlyCopy> createListOfOnlyCopy(int quantity);
};
-#endif
+#endif // ONLYCOPYCLASS_H
diff --git a/sources/shiboken6/tests/libsample/overload.cpp b/sources/shiboken6/tests/libsample/overload.cpp
index d533b4014..34da28e03 100644
--- a/sources/shiboken6/tests/libsample/overload.cpp
+++ b/sources/shiboken6/tests/libsample/overload.cpp
@@ -35,11 +35,13 @@ int Overload::differentReturnTypes(ParamEnum, int val)
int Overload::intOverloads(const Point &, double)
{
- return 1; }
+ return 1;
+}
int Overload::intOverloads(int, int)
{
- return 2; }
+ return 2;
+}
int Overload::intOverloads(int, int, double)
{
diff --git a/sources/shiboken6/tests/libsample/overload.h b/sources/shiboken6/tests/libsample/overload.h
index 91de8a963..b640bf7c7 100644
--- a/sources/shiboken6/tests/libsample/overload.h
+++ b/sources/shiboken6/tests/libsample/overload.h
@@ -17,6 +17,8 @@
class LIBSAMPLE_API Overload
{
public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Overload)
+
enum FunctionEnum {
Function0,
Function1,
@@ -32,13 +34,13 @@ public:
Param1
};
- Overload() {}
- virtual ~Overload() {}
+ Overload() noexcept = default;
+ virtual ~Overload() = default;
FunctionEnum overloaded();
- FunctionEnum overloaded(Size* size);
- FunctionEnum overloaded(Point* point, ParamEnum param);
- FunctionEnum overloaded(const Point& point);
+ FunctionEnum overloaded(Size *size);
+ FunctionEnum overloaded(Point *point, ParamEnum param);
+ FunctionEnum overloaded(const Point &point);
void differentReturnTypes(ParamEnum param = Param0);
int differentReturnTypes(ParamEnum param, int val);
@@ -51,7 +53,7 @@ public:
FunctionEnum intDoubleOverloads(double a0, double a1) const;
void singleOverload(Point *x);
- Point* singleOverload() {return new Point();}
+ Point *singleOverload() { return new Point(); }
// Similar to QImage::trueMatrix(QMatrix,int,int) and QImage::trueMatrix(QTransform,int,int)
FunctionEnum wrapperIntIntOverloads(const Point &arg0, int arg1, int arg2);
@@ -60,7 +62,7 @@ public:
// Similar to QImage constructor
FunctionEnum strBufferOverloads(const Str &arg0, const char *arg1 = nullptr,
bool arg2 = true);
- FunctionEnum strBufferOverloads(unsigned char* arg0, int arg1);
+ FunctionEnum strBufferOverloads(unsigned char *arg0, int arg1);
FunctionEnum strBufferOverloads() { return Function2; }
// Similar to QPainter::drawText(...)
@@ -95,7 +97,7 @@ public:
FunctionEnum acceptSequence(const Str &a0, ParamEnum a1 = Param0);
FunctionEnum acceptSequence(const Size &a0);
// The type must be changed to PySequence.
- FunctionEnum acceptSequence(const char* const a0[]);
+ FunctionEnum acceptSequence(const char *const a0[]);
FunctionEnum acceptSequence(void *a0);
};
diff --git a/sources/shiboken6/tests/libsample/overloadsort.h b/sources/shiboken6/tests/libsample/overloadsort.h
index 473828da9..ee269cc21 100644
--- a/sources/shiboken6/tests/libsample/overloadsort.h
+++ b/sources/shiboken6/tests/libsample/overloadsort.h
@@ -11,13 +11,13 @@
class ImplicitTarget
{
public:
- ImplicitTarget(){}
+ ImplicitTarget() = default;
};
class ImplicitBase
{
public:
- ImplicitBase(){}
+ ImplicitBase() = default;
ImplicitBase(const ImplicitTarget &b);
};
@@ -39,9 +39,9 @@ public:
const char *overloadDeep(int x, ImplicitBase &y);
- inline const char* pyObjOverload(int, int) { return "int,int"; }
- inline const char* pyObjOverload(unsigned char*, int) { return "PyObject,int"; }
-
+ inline const char *pyObjOverload(int, int) { return "int,int"; }
+ inline const char *pyObjOverload(unsigned char *, int)
+ { return "PyObject,int"; }
};
class LIBSAMPLE_API CustomOverloadSequence
@@ -52,4 +52,3 @@ public:
};
#endif // OVERLOADSORT_H
-
diff --git a/sources/shiboken6/tests/libsample/pairuser.cpp b/sources/shiboken6/tests/libsample/pairuser.cpp
index f1f182c5a..5b7eb4d8c 100644
--- a/sources/shiboken6/tests/libsample/pairuser.cpp
+++ b/sources/shiboken6/tests/libsample/pairuser.cpp
@@ -1,32 +1,24 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
#include "pairuser.h"
-using namespace std;
-
-std::pair<int, int>
-PairUser::callCreatePair()
+std::pair<int, int> PairUser::callCreatePair()
{
return createPair();
}
-std::pair<int, int>
-PairUser::createPair()
+std::pair<int, int> PairUser::createPair()
{
- return std::pair<int, int>(10, 20);
+ return {10, 20};
}
-std::pair<Complex, Complex>
-PairUser::createComplexPair(Complex cpx0, Complex cpx1)
+std::pair<Complex, Complex> PairUser::createComplexPair(Complex cpx0, Complex cpx1)
{
- return std::pair<Complex, Complex>(cpx0, cpx1);
+ return {cpx0, cpx1};
}
-double
-PairUser::sumPair(std::pair<int, double> pair)
+double PairUser::sumPair(std::pair<int, double> pair)
{
return ((double) pair.first) + pair.second;
}
-
diff --git a/sources/shiboken6/tests/libsample/pairuser.h b/sources/shiboken6/tests/libsample/pairuser.h
index 313651c06..ee51d818e 100644
--- a/sources/shiboken6/tests/libsample/pairuser.h
+++ b/sources/shiboken6/tests/libsample/pairuser.h
@@ -4,16 +4,18 @@
#ifndef PAIRUSER_H
#define PAIRUSER_H
-#include <utility>
+#include "libsamplemacros.h"
#include "complex.h"
-#include "libsamplemacros.h"
+#include <utility>
class LIBSAMPLE_API PairUser
{
public:
- PairUser() {}
- virtual ~PairUser() {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(PairUser)
+
+ PairUser() noexcept = default;
+ virtual ~PairUser() = default;
virtual std::pair<int, int> createPair();
std::pair<int, int> callCreatePair();
@@ -26,5 +28,5 @@ public:
private:
std::pair<int, int> m_pair;
};
-#endif // PAIRUSER_H
+#endif // PAIRUSER_H
diff --git a/sources/shiboken6/tests/libsample/pen.cpp b/sources/shiboken6/tests/libsample/pen.cpp
index 8e216323f..76473a264 100644
--- a/sources/shiboken6/tests/libsample/pen.cpp
+++ b/sources/shiboken6/tests/libsample/pen.cpp
@@ -45,9 +45,7 @@ void Brush::setColor(const Color &newColor)
m_color = newColor;
}
-Pen::Pen() : m_ctor(EmptyCtor)
-{
-}
+Pen::Pen() = default;
Pen::Pen(SampleNamespace::Option) : m_ctor(EnumCtor)
{
@@ -61,9 +59,9 @@ Pen::Pen(const Pen &) : m_ctor(CopyCtor)
{
}
-Pen::Pen(Pen &&) = default;
-Pen &Pen::operator=(const Pen& pen) = default;
-Pen &Pen::operator=(Pen &&) = default;
+Pen::Pen(Pen &&) noexcept = default;
+Pen &Pen::operator=(const Pen &pen) = default;
+Pen &Pen::operator=(Pen &&) noexcept = default;
int Pen::ctorType()
{
diff --git a/sources/shiboken6/tests/libsample/pen.h b/sources/shiboken6/tests/libsample/pen.h
index 114810d25..6f528f0f9 100644
--- a/sources/shiboken6/tests/libsample/pen.h
+++ b/sources/shiboken6/tests/libsample/pen.h
@@ -15,6 +15,7 @@ public:
Color(unsigned int arg);
bool isNull() const;
+
private:
bool m_null = true;
};
@@ -48,11 +49,12 @@ public:
Pen();
Pen(SampleNamespace::Option option);
- Pen(const Color& color);
+ Pen(const Color &color);
Pen(const Pen &pen);
- Pen(Pen &&);
+ Pen(Pen &&) noexcept;
Pen &operator=(const Pen &pen);
- Pen &operator=(Pen &&);
+ Pen &operator=(Pen &&) noexcept;
+ ~Pen() = default;
// PYSIDE-1325, default initializer
void drawLine(int x1, int y1, int x2, int y2, RenderHints renderHints = {});
@@ -63,7 +65,7 @@ public:
void setRenderHints(RenderHints h);
private:
- int m_ctor;
+ int m_ctor = EmptyCtor;
RenderHints m_renderHints = None;
};
diff --git a/sources/shiboken6/tests/libsample/photon.cpp b/sources/shiboken6/tests/libsample/photon.cpp
index f98a7c891..2a7f20e33 100644
--- a/sources/shiboken6/tests/libsample/photon.cpp
+++ b/sources/shiboken6/tests/libsample/photon.cpp
@@ -5,21 +5,27 @@
namespace Photon
{
+
const ClassType Base::staticType;
-int callCalculateForValueDuplicatorPointer(ValueDuplicator* value)
+
+int callCalculateForValueDuplicatorPointer(ValueDuplicator *value)
{
return value->calculate();
}
-int callCalculateForValueDuplicatorReference(ValueDuplicator& value)
+
+int callCalculateForValueDuplicatorReference(ValueDuplicator &value)
{
return value.calculate();
}
-int countValueIdentities(const std::list<ValueIdentity>& values)
+
+int countValueIdentities(const std::list<ValueIdentity> &values)
{
return values.size();
}
-int countValueDuplicators(const std::list<TemplateBase<DuplicatorType> >& values)
+
+int countValueDuplicators(const std::list<TemplateBase<DuplicatorType> > &values)
{
return values.size();
}
+
} // namespace Photon
diff --git a/sources/shiboken6/tests/libsample/photon.h b/sources/shiboken6/tests/libsample/photon.h
index 2fbf87d25..2debe47d1 100644
--- a/sources/shiboken6/tests/libsample/photon.h
+++ b/sources/shiboken6/tests/libsample/photon.h
@@ -4,9 +4,10 @@
#ifndef PHOTON_H
#define PHOTON_H
-#include <list>
#include "libsamplemacros.h"
+#include <list>
+
// This namespace and classes simulate
// situations found in Qt's phonon module.
@@ -22,8 +23,11 @@ enum ClassType {
class LIBSAMPLE_API Base
{
public:
- explicit Base(int value) : m_value(value) {}
- virtual ~Base() {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Base)
+
+ explicit Base(int value) noexcept : m_value(value) {}
+ virtual ~Base() = default;
+
inline void setValue(int value) { m_value = value; }
inline int value() const { return m_value; }
@@ -42,12 +46,14 @@ class LIBSAMPLE_API TemplateBase : public Base
{
public:
explicit TemplateBase(int value) : Base(value) {}
- inline int multiplicator() const { return (int)CLASS_TYPE; }
- inline int calculate() const { return m_value * ((int)CLASS_TYPE); }
+ inline int multiplicator() const { return int(CLASS_TYPE); }
+ inline int calculate() const { return m_value * (int(CLASS_TYPE)); }
static inline ClassType classType() { return CLASS_TYPE; }
- inline int sumValueUsingPointer(TemplateBase<CLASS_TYPE>* other) const { return m_value + other->m_value; }
- inline int sumValueUsingReference(TemplateBase<CLASS_TYPE>& other) const { return m_value + other.m_value; }
+ inline int sumValueUsingPointer(TemplateBase<CLASS_TYPE> *other) const
+ { return m_value + other->m_value; }
+ inline int sumValueUsingReference(TemplateBase<CLASS_TYPE> &other) const
+ { return m_value + other.m_value; }
inline std::list<TemplateBase<CLASS_TYPE> > getListOfThisTemplateBase()
{
@@ -57,7 +63,8 @@ public:
return objs;
}
- static inline TemplateBase<CLASS_TYPE>* passPointerThrough(TemplateBase<CLASS_TYPE>* obj) { return obj; }
+ static inline TemplateBase<CLASS_TYPE> *passPointerThrough(TemplateBase<CLASS_TYPE> *obj)
+ { return obj; }
ClassType type() const override { return CLASS_TYPE; }
static const ClassType staticType = CLASS_TYPE;
@@ -71,43 +78,31 @@ template class LIBSAMPLE_API TemplateBase<DuplicatorType>;
using ValueIdentity = TemplateBase<IdentityType>;
using ValueDuplicator = TemplateBase<DuplicatorType>;
-LIBSAMPLE_API int callCalculateForValueDuplicatorPointer(ValueDuplicator* value);
-LIBSAMPLE_API int callCalculateForValueDuplicatorReference(ValueDuplicator& value);
-LIBSAMPLE_API int countValueIdentities(const std::list<ValueIdentity>& values);
-LIBSAMPLE_API int countValueDuplicators(const std::list<TemplateBase<DuplicatorType> >& values);
-
-// This simulates an internal error (SEGV) caused by 'noexcept' in
-// boost::intrusive_ptr before support for 'noexcept' was added. The ENTIRE
-// code below is needed to trigger the exception; it isn't seen with just a
-// 'noexcept' following a declaration.
-//
-// NOTE: For reasons that should be fairly obvious, this test unfortunately can
-// only be "run" when building in C++11 mode.
-#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
-# define PHOTON_NOEXCEPT noexcept
-#else
-# define PHOTON_NOEXCEPT
-#endif
+LIBSAMPLE_API int callCalculateForValueDuplicatorPointer(ValueDuplicator *value);
+LIBSAMPLE_API int callCalculateForValueDuplicatorReference(ValueDuplicator &value);
+LIBSAMPLE_API int countValueIdentities(const std::list<ValueIdentity> &values);
+LIBSAMPLE_API int countValueDuplicators(const std::list<TemplateBase<DuplicatorType> > &values);
+
class Pointer
{
public:
- Pointer() PHOTON_NOEXCEPT : px(nullptr) {}
- Pointer(int* p) : px(p) {}
+ Pointer() noexcept = default;
+ explicit Pointer(int *p) : px(p) {}
- void reset() PHOTON_NOEXCEPT { Pointer().swap(*this); }
+ void reset() noexcept { Pointer().swap(*this); }
- int* get() const PHOTON_NOEXCEPT { return px; }
- int& operator*() const { return *px; }
+ int *get() const noexcept { return px; }
+ int &operator*() const { return *px; }
- void swap(Pointer& rhs) PHOTON_NOEXCEPT
+ void swap(Pointer &rhs) noexcept
{
- int* tmp = px;
+ int *tmp = px;
px = rhs.px;
rhs.px = tmp;
}
private:
- int* px;
+ int *px = nullptr;
};
} // namespace Photon
diff --git a/sources/shiboken6/tests/libsample/point.cpp b/sources/shiboken6/tests/libsample/point.cpp
index 397dea3e6..0a28e877f 100644
--- a/sources/shiboken6/tests/libsample/point.cpp
+++ b/sources/shiboken6/tests/libsample/point.cpp
@@ -1,21 +1,19 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
#include "point.h"
-using namespace std;
+#include <iostream>
-Point::Point(int x, int y) : m_x(x), m_y(y)
+Point::Point(int x, int y) noexcept : m_x(x), m_y(y)
{
}
-Point::Point(double x, double y) : m_x(x), m_y(y)
+Point::Point(double x, double y) noexcept : m_x(x), m_y(y)
{
}
-void
-Point::midpoint(const Point& other, Point* midpoint) const
+void Point::midpoint(const Point &other, Point *midpoint) const
{
if (!midpoint)
return;
@@ -23,108 +21,91 @@ Point::midpoint(const Point& other, Point* midpoint) const
midpoint->setY((m_y + other.m_y) / 2.0);
}
-Point*
-Point::copy() const
+Point *Point::copy() const
{
- Point* pt = new Point();
+ Point *pt = new Point();
pt->m_x = m_x;
pt->m_y = m_y;
return pt;
}
-void
-Point::show()
+void Point::show() const
{
- cout << "(x: " << m_x << ", y: " << m_y << ")";
+ std::cout << "(x: " << m_x << ", y: " << m_y << ")";
}
-bool
-Point::operator==(const Point& other)
+bool Point::operator==(const Point &other) const
{
return m_x == other.m_x && m_y == other.m_y;
}
-Point
-Point::operator+(const Point& other)
+Point Point::operator+(const Point &other)
{
- return Point(m_x + other.m_x, m_y + other.m_y);
+ return {m_x + other.m_x, m_y + other.m_y};
}
-Point
-Point::operator-(const Point& other)
+Point Point::operator-(const Point &other)
{
- return Point(m_x - other.m_x, m_y - other.m_y);
+ return {m_x - other.m_x, m_y - other.m_y};
}
-Point&
-Point::operator+=(Point &other)
+Point &Point::operator+=(Point &other)
{
m_x += other.m_x;
m_y += other.m_y;
return *this;
}
-Point&
-Point::operator-=(Point &other)
+Point &Point::operator-=(Point &other)
{
m_x -= other.m_x;
m_y -= other.m_y;
return *this;
}
-Point
-operator*(const Point& pt, double mult)
+Point operator*(const Point &pt, double mult)
{
return Point(pt.m_x * mult, pt.m_y * mult);
}
-Point
-operator*(const Point& pt, int mult)
+Point operator*(const Point &pt, int mult)
{
- return Point(((int) pt.m_x) * mult, ((int) pt.m_y) * mult);
+ return {int(pt.m_x) * mult, int(pt.m_y) * mult};
}
-Point
-operator*(double mult, const Point& pt)
+Point operator*(double mult, const Point &pt)
{
- return Point(pt.m_x * mult, pt.m_y * mult);
+ return {pt.m_x * mult, pt.m_y * mult};
}
-Point
-operator*(int mult, const Point& pt)
+Point operator*(int mult, const Point &pt)
{
- return Point(((int) pt.m_x) * mult, ((int) pt.m_y) * mult);
+ return {int(pt.m_x) * mult, int(pt.m_y) * mult};
}
-Point
-operator-(const Point& pt)
+Point operator-(const Point &pt)
{
- return Point(-pt.m_x, -pt.m_y);
+ return {-pt.m_x, -pt.m_y};
}
-bool
-operator!(const Point& pt)
+bool operator!(const Point &pt)
{
- return (pt.m_x == 0.0 && pt.m_y == 0.0);
+ return pt.m_x == 0.0 && pt.m_y == 0.0;
}
-Point
-Point::operator/(int operand)
+Point Point::operator/(int operand)
{
- return Point(m_x/operand, m_y/operand);
+ return {m_x/operand, m_y/operand};
}
-Complex
-transmutePointIntoComplex(const Point& point)
+Complex transmutePointIntoComplex(const Point &point)
{
Complex cpx(point.x(), point.y());
return cpx;
}
-Point
-transmuteComplexIntoPoint(const Complex& cpx)
+Point transmuteComplexIntoPoint(const Complex &cpx)
{
Point pt(cpx.real(), cpx.imag());
return pt;
}
-
diff --git a/sources/shiboken6/tests/libsample/point.h b/sources/shiboken6/tests/libsample/point.h
index 717658b09..7e5d128ab 100644
--- a/sources/shiboken6/tests/libsample/point.h
+++ b/sources/shiboken6/tests/libsample/point.h
@@ -4,17 +4,19 @@
#ifndef POINT_H
#define POINT_H
+#include "libsamplemacros.h"
#include "complex.h"
-#include <utility>
-#include "libsamplemacros.h"
+#include <utility>
class LIBSAMPLE_API Point
{
public:
- Point(int x = 0, int y = 0);
- Point(double x, double y);
- ~Point() {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Point)
+
+ Point(int x = 0, int y = 0) noexcept;
+ Point(double x, double y) noexcept;
+ ~Point() = default;
inline double x() const { return m_x; }
inline double y() const { return m_y; }
@@ -27,48 +29,48 @@ public:
// This method could simply return the midpoint,
// but the interesting part of the test is to set the
// result in the pointer argument.
- void midpoint(const Point& other, Point* midpoint) const;
+ void midpoint(const Point &other, Point *midpoint) const;
- Point* copy() const;
+ Point *copy() const;
- inline const Point& getConstReferenceToSelf() const { return *this; }
- inline const Point* getSelf() const { return this; }
+ inline const Point &getConstReferenceToSelf() const { return *this; }
+ inline const Point *getSelf() const { return this; }
// The != operator is not implemented for the purpose of testing
// for the absense of the __ne__ method in the Python binding.
- bool operator==(const Point& other);
+ bool operator==(const Point &other) const;
- Point operator+(const Point& other);
- Point operator-(const Point& other);
+ Point operator+(const Point &other);
+ Point operator-(const Point &other);
Point operator/(int operand);
- friend LIBSAMPLE_API Point operator*(const Point& pt, double mult);
- friend LIBSAMPLE_API Point operator*(const Point& pt, int mult);
- friend LIBSAMPLE_API Point operator*(double mult, const Point& pt);
- friend LIBSAMPLE_API Point operator*(int mult, const Point& pt);
- friend LIBSAMPLE_API Point operator-(const Point& pt);
- friend LIBSAMPLE_API bool operator!(const Point& pt);
+ friend LIBSAMPLE_API Point operator*(const Point &pt, double mult);
+ friend LIBSAMPLE_API Point operator*(const Point &pt, int mult);
+ friend LIBSAMPLE_API Point operator*(double mult, const Point &pt);
+ friend LIBSAMPLE_API Point operator*(int mult, const Point &pt);
+ friend LIBSAMPLE_API Point operator-(const Point &pt);
+ friend LIBSAMPLE_API bool operator!(const Point &pt);
- Point& operator+=(Point &other);
- Point& operator-=(Point &other);
+ Point &operator+=(Point &other);
+ Point &operator-=(Point &other);
- void show();
+ void show() const;
private:
double m_x;
double m_y;
};
-LIBSAMPLE_API Point operator*(const Point& pt, double mult);
-LIBSAMPLE_API Point operator*(const Point& pt, int mult);
-LIBSAMPLE_API Point operator*(double mult, const Point& pt);
-LIBSAMPLE_API Point operator*(int mult, const Point& pt);
-LIBSAMPLE_API Point operator-(const Point& pt);
-LIBSAMPLE_API bool operator!(const Point& pt);
+LIBSAMPLE_API Point operator*(const Point &pt, double mult);
+LIBSAMPLE_API Point operator*(const Point &pt, int mult);
+LIBSAMPLE_API Point operator*(double mult, const Point &pt);
+LIBSAMPLE_API Point operator*(int mult, const Point &pt);
+LIBSAMPLE_API Point operator-(const Point &pt);
+LIBSAMPLE_API bool operator!(const Point &pt);
-LIBSAMPLE_API Complex transmutePointIntoComplex(const Point& point);
-LIBSAMPLE_API Point transmuteComplexIntoPoint(const Complex& cpx);
+LIBSAMPLE_API Complex transmutePointIntoComplex(const Point &point);
+LIBSAMPLE_API Point transmuteComplexIntoPoint(const Complex &cpx);
-LIBSAMPLE_API Point operator*(const Point& pt, double multiplier);
+LIBSAMPLE_API Point operator*(const Point &pt, double multiplier);
#endif // POINT_H
diff --git a/sources/shiboken6/tests/libsample/pointerholder.h b/sources/shiboken6/tests/libsample/pointerholder.h
index 36ce32205..26f1cf0a6 100644
--- a/sources/shiboken6/tests/libsample/pointerholder.h
+++ b/sources/shiboken6/tests/libsample/pointerholder.h
@@ -9,12 +9,15 @@
class PointerHolder
{
public:
- explicit PointerHolder(void* ptr) : m_pointer(ptr) {}
- ~PointerHolder() {}
- inline void* pointer() const { return m_pointer; }
+ LIBMINIMAL_DEFAULT_COPY_MOVE(PointerHolder)
+
+ explicit PointerHolder(void *ptr) : m_pointer(ptr) {}
+ ~PointerHolder() = default;
+
+ inline void *pointer() const { return m_pointer; }
+
private:
- void* m_pointer;
+ void *m_pointer;
};
#endif // POINTERHOLDER_H
-
diff --git a/sources/shiboken6/tests/libsample/pointf.cpp b/sources/shiboken6/tests/libsample/pointf.cpp
index f68dd0f41..736a5c6b5 100644
--- a/sources/shiboken6/tests/libsample/pointf.cpp
+++ b/sources/shiboken6/tests/libsample/pointf.cpp
@@ -1,21 +1,19 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
#include "pointf.h"
-using namespace std;
+#include <iostream>
-PointF::PointF(const Point& point) : m_x(point.x()), m_y(point.y())
+PointF::PointF(const Point &point) noexcept : m_x(point.x()), m_y(point.y())
{
}
-PointF::PointF(double x, double y) : m_x(x), m_y(y)
+PointF::PointF(double x, double y) noexcept : m_x(x), m_y(y)
{
}
-void
-PointF::midpoint(const PointF& other, PointF* midpoint) const
+void PointF::midpoint(const PointF &other, PointF *midpoint) const
{
if (!midpoint)
return;
@@ -23,79 +21,66 @@ PointF::midpoint(const PointF& other, PointF* midpoint) const
midpoint->setY((m_y + other.m_y) / 2.0);
}
-void
-PointF::show()
+void PointF::show() const
{
- cout << "(x: " << m_x << ", y: " << m_y << ")";
+ std::cout << "(x: " << m_x << ", y: " << m_y << ")";
}
-bool
-PointF::operator==(const PointF& other)
+bool PointF::operator==(const PointF &other) const
{
return m_x == other.m_x && m_y == other.m_y;
}
-PointF
-PointF::operator+(const PointF& other)
+PointF PointF::operator+(const PointF &other)
{
- return PointF(m_x + other.m_x, m_y + other.m_y);
+ return {m_x + other.m_x, m_y + other.m_y};
}
-PointF
-PointF::operator-(const PointF& other)
+PointF PointF::operator-(const PointF &other)
{
- return PointF(m_x - other.m_x, m_y - other.m_y);
+ return {m_x - other.m_x, m_y - other.m_y};
}
-PointF&
-PointF::operator+=(PointF &other)
+PointF &PointF::operator+=(PointF &other)
{
m_x += other.m_x;
m_y += other.m_y;
return *this;
}
-PointF&
-PointF::operator-=(PointF &other)
+PointF &PointF::operator-=(PointF &other)
{
m_x -= other.m_x;
m_y -= other.m_y;
return *this;
}
-PointF
-operator*(const PointF& pt, double mult)
+PointF operator*(const PointF &pt, double mult)
{
- return PointF(pt.m_x * mult, pt.m_y * mult);
+ return {pt.m_x * mult, pt.m_y * mult};
}
-PointF
-operator*(const PointF& pt, int mult)
+PointF operator*(const PointF &pt, int mult)
{
- return PointF(((int) pt.m_x) * mult, ((int) pt.m_y) * mult);
+ return PointF(int(pt.m_x) * mult, int(pt.m_y) * mult);
}
-PointF
-operator*(double mult, const PointF& pt)
+PointF operator*(double mult, const PointF &pt)
{
- return PointF(pt.m_x * mult, pt.m_y * mult);
+ return {pt.m_x * mult, pt.m_y * mult};
}
-PointF
-operator*(int mult, const PointF& pt)
+PointF operator*(int mult, const PointF &pt)
{
- return PointF(((int) pt.m_x) * mult, ((int) pt.m_y) * mult);
+ return PointF(int(pt.m_x) * mult, int(pt.m_y) * mult);
}
-PointF
-operator-(const PointF& pt)
+PointF operator-(const PointF &pt)
{
- return PointF(-pt.m_x, -pt.m_y);
+ return {-pt.m_x, -pt.m_y};
}
-bool
-operator!(const PointF& pt)
+bool operator!(const PointF &pt)
{
- return (pt.m_x == 0.0 && pt.m_y == 0.0);
+ return pt.m_x == 0.0 && pt.m_y == 0.0;
}
-
diff --git a/sources/shiboken6/tests/libsample/pointf.h b/sources/shiboken6/tests/libsample/pointf.h
index 86c8c9d2a..49e009467 100644
--- a/sources/shiboken6/tests/libsample/pointf.h
+++ b/sources/shiboken6/tests/libsample/pointf.h
@@ -4,17 +4,19 @@
#ifndef POINTF_H
#define POINTF_H
+#include "libsamplemacros.h"
#include "point.h"
-#include <utility>
-#include "libsamplemacros.h"
+#include <utility>
class LIBSAMPLE_API PointF
{
public:
- PointF(const Point& point);
- PointF(double x = 0.0, double y = 0.0);
- ~PointF() {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(PointF)
+
+ PointF(const Point &point) noexcept;
+ PointF(double x = 0.0, double y = 0.0) noexcept;
+ ~PointF() noexcept = default;
inline double x() const { return m_x; }
inline double y() const { return m_y; }
@@ -25,39 +27,39 @@ public:
// This method could simply return the midpoint,
// but the interesting part of the test is to set the
// result in the pointer argument.
- void midpoint(const PointF& other, PointF* midpoint) const;
+ void midpoint(const PointF &other, PointF *midpoint) const;
// The != operator is not implemented for the purpose of testing
// for the absence of the __ne__ method in the Python binding.
- bool operator==(const PointF& other);
+ bool operator==(const PointF &other) const;
- PointF operator+(const PointF& other);
- PointF operator-(const PointF& other);
+ PointF operator+(const PointF &other);
+ PointF operator-(const PointF &other);
- friend LIBSAMPLE_API PointF operator*(const PointF& pt, double mult);
- friend LIBSAMPLE_API PointF operator*(const PointF& pt, int mult);
- friend LIBSAMPLE_API PointF operator*(double mult, const PointF& pt);
- friend LIBSAMPLE_API PointF operator*(int mult, const PointF& pt);
- friend LIBSAMPLE_API PointF operator-(const PointF& pt);
- friend LIBSAMPLE_API bool operator!(const PointF& pt);
+ friend LIBSAMPLE_API PointF operator*(const PointF &pt, double mult);
+ friend LIBSAMPLE_API PointF operator*(const PointF &pt, int mult);
+ friend LIBSAMPLE_API PointF operator*(double mult, const PointF &pt);
+ friend LIBSAMPLE_API PointF operator*(int mult, const PointF &pt);
+ friend LIBSAMPLE_API PointF operator-(const PointF &pt);
+ friend LIBSAMPLE_API bool operator!(const PointF &pt);
- PointF& operator+=(PointF &other);
- PointF& operator-=(PointF &other);
+ PointF &operator+=(PointF &other);
+ PointF &operator-=(PointF &other);
- void show();
+ void show() const;
private:
double m_x;
double m_y;
};
-LIBSAMPLE_API PointF operator*(const PointF& pt, double mult);
-LIBSAMPLE_API PointF operator*(const PointF& pt, int mult);
-LIBSAMPLE_API PointF operator*(double mult, const PointF& pt);
-LIBSAMPLE_API PointF operator*(int mult, const PointF& pt);
-LIBSAMPLE_API PointF operator-(const PointF& pt);
-LIBSAMPLE_API bool operator!(const PointF& pt);
+LIBSAMPLE_API PointF operator*(const PointF &pt, double mult);
+LIBSAMPLE_API PointF operator*(const PointF &pt, int mult);
+LIBSAMPLE_API PointF operator*(double mult, const PointF &pt);
+LIBSAMPLE_API PointF operator*(int mult, const PointF &pt);
+LIBSAMPLE_API PointF operator-(const PointF &pt);
+LIBSAMPLE_API bool operator!(const PointF &pt);
-LIBSAMPLE_API PointF operator*(const PointF& pt, double multiplier);
+LIBSAMPLE_API PointF operator*(const PointF &pt, double multiplier);
#endif // POINTF_H
diff --git a/sources/shiboken6/tests/libsample/polygon.cpp b/sources/shiboken6/tests/libsample/polygon.cpp
index 617ac4f9f..6af597192 100644
--- a/sources/shiboken6/tests/libsample/polygon.cpp
+++ b/sources/shiboken6/tests/libsample/polygon.cpp
@@ -1,34 +1,26 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
#include "polygon.h"
-using namespace std;
-
-Polygon::Polygon(double x, double y)
+Polygon::Polygon(double x, double y) : m_points({Point(x, y)})
{
- m_points.push_back(Point(x, y));
}
-Polygon::Polygon(Point point)
+Polygon::Polygon(Point point) : m_points({point})
{
- m_points.push_back(point);
}
-Polygon::Polygon(PointList points)
+Polygon::Polygon(PointList points) : m_points(points)
{
- m_points = points;
}
-void
-Polygon::addPoint(Point point)
+void Polygon::addPoint(Point point)
{
m_points.push_back(point);
}
-Polygon
-Polygon::doublePolygonScale(Polygon polygon)
+Polygon Polygon::doublePolygonScale(Polygon polygon)
{
Polygon result;
for (const auto &point : polygon.points())
@@ -36,15 +28,12 @@ Polygon::doublePolygonScale(Polygon polygon)
return result;
}
-void
-Polygon::stealOwnershipFromPython(Point* point)
+void Polygon::stealOwnershipFromPython(Point *point)
{
delete point;
}
-void
-Polygon::stealOwnershipFromPython(Polygon* polygon)
+void Polygon::stealOwnershipFromPython(Polygon *polygon)
{
delete polygon;
}
-
diff --git a/sources/shiboken6/tests/libsample/polygon.h b/sources/shiboken6/tests/libsample/polygon.h
index 9a7586d24..2424ddd51 100644
--- a/sources/shiboken6/tests/libsample/polygon.h
+++ b/sources/shiboken6/tests/libsample/polygon.h
@@ -4,38 +4,36 @@
#ifndef POLYGON_H
#define POLYGON_H
-#include <list>
+#include "libsamplemacros.h"
#include "point.h"
-#include "libsamplemacros.h"
+#include <list>
-class LIBSAMPLE_API Polygon
+class LIBSAMPLE_API Polygon // should be moveable
{
public:
using PointList = std::list<Point>;
- Polygon() {}
+ Polygon() noexcept = default;
Polygon(double x, double y);
Polygon(Point point);
Polygon(PointList points);
- ~Polygon() {}
void addPoint(Point point);
- inline const PointList& points() const { return m_points; }
+ inline const PointList &points() const { return m_points; }
// This method intentionally receives and returns copies of a Polygon object.
static Polygon doublePolygonScale(Polygon polygon);
// This method invalidates the argument to be used for Polygon(Point) implicit conversion.
- static void stealOwnershipFromPython(Point* point);
+ static void stealOwnershipFromPython(Point *point);
// This method invalidates the argument to be used in a call to doublePolygonScale(Polygon).
- static void stealOwnershipFromPython(Polygon* polygon);
+ static void stealOwnershipFromPython(Polygon *polygon);
private:
PointList m_points;
};
#endif // POLYGON_H
-
diff --git a/sources/shiboken6/tests/libsample/privatector.h b/sources/shiboken6/tests/libsample/privatector.h
index 760fe4d13..3b38414f8 100644
--- a/sources/shiboken6/tests/libsample/privatector.h
+++ b/sources/shiboken6/tests/libsample/privatector.h
@@ -9,22 +9,22 @@
class PrivateCtor
{
public:
- inline static PrivateCtor* instance()
+ inline static PrivateCtor *instance()
{
static PrivateCtor self;
- self.m_instanciations++;
+ self.m_instantiations++;
return &self;
}
inline int instanceCalls()
{
- return m_instanciations;
+ return m_instantiations;
}
private:
- int m_instanciations;
+ int m_instantiations = 0;
- PrivateCtor() : m_instanciations(0) {}
+ PrivateCtor() = default;
};
class DeletedDefaultCtor
@@ -39,4 +39,4 @@ public:
~DeletedDefaultCtor() = default;
};
-#endif
+#endif // PRIVATECTOR_H
diff --git a/sources/shiboken6/tests/libsample/privatedtor.h b/sources/shiboken6/tests/libsample/privatedtor.h
index 84591ccb2..05f18ea53 100644
--- a/sources/shiboken6/tests/libsample/privatedtor.h
+++ b/sources/shiboken6/tests/libsample/privatedtor.h
@@ -9,27 +9,28 @@
class PrivateDtor
{
public:
- inline static PrivateDtor* instance()
+ LIBMINIMAL_DISABLE_COPY_MOVE(PrivateDtor)
+
+ inline static PrivateDtor *instance()
{
static PrivateDtor self;
- self.m_instanciations++;
+ self.m_instantiations++;
return &self;
}
inline int instanceCalls()
{
- return m_instanciations;
+ return m_instantiations;
}
protected:
- inline int protectedInstanceCalls() { return m_instanciations; }
+ inline int protectedInstanceCalls() { return m_instantiations; }
private:
- int m_instanciations;
+ int m_instantiations = 0;
- PrivateDtor() : m_instanciations(0) {}
- PrivateDtor(const PrivateDtor&) {}
- ~PrivateDtor() {}
+ PrivateDtor() noexcept = default;
+ ~PrivateDtor() = default;
};
-#endif
+#endif // PRIVATEDTOR_H
diff --git a/sources/shiboken6/tests/libsample/protected.h b/sources/shiboken6/tests/libsample/protected.h
index 5f2c788fb..059cced5d 100644
--- a/sources/shiboken6/tests/libsample/protected.h
+++ b/sources/shiboken6/tests/libsample/protected.h
@@ -7,24 +7,28 @@
#include "libsamplemacros.h"
#include "objecttype.h"
#include "point.h"
+
#include <string>
#include <list>
class LIBSAMPLE_API ProtectedNonPolymorphic
{
public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ProtectedNonPolymorphic)
+
explicit ProtectedNonPolymorphic(const char *name) : m_name(name) {}
- ~ProtectedNonPolymorphic() {}
+ ~ProtectedNonPolymorphic() = default;
- inline const char* publicName() { return m_name.c_str(); }
+ inline const char *publicName() { return m_name.c_str(); }
- inline static ProtectedNonPolymorphic* create() { return new ProtectedNonPolymorphic("created"); }
+ inline static ProtectedNonPolymorphic *create()
+ { return new ProtectedNonPolymorphic("created"); }
protected:
- inline const char* protectedName() { return m_name.c_str(); }
+ inline const char *protectedName() { return m_name.c_str(); }
inline int protectedSum(int a0, int a1) { return a0 + a1; }
inline int modifiedProtectedSum(int a0, int a1) { return a0 + a1; }
- inline static const char* protectedStatic() { return "protectedStatic"; }
+ inline static const char *protectedStatic() { return "protectedStatic"; }
const char *dataTypeName(void *data = nullptr) const;
const char *dataTypeName(int data) const;
@@ -35,15 +39,18 @@ private:
class LIBSAMPLE_API ProtectedPolymorphic
{
public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ProtectedPolymorphic)
+
explicit ProtectedPolymorphic(const char *name) : m_name(name) {}
- virtual ~ProtectedPolymorphic() {}
+ virtual ~ProtectedPolymorphic() = default;
- inline static ProtectedPolymorphic* create() { return new ProtectedPolymorphic("created"); }
- inline const char* publicName() { return m_name.c_str(); }
- inline const char* callProtectedName() { return protectedName(); }
+ inline static ProtectedPolymorphic *create()
+ { return new ProtectedPolymorphic("created"); }
+ inline const char *publicName() { return m_name.c_str(); }
+ inline const char *callProtectedName() { return protectedName(); }
protected:
- virtual const char* protectedName() { return m_name.c_str(); }
+ virtual const char *protectedName() { return m_name.c_str(); }
private:
std::string m_name;
@@ -52,22 +59,29 @@ private:
class LIBSAMPLE_API ProtectedPolymorphicDaughter : public ProtectedPolymorphic
{
public:
- explicit ProtectedPolymorphicDaughter(const char *name) : ProtectedPolymorphic(name) {}
- inline static ProtectedPolymorphicDaughter* create() { return new ProtectedPolymorphicDaughter("created"); }
+ explicit ProtectedPolymorphicDaughter(const char *name) :
+ ProtectedPolymorphic(name) {}
+ inline static ProtectedPolymorphicDaughter *create()
+ { return new ProtectedPolymorphicDaughter("created"); }
};
class LIBSAMPLE_API ProtectedPolymorphicGrandDaughter: public ProtectedPolymorphicDaughter
{
public:
- explicit ProtectedPolymorphicGrandDaughter(const char *name) : ProtectedPolymorphicDaughter(name) {}
- inline static ProtectedPolymorphicGrandDaughter* create() { return new ProtectedPolymorphicGrandDaughter("created"); }
+ explicit ProtectedPolymorphicGrandDaughter(const char *name) :
+ ProtectedPolymorphicDaughter(name) {}
+ inline static ProtectedPolymorphicGrandDaughter *create()
+ { return new ProtectedPolymorphicGrandDaughter("created"); }
};
class LIBSAMPLE_API ProtectedVirtualDestructor
{
public:
- ProtectedVirtualDestructor() {}
- inline static ProtectedVirtualDestructor* create() { return new ProtectedVirtualDestructor(); }
+ LIBMINIMAL_DISABLE_COPY_MOVE(ProtectedVirtualDestructor)
+
+ ProtectedVirtualDestructor() noexcept = default;
+ inline static ProtectedVirtualDestructor *create()
+ { return new ProtectedVirtualDestructor(); }
inline static int dtorCalled() { return dtor_called; }
inline static void resetDtorCounter() { dtor_called = 0; }
protected:
@@ -79,8 +93,10 @@ private:
class LIBSAMPLE_API ProtectedEnumClass
{
public:
- ProtectedEnumClass() {}
- virtual ~ProtectedEnumClass() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(ProtectedEnumClass)
+
+ ProtectedEnumClass() noexcept = default;
+ virtual ~ProtectedEnumClass() = default;
enum PublicEnum {
PublicItem0,
PublicItem1
@@ -90,36 +106,33 @@ protected:
ProtectedItem0,
ProtectedItem1
};
- ProtectedEnum callProtectedEnumMethod(ProtectedEnum in) { return protectedEnumMethod(in); }
- inline PublicEnum callPublicEnumMethod(PublicEnum in) { return publicEnumMethod(in); }
+ ProtectedEnum callProtectedEnumMethod(ProtectedEnum in)
+ { return protectedEnumMethod(in); }
+ inline PublicEnum callPublicEnumMethod(PublicEnum in)
+ { return publicEnumMethod(in); }
virtual ProtectedEnum protectedEnumMethod(ProtectedEnum in) { return in; }
virtual PublicEnum publicEnumMethod(PublicEnum in) { return in; }
};
-
class LIBSAMPLE_API ProtectedProperty
{
public:
- ProtectedProperty()
- : protectedValueTypeProperty(Point(0, 0)),
- protectedProperty(0),
- protectedEnumProperty(Event::NO_EVENT),
- protectedValueTypePointerProperty(nullptr),
- protectedObjectTypeProperty(nullptr)
- {}
+ ProtectedProperty() = default;
+
protected:
// This is deliberately the first member to test wrapper registration
// for value type members sharing the same memory address.
- Point protectedValueTypeProperty;
- int protectedProperty;
+ Point protectedValueTypeProperty{0, 0};
+ int protectedProperty = 0;
std::list<int> protectedContainerProperty;
- Event::EventType protectedEnumProperty;
- Point* protectedValueTypePointerProperty;
- ObjectType* protectedObjectTypeProperty;
+ Event::EventType protectedEnumProperty = Event::NO_EVENT;
+ Point *protectedValueTypePointerProperty = nullptr;
+ ObjectType *protectedObjectTypeProperty = nullptr;
};
-LIBSAMPLE_API inline ProtectedProperty* createProtectedProperty() {
+LIBSAMPLE_API inline ProtectedProperty *createProtectedProperty()
+{
return new ProtectedProperty;
}
diff --git a/sources/shiboken6/tests/libsample/rect.h b/sources/shiboken6/tests/libsample/rect.h
index ca3b1912d..53296d26c 100644
--- a/sources/shiboken6/tests/libsample/rect.h
+++ b/sources/shiboken6/tests/libsample/rect.h
@@ -9,53 +9,46 @@
class LIBSAMPLE_API Rect
{
public:
- Rect()
- {
- m_left = m_top = 0;
- m_right = m_bottom = -1;
- }
- Rect(int left, int top, int right, int bottom)
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Rect)
+
+ Rect() noexcept = default;
+ explicit Rect(int left, int top, int right, int bottom) noexcept
: m_left(left), m_top(top), m_right(right), m_bottom(bottom) { }
- ~Rect() {}
+ ~Rect() = default;
+
inline int left() const { return m_left; }
inline int top() const { return m_top; }
inline int right() const { return m_right; }
inline int bottom() const { return m_bottom; }
private:
- int m_left;
- int m_top;
- int m_right;
- int m_bottom;
+ int m_left = 0;
+ int m_top = 0;
+ int m_right = -1;
+ int m_bottom = -1;
};
class LIBSAMPLE_API RectF
{
public:
- RectF()
- {
- m_left = m_top = 0;
- m_right = m_bottom = -1;
- }
- RectF(int left, int top, int right, int bottom)
+ LIBMINIMAL_DEFAULT_COPY_MOVE(RectF)
+
+ RectF() noexcept = default;
+ explicit RectF(int left, int top, int right, int bottom) noexcept
: m_left(left), m_top(top), m_right(right), m_bottom(bottom) { }
- RectF(const Rect& other)
- {
- m_left = other.left();
- m_top = other.top();
- m_right = other.right();
- m_bottom = other.bottom();
- }
- ~RectF() {}
+ RectF(const Rect &other) noexcept :
+ m_left(other.left()), m_top(other.top()),
+ m_right(other.right()), m_bottom(other.bottom()) {}
+ ~RectF() = default;
+
inline double left() const { return m_left; }
inline double top() const { return m_top; }
inline double right() const { return m_right; }
inline double bottom() const { return m_bottom; }
private:
- double m_left;
- double m_top;
- double m_right;
- double m_bottom;
+ double m_left = 0;
+ double m_top = 0;
+ double m_right = -1;
+ double m_bottom = -1;
};
#endif // RECT_H
-
diff --git a/sources/shiboken6/tests/libsample/reference.cpp b/sources/shiboken6/tests/libsample/reference.cpp
index 25db84bfd..29dcfc054 100644
--- a/sources/shiboken6/tests/libsample/reference.cpp
+++ b/sources/shiboken6/tests/libsample/reference.cpp
@@ -1,15 +1,13 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
#include "reference.h"
-using namespace std;
+#include <iostream>
-void
-Reference::show() const
+void Reference::show() const
{
- cout << "Reference.objId: " << m_objId << ", address: " << this;
+ std::cout << "Reference.objId: " << m_objId << ", address: " << this;
}
Reference &Reference::returnMySecondArg(int, Reference &ref)
@@ -17,45 +15,37 @@ Reference &Reference::returnMySecondArg(int, Reference &ref)
return ref;
}
-int
-Reference::usesReferenceVirtual(Reference& r, int inc)
+int Reference::usesReferenceVirtual(Reference &r, int inc)
{
return r.m_objId + inc;
}
-int
-Reference::usesConstReferenceVirtual(const Reference& r, int inc)
+int Reference::usesConstReferenceVirtual(const Reference &r, int inc)
{
return r.m_objId + inc;
}
-int
-Reference::callUsesReferenceVirtual(Reference& r, int inc)
+int Reference::callUsesReferenceVirtual(Reference &r, int inc)
{
return usesReferenceVirtual(r, inc);
}
-int
-Reference::callUsesConstReferenceVirtual(const Reference& r, int inc)
+int Reference::callUsesConstReferenceVirtual(const Reference &r, int inc)
{
return usesConstReferenceVirtual(r, inc);
}
-void
-Reference::alterReferenceIdVirtual(Reference& r)
+void Reference::alterReferenceIdVirtual(Reference &r)
{
r.setObjId(r.objId() * Reference::multiplier());
}
-void
-Reference::callAlterReferenceIdVirtual(Reference& r)
+void Reference::callAlterReferenceIdVirtual(Reference &r)
{
alterReferenceIdVirtual(r);
}
-ObjTypeReference::~ObjTypeReference()
-{
-}
+ObjTypeReference::~ObjTypeReference() = default;
ObjTypeReference &ObjTypeReference::returnMySecondArg(int, ObjTypeReference &ref)
{
diff --git a/sources/shiboken6/tests/libsample/reference.h b/sources/shiboken6/tests/libsample/reference.h
index 1dc7aaf7c..52818d9ea 100644
--- a/sources/shiboken6/tests/libsample/reference.h
+++ b/sources/shiboken6/tests/libsample/reference.h
@@ -9,34 +9,37 @@
class LIBSAMPLE_API Reference
{
public:
- explicit Reference(int objId = -1)
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Reference)
+
+ explicit Reference(int objId = -1) noexcept
: m_objId(objId) {}
- virtual ~Reference() {}
+ virtual ~Reference() = default;
- inline int objId() { return m_objId; }
+ inline int objId() const { return m_objId; }
inline void setObjId(int objId) { m_objId = objId; }
- inline static int usesReference(Reference& r) { return r.m_objId; }
- inline static int usesConstReference(const Reference& r) { return r.m_objId; }
+ inline static int usesReference(Reference &r) { return r.m_objId; }
+ inline static int usesConstReference(const Reference &r) { return r.m_objId; }
- virtual int usesReferenceVirtual(Reference& r, int inc);
- virtual int usesConstReferenceVirtual(const Reference& r, int inc);
+ virtual int usesReferenceVirtual(Reference &r, int inc);
+ virtual int usesConstReferenceVirtual(const Reference &r, int inc);
- int callUsesReferenceVirtual(Reference& r, int inc);
- int callUsesConstReferenceVirtual(const Reference& r, int inc);
+ int callUsesReferenceVirtual(Reference &r, int inc);
+ int callUsesConstReferenceVirtual(const Reference &r, int inc);
- virtual void alterReferenceIdVirtual(Reference& r);
- void callAlterReferenceIdVirtual(Reference& r);
+ virtual void alterReferenceIdVirtual(Reference &r);
+ void callAlterReferenceIdVirtual(Reference &r);
void show() const;
inline static int multiplier() { return 10; }
- virtual Reference& returnMyFirstArg(Reference& ref) { return ref; }
- virtual Reference& returnMySecondArg(int a, Reference &ref);
+ virtual Reference &returnMyFirstArg(Reference &ref) { return ref; }
+ virtual Reference &returnMySecondArg(int a, Reference &ref);
// nonsense operator to test if Shiboken is ignoring dereference operators.
int operator*() { return m_objId; }
+
private:
int m_objId;
};
@@ -44,13 +47,16 @@ private:
class LIBSAMPLE_API ObjTypeReference
{
public:
- ObjTypeReference() {}
- ObjTypeReference(const ObjTypeReference&) {}
+ LIBMINIMAL_DISABLE_MOVE(ObjTypeReference)
+
+ ObjTypeReference() noexcept = default;
+ ObjTypeReference(const ObjTypeReference &) noexcept = default;
+ ObjTypeReference &operator=(const ObjTypeReference &) = delete;
virtual ~ObjTypeReference();
- virtual ObjTypeReference& returnMyFirstArg(ObjTypeReference& ref) { return ref; }
+
+ virtual ObjTypeReference &returnMyFirstArg(ObjTypeReference &ref) { return ref; }
virtual ObjTypeReference &returnMySecondArg(int a, ObjTypeReference &ref);
- virtual ObjTypeReference& justAPureVirtualFunc(ObjTypeReference& ref) = 0;
+ virtual ObjTypeReference &justAPureVirtualFunc(ObjTypeReference &ref) = 0;
};
#endif // REFERENCE_H
-
diff --git a/sources/shiboken6/tests/libsample/removednamespaces.h b/sources/shiboken6/tests/libsample/removednamespaces.h
index 08b28fae5..669f2ebf0 100644
--- a/sources/shiboken6/tests/libsample/removednamespaces.h
+++ b/sources/shiboken6/tests/libsample/removednamespaces.h
@@ -46,4 +46,3 @@ namespace RemovedNamespace3
} // namespace UnremovedNamespace
#endif // REMOVEDNAMESPACE_H
-
diff --git a/sources/shiboken6/tests/libsample/sample.cpp b/sources/shiboken6/tests/libsample/sample.cpp
index 7437a341b..5b5f8588b 100644
--- a/sources/shiboken6/tests/libsample/sample.cpp
+++ b/sources/shiboken6/tests/libsample/sample.cpp
@@ -15,7 +15,7 @@ int sample::value() const
return m_value;
}
-bool operator==(const sample&s1, const sample&s2)
+bool operator==(const sample &s1, const sample &s2)
{
return s1.value() == s2.value();
}
diff --git a/sources/shiboken6/tests/libsample/sample.h b/sources/shiboken6/tests/libsample/sample.h
index 756b4687e..27909571a 100644
--- a/sources/shiboken6/tests/libsample/sample.h
+++ b/sources/shiboken6/tests/libsample/sample.h
@@ -20,9 +20,9 @@ namespace sample
};
// shiboken must not generate richcompare for namespace sample
- LIBSAMPLE_API bool operator==(const sample&s1, const sample&s2);
+ LIBSAMPLE_API bool operator==(const sample &s1, const sample &s2);
const int INT_CONSTANT = 42;
}
-#endif
+#endif // SAMPLE_H
diff --git a/sources/shiboken6/tests/libsample/samplenamespace.cpp b/sources/shiboken6/tests/libsample/samplenamespace.cpp
index 8d1fa888f..eae5af2d2 100644
--- a/sources/shiboken6/tests/libsample/samplenamespace.cpp
+++ b/sources/shiboken6/tests/libsample/samplenamespace.cpp
@@ -1,12 +1,11 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
-#include <cstdlib>
-#include <time.h>
#include "samplenamespace.h"
-using namespace std;
+#include <iostream>
+#include <cstdlib>
+#include <ctime>
namespace SampleNamespace
{
@@ -18,45 +17,43 @@ SomeClass::PublicScopedEnum SomeClass::protectedMethodReturningPublicScopedEnum(
return PublicScopedEnum::v1;
}
-OutValue
-enumInEnumOut(InValue in)
+OutValue enumInEnumOut(InValue in)
{
- OutValue retval;
+ auto retval = OutValue(-1);
switch(in) {
- case ZeroIn:
- retval = ZeroOut;
- break;
- case OneIn:
- retval = OneOut;
- break;
- case TwoIn:
- retval = TwoOut;
- break;
- default:
- retval = (OutValue) -1;
+ case ZeroIn:
+ retval = ZeroOut;
+ break;
+ case OneIn:
+ retval = OneOut;
+ break;
+ case TwoIn:
+ retval = TwoOut;
+ break;
+ default:
+ break;
}
return retval;
}
-Option
-enumArgumentWithDefaultValue(Option opt)
+Option enumArgumentWithDefaultValue(Option opt)
{
return opt;
}
-int
-getNumber(Option opt)
+int getNumber(Option opt)
{
int retval;
switch(opt) {
- case RandomNumber:
- retval = rand() % 100;
- break;
- case UnixTime:
- retval = (int) time(nullptr);
- break;
- default:
- retval = 0;
+ case RandomNumber:
+ retval = rand() % 100;
+ break;
+ case UnixTime:
+ retval = int(std::time(nullptr));
+ break;
+ default:
+ retval = 0;
+ break;
}
return retval;
}
@@ -68,8 +65,7 @@ void doSomethingWithArray(const unsigned char *, unsigned int, const char *)
// to check compilation issues, i.e. if it compiles, it's ok.
}
-int
-enumItemAsDefaultValueToIntArgument(int value)
+int enumItemAsDefaultValueToIntArgument(int value)
{
return value;
}
@@ -90,14 +86,12 @@ void forceDecisorSideB(int, const Point &, const Str &, ObjectType *)
{
}
-double
-passReferenceToValueType(const Point& point, double multiplier)
+double passReferenceToValueType(const Point &point, double multiplier)
{
return (point.x() + point.y()) * multiplier;
}
-int
-passReferenceToObjectType(const ObjectType& obj, int multiplier)
+int passReferenceToObjectType(const ObjectType &obj, int multiplier)
{
return obj.objectName().size() * multiplier;
}
diff --git a/sources/shiboken6/tests/libsample/samplenamespace.h b/sources/shiboken6/tests/libsample/samplenamespace.h
index da75ead50..99a0787ee 100644
--- a/sources/shiboken6/tests/libsample/samplenamespace.h
+++ b/sources/shiboken6/tests/libsample/samplenamespace.h
@@ -4,12 +4,13 @@
#ifndef SAMPLENAMESPACE_H
#define SAMPLENAMESPACE_H
-#include <list>
#include "libsamplemacros.h"
#include "str.h"
#include "point.h"
#include "objecttype.h"
+#include <list>
+
// Anonymous global enum
enum {
AnonymousGlobalEnum_Value0,
@@ -25,10 +26,10 @@ inline namespace InlineNamespace
class LIBSAMPLE_API ClassWithinInlineNamespace {
public:
- ClassWithinInlineNamespace() = default;
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ClassWithinInlineNamespace)
+
+ ClassWithinInlineNamespace() noexcept = default;
~ClassWithinInlineNamespace() = default;
- ClassWithinInlineNamespace(const ClassWithinInlineNamespace &) = default;
- ClassWithinInlineNamespace& operator=(const ClassWithinInlineNamespace &) = default;
void setValue(EnumWithinInlineNamespace v) { m_value = v; }
EnumWithinInlineNamespace value() const { return m_value; }
@@ -74,7 +75,8 @@ inline double powerOfTwo(double num) {
return num * num;
}
-LIBSAMPLE_API void doSomethingWithArray(const unsigned char *data, unsigned int size, const char *format = nullptr);
+LIBSAMPLE_API void doSomethingWithArray(const unsigned char *data, unsigned int size,
+ const char *format = nullptr);
LIBSAMPLE_API int enumItemAsDefaultValueToIntArgument(int value = ZeroIn);
@@ -89,7 +91,10 @@ public:
class OkThisIsRecursiveEnough
{
public:
- virtual ~OkThisIsRecursiveEnough() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(OkThisIsRecursiveEnough)
+
+ OkThisIsRecursiveEnough() noexcept = default;
+ virtual ~OkThisIsRecursiveEnough() = default;
enum NiceEnum {
NiceValue1, NiceValue2
};
@@ -98,8 +103,9 @@ public:
NiceClassValue1, NiceClassValue2
};
- inline int someMethod(SomeInnerClass*) { return 0; }
- virtual OkThisIsRecursiveEnough* someVirtualMethod(OkThisIsRecursiveEnough* arg) { return arg; }
+ inline int someMethod(SomeInnerClass *) { return 0; }
+ virtual OkThisIsRecursiveEnough *someVirtualMethod(OkThisIsRecursiveEnough *arg)
+ { return arg; }
};
protected:
enum ProtectedEnum {
@@ -119,7 +125,8 @@ protected:
PublicScopedEnum protectedMethodReturningPublicScopedEnum() const;
};
-LIBSAMPLE_API inline int enumAsInt(SomeClass::PublicScopedEnum value) { return static_cast<int>(value); }
+LIBSAMPLE_API inline int enumAsInt(SomeClass::PublicScopedEnum value)
+{ return static_cast<int>(value); }
class DerivedFromNamespace : public SomeClass::SomeInnerClass::OkThisIsRecursiveEnough
{
@@ -128,29 +135,30 @@ public:
// only to cause namespace confusion
// enum SampleNamespace {
// };
- virtual OkThisIsRecursiveEnough* someVirtualMethod(OkThisIsRecursiveEnough* arg) { return arg; }
+ virtual OkThisIsRecursiveEnough *someVirtualMethod(OkThisIsRecursiveEnough *arg) { return arg; }
inline OkThisIsRecursiveEnough *methodReturningTypeFromParentScope() { return nullptr; }
};
// The combination of the following two overloaded methods could trigger a
// problematic behaviour on the overload decisor, if it isn't working properly.
LIBSAMPLE_API void forceDecisorSideA(ObjectType *object = nullptr);
-LIBSAMPLE_API void forceDecisorSideA(const Point& pt, const Str& text, ObjectType* object = 0);
+LIBSAMPLE_API void forceDecisorSideA(const Point &pt, const Str &text,
+ ObjectType *object = nullptr);
// The combination of the following two overloaded methods could trigger a
// problematic behaviour on the overload decisor, if it isn't working properly.
// This is a variation of forceDecisorSideB.
LIBSAMPLE_API void forceDecisorSideB(int a, ObjectType *object = nullptr);
-LIBSAMPLE_API void forceDecisorSideB(int a, const Point &pt, const Str &text, ObjectType *object = nullptr);
+LIBSAMPLE_API void forceDecisorSideB(int a, const Point &pt, const Str &text,
+ ObjectType *object = nullptr);
// Add a new signature on type system with only a Point value as parameter.
-LIBSAMPLE_API double passReferenceToValueType(const Point& point, double multiplier);
+LIBSAMPLE_API double passReferenceToValueType(const Point &point, double multiplier);
// Add a new signature on type system with only a ObjectType pointer as parameter.
-LIBSAMPLE_API int passReferenceToObjectType(const ObjectType& obj, int multiplier);
+LIBSAMPLE_API int passReferenceToObjectType(const ObjectType &obj, int multiplier);
extern LIBSAMPLE_API int variableInNamespace;
} // namespace SampleNamespace
#endif // SAMPLENAMESPACE_H
-
diff --git a/sources/shiboken6/tests/libsample/sbkdate.h b/sources/shiboken6/tests/libsample/sbkdate.h
index d102f62b8..5e1dd0b84 100644
--- a/sources/shiboken6/tests/libsample/sbkdate.h
+++ b/sources/shiboken6/tests/libsample/sbkdate.h
@@ -9,7 +9,7 @@
class LIBSAMPLE_API SbkDate
{
public:
- SbkDate(int d, int m, int y);
+ explicit SbkDate(int d, int m, int y);
int day() const;
int month() const;
@@ -22,4 +22,3 @@ private:
};
#endif // SBKDATE_H
-
diff --git a/sources/shiboken6/tests/libsample/simplefile.cpp b/sources/shiboken6/tests/libsample/simplefile.cpp
index e0e42e268..e51b14088 100644
--- a/sources/shiboken6/tests/libsample/simplefile.cpp
+++ b/sources/shiboken6/tests/libsample/simplefile.cpp
@@ -1,83 +1,73 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <stdlib.h>
-#include <string.h>
-#include <fstream>
#include "simplefile.h"
-class SimpleFile_p
+#include <cstdlib>
+#include <cstdio>
+#include <string>
+#include <filesystem>
+
+class SimpleFilePrivate
{
public:
- SimpleFile_p(const char* filename) : m_descriptor(nullptr), m_size(0)
- {
- m_filename = strdup(filename);
- }
+ LIBMINIMAL_DISABLE_COPY_MOVE(SimpleFilePrivate)
- ~SimpleFile_p()
- {
- free(m_filename);
- }
+ SimpleFilePrivate(const char *filename) : m_filename(filename) {}
+ ~SimpleFilePrivate() = default;
- char* m_filename;
- FILE* m_descriptor;
- long m_size;
+ std::string m_filename;
+ FILE *m_descriptor = nullptr;
+ long m_size = 0;
};
-SimpleFile::SimpleFile(const char* filename)
+SimpleFile::SimpleFile(const char *filename) :
+ p(std::make_unique<SimpleFilePrivate>(filename))
{
- p = new SimpleFile_p(filename);
}
SimpleFile::~SimpleFile()
{
close();
- delete p;
}
-const char* SimpleFile::filename()
+const char *SimpleFile::filename()
{
- return p->m_filename;
+ return p->m_filename.c_str();
}
-long SimpleFile::size()
+long SimpleFile::size() const
{
return p->m_size;
}
-bool
-SimpleFile::open()
+bool SimpleFile::open()
{
- if ((p->m_descriptor = fopen(p->m_filename, "rb")) == nullptr)
+ auto *descriptor = std::fopen(p->m_filename.c_str(), "rb");
+ if (descriptor == nullptr)
return false;
- fseek(p->m_descriptor, 0, SEEK_END);
- p->m_size = ftell(p->m_descriptor);
- rewind(p->m_descriptor);
+ p->m_descriptor = descriptor;
+ const auto size = std::filesystem::file_size(std::filesystem::path(p->m_filename));
+ p->m_size = long(size);
return true;
}
-void
-SimpleFile::close()
+void SimpleFile::close()
{
- if (p->m_descriptor) {
- fclose(p->m_descriptor);
+ if (p->m_descriptor != nullptr) {
+ std::fclose(p->m_descriptor);
p->m_descriptor = nullptr;
}
}
-bool
-SimpleFile::exists() const
+bool SimpleFile::exists() const
{
- std::ifstream ifile(p->m_filename);
- return !ifile.fail();
+ return std::filesystem::exists(std::filesystem::path(p->m_filename));
}
-bool
-SimpleFile::exists(const char* filename)
+bool SimpleFile::exists(const char *filename)
{
- std::ifstream ifile(filename);
- return !ifile.fail();
+ return std::filesystem::exists(std::filesystem::path(filename));
}
-
diff --git a/sources/shiboken6/tests/libsample/simplefile.h b/sources/shiboken6/tests/libsample/simplefile.h
index 765b46095..e4612c944 100644
--- a/sources/shiboken6/tests/libsample/simplefile.h
+++ b/sources/shiboken6/tests/libsample/simplefile.h
@@ -5,27 +5,30 @@
#define SIMPLEFILE_H
#include "libsamplemacros.h"
-#include <stdio.h>
-class SimpleFile_p;
+#include <memory>
+
+class SimpleFilePrivate;
class LIBSAMPLE_API SimpleFile
{
public:
- explicit SimpleFile(const char* filename);
+ LIBMINIMAL_DISABLE_COPY(SimpleFile)
+ LIBMINIMAL_DEFAULT_MOVE(SimpleFile)
+
+ explicit SimpleFile(const char *filename);
~SimpleFile();
- const char* filename();
- long size();
+ const char *filename();
+ long size() const;
bool open();
void close();
bool exists() const;
- static bool exists(const char* filename);
+ static bool exists(const char *filename);
private:
- SimpleFile_p *p;
+ std::unique_ptr<SimpleFilePrivate> p;
};
#endif // SIMPLEFILE_H
-
diff --git a/sources/shiboken6/tests/libsample/size.cpp b/sources/shiboken6/tests/libsample/size.cpp
index 5edb8a77b..0291d6e86 100644
--- a/sources/shiboken6/tests/libsample/size.cpp
+++ b/sources/shiboken6/tests/libsample/size.cpp
@@ -1,14 +1,11 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-#include <iostream>
#include "size.h"
-using namespace std;
+#include <iostream>
-void
-Size::show() const
+void Size::show() const
{
- cout << "(width: " << m_width << ", height: " << m_height << ")";
+ std::cout << "(width: " << m_width << ", height: " << m_height << ")";
}
-
diff --git a/sources/shiboken6/tests/libsample/size.h b/sources/shiboken6/tests/libsample/size.h
index ac57065af..2d194e96b 100644
--- a/sources/shiboken6/tests/libsample/size.h
+++ b/sources/shiboken6/tests/libsample/size.h
@@ -9,23 +9,26 @@
class LIBSAMPLE_API Size
{
public:
- Size(double width = 0.0, double height = 0.0) : m_width(width), m_height(height) {}
- ~Size() {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Size)
- inline double width() { return m_width; }
+ explicit Size(double width = 0.0, double height = 0.0) noexcept :
+ m_width(width), m_height(height) {}
+ ~Size() = default;
+
+ inline double width() const { return m_width; }
inline void setWidth(double width) { m_width = width; }
- inline double height() { return m_height; }
+ inline double height() const { return m_height; }
inline void setHeight(double height) { m_height = height; }
inline double calculateArea() const { return m_width * m_height; }
// Comparison Operators
- inline bool operator<(const Size& other)
+ inline bool operator<(const Size &other)
{
return calculateArea() < other.calculateArea();
}
- inline bool operator>(const Size& other)
+ inline bool operator>(const Size &other)
{
// On some x86 hardware and compiler combinations, floating point
// comparisons may fail due to a hardware bug. One workaround is to
@@ -37,7 +40,7 @@ public:
return a > b;
}
- inline bool operator<=(const Size& other)
+ inline bool operator<=(const Size &other)
{
// See comments for operator>()
double a = calculateArea();
@@ -45,7 +48,7 @@ public:
return a <= b;
}
- inline bool operator>=(const Size& other)
+ inline bool operator>=(const Size &other)
{
return calculateArea() >= other.calculateArea();
}
@@ -56,28 +59,28 @@ public:
inline bool operator>=(double area) { return calculateArea() >= area; }
// Arithmetic Operators
- inline Size& operator+=(const Size& s)
+ inline Size &operator+=(const Size &s)
{
m_width += s.m_width;
m_height += s.m_height;
return *this;
}
- inline Size& operator-=(const Size& s)
+ inline Size &operator-=(const Size &s)
{
m_width -= s.m_width;
m_height -= s.m_height;
return *this;
}
- inline Size& operator*=(double mult)
+ inline Size &operator*=(double mult)
{
m_width *= mult;
m_height *= mult;
return *this;
}
- inline Size& operator/=(double div)
+ inline Size &operator/=(double div)
{
m_width /= div;
m_height /= div;
@@ -89,11 +92,11 @@ public:
// External operators
friend inline bool operator==(const Size&, const Size&);
friend inline bool operator!=(const Size&, const Size&);
- friend inline const Size operator+(const Size&, const Size&);
- friend inline const Size operator-(const Size&, const Size&);
- friend inline const Size operator*(const Size&, double);
- friend inline const Size operator*(double, const Size&);
- friend inline const Size operator/(const Size&, double);
+ friend inline Size operator+(const Size&, const Size&);
+ friend inline Size operator-(const Size&, const Size&);
+ friend inline Size operator*(const Size&, double);
+ friend inline Size operator*(double, const Size&);
+ friend inline Size operator/(const Size&, double);
friend inline bool operator<(double, const Size&);
friend inline bool operator>(double, const Size&);
@@ -108,70 +111,71 @@ private:
};
// Comparison Operators
-inline bool operator!=(const Size& s1, const Size& s2)
+inline bool operator!=(const Size &s1, const Size &s2)
{
return s1.m_width != s2.m_width || s1.m_height != s2.m_height;
}
-inline bool operator==(const Size& s1, const Size& s2)
+inline bool operator==(const Size &s1, const Size &s2)
{
return s1.m_width == s2.m_width && s1.m_height == s2.m_height;
}
-inline bool operator<(double area, const Size& s)
+inline bool operator<(double area, const Size &s)
{
return area < s.calculateArea();
}
-inline bool operator>(double area, const Size& s)
+inline bool operator>(double area, const Size &s)
{
return area > s.calculateArea();
}
-inline bool operator<=(double area, const Size& s)
+inline bool operator<=(double area, const Size &s)
{
return area <= s.calculateArea();
}
-inline bool operator>=(double area, const Size& s)
+inline bool operator>=(double area, const Size &s)
{
return area >= s.calculateArea();
}
// Arithmetic Operators
-inline const Size operator+(const Size& s1, const Size& s2)
+inline Size operator+(const Size &s1, const Size &s2)
{
return Size(s1.m_width + s2.m_width, s1.m_height + s2.m_height);
}
-inline const Size operator-(const Size& s1, const Size& s2)
+inline Size operator-(const Size &s1, const Size &s2)
{
return Size(s1.m_width - s2.m_width, s1.m_height - s2.m_height);
}
-inline const Size operator*(const Size& s, double mult)
+inline Size operator*(const Size &s, double mult)
{
return Size(s.m_width * mult, s.m_height * mult);
}
-inline const Size operator*(double mult, const Size& s)
+inline Size operator*(double mult, const Size &s)
{
return Size(s.m_width * mult, s.m_height * mult);
}
-inline const Size operator/(const Size& s, double div)
+inline Size operator/(const Size &s, double div)
{
return Size(s.m_width / div, s.m_height / div);
}
using real = double;
using ushort = unsigned short;
+
class LIBSAMPLE_API SizeF
{
public:
- SizeF(real width, real height) : m_width(width), m_height(height) {}
- real width() { return m_width; }
- real height() { return m_height; }
+ explicit SizeF(real width, real height) : m_width(width), m_height(height) {}
+ real width() const { return m_width; }
+ real height() const { return m_height; }
static inline ushort passTypedefOfUnsignedShort(ushort value) { return value; }
private:
real m_width;
@@ -179,4 +183,3 @@ private:
};
#endif // SIZE_H
-
diff --git a/sources/shiboken6/tests/libsample/sometime.cpp b/sources/shiboken6/tests/libsample/sometime.cpp
index 8a3802deb..ad9a0d81c 100644
--- a/sources/shiboken6/tests/libsample/sometime.cpp
+++ b/sources/shiboken6/tests/libsample/sometime.cpp
@@ -2,10 +2,10 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "sometime.h"
-#include <stdio.h>
-void
-Time::setTime()
+#include <cstdio>
+
+void Time::setTime()
{
m_hour = 0;
m_minute = 0;
@@ -14,8 +14,7 @@ Time::setTime()
m_is_null = true;
}
-void
-Time::setTime(int h, int m, int s, int ms)
+void Time::setTime(int h, int m, int s, int ms)
{
m_hour = h;
m_minute = m;
@@ -24,9 +23,7 @@ Time::setTime(int h, int m, int s, int ms)
m_is_null = false;
}
-
-Time::NumArgs
-Time::somethingCompletelyDifferent()
+Time::NumArgs Time::somethingCompletelyDifferent()
{
return ZeroArgs;
}
@@ -40,18 +37,17 @@ Time::NumArgs Time::somethingCompletelyDifferent(int, int, ImplicitConv ic, Obje
return ThreeArgs;
}
-Str
-Time::toString() const
+Str Time::toString() const
{
if (m_is_null)
return Str();
char buffer[13];
- snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d.%03d", m_hour, m_minute, m_second, m_msec);
+ std::snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d.%03d",
+ m_hour, m_minute, m_second, m_msec);
return Str(buffer);
}
-bool
-Time::operator==(const Time& other) const
+bool Time::operator==(const Time &other) const
{
return m_hour == other.m_hour
&& m_minute == other.m_minute
@@ -60,8 +56,7 @@ Time::operator==(const Time& other) const
&& m_is_null == other.m_is_null;
}
-bool
-Time::operator!=(const Time& other) const
+bool Time::operator!=(const Time &other) const
{
return !operator==(other);
}
@@ -70,4 +65,3 @@ Time::operator Str() const
{
return Time::toString();
}
-
diff --git a/sources/shiboken6/tests/libsample/sometime.h b/sources/shiboken6/tests/libsample/sometime.h
index 0e3442db0..575d4b136 100644
--- a/sources/shiboken6/tests/libsample/sometime.h
+++ b/sources/shiboken6/tests/libsample/sometime.h
@@ -12,6 +12,8 @@
class LIBSAMPLE_API Time
{
public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Time)
+
enum NumArgs {
ZeroArgs,
TwoArgs,
@@ -19,14 +21,12 @@ public:
FourArgs
};
- Time()
- : m_hour(0), m_minute(0), m_second(0), m_msec(0), m_is_null(true)
- {}
- Time(int h, int m, int s = 0, int ms = 0)
- : m_hour(h), m_minute(m), m_second(s), m_msec(ms), m_is_null(false)
+ Time() noexcept = default;
+ explicit Time(int h, int m, int s = 0, int ms = 0) noexcept:
+ m_hour(h), m_minute(m), m_second(s), m_msec(ms), m_is_null(false)
{}
- ~Time() {}
+ ~Time() = default;
inline bool isNull() const { return m_is_null; }
@@ -48,20 +48,19 @@ public:
ObjectType *type = nullptr);
Str toString() const;
- bool operator==(const Time& other) const;
- bool operator!=(const Time& other) const;
+ bool operator==(const Time &other) const;
+ bool operator!=(const Time &other) const;
// This cast operator must become an implicit conversion of Str.
operator Str() const;
private:
- int m_hour;
- int m_minute;
- int m_second;
- int m_msec;
+ int m_hour = 0;
+ int m_minute = 0;
+ int m_second = 0;
+ int m_msec = 0;
- bool m_is_null;
+ bool m_is_null = true;
};
#endif // SOMETIME_H
-
diff --git a/sources/shiboken6/tests/libsample/stdcomplex.cpp b/sources/shiboken6/tests/libsample/stdcomplex.cpp
new file mode 100644
index 000000000..847174387
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/stdcomplex.cpp
@@ -0,0 +1,32 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "stdcomplex.h"
+
+#include <iostream>
+
+StdComplex::StdComplex() noexcept = default;
+
+StdComplex::StdComplex(double re, double img) noexcept : m_impl(re, img)
+{
+}
+
+StdComplex::operator int() const
+{
+ return std::lround(abs_value());
+}
+
+StdComplex::StdComplex(const Impl &impl) noexcept : m_impl(impl)
+{
+}
+
+StdComplex StdComplex::pow(const StdComplex &exp) const
+{
+ return StdComplex(std::pow(m_impl, exp.m_impl));
+}
+
+std::ostream &operator<<(std::ostream &str, const StdComplex &c)
+{
+ str << "Complex(" << c.real() << ", " << c.imag() << ')';
+ return str;
+}
diff --git a/sources/shiboken6/tests/libsample/stdcomplex.h b/sources/shiboken6/tests/libsample/stdcomplex.h
new file mode 100644
index 000000000..b39b80612
--- /dev/null
+++ b/sources/shiboken6/tests/libsample/stdcomplex.h
@@ -0,0 +1,55 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef STDCOMPLEX_H
+#define STDCOMPLEX_H
+
+#include "libsamplemacros.h"
+
+#include <complex>
+#include <iosfwd>
+
+// A complex number based on std::complex for exercising esoteric number
+// protocols (Py_nb_). For standard number protocols, see Point.
+
+class LIBSAMPLE_API StdComplex
+{
+ using Impl = std::complex<double>;
+
+public:
+ StdComplex() noexcept;
+ explicit StdComplex(double re, double img) noexcept;
+
+ double real() const { return m_impl.real(); }
+ double imag() const { return m_impl.imag(); }
+
+ double abs_value() const { return std::abs(m_impl); } // abs() is reserved Python word
+
+ StdComplex pow(const StdComplex &exp) const;
+
+ operator double() const { return abs_value(); }
+ operator int() const;
+
+ friend inline bool operator==(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return c1.m_impl == c2.m_impl; }
+ friend inline bool operator!=(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return c1.m_impl != c2.m_impl; }
+
+ friend inline StdComplex operator+(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return StdComplex(c1.m_impl + c2.m_impl); }
+ friend inline StdComplex operator-(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return StdComplex(c1.m_impl - c2.m_impl); }
+ friend inline StdComplex operator*(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return StdComplex(c1.m_impl * c2.m_impl); }
+ friend inline StdComplex operator/(const StdComplex &c1, const StdComplex &c2) noexcept
+ { return StdComplex(c1.m_impl / c2.m_impl); }
+
+private:
+ explicit StdComplex(const Impl &impl) noexcept;
+
+ Impl m_impl;
+};
+
+std::ostream &operator<<(std::ostream &str, const StdComplex &c);
+
+#endif // STDCOMPLEX_H
diff --git a/sources/shiboken6/tests/libsample/str.cpp b/sources/shiboken6/tests/libsample/str.cpp
index dd7909bef..742c0bb01 100644
--- a/sources/shiboken6/tests/libsample/str.cpp
+++ b/sources/shiboken6/tests/libsample/str.cpp
@@ -2,82 +2,73 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "str.h"
+
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
-using namespace std;
-
Str::Str(char c)
{
char str[2] = { c, 0 };
init(str);
}
-Str::Str(const char* cstr)
+Str::Str(const char *cstr)
{
init(cstr);
}
-void
-Str::init(const char* cstr)
+void Str::init(const char *cstr)
{
if (cstr)
m_str = cstr;
}
-Str
-Str::arg(const Str& s) const
+Str Str::arg(const Str &s) const
{
size_t idx = m_str.find_first_of("%VAR");
- if (idx == std::string::npos) {
+ if (idx == std::string::npos)
return *this;
- } else {
- std::string result = m_str;
- result.replace(idx, 4, s.m_str);
- return result.c_str();
- }
+
+ std::string result = m_str;
+ result.replace(idx, 4, s.m_str);
+ return result.c_str();
}
-Str&
-Str::append(const Str& s)
+Str &Str::append(const Str &s)
{
m_str += s.m_str;
return *this;
}
-Str&
-Str::prepend(const Str& s)
+Str &Str::prepend(const Str &s)
{
m_str = s.m_str + m_str;
return *this;
}
-const char*
-Str::cstring() const
+const char *Str::cstring() const
{
return m_str.c_str();
}
-int
-Str::toInt(bool* ok, int base) const
+int Str::toInt(bool *ok, int base) const
{
- bool my_ok;
int result = 0;
- istringstream conv(m_str);
+ std::istringstream conv(m_str);
switch (base) {
- case 8:
- conv >> std::oct >> result;
- break;
- case 10:
- conv >> std::dec >> result;
- break;
- case 16:
- conv >> std::hex >> result;
- break;
+ case 8:
+ conv >> std::oct >> result;
+ break;
+ case 10:
+ conv >> std::dec >> result;
+ break;
+ case 16:
+ conv >> std::hex >> result;
+ break;
}
- my_ok = istringstream::eofbit & conv.rdstate();
+ const bool my_ok = std::istringstream::eofbit & conv.rdstate();
if (!my_ok)
result = 0;
if (ok)
@@ -85,20 +76,17 @@ Str::toInt(bool* ok, int base) const
return result;
}
-void
-Str::show() const
+void Str::show() const
{
- printf("%s", cstring());
+ std::printf("%s", cstring());
}
-char
-Str::get_char(int pos) const
+char Str::get_char(int pos) const
{
return m_str[pos];
}
-bool
-Str::set_char(int pos, char ch)
+bool Str::set_char(int pos, char ch)
{
m_str[pos] = ch;
return true;
@@ -106,42 +94,42 @@ Str::set_char(int pos, char ch)
Str Str::operator+(int number) const
{
- ostringstream in;
+ std::ostringstream in;
in << m_str << number;
return in.str().c_str();
}
-bool Str::operator==(const Str& other) const
+bool Str::operator==(const Str &other) const
{
return m_str == other.m_str;
}
-Str operator+(int number, const Str& str)
+Str operator+(int number, const Str &str)
{
- ostringstream in;
+ std::ostringstream in;
in << number << str.m_str;
return in.str().c_str();
}
-bool Str::operator<(const Str& other) const
+bool Str::operator<(const Str &other) const
{
return m_str < other.m_str;
}
-unsigned int strHash(const Str& str)
+unsigned int strHash(const Str &str)
{
unsigned int result = 0;
for (char c : str.m_str)
- result = 5u * result + unsigned(c);
+ result = 5U * result + unsigned(c);
return result;
}
-void changePStr(PStr* pstr, const char* suffix)
+void changePStr(PStr *pstr, const char *suffix)
{
pstr->append(suffix);
}
-void duplicatePStr(PStr* pstr)
+void duplicatePStr(PStr *pstr)
{
if (!pstr)
return;
diff --git a/sources/shiboken6/tests/libsample/str.h b/sources/shiboken6/tests/libsample/str.h
index a58f34bdb..6b3386cef 100644
--- a/sources/shiboken6/tests/libsample/str.h
+++ b/sources/shiboken6/tests/libsample/str.h
@@ -3,22 +3,23 @@
#ifndef STR_H
#define STR_H
-#include <string>
#include "libsamplemacros.h"
+#include <string>
+
class LIBSAMPLE_API Str
{
public:
Str(char c);
- Str(const char* cstr = "");
+ Str(const char *cstr = "");
- Str arg(const Str& s) const;
+ Str arg(const Str &s) const;
- Str& append(const Str& s);
- Str& prepend(const Str& s);
+ Str &append(const Str &s);
+ Str &prepend(const Str &s);
- const char* cstring() const;
+ const char *cstring() const;
char get_char(int pos) const;
bool set_char(int pos, char ch);
@@ -26,26 +27,26 @@ public:
void show() const;
- inline int size() const { return m_str.size(); }
+ inline int size() const { return int(m_str.size()); }
// nonsense operator just to test reverse operators
Str operator+(int number) const;
- bool operator==(const Str& other) const;
- bool operator<(const Str& other) const;
+ bool operator==(const Str &other) const;
+ bool operator<(const Str &other) const;
private:
- void init(const char* cstr);
+ void init(const char *cstr);
std::string m_str;
- friend LIBSAMPLE_API Str operator+(int number, const Str& str);
- friend LIBSAMPLE_API unsigned int strHash(const Str& str);
+ friend LIBSAMPLE_API Str operator+(int number, const Str &str);
+ friend LIBSAMPLE_API unsigned int strHash(const Str &str);
};
-LIBSAMPLE_API Str operator+(int number, const Str& str);
-LIBSAMPLE_API unsigned int strHash(const Str& str);
+LIBSAMPLE_API Str operator+(int number, const Str &str);
+LIBSAMPLE_API unsigned int strHash(const Str &str);
using PStr = Str;
-LIBSAMPLE_API void changePStr(PStr* pstr, const char* suffix);
+LIBSAMPLE_API void changePStr(PStr *pstr, const char *suffix);
LIBSAMPLE_API void duplicatePStr(PStr *pstr = nullptr);
#endif // STR_H
diff --git a/sources/shiboken6/tests/libsample/strlist.cpp b/sources/shiboken6/tests/libsample/strlist.cpp
index 845b83a0d..5840a0516 100644
--- a/sources/shiboken6/tests/libsample/strlist.cpp
+++ b/sources/shiboken6/tests/libsample/strlist.cpp
@@ -5,15 +5,13 @@
#include <algorithm>
-bool
-StrList::operator==(const std::list<Str>& other) const
+bool StrList::operator==(const std::list<Str> &other) const
{
return size() == other.size()
&& std::equal(begin(), end(), other.begin());
}
-Str
-StrList::join(const Str& sep) const
+Str StrList::join(const Str &sep) const
{
Str result;
const auto i1 = begin();
diff --git a/sources/shiboken6/tests/libsample/strlist.h b/sources/shiboken6/tests/libsample/strlist.h
index eb89b4c58..01865a5b4 100644
--- a/sources/shiboken6/tests/libsample/strlist.h
+++ b/sources/shiboken6/tests/libsample/strlist.h
@@ -4,10 +4,10 @@
#ifndef STRLIST_H
#define STRLIST_H
-#include <list>
+#include "libsamplemacros.h"
#include "str.h"
-#include "libsamplemacros.h"
+#include <list>
class LIBSAMPLE_API StrList : public std::list<Str>
{
@@ -19,24 +19,29 @@ public:
ListOfStrCtor
};
- inline StrList() : m_ctorUsed(NoParamsCtor) {}
- inline explicit StrList(const Str& str) : m_ctorUsed(StrCtor) { push_back(str); }
- inline StrList(const std::list<Str>& lst) : std::list<Str>(lst), m_ctorUsed(ListOfStrCtor) {}
+ inline StrList() = default;
+ inline StrList(const std::list<Str> &lst) :
+ std::list<Str>(lst), m_ctorUsed(ListOfStrCtor) {}
+ inline explicit StrList(const Str &str) :
+ m_ctorUsed(StrCtor) { push_back(str); }
+ inline StrList(const StrList &lst) :
+ std::list<Str>(lst), m_ctorUsed(CopyCtor) {}
- inline StrList(const StrList &lst) : std::list<Str>(lst), m_ctorUsed(CopyCtor) {}
StrList(StrList &&) = default;
StrList &operator=(const StrList &) = default;
StrList &operator=(StrList &&) = default;
+ ~StrList() = default;
+
+ inline void append(const Str &str) { push_back(str); }
+ Str join(const Str &sep) const;
- inline void append(Str str) { push_back(str); }
- Str join(const Str& sep) const;
+ bool operator==(const std::list<Str> &other) const;
+ inline bool operator!=(const std::list<Str> &other) const { return !(*this == other); }
- bool operator==(const std::list<Str>& other) const;
- inline bool operator!=(const std::list<Str>& other) const { return !(*this == other); }
+ CtorEnum constructorUsed() const { return m_ctorUsed; }
- CtorEnum constructorUsed() { return m_ctorUsed; }
private:
- CtorEnum m_ctorUsed;
+ CtorEnum m_ctorUsed = NoParamsCtor;
};
using PStrList = StrList;
diff --git a/sources/shiboken6/tests/libsample/templateptr.h b/sources/shiboken6/tests/libsample/templateptr.h
index e8145b90d..bf230c363 100644
--- a/sources/shiboken6/tests/libsample/templateptr.h
+++ b/sources/shiboken6/tests/libsample/templateptr.h
@@ -4,15 +4,16 @@
#ifndef TEMPLATEPTR_H
#define TEMPLATEPTR_H
-#include <utility>
-#include <list>
#include "libsamplemacros.h"
#include "blackbox.h"
+#include <utility>
+#include <list>
+
class LIBSAMPLE_API TemplatePtr
{
public:
- void dummy(std::list<std::pair<BlackBox *, BlackBox *> > & items);
+ void dummy(std::list<std::pair<BlackBox *, BlackBox *> > &items);
};
-#endif
+#endif // TEMPLATEPTR_H
diff --git a/sources/shiboken6/tests/libsample/transform.cpp b/sources/shiboken6/tests/libsample/transform.cpp
index d23cb6179..5ccf5d1ed 100644
--- a/sources/shiboken6/tests/libsample/transform.cpp
+++ b/sources/shiboken6/tests/libsample/transform.cpp
@@ -4,37 +4,25 @@
#include "transform.h"
-#ifdef _WIN32
-#include <math.h>
-#include <float.h>
-static inline bool isfinite(double a) { return _finite(a); }
-#else
#include <cmath>
-#endif
-using namespace std;
-
-Point applyHomogeneousTransform(
- const Point& in,
- double m11, double m12, double m13,
- double m21, double m22, double m23,
- double m31, double m32, double m33,
- bool* okay)
+Point applyHomogeneousTransform(const Point &in,
+ double m11, double m12, double m13,
+ double m21, double m22, double m23,
+ double m31, double m32, double m33,
+ bool *okay)
{
double x = m11 * in.x() + m12 * in.y() + m13;
double y = m21 * in.x() + m22 * in.y() + m23;
double w = m31 * in.x() + m32 * in.y() + m33;
- if (isfinite(w) && fabs(w) > 1e-10)
- {
+ if (std::isfinite(w) && fabs(w) > 1e-10) {
if (okay)
*okay = true;
- return Point(x / w, y / w);
- }
- else
- {
- if (okay)
- *okay = false;
- return Point();
+ return {x / w, y / w};
}
+
+ if (okay)
+ *okay = false;
+ return {};
}
diff --git a/sources/shiboken6/tests/libsample/transform.h b/sources/shiboken6/tests/libsample/transform.h
index a39445c40..34ebf40d3 100644
--- a/sources/shiboken6/tests/libsample/transform.h
+++ b/sources/shiboken6/tests/libsample/transform.h
@@ -9,12 +9,10 @@
#include "libsamplemacros.h"
-LIBSAMPLE_API Point
-applyHomogeneousTransform(
- const Point& in,
- double m11, double m12, double m13,
- double m21, double m22, double m23,
- double m31, double m32, double m33,
- bool* okay);
+LIBSAMPLE_API Point applyHomogeneousTransform(const Point &in,
+ double m11, double m12, double m13,
+ double m21, double m22, double m23,
+ double m31, double m32, double m33,
+ bool *okay);
#endif // TRANSFORM_H
diff --git a/sources/shiboken6/tests/libsample/valueandvirtual.h b/sources/shiboken6/tests/libsample/valueandvirtual.h
index 25391cc0c..799e11e40 100644
--- a/sources/shiboken6/tests/libsample/valueandvirtual.h
+++ b/sources/shiboken6/tests/libsample/valueandvirtual.h
@@ -4,18 +4,22 @@
#ifndef VALUEANDVIRTUAL_H
#define VALUEANDVIRTUAL_H
+#include "libsamplemacros.h"
+
class ValueAndVirtual
{
public:
- ValueAndVirtual(int id) : m_id(id) {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ValueAndVirtual)
+
+ explicit ValueAndVirtual(int id) noexcept : m_id(id) {}
+ virtual ~ValueAndVirtual() = default;
bool operator()(int id, int id2) { return id == id2; }
- inline int id() { return m_id; }
- virtual ~ValueAndVirtual() {};
+ inline int id() const { return m_id; }
+
private:
int m_id;
};
#endif // VALUEANDVIRTUAL_H
-
diff --git a/sources/shiboken6/tests/libsample/virtualmethods.cpp b/sources/shiboken6/tests/libsample/virtualmethods.cpp
index fa2247a69..515564664 100644
--- a/sources/shiboken6/tests/libsample/virtualmethods.cpp
+++ b/sources/shiboken6/tests/libsample/virtualmethods.cpp
@@ -5,14 +5,12 @@
int VirtualDtor::dtor_called = 0;
-double
-VirtualMethods::virtualMethod0(Point pt, int val, Complex cpx, bool b)
+double VirtualMethods::virtualMethod0(Point pt, int val, Complex cpx, bool b)
{
return (pt.x() * pt.y() * val) + cpx.imag() + ((int) b);
}
-bool
-VirtualMethods::createStr(const char* text, Str*& ret)
+bool VirtualMethods::createStr(const char *text, Str *&ret)
{
if (!text) {
ret = nullptr;
@@ -23,8 +21,7 @@ VirtualMethods::createStr(const char* text, Str*& ret)
return true;
}
-void
-VirtualMethods::getMargins(int* left, int* top, int* right, int* bottom) const
+void VirtualMethods::getMargins(int *left, int *top, int *right, int *bottom) const
{
*left = m_left;
*top = m_top;
diff --git a/sources/shiboken6/tests/libsample/virtualmethods.h b/sources/shiboken6/tests/libsample/virtualmethods.h
index 5a1438a4a..b7172ad0d 100644
--- a/sources/shiboken6/tests/libsample/virtualmethods.h
+++ b/sources/shiboken6/tests/libsample/virtualmethods.h
@@ -17,11 +17,10 @@
class LIBSAMPLE_API VirtualMethods
{
public:
- VirtualMethods(Str name = "VirtualMethods") : m_name(name)
- {
- m_left = m_top = m_right = m_bottom = 0;
- }
- virtual ~VirtualMethods() {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(VirtualMethods)
+
+ explicit VirtualMethods(Str name = "VirtualMethods") : m_name(name) {}
+ virtual ~VirtualMethods() = default;
virtual double virtualMethod0(Point pt, int val, Complex cpx, bool b);
double callVirtualMethod0(Point pt, int val, Complex cpx, bool b)
@@ -61,12 +60,14 @@ public:
void callCallMe() { callMe(); }
// Passing reference to pointers.
- virtual bool createStr(const char* text, Str*& ret);
- bool callCreateStr(const char* text, Str*& ret) { return createStr(text, ret); }
+ virtual bool createStr(const char *text, Str *&ret);
+ bool callCreateStr(const char *text, Str *&ret) { return createStr(text, ret); }
// Return a non-binded method
- std::list<Str> callStrListToStdList(const StrList& strList) { return strListToStdList(strList); }
- virtual std::list<Str> strListToStdList(const StrList& strList ) { return strList; }
+ std::list<Str> callStrListToStdList(const StrList &strList)
+ { return strListToStdList(strList); }
+ virtual std::list<Str> strListToStdList(const StrList &strList )
+ { return strList; }
void setMargins(int left, int top, int right, int bottom)
{
@@ -75,8 +76,8 @@ public:
m_right = right;
m_bottom = bottom;
}
- virtual void getMargins(int* left, int* top, int* right, int* bottom) const;
- void callGetMargins(int* left, int* top, int* right, int* bottom) const
+ virtual void getMargins(int *left, int *top, int *right, int *bottom) const;
+ void callGetMargins(int *left, int *top, int *right, int *bottom) const
{
getMargins(left, top, right, bottom);
}
@@ -84,7 +85,7 @@ public:
virtual int recursionOnModifiedVirtual(Str arg) const;
int callRecursionOnModifiedVirtual(Str arg) const { return recursionOnModifiedVirtual(arg); }
- virtual const Str & returnConstRef() const;
+ virtual const Str &returnConstRef() const;
virtual int stringViewLength(std::string_view in) const;
@@ -94,10 +95,10 @@ protected:
private:
Str m_name;
- int m_left;
- int m_top;
- int m_right;
- int m_bottom;
+ int m_left = 0;
+ int m_top = 0;
+ int m_right = 0;
+ int m_bottom = 0;
};
class LIBSAMPLE_API VirtualDaughter : public VirtualMethods
@@ -128,10 +129,12 @@ public:
class LIBSAMPLE_API VirtualDtor
{
public:
- VirtualDtor() {}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(VirtualDtor)
+
+ VirtualDtor() noexcept = default;
virtual ~VirtualDtor() { dtor_called++; }
- static VirtualDtor* create() { return new VirtualDtor(); }
+ static VirtualDtor *create() { return new VirtualDtor(); }
static int dtorCalled() { return dtor_called; }
static void resetDtorCounter() { dtor_called = 0; }
@@ -140,4 +143,3 @@ private:
};
#endif // VIRTUALMETHODS_H
-
diff --git a/sources/shiboken6/tests/libsample/voidholder.h b/sources/shiboken6/tests/libsample/voidholder.h
index b5e59ba3d..3f0f4d973 100644
--- a/sources/shiboken6/tests/libsample/voidholder.h
+++ b/sources/shiboken6/tests/libsample/voidholder.h
@@ -9,21 +9,24 @@
class VoidHolder
{
public:
- explicit VoidHolder(void *ptr = nullptr) : m_ptr(ptr) {}
- ~VoidHolder() {}
- inline void* voidPointer() { return m_ptr; }
- inline static void* gimmeMeSomeVoidPointer()
+ LIBMINIMAL_DEFAULT_COPY_MOVE(VoidHolder)
+
+ explicit VoidHolder(void *ptr = nullptr) noexcept : m_ptr(ptr) {}
+ ~VoidHolder() = default;
+
+ inline void *voidPointer() { return m_ptr; }
+ inline static void *gimmeMeSomeVoidPointer()
{
- static void* pointerToSomething = new VoidHolder();
+ static void *pointerToSomething = new VoidHolder();
return pointerToSomething;
}
void *takeVoidPointer(void *item)
{
return item;
}
+
private:
- void* m_ptr;
+ void *m_ptr;
};
#endif // VOIDHOLDER_H
-
diff --git a/sources/shiboken6/tests/libsmart/CMakeLists.txt b/sources/shiboken6/tests/libsmart/CMakeLists.txt
index 1a3a989da..95f0cffd6 100644
--- a/sources/shiboken6/tests/libsmart/CMakeLists.txt
+++ b/sources/shiboken6/tests/libsmart/CMakeLists.txt
@@ -1,10 +1,19 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(libsmart)
set(libsmart_SRC
-smart.cpp
-stdsharedptrtestbench.cpp
-stdoptionaltestbench.cpp
-stduniqueptrtestbench.cpp
+libsmartmacros.h
+smart.cpp smart.h
+smart_integer.h
+smart_obj.h
+smart_registry.h
+smart_sharedptr.h
+smart_test.h
+stdoptionaltestbench.cpp stdoptionaltestbench.h
+stdsharedptrtestbench.cpp stdsharedptrtestbench.h
+stduniqueptrtestbench.cpp stduniqueptrtestbench.h
)
add_library(libsmart SHARED ${libsmart_SRC})
diff --git a/sources/shiboken6/tests/libsmart/smart_integer.h b/sources/shiboken6/tests/libsmart/smart_integer.h
index f2381cabb..42a441a00 100644
--- a/sources/shiboken6/tests/libsmart/smart_integer.h
+++ b/sources/shiboken6/tests/libsmart/smart_integer.h
@@ -11,6 +11,8 @@ public:
Integer();
Integer(const Integer &other);
Integer &operator=(const Integer &other);
+ Integer(Integer &&other) noexcept = default;
+ Integer &operator=(Integer &&other) noexcept = default;
~Integer();
void printInteger() const;
@@ -58,6 +60,9 @@ public:
Integer2();
Integer2(const Integer2 &);
Integer2 &operator=(const Integer2 &);
+ Integer2(Integer2 &&other) = delete;
+ Integer2 &operator=(Integer2 &&other) = delete;
+ ~Integer2() = default;
};
} // namespace Smart
diff --git a/sources/shiboken6/tests/libsmart/smart_obj.h b/sources/shiboken6/tests/libsmart/smart_obj.h
index 901d69696..9f4f8425d 100644
--- a/sources/shiboken6/tests/libsmart/smart_obj.h
+++ b/sources/shiboken6/tests/libsmart/smart_obj.h
@@ -17,6 +17,10 @@ namespace Smart { class Integer2; }
class LIB_SMART_API Obj {
public:
Obj();
+ Obj(const Obj &other) = delete;
+ Obj &operator=(const Obj &other) = delete;
+ Obj(Obj &&other) = delete;
+ Obj &operator=(Obj &&other) = delete;
virtual ~Obj();
void printObj();
diff --git a/sources/shiboken6/tests/libsmart/smart_sharedptr.h b/sources/shiboken6/tests/libsmart/smart_sharedptr.h
index 7d0365dd0..dc665810a 100644
--- a/sources/shiboken6/tests/libsmart/smart_sharedptr.h
+++ b/sources/shiboken6/tests/libsmart/smart_sharedptr.h
@@ -20,6 +20,8 @@ struct SharedPtrBase
template <class T>
class SharedPtr : public SharedPtrBase {
public:
+ LIBMINIMAL_DEFAULT_MOVE(SharedPtr)
+
SharedPtr() { logDefaultConstructor(typeid(T).name(), this); }
SharedPtr(T *v) : mPtr(v)
@@ -38,9 +40,10 @@ public:
logCopyConstructor(typeid(T).name(), this, data());
}
- SharedPtr& operator=(const SharedPtr& other)
+ SharedPtr &operator=(const SharedPtr &other)
{
- mPtr = other.mPtr;
+ if (this != &other)
+ mPtr = other.mPtr;
return *this;
}
diff --git a/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp
index a7b73cc81..1be93db66 100644
--- a/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp
+++ b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp
@@ -51,6 +51,26 @@ void StdSharedPtrTestBench::printInt(const std::shared_ptr<int> &p)
std::cerr << '\n';
}
+std::shared_ptr<std::string> StdSharedPtrTestBench::createString(const char *text)
+{
+ return std::make_shared<std::string>(text);
+}
+
+std::shared_ptr<std::string> StdSharedPtrTestBench::createNullString()
+{
+ return {};
+}
+
+void StdSharedPtrTestBench::printString(const std::shared_ptr<std::string> &p)
+{
+ std::cerr << __FUNCTION__ << ' ';
+ if (p.get())
+ std::cerr << '"' << *p << '"';
+ else
+ std::cerr << "nullptr";
+ std::cerr << '\n';
+}
+
StdSharedPtrVirtualMethodTester::StdSharedPtrVirtualMethodTester() = default;
StdSharedPtrVirtualMethodTester::~StdSharedPtrVirtualMethodTester() = default;
diff --git a/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h
index 8991cded6..04d75d5ef 100644
--- a/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h
+++ b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h
@@ -7,6 +7,7 @@
#include "libsmartmacros.h"
#include <memory>
+#include <string>
class Integer;
@@ -23,6 +24,10 @@ public:
static std::shared_ptr<int> createInt(int v = 42);
static std::shared_ptr<int> createNullInt();
static void printInt(const std::shared_ptr<int> &);
+
+ static std::shared_ptr<std::string> createString(const char *text);
+ static std::shared_ptr<std::string> createNullString();
+ static void printString(const std::shared_ptr<std::string> &);
};
class LIB_SMART_API StdSharedPtrVirtualMethodTester
diff --git a/sources/shiboken6/tests/minimalbinding/CMakeLists.txt b/sources/shiboken6/tests/minimalbinding/CMakeLists.txt
index 1b8c259e6..7f132bd34 100644
--- a/sources/shiboken6/tests/minimalbinding/CMakeLists.txt
+++ b/sources/shiboken6/tests/minimalbinding/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(minimal)
set(minimal_TYPESYSTEM
@@ -6,9 +9,11 @@ ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_minimal.xml
set(minimal_SRC
${CMAKE_CURRENT_BINARY_DIR}/minimal/minimal_module_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/minimal/containeruser_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/minimal/obj_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/minimal/val_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/minimal/listuser_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/minimal/spanuser_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/minimal/minbooluser_wrapper.cpp
)
diff --git a/sources/shiboken6/tests/minimalbinding/brace_pattern_test.py b/sources/shiboken6/tests/minimalbinding/brace_pattern_test.py
index f625fc776..946a869db 100644
--- a/sources/shiboken6/tests/minimalbinding/brace_pattern_test.py
+++ b/sources/shiboken6/tests/minimalbinding/brace_pattern_test.py
@@ -11,7 +11,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from shiboken6 import Shiboken
+from shiboken6 import Shiboken # noqa: F401
from shibokensupport.signature.lib.tool import build_brace_pattern
@@ -21,8 +21,9 @@ against a slower reference implementation.
The pattern is crucial, because it is used heavily in signature.parser .
"""
-# A slow reference parser for braces and strings
+
def check(s):
+ """A slow reference parser for braces and strings"""
open, close = "[{(<", "]})>"
escape, quote = "\\", '"'
instring = blind = False
@@ -41,8 +42,7 @@ def check(s):
stack.append(c)
elif c in close:
pos = close.index(c)
- if ((len(stack) > 0) and
- (open[pos] == stack[len(stack)-1])):
+ if len(stack) > 0 and open[pos] == stack[len(stack) - 1]:
stack.pop()
else:
return False
diff --git a/sources/shiboken6/tests/minimalbinding/containeruser_test.py b/sources/shiboken6/tests/minimalbinding/containeruser_test.py
new file mode 100644
index 000000000..25d683957
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/containeruser_test.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from shiboken_paths import init_paths
+init_paths()
+
+from minimal import ContainerUser
+
+
+class ContainerTest(unittest.TestCase):
+ """Simple test for converting std::vector and using an opaque container.
+ For advanced tests, see ListUser."""
+ def testVectorConversion(self):
+ v = ContainerUser.createIntVector(4)
+ self.assertEqual(ContainerUser.sumIntVector(v), 6)
+
+ def testVectorOpaqueContainer(self):
+ cu = ContainerUser()
+ oc = cu.intVector()
+ self.assertEqual(oc[0], 1)
+ oc[0] = 42
+ self.assertEqual(cu.intVector()[0], 42)
+
+ def testArrayConversion(self):
+ v = ContainerUser.createIntArray()
+ self.assertEqual(ContainerUser.sumIntArray(v), 6)
+
+ def testArrayOpaqueContainer(self):
+ cu = ContainerUser()
+ oc = cu.intArray()
+ self.assertEqual(oc[0], 1)
+ oc[0] = 42
+ self.assertEqual(cu.intArray()[0], 42)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/minimalbinding/global.h b/sources/shiboken6/tests/minimalbinding/global.h
index 573e826d7..fc5c59a26 100644
--- a/sources/shiboken6/tests/minimalbinding/global.h
+++ b/sources/shiboken6/tests/minimalbinding/global.h
@@ -2,7 +2,9 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "obj.h"
+#include "containeruser.h"
#include "val.h"
#include "minbool.h"
#include "listuser.h"
+#include "spanuser.h"
#include "typedef.h"
diff --git a/sources/shiboken6/tests/minimalbinding/listuser_test.py b/sources/shiboken6/tests/minimalbinding/listuser_test.py
index fc108950f..b30bb653a 100644
--- a/sources/shiboken6/tests/minimalbinding/listuser_test.py
+++ b/sources/shiboken6/tests/minimalbinding/listuser_test.py
@@ -32,7 +32,7 @@ class ExtListUser(ListUser):
return [not mb1, not mb2]
def oredMinBoolList(self, minBoolList):
- return not reduce(lambda a, b: a|b, minBoolList)
+ return not reduce(lambda a, b: a | b, minBoolList)
def createValList(self, num):
return [Val(i) for i in range(0, num * 2, 2)]
@@ -95,8 +95,14 @@ class IntListConversionTest(unittest.TestCase):
def testSumIntList(self):
lu = ListUser()
lst = range(4)
- self.assertEqual(lu.sumIntList(lst), sum(lst))
- self.assertEqual(lu.callSumIntList(lst), sum(lst))
+ expected = sum(lst)
+ self.assertEqual(lu.sumIntList(lst), expected)
+ self.assertEqual(lu.callSumIntList(lst), expected)
+ self.assertEqual(lu.sumIntListDefaultParam(lst), expected)
+ self.assertEqual(lu.sumIntListDefaultParamConstRef(lst), expected)
+ # PYSIDE-2454: Check container default parameters (1,2,3)
+ self.assertEqual(lu.sumIntListDefaultParam(), 6)
+ self.assertEqual(lu.sumIntListDefaultParamConstRef(), 6)
def testSumIntListFromExtendedClass(self):
lu = ExtListUser()
@@ -297,14 +303,16 @@ class ListOfIntListConversionTest(unittest.TestCase):
def testSumListOfIntListsFromExtendedClass(self):
lu = ExtListUser()
lst = [range(4)] * 4
- self.assertEqual(lu.sumListOfIntLists(lst), sum([sum(line) for line in [range(4)] * 4]) * 2)
- self.assertEqual(lu.callSumListOfIntLists(lst), sum([sum(line) for line in [range(4)] * 4]) * 2)
+ self.assertEqual(lu.sumListOfIntLists(lst),
+ sum([sum(line) for line in [range(4)] * 4]) * 2)
+ self.assertEqual(lu.callSumListOfIntLists(lst),
+ sum([sum(line) for line in [range(4)] * 4]) * 2)
def testOpaqueContainer(self):
lu = ListUser()
# Set via Python
- python_list = [1,2]
+ python_list = [1, 2]
lu.setStdIntList(python_list)
self.assertEqual(len(lu.m_stdIntList), 2)
self.assertEqual(lu.m_stdIntList[0], 1)
@@ -325,8 +333,8 @@ class ListOfIntListConversionTest(unittest.TestCase):
self.assertEqual(lu.m_stdIntList[2], 5)
# Access list via getter
- l = lu.getIntList()
- l.append(6)
+ il = lu.getIntList()
+ il.append(6)
self.assertEqual(len(lu.m_stdIntList), 4)
self.assertEqual(lu.m_stdIntList[3], 6)
diff --git a/sources/shiboken6/tests/minimalbinding/minbool_test.py b/sources/shiboken6/tests/minimalbinding/minbool_test.py
index 331b410b3..d9ce0eac0 100644
--- a/sources/shiboken6/tests/minimalbinding/minbool_test.py
+++ b/sources/shiboken6/tests/minimalbinding/minbool_test.py
@@ -13,32 +13,34 @@ init_paths()
from minimal import MinBoolUser
+
class DerivedMinBoolUser (MinBoolUser):
def returnMyselfVirtual(self):
return MinBoolUser()
+
class MinBoolTest(unittest.TestCase):
def testMinBoolUser(self):
mbuTrue = MinBoolUser()
mbuFalse = MinBoolUser()
mbuTrue.setMinBool(True)
- self.assertEqual(mbuFalse.minBool(), False)
- self.assertEqual(mbuTrue.minBool(), True)
- self.assertEqual(mbuTrue.callInvertedMinBool(), False)
+ self.assertFalse(mbuFalse.minBool())
+ self.assertTrue(mbuTrue.minBool())
+ self.assertFalse(mbuTrue.callInvertedMinBool())
- self.assertEqual(mbuTrue.minBool() == True, True)
- self.assertEqual(False == mbuFalse.minBool(), True)
- self.assertEqual(mbuTrue.minBool() == mbuFalse.minBool(), False)
+ self.assertTrue(mbuTrue.minBool())
+ self.assertFalse(mbuFalse.minBool())
+ self.assertTrue(mbuTrue.minBool() != mbuFalse.minBool())
- self.assertEqual(mbuFalse.minBool() != True, True)
- self.assertEqual(True != mbuFalse.minBool(), True)
- self.assertEqual(mbuTrue.minBool() != mbuFalse.minBool(), True)
+ self.assertFalse(mbuFalse.minBool())
+ self.assertFalse(mbuFalse.minBool())
+ self.assertTrue(mbuTrue.minBool() != mbuFalse.minBool())
def testVirtuals(self):
dmbu = DerivedMinBoolUser()
self.assertEqual(dmbu.invertedMinBool(), True)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject b/sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject
index d68e3811f..ab19dc443 100644
--- a/sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject
+++ b/sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject
@@ -1,5 +1,6 @@
{
"files": ["brace_pattern_test.py",
+ "containeruser_test.py",
"listuser_test.py",
"minbool_test.py",
"obj_test.py",
diff --git a/sources/shiboken6/tests/minimalbinding/obj_test.py b/sources/shiboken6/tests/minimalbinding/obj_test.py
index 0d8a2dced..e873845de 100644
--- a/sources/shiboken6/tests/minimalbinding/obj_test.py
+++ b/sources/shiboken6/tests/minimalbinding/obj_test.py
@@ -12,6 +12,7 @@ from shiboken_paths import init_paths
init_paths()
from minimal import Obj
+
class ExtObj(Obj):
def __init__(self, objId):
Obj.__init__(self, objId)
@@ -91,4 +92,3 @@ class ObjTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/minimalbinding/spanuser_test.py b/sources/shiboken6/tests/minimalbinding/spanuser_test.py
new file mode 100644
index 000000000..6db6aa616
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/spanuser_test.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from shiboken_paths import init_paths
+init_paths()
+
+from minimal import SpanUser
+
+
+class IntSpanTest(unittest.TestCase):
+
+ def testCreateIntSpan(self):
+ if not SpanUser.enabled():
+ return
+ expected = [1, 2, 3]
+ self.assertEqual(SpanUser.getIntSpan3(), expected)
+ self.assertEqual(SpanUser.getIntSpan(), expected)
+ self.assertEqual(SpanUser.getConstIntSpan3(), expected)
+
+ self.assertEqual(SpanUser.sumIntSpan3(expected), 6)
+ self.assertEqual(SpanUser.sumIntSpan(expected), 6)
+ self.assertEqual(SpanUser.sumConstIntSpan3(expected), 6)
+
+ def testSpanOpaqueContainer(self):
+ if not SpanUser.enabled():
+ return
+ oc = SpanUser.getIntSpan3_OpaqueContainer() # 1,2,3
+ oc[1] = 10
+ oc = SpanUser.getIntSpan3_OpaqueContainer()
+ # note: This converts to std::vector
+ self.assertEqual(SpanUser.sumIntSpan3(oc), 14)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/minimalbinding/typedef_test.py b/sources/shiboken6/tests/minimalbinding/typedef_test.py
index 1d878be30..c2fc8fc12 100644
--- a/sources/shiboken6/tests/minimalbinding/typedef_test.py
+++ b/sources/shiboken6/tests/minimalbinding/typedef_test.py
@@ -2,7 +2,6 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-from functools import reduce
import os
import sys
import unittest
@@ -11,7 +10,9 @@ from pathlib import Path
sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from minimal import *
+from minimal import (arrayFunc, arrayFuncInt, arrayFuncIntReturn,
+ arrayFuncIntReturnTypedef, arrayFuncIntTypedef,
+ arrayFuncReturn, arrayFuncReturnTypedef, arrayFuncTypedef)
try:
import numpy as np
@@ -31,29 +32,37 @@ class TypedefTest(unittest.TestCase):
self.assertTrue(arrayFuncInt(none), "None is empty, arrayFuncInt should return true")
self.assertFalse(arrayFuncInt(full), "Full is NOT empty, arrayFuncInt should return false")
- self.assertTrue(arrayFuncInt(np.array(none)), "None is empty, arrayFuncInt should return true")
- self.assertFalse(arrayFuncInt(np.array(full)), "Full is NOT empty, arrayFuncInt should return false")
+ self.assertTrue(arrayFuncInt(np.array(none)),
+ "None is empty, arrayFuncInt should return true")
+ self.assertFalse(arrayFuncInt(np.array(full)),
+ "Full is NOT empty, arrayFuncInt should return false")
def test_arrayFuncIntTypedef(self):
none = ()
full = (1, 2, 3)
- self.assertTrue(arrayFuncIntTypedef(none), "None is empty, arrayFuncIntTypedef should return true")
- self.assertFalse(arrayFuncIntTypedef(full), "Full is NOT empty, arrayFuncIntTypedef should return false")
+ self.assertTrue(arrayFuncIntTypedef(none),
+ "None is empty, arrayFuncIntTypedef should return true")
+ self.assertFalse(arrayFuncIntTypedef(full),
+ "Full is NOT empty, arrayFuncIntTypedef should return false")
- self.assertTrue(arrayFuncIntTypedef(np.array(none)), "None is empty, arrayFuncIntTypedef should return true")
- self.assertFalse(arrayFuncIntTypedef(np.array(full)), "Full is NOT empty, arrayFuncIntTypedef should return false")
+ self.assertTrue(arrayFuncIntTypedef(np.array(none)),
+ "None is empty, arrayFuncIntTypedef should return true")
+ self.assertFalse(arrayFuncIntTypedef(np.array(full)),
+ "Full is NOT empty, arrayFuncIntTypedef should return false")
def test_arrayFuncIntReturn(self):
none = arrayFuncIntReturn(0)
full = arrayFuncIntReturn(self.the_size)
self.assertTrue((len(none) == 0), "none should be empty")
- self.assertTrue((len(full) == self.the_size), "full should have " + str(self.the_size) + " elements")
+ self.assertTrue((len(full) == self.the_size),
+ f"full should have {self.the_size} elements")
def test_arrayFuncIntReturnTypedef(self):
none = arrayFuncIntReturnTypedef(0)
full = arrayFuncIntReturnTypedef(self.the_size)
self.assertTrue((len(none) == 0), "none should be empty")
- self.assertTrue((len(full) == self.the_size), "full should have " + str(self.the_size) + " elements")
+ self.assertTrue((len(full) == self.the_size),
+ f"full should have {self.the_size} elements")
def test_arrayFunc(self):
none = ()
@@ -62,30 +71,37 @@ class TypedefTest(unittest.TestCase):
self.assertFalse(arrayFunc(full), "Full is NOT empty, arrayFunc should return false")
self.assertTrue(arrayFunc(np.array(none)), "None is empty, arrayFunc should return true")
- self.assertFalse(arrayFunc(np.array(full)), "Full is NOT empty, arrayFunc should return false")
+ self.assertFalse(arrayFunc(np.array(full)),
+ "Full is NOT empty, arrayFunc should return false")
def test_arrayFuncTypedef(self):
none = ()
full = (1, 2, 3)
- self.assertTrue(arrayFuncTypedef(none), "None is empty, arrayFuncTypedef should return true")
- self.assertFalse(arrayFuncTypedef(full), "Full is NOT empty, arrayFuncTypedef should return false")
+ self.assertTrue(arrayFuncTypedef(none),
+ "None is empty, arrayFuncTypedef should return true")
+ self.assertFalse(arrayFuncTypedef(full),
+ "Full is NOT empty, arrayFuncTypedef should return false")
- self.assertTrue(arrayFuncTypedef(np.array(none)), "None is empty, arrayFuncTypedef should return true")
- self.assertFalse(arrayFuncTypedef(np.array(full)), "Full is NOT empty, arrayFuncTypedef should return false")
+ self.assertTrue(arrayFuncTypedef(np.array(none)),
+ "None is empty, arrayFuncTypedef should return true")
+ self.assertFalse(arrayFuncTypedef(np.array(full)),
+ "Full is NOT empty, arrayFuncTypedef should return false")
def test_arrayFuncReturn(self):
none = arrayFuncReturn(0)
full = arrayFuncReturn(self.the_size)
self.assertTrue((len(none) == 0), "none should be empty")
- self.assertTrue((len(full) == self.the_size), "full should have " + str(self.the_size) + " elements")
+ self.assertTrue((len(full) == self.the_size),
+ f"full should have {self.the_size} elements")
def test_arrayFuncReturnTypedef(self):
none = arrayFuncReturnTypedef(0)
full = arrayFuncReturnTypedef(self.the_size)
self.assertTrue((len(none) == 0), "none should be empty")
- self.assertTrue((len(full) == self.the_size), "full should have " + str(self.the_size) + " elements")
+ self.assertTrue((len(full) == self.the_size),
+ f"full should have {self.the_size} elements")
if __name__ == '__main__':
- if np != None:
+ if np is not None:
unittest.main()
diff --git a/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml b/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml
index 3fac1b2b3..e18bf8686 100644
--- a/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml
+++ b/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml
@@ -15,20 +15,15 @@
</conversion-rule>
</primitive-type>
- <container-type name="std::list" type="list"
- opaque-containers="int:StdIntList">
- <include file-name="list" location="global"/>
- <conversion-rule>
- <native-to-target>
- <insert-template name="shiboken_conversion_cppsequence_to_pylist"/>
- </native-to-target>
- <target-to-native>
- <add-conversion type="PySequence">
- <insert-template name="shiboken_conversion_pyiterable_to_cppsequentialcontainer"/>
- </add-conversion>
- </target-to-native>
- </conversion-rule>
- </container-type>
+ <opaque-container name="std::list" opaque-containers="int:StdIntList"/>
+
+ <opaque-container name="std::vector" opaque-containers="int:StdIntVector"/>
+
+ <opaque-container name="std::array" opaque-containers="int,3:StdIntArray"/>
+
+ <?if c++20?> <!-- FIXME PYSIDE 7: Remove "if" -->
+ <opaque-container name="std::span" opaque-containers="int,3:StdIntSpan3"/>
+ <?endif?>
<object-type name="Obj"/>
<value-type name="Val">
@@ -47,8 +42,32 @@
</modify-argument>
</modify-function>
</value-type>
+
+ <value-type name="SpanUser">
+ <?if c++20?> <!-- FIXME PYSIDE 7: Remove "if" -->
+ <modify-function signature="getIntSpan3_OpaqueContainer()">
+ <modify-argument index="return">
+ <replace-type modified-type="StdIntSpan3"/>
+ </modify-argument>
+ </modify-function>
+ <?endif?>
+ </value-type>
+
<value-type name="MinBoolUser"/>
+ <value-type name="ContainerUser">
+ <modify-function signature="intVector()">
+ <modify-argument index="return">
+ <replace-type modified-type="StdIntVector"/>
+ </modify-argument>
+ </modify-function>
+ <modify-function signature="intArray()">
+ <modify-argument index="return">
+ <replace-type modified-type="StdIntArray"/>
+ </modify-argument>
+ </modify-function>
+ </value-type>
+
<!-- Test wrapping of a typedef -->
<function signature="arrayFuncInt(std::vector&lt;int&gt;)" />
<!-- Note manual expansion of the typedef -->
diff --git a/sources/shiboken6/tests/minimalbinding/val_test.py b/sources/shiboken6/tests/minimalbinding/val_test.py
index 6403b5f14..b8225a247 100644
--- a/sources/shiboken6/tests/minimalbinding/val_test.py
+++ b/sources/shiboken6/tests/minimalbinding/val_test.py
@@ -92,4 +92,3 @@ class ValTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/otherbinding/CMakeLists.txt b/sources/shiboken6/tests/otherbinding/CMakeLists.txt
index c5e5390fb..2172593d3 100644
--- a/sources/shiboken6/tests/otherbinding/CMakeLists.txt
+++ b/sources/shiboken6/tests/otherbinding/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(other)
set(other_TYPESYSTEM
diff --git a/sources/shiboken6/tests/otherbinding/collector_external_operator_test.py b/sources/shiboken6/tests/otherbinding/collector_external_operator_test.py
index ab9a67345..2ba21653d 100644
--- a/sources/shiboken6/tests/otherbinding/collector_external_operator_test.py
+++ b/sources/shiboken6/tests/otherbinding/collector_external_operator_test.py
@@ -16,6 +16,7 @@ init_paths()
from sample import Collector, ObjectType
from other import OtherObjectType
+
class CollectorOtherObjectType(unittest.TestCase):
'''Test cases for Collector << OtherObjectType'''
@@ -33,6 +34,6 @@ class CollectorOtherObjectType(unittest.TestCase):
collector << obj
self.assertEqual(collector.items()[0], obj.identifier() * 2)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/otherbinding/conversion_operator_for_class_without_implicit_conversions_test.py b/sources/shiboken6/tests/otherbinding/conversion_operator_for_class_without_implicit_conversions_test.py
index 220cd3c98..bd00b5892 100644
--- a/sources/shiboken6/tests/otherbinding/conversion_operator_for_class_without_implicit_conversions_test.py
+++ b/sources/shiboken6/tests/otherbinding/conversion_operator_for_class_without_implicit_conversions_test.py
@@ -18,8 +18,10 @@ init_paths()
from sample import NoImplicitConversion
from other import ExtendsNoImplicitConversion
+
class ConversionOperatorForClassWithoutImplicitConversionsTest(unittest.TestCase):
- '''Tests calling NoImplicitConversion constructor using a ExtendsNoImplicitConversion parameter.'''
+ '''Tests calling NoImplicitConversion constructor using a
+ ExtendsNoImplicitConversion parameter.'''
def testNoImplicitConversion(self):
'''Basic test to see if the NoImplicitConversion is Ok.'''
@@ -27,27 +29,33 @@ class ConversionOperatorForClassWithoutImplicitConversionsTest(unittest.TestCase
# NoImplicitConversion.receivesNoImplicitConversionByValue(NoImplicitConversion)
self.assertEqual(obj.objId(), NoImplicitConversion.receivesNoImplicitConversionByValue(obj))
# NoImplicitConversion.receivesNoImplicitConversionByPointer(NoImplicitConversion*)
- self.assertEqual(obj.objId(), NoImplicitConversion.receivesNoImplicitConversionByPointer(obj))
+ self.assertEqual(obj.objId(),
+ NoImplicitConversion.receivesNoImplicitConversionByPointer(obj))
# NoImplicitConversion.receivesNoImplicitConversionByReference(NoImplicitConversion&)
- self.assertEqual(obj.objId(), NoImplicitConversion.receivesNoImplicitConversionByReference(obj))
+ self.assertEqual(obj.objId(),
+ NoImplicitConversion.receivesNoImplicitConversionByReference(obj))
def testPassingExtendsNoImplicitConversionAsNoImplicitConversionByValue(self):
- '''Gives an ExtendsNoImplicitConversion object to a function expecting a NoImplicitConversion, passing by value.'''
+ '''Gives an ExtendsNoImplicitConversion object to a function expecting a
+ NoImplicitConversion, passing by value.'''
obj = ExtendsNoImplicitConversion(123)
self.assertEqual(obj.objId(), NoImplicitConversion.receivesNoImplicitConversionByValue(obj))
def testPassingExtendsNoImplicitConversionAsNoImplicitConversionByReference(self):
- '''Gives an ExtendsNoImplicitConversion object to a function expecting a NoImplicitConversion, passing by reference.'''
+ '''Gives an ExtendsNoImplicitConversion object to a function expecting a
+ NoImplicitConversion, passing by reference.'''
obj = ExtendsNoImplicitConversion(123)
- self.assertEqual(obj.objId(), NoImplicitConversion.receivesNoImplicitConversionByReference(obj))
+ self.assertEqual(obj.objId(),
+ NoImplicitConversion.receivesNoImplicitConversionByReference(obj))
def testPassingExtendsNoImplicitConversionAsNoImplicitConversionByPointer(self):
- '''Gives an ExtendsNoImplicitConversion object to a function expecting a NoImplicitConversion, passing by pointer.
- This should not be accepted, since pointers should not be converted.'''
+ '''Gives an ExtendsNoImplicitConversion object to a function expecting
+ a NoImplicitConversion, passing by pointer. This should not be
+ accepted, since pointers should not be converted.'''
obj = ExtendsNoImplicitConversion(123)
- self.assertRaises(TypeError, NoImplicitConversion.receivesNoImplicitConversionByPointer, obj)
+ self.assertRaises(TypeError,
+ NoImplicitConversion.receivesNoImplicitConversionByPointer, obj)
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py b/sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py
index 169f5259d..abbef6231 100644
--- a/sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py
+++ b/sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py
@@ -16,6 +16,7 @@ init_paths()
from sample import Point
from other import Number
+
class PointOperationsWithNumber(unittest.TestCase):
'''Test cases for libsample's Point multiply operator defined in libother module.'''
@@ -39,6 +40,6 @@ class PointOperationsWithNumber(unittest.TestCase):
num = Number(11)
self.assertEqual(pt * num.value(), pt * 11)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/otherbinding/module_reload_test.py b/sources/shiboken6/tests/otherbinding/module_reload_test.py
index 5be2b4191..bde2f5236 100644
--- a/sources/shiboken6/tests/otherbinding/module_reload_test.py
+++ b/sources/shiboken6/tests/otherbinding/module_reload_test.py
@@ -21,6 +21,7 @@ dst = workdir / 'test_module.py'
shutil.copyfile(src, dst)
sys.path.append(os.fspath(workdir))
+
class TestModuleReloading(unittest.TestCase):
def testModuleReloading(self):
@@ -32,5 +33,6 @@ class TestModuleReloading(unittest.TestCase):
reload(test_module)
self.assertFalse(oldObject is test_module.obj)
+
if __name__ == "__main__":
unittest.main()
diff --git a/sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py b/sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py
index 5e3536c93..d6c356436 100644
--- a/sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py
+++ b/sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py
@@ -2,7 +2,8 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-'''Tests calling Str constructor using a Number parameter, being that number defines a cast operator to Str.'''
+'''Tests calling Str constructor using a Number parameter, being that number defines
+ a cast operator to Str.'''
import os
import sys
@@ -16,8 +17,10 @@ init_paths()
from sample import Str
from other import Number
+
class NewCtorOperatorTest(unittest.TestCase):
- '''Tests calling Str constructor using a Number parameter, being that number defines a cast operator to Str.'''
+ '''Tests calling Str constructor using a Number parameter, being that number
+ defines a cast operator to Str.'''
def testNumber(self):
'''Basic test to see if the Number class is Ok.'''
@@ -29,8 +32,8 @@ class NewCtorOperatorTest(unittest.TestCase):
'''Try to build a Str from 'sample' module with a Number argument from 'other' module.'''
value = 123
num = Number(value)
- string = Str(num)
+ string = Str(num) # noqa: F841
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/otherbinding/objtypehashes_test.py b/sources/shiboken6/tests/otherbinding/objtypehashes_test.py
index d2c441058..d2cd7de5b 100644
--- a/sources/shiboken6/tests/otherbinding/objtypehashes_test.py
+++ b/sources/shiboken6/tests/otherbinding/objtypehashes_test.py
@@ -9,10 +9,10 @@ from pathlib import Path
sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
-from other import *
+from sample import HandleHolder
from shiboken6 import Shiboken
+
class TestHashFuncs (unittest.TestCase):
def testIt(self):
@@ -30,6 +30,5 @@ class TestHashFuncs (unittest.TestCase):
self.assertEqual(hash1_2, hash1)
-
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/otherbinding/otherderived_test.py b/sources/shiboken6/tests/otherbinding/otherderived_test.py
index 1b876e1ed..459f474f1 100644
--- a/sources/shiboken6/tests/otherbinding/otherderived_test.py
+++ b/sources/shiboken6/tests/otherbinding/otherderived_test.py
@@ -17,6 +17,7 @@ init_paths()
from sample import Abstract, Derived
from other import OtherDerived, Number
+
class Multiple(Derived, Number):
def __init__(self):
Derived.__init__(self, 42)
@@ -25,6 +26,7 @@ class Multiple(Derived, Number):
def testCall(self):
return True
+
class OtherDeviant(OtherDerived):
def __init__(self):
OtherDerived.__init__(self)
@@ -40,6 +42,7 @@ class OtherDeviant(OtherDerived):
def className(self):
return 'OtherDeviant'
+
class MultipleTest(unittest.TestCase):
'''Test case for Multiple derived class'''
@@ -58,6 +61,7 @@ class MultipleTest(unittest.TestCase):
self.assertTrue(o.value(), 42)
self.assertTrue(o.testCall())
+
class OtherDerivedTest(unittest.TestCase):
'''Test case for OtherDerived class'''
@@ -68,13 +72,15 @@ class OtherDerivedTest(unittest.TestCase):
self.assertTrue(inherited_methods.issubset(dir(OtherDerived)))
def testReimplementedPureVirtualMethodCall(self):
- '''Test if a Python override of a implemented pure virtual method is correctly called from C++.'''
+ '''Test if a Python override of a implemented pure virtual method is
+ correctly called from C++.'''
d = OtherDeviant()
d.callPureVirtual()
self.assertTrue(d.pure_virtual_called)
def testReimplementedVirtualMethodCall(self):
- '''Test if a Python override of a reimplemented virtual method is correctly called from C++.'''
+ '''Test if a Python override of a reimplemented virtual method is
+ correctly called from C++.'''
d = OtherDeviant()
d.callUnpureVirtual()
self.assertTrue(d.unpure_virtual_called)
@@ -86,7 +92,8 @@ class OtherDerivedTest(unittest.TestCase):
self.assertEqual(d.getClassName(), 'OtherDerived')
def testReimplementedVirtualMethodCallReturningString(self):
- '''Test if a Python override of a reimplemented virtual method is correctly called from C++.'''
+ '''Test if a Python override of a reimplemented virtual method is
+ correctly called from C++.'''
d = OtherDeviant()
self.assertEqual(d.className(), 'OtherDeviant')
self.assertEqual(d.getClassName(), 'OtherDeviant')
@@ -97,6 +104,6 @@ class OtherDerivedTest(unittest.TestCase):
d = OtherDerived(objId)
self.assertEqual(Abstract.getObjectId(d), objId)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py b/sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py
index 9ac2456c0..198c71693 100644
--- a/sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py
+++ b/sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py
@@ -13,8 +13,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from other import (OtherValueWithUnitUser, ValueWithUnitIntInch,
- ValueWithUnitIntMillimeter)
+from other import (OtherValueWithUnitUser, ValueWithUnitIntMillimeter)
from sample import (ValueWithUnitDoubleMillimeter)
diff --git a/sources/shiboken6/tests/otherbinding/signature_test.py b/sources/shiboken6/tests/otherbinding/signature_test.py
index 93f080e6d..8db3e566b 100644
--- a/sources/shiboken6/tests/otherbinding/signature_test.py
+++ b/sources/shiboken6/tests/otherbinding/signature_test.py
@@ -16,8 +16,6 @@ init_paths()
from other import OtherObjectType
from shiboken_test_helper import objectFullname
-from shiboken6 import Shiboken
-
from shibokensupport.signature import get_signature
@@ -29,7 +27,7 @@ class SignatureTest(unittest.TestCase):
def testNamespaceFromOtherModule(self):
argType = get_signature(OtherObjectType.enumAsInt).parameters["value"].annotation
self.assertEqual(objectFullname(argType),
- "sample.SampleNamespace.SomeClass.PublicScopedEnum")
+ "sample.SampleNamespace.SomeClass.PublicScopedEnum")
if __name__ == '__main__':
diff --git a/sources/shiboken6/tests/otherbinding/smartptr_test.py b/sources/shiboken6/tests/otherbinding/smartptr_test.py
index 6479e6337..fd5c7fa09 100644
--- a/sources/shiboken6/tests/otherbinding/smartptr_test.py
+++ b/sources/shiboken6/tests/otherbinding/smartptr_test.py
@@ -13,8 +13,6 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from smart import Integer
-from sample import Str
from other import SmartPtrTester
diff --git a/sources/shiboken6/tests/otherbinding/star_import_test.py b/sources/shiboken6/tests/otherbinding/star_import_test.py
new file mode 100644
index 000000000..4b5f1d270
--- /dev/null
+++ b/sources/shiboken6/tests/otherbinding/star_import_test.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+"""PYSIDE-2404: Test whether star imports work as they require special handling
+ by the lazy initialization."""
+
+import os
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from shiboken_paths import init_paths
+init_paths()
+
+SHIBOKEN_NAME = "shiboken6.Shiboken"
+MINIMAL_NAME = "minimal"
+OTHER_NAME = "other"
+
+shiboken_loaded = 1 if sys.modules.get(SHIBOKEN_NAME) else 0
+minimal_loaded = 1 if sys.modules.get(MINIMAL_NAME) else 0
+other_loaded = 1 if sys.modules.get(OTHER_NAME) else 0
+
+from minimal import * # noqa: F403
+
+shiboken_loaded += 2 if sys.modules.get(SHIBOKEN_NAME) else 0
+minimal_loaded += 2 if sys.modules.get(MINIMAL_NAME) else 0
+other_loaded += 2 if sys.modules.get(OTHER_NAME) else 0
+
+from other import Number # noqa: F403
+from other import * # noqa: F403
+
+shiboken_loaded += 4 if sys.modules.get(SHIBOKEN_NAME) else 0
+minimal_loaded += 4 if sys.modules.get(MINIMAL_NAME) else 0
+other_loaded = +4 if sys.modules.get(OTHER_NAME) else 0
+
+import shiboken6.Shiboken # noqa: F401 F403
+
+shiboken_loaded += 8 if sys.modules.get(SHIBOKEN_NAME) else 0
+
+
+class ValTest(unittest.TestCase):
+
+ def test(self):
+ val_id = 123
+ val = Val(val_id) # noqa: F405
+ self.assertEqual(val.valId(), val_id)
+
+
+class Simple(Number):
+
+ def __init__(self):
+ Number.__init__(self, 42)
+
+
+class OtherTest(unittest.TestCase):
+
+ def testConstructor(self):
+ o = Simple()
+ self.assertTrue(isinstance(o, Number))
+
+
+class StarImportTest(unittest.TestCase):
+ """
+ This test is meant for Lazy Init.
+ We explicitly choose modules which are able to lazy load.
+
+ The ValTest:
+ ------------
+ We load something with `import *`.
+ There is no module from our known ones imported.
+ This means we need stack introspection to find out that this was
+ a star import and we must disable lazyness.
+
+ The OtherTest:
+ --------------
+ We load something normally that should be lazy.
+ After that, we follow with a star import.
+ Now the stack introspection does not work, because the loading is
+ cached. The first import did a lazy load. The following star import
+ needs to undo the lazyness. But now we have a redirected import.
+
+ All tests simply check if the objects are real and not just names.
+ The <module>_loaded tests prevend upcoming internal dependencies.
+
+ To make sure that Shiboken is really not involved, it is checked
+ and really imported afterwards (ensuring nothing is misspelled).
+ """
+
+ def testStar(self):
+ self.assertEqual(other_loaded, 4)
+ self.assertEqual(minimal_loaded, 6)
+ self.assertEqual(shiboken_loaded, 14)
+ # Interesting effect: Did not expect that shiboken is loaded at all.
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/otherbinding/test_module_template.py b/sources/shiboken6/tests/otherbinding/test_module_template.py
index 183ba9fe5..36ab43ae3 100644
--- a/sources/shiboken6/tests/otherbinding/test_module_template.py
+++ b/sources/shiboken6/tests/otherbinding/test_module_template.py
@@ -1,13 +1,22 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-from other import *
-from sample import *
+import os
+import sys
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from shiboken_paths import init_paths
+init_paths()
+
+from other import OtherObjectType
+from sample import ObjectType
class MyObjectType(ObjectType):
pass
+
class MyOtherObjectType(OtherObjectType):
value = 10
diff --git a/sources/shiboken6/tests/otherbinding/typediscovery_test.py b/sources/shiboken6/tests/otherbinding/typediscovery_test.py
index 51fc7c01b..39dc5cf0f 100644
--- a/sources/shiboken6/tests/otherbinding/typediscovery_test.py
+++ b/sources/shiboken6/tests/otherbinding/typediscovery_test.py
@@ -13,9 +13,11 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import Abstract, Base1, Derived, MDerived1, MDerived3, SonOfMDerived1
+from sample import (Abstract, Base1, Derived,
+ MDerived1, SonOfMDerived1, MDerived3)
from other import OtherMultipleDerived
+
class TypeDiscoveryTest(unittest.TestCase):
def testPureVirtualsOfImpossibleTypeDiscovery(self):
@@ -29,18 +31,23 @@ class TypeDiscoveryTest(unittest.TestCase):
self.assertEqual(type(a), Derived)
def testMultipleInheritance(self):
- obj = OtherMultipleDerived.createObject("Base1");
+ obj = OtherMultipleDerived.createObject("Base1")
self.assertEqual(type(obj), Base1)
- # PYSIDE-868: In case of multiple inheritance, a factory
+ # PYSIDE-868: In case of single line direct inheritance,
+ # a factory function will return the class wrapper
+ # of the derived class.
+ obj = OtherMultipleDerived.createObject("MDerived1")
+ self.assertEqual(type(obj), MDerived1)
+ obj = OtherMultipleDerived.createObject("SonOfMDerived1")
+ self.assertEqual(type(obj), SonOfMDerived1)
+ obj = OtherMultipleDerived.createObject("MDerived3")
+ self.assertEqual(type(obj), MDerived3)
+ # PYSIDE-868: OtherMultipleDerived inherits
+ # OtherBase, Base1. In this case, a factory
# function will return the base class wrapper.
- obj = OtherMultipleDerived.createObject("MDerived1");
- self.assertEqual(type(obj), Base1)
- obj = OtherMultipleDerived.createObject("SonOfMDerived1");
- self.assertEqual(type(obj), Base1)
- obj = OtherMultipleDerived.createObject("MDerived3");
- self.assertEqual(type(obj), Base1)
- obj = OtherMultipleDerived.createObject("OtherMultipleDerived");
+ obj = OtherMultipleDerived.createObject("OtherMultipleDerived")
self.assertEqual(type(obj), Base1)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/otherbinding/typesystem_other.xml b/sources/shiboken6/tests/otherbinding/typesystem_other.xml
index 4081548fc..ade1c8bad 100644
--- a/sources/shiboken6/tests/otherbinding/typesystem_other.xml
+++ b/sources/shiboken6/tests/otherbinding/typesystem_other.xml
@@ -17,8 +17,4 @@
<typedef-type name="ValueWithUnitIntInch" source="ValueWithUnit&lt;int,LengthUnit::Inch&gt;"/>
<typedef-type name="ValueWithUnitIntMillimeter" source="ValueWithUnit&lt;int,LengthUnit::Millimeter&gt;"/>
<value-type name="OtherValueWithUnitUser"/>
-
- <suppress-warning text="signature 'operator!=(ByteArray,const char*)' for function modification in 'ByteArray' not found." />
- <suppress-warning text="signature 'operator+(ByteArray,const char*)' for function modification in 'ByteArray' not found." />
- <suppress-warning text="signature 'operator==(ByteArray,const char*)' for function modification in 'ByteArray' not found." />
</typesystem>
diff --git a/sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py b/sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py
index b464fa566..15a988326 100644
--- a/sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py
+++ b/sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py
@@ -14,6 +14,7 @@ from shiboken_paths import init_paths
init_paths()
from other import Number
+
class UserDefinedPrimitiveTypeFromRequiredModuleTest(unittest.TestCase):
def testUsersPrimitiveFromRequiredModuleAsArgument(self):
@@ -28,5 +29,6 @@ class UserDefinedPrimitiveTypeFromRequiredModuleTest(unittest.TestCase):
cpx = number.toComplex()
self.assertEqual(number.value(), int(cpx.real))
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/otherbinding/wrongctor_test.py b/sources/shiboken6/tests/otherbinding/wrongctor_test.py
index 9aacfa9ac..b9251b428 100644
--- a/sources/shiboken6/tests/otherbinding/wrongctor_test.py
+++ b/sources/shiboken6/tests/otherbinding/wrongctor_test.py
@@ -10,17 +10,19 @@ from pathlib import Path
sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
-from other import *
+from sample import Abstract, ObjectType
+from other import OtherDerived
+
class Foo(OtherDerived):
def __init__(self):
- Abstract.__init__(self, 2) # this should raise an exception
+ Abstract.__init__(self, 2) # this should raise an exception
+
class Foo2(ObjectType, OtherDerived):
def __init__(self):
ObjectType.__init__(self)
- Abstract.__init__(self, 2) # this should raise an exception
+ Abstract.__init__(self, 2) # this should raise an exception
class WrongCtorTest(unittest.TestCase):
diff --git a/sources/shiboken6/tests/qtxmltosphinx/CMakeLists.txt b/sources/shiboken6/tests/qtxmltosphinx/CMakeLists.txt
index ff9207350..11b22f038 100644
--- a/sources/shiboken6/tests/qtxmltosphinx/CMakeLists.txt
+++ b/sources/shiboken6/tests/qtxmltosphinx/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
# Standalone-buildable
diff --git a/sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt b/sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt
index 7b3f354ee..25074e716 100644
--- a/sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt
+++ b/sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
project(qtxmltosphinxtest)
diff --git a/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp
index e30033ae7..45cecd1a1 100644
--- a/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp
+++ b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp
@@ -5,9 +5,12 @@
#include "qtxmltosphinx.h"
#include <QtTest/QTest>
+#include <QtCore/QBuffer>
#include <QtCore/QDebug>
#include <QtCore/QLoggingCategory>
+using namespace Qt::StringLiterals;
+
Q_LOGGING_CATEGORY(lcQtXmlToSphinxTest, "qt.sphinxtabletest");
// QtXmlToSphinxDocGeneratorInterface
@@ -271,6 +274,43 @@ void QtXmlToSphinxTest::testTable_data()
QTest::newRow("testRowSpan2")
<< QString::fromLatin1(xml) << QString::fromLatin1(expected);
+ // testNestedList
+ xml = R"(<table>
+ <row>
+ <item>
+ <list type="bullet">
+ <item>
+ <para>I11</para>
+ </item>
+ <item>
+ <para>I21</para>
+ </item>
+ </list>
+ </item>
+ <item>
+ <list type="bullet">
+ <item>
+ <para>I12</para>
+ </item>
+ <item>
+ <para>I22</para>
+ </item>
+ </list>
+ </item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +---------+---------+
+ | * I11| * I12|
+ | * I21| * I22|
+ +---------+---------+
+
+)";
+
+ QTest::newRow("testNestedList")
+ << QString::fromLatin1(xml) << QString::fromLatin1(expected);
+
// testBrokenTable
xml = R"(<table>
<header>
@@ -344,7 +384,7 @@ void QtXmlToSphinxTest::testTable()
QCOMPARE(actual, expected);
}
-using TablePtr = QSharedPointer<QtXmlToSphinx::Table>;
+using TablePtr = std::shared_ptr<QtXmlToSphinx::Table>;
Q_DECLARE_METATYPE(TablePtr);
@@ -421,4 +461,51 @@ void QtXmlToSphinxTest::testTableFormattingIoDevice()
QCOMPARE(actual, expected);
}
+void QtXmlToSphinxTest::testSnippetExtraction_data()
+{
+ QTest::addColumn<QByteArray>("file");
+ QTest::addColumn<QLatin1StringView>("id");
+ QTest::addColumn<QString>("expected");
+
+ const char *fileCpp = R"(bla
+// ![snip1]
+snip1_line1
+// ![snip1] // ![snip2]
+snip2_line1
+snip2_line2
+// ![snip2] // ![snip3]
+)";
+
+ constexpr auto id = "snip2"_L1;
+ const QString expected = uR"(snip2_line1
+snip2_line2
+)"_s;
+
+ const char *filePython = R"(bla
+# ![snip1]
+snip1_line1
+# ![snip1] # ![snip2]
+snip2_line1
+snip2_line2
+# ![snip2] # ![snip3]
+)";
+
+ QTest::newRow("c++") << QByteArray(fileCpp) << id << expected;
+ QTest::newRow("Python") << QByteArray(filePython) << id << expected;
+}
+
+void QtXmlToSphinxTest::testSnippetExtraction()
+{
+ QFETCH(QByteArray, file);
+ QFETCH(QLatin1StringView, id);
+ QFETCH(QString, expected);
+
+ QBuffer buffer(&file);
+ QVERIFY(buffer.open(QIODevice::ReadOnly));
+ QString errorMessage;
+ QString actual = QtXmlToSphinx::readSnippet(buffer, id, &errorMessage);
+ QVERIFY2(errorMessage.isEmpty(), qPrintable(errorMessage));
+ QCOMPARE(actual, expected);
+}
+
QTEST_APPLESS_MAIN( QtXmlToSphinxTest)
diff --git a/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h
index 1c46789d8..0a210b7a0 100644
--- a/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h
+++ b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h
@@ -27,6 +27,8 @@ private slots:
void testTableFormatting();
void testTableFormattingIoDevice_data();
void testTableFormattingIoDevice();
+ void testSnippetExtraction_data();
+ void testSnippetExtraction();
private:
QString transformXml(const QString &xml) const;
diff --git a/sources/shiboken6/tests/samplebinding/CMakeLists.txt b/sources/shiboken6/tests/samplebinding/CMakeLists.txt
index 44b576cca..fc812feb8 100644
--- a/sources/shiboken6/tests/samplebinding/CMakeLists.txt
+++ b/sources/shiboken6/tests/samplebinding/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(sample)
set(sample_TYPESYSTEM
@@ -113,6 +116,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_someclass_someinnerclass_wrap
${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_someclass_someotherinnerclass_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_someclass_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_derivedfromnamespace_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/stdcomplex_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/simplefile_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/size_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sizef_wrapper.cpp
diff --git a/sources/shiboken6/tests/samplebinding/__del___test.py b/sources/shiboken6/tests/samplebinding/__del___test.py
index 2d38b24d7..456886614 100644
--- a/sources/shiboken6/tests/samplebinding/__del___test.py
+++ b/sources/shiboken6/tests/samplebinding/__del___test.py
@@ -16,11 +16,13 @@ import sample
delCalled = False
+
class MyObject(sample.ObjectType):
def __del__(self):
global delCalled
delCalled = True
+
class TestDel(unittest.TestCase):
def testIt(self):
a = MyObject()
@@ -29,6 +31,6 @@ class TestDel(unittest.TestCase):
gc.collect()
self.assertTrue(delCalled)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/abstract_test.py b/sources/shiboken6/tests/samplebinding/abstract_test.py
index 252541af1..89e87be1d 100644
--- a/sources/shiboken6/tests/samplebinding/abstract_test.py
+++ b/sources/shiboken6/tests/samplebinding/abstract_test.py
@@ -15,10 +15,12 @@ init_paths()
from sample import Abstract
+
class Incomplete(Abstract):
def __init__(self):
Abstract.__init__(self)
+
class Concrete(Abstract):
def __init__(self):
Abstract.__init__(self)
@@ -60,12 +62,7 @@ class AbstractTest(unittest.TestCase):
# Python and calling it from C++ is undefined until it's decided how to
# cast the Python data types to void pointers
c = Concrete()
- self.assertEqual(c.pureVirtualReturningVoidPtr(),42)
-
- def testReimplementedVirtualMethodCall(self):
- '''Test if instanciation of an abstract class raises the correct exception.'''
- i = Concrete()
- self.assertRaises(NotImplementedError, i.callPureVirtual)
+ self.assertEqual(c.pureVirtualReturningVoidPtr(), 42)
def testReimplementedVirtualMethodCall(self):
'''Test if a Python override of a virtual method is correctly called from C++.'''
@@ -85,6 +82,6 @@ class AbstractTest(unittest.TestCase):
c.callVirtualGettingEnum(Abstract.Short)
self.assertTrue(c.virtual_getting_enum)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/addedfunction_test.py b/sources/shiboken6/tests/samplebinding/addedfunction_test.py
index 879bba7f2..0b5680143 100644
--- a/sources/shiboken6/tests/samplebinding/addedfunction_test.py
+++ b/sources/shiboken6/tests/samplebinding/addedfunction_test.py
@@ -14,6 +14,7 @@ from shiboken_paths import init_paths
init_paths()
from sample import SampleNamespace, ObjectType, Point
+
class TestAddedFunctionsWithSimilarTypes(unittest.TestCase):
'''Adds new signatures very similar to already existing ones.'''
@@ -38,5 +39,6 @@ class TestAddedFunctionsWithSimilarTypes(unittest.TestCase):
control = len(obj.objectName())
self.assertEqual(SampleNamespace.passReferenceToObjectType(obj), control)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_test.py b/sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_test.py
index 3a570ccfd..2a739033b 100644
--- a/sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_test.py
+++ b/sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_test.py
@@ -14,18 +14,20 @@ from shiboken_paths import init_paths
init_paths()
from sample import sum2d, sumproduct
+
class TestAddedFunctionsWithContainerArgs(unittest.TestCase):
'''Tests added functions with nested and multi-argument container types.'''
def testNestedContainerType(self):
'''Test added function with single-argument containers.'''
- values = [[1,2],[3,4,5],[6]]
+ values = [[1, 2], [3, 4, 5], [6]]
self.assertEqual(sum2d(values), 21)
def testMultiArgContainerType(self):
'''Test added function with a two-argument container.'''
- values = [(1,2),(3,4),(5,6)]
+ values = [(1, 2), (3, 4), (5, 6)]
self.assertEqual(sumproduct(values), 44)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/argumentmodifications_test.py b/sources/shiboken6/tests/samplebinding/argumentmodifications_test.py
index 8158f89d2..b0ca56a6d 100644
--- a/sources/shiboken6/tests/samplebinding/argumentmodifications_test.py
+++ b/sources/shiboken6/tests/samplebinding/argumentmodifications_test.py
@@ -16,6 +16,7 @@ init_paths()
from sample import Modifications, Point
+
class ArgumentModificationsTest(unittest.TestCase):
'''Test cases for method arguments modifications performed as described on typesystem.'''
@@ -40,7 +41,8 @@ class ArgumentModificationsTest(unittest.TestCase):
def testArgRemoval1(self):
'''Tests argument removal modifications on Modifications.argRemoval1.'''
- # void [-> PyObject*] argRemoval1(int, bool, Point = Point(1, 2) [removed], Point = Point(3, 4) [removed], int = 333)
+ # void [-> PyObject*] argRemoval1(int, bool, Point = Point(1, 2) [removed],
+ # Point = Point(3, 4) [removed], int = 333)
# code-injection: returns tuple with received parameters plus removed ones
a0, a1, a2 = 1, True, 2
self.assertEqual(self.mods.argRemoval1(a0, a1), (a0, a1, Point(1, 2), Point(3, 4), 333))
@@ -51,7 +53,8 @@ class ArgumentModificationsTest(unittest.TestCase):
def testArgRemoval2(self):
'''Tests argument removal modifications on Modifications.argRemoval2.'''
- # void [-> PyObject*] argRemoval2(int, bool, Point = Point(1, 2) [removed], Point = Point(3, 4) [removed], int = 333)
+ # void [-> PyObject*] argRemoval2(int, bool, Point = Point(1, 2)
+ # [removed], Point = Point(3, 4) [removed], int = 333)
# code-injection: returns tuple with received parameters plus removed ones
a0, a1, a2 = 1, True, 2
self.assertEqual(self.mods.argRemoval2(a0, a1), (a0, a1, Point(1, 2), Point(3, 4), 333))
@@ -59,7 +62,8 @@ class ArgumentModificationsTest(unittest.TestCase):
def testArgRemoval3(self):
'''Tests argument removal modifications on Modifications.argRemoval3.'''
- # void [-> PyObject*] argRemoval3(int, Point = Point(1, 2) [removed], bool = true, Point = Point(3, 4) [removed], int = 333)
+ # void [-> PyObject*] argRemoval3(int, Point = Point(1, 2) [removed],
+ # bool = true, Point = Point(3, 4) [removed], int = 333)
# code-injection: returns tuple with received parameters plus removed ones
a0, a1, a2 = 1, True, 2
self.assertEqual(self.mods.argRemoval3(a0), (a0, Point(1, 2), True, Point(3, 4), 333))
@@ -68,7 +72,8 @@ class ArgumentModificationsTest(unittest.TestCase):
def testArgRemoval4(self):
'''Tests argument removal modifications on Modifications.argRemoval4.'''
- # void [-> PyObject*] argRemoval4(int, Point [removed, new val = Point(6, 9)], bool, Point = Point(3, 4) [removed], int = 333)
+ # void [-> PyObject*] argRemoval4(int, Point [removed, new val = Point(6, 9)], bool,
+ # Point = Point(3, 4) [removed], int = 333)
# code-injection: returns tuple with received parameters plus removed ones
a0, a1, a2 = 1, True, 2
self.assertRaises(TypeError, self.mods.argRemoval4, a0)
@@ -88,6 +93,6 @@ class ArgumentModificationsTest(unittest.TestCase):
# code-injection: returns tuple with received parameters plus removed ones
self.assertEqual(self.mods.argRemoval5(a0, a1, a2), (200, a0, a1, a2))
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/array_numpy_test.py b/sources/shiboken6/tests/samplebinding/array_numpy_test.py
index ba9194122..0d73bca1c 100644
--- a/sources/shiboken6/tests/samplebinding/array_numpy_test.py
+++ b/sources/shiboken6/tests/samplebinding/array_numpy_test.py
@@ -22,24 +22,26 @@ try:
except ImportError:
pass
+
class ArrayTester(unittest.TestCase):
'''Test case for NumPy arrays.'''
def testIntArray(self):
- intList = numpy.array([1, 2, 3, 4], dtype = 'int32')
+ intList = numpy.array([1, 2, 3, 4], dtype='int32')
self.assertEqual(sample.sumIntArray(intList), 10)
def testDoubleArray(self):
- doubleList = numpy.array([1, 2, 3, 4], dtype = 'double')
+ doubleList = numpy.array([1, 2, 3, 4], dtype='double')
self.assertEqual(sample.sumDoubleArray(doubleList), 10)
def testIntMatrix(self):
- intMatrix = numpy.array([[1, 2, 3], [4, 5, 6]], dtype = 'int32')
+ intMatrix = numpy.array([[1, 2, 3], [4, 5, 6]], dtype='int32')
self.assertEqual(sample.sumIntMatrix(intMatrix), 21)
def testDoubleMatrix(self):
- doubleMatrix = numpy.array([[1, 2, 3], [4, 5, 6]], dtype = 'double')
+ doubleMatrix = numpy.array([[1, 2, 3], [4, 5, 6]], dtype='double')
self.assertEqual(sample.sumDoubleMatrix(doubleMatrix), 21)
+
if __name__ == '__main__' and hasNumPy:
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/array_sequence_test.py b/sources/shiboken6/tests/samplebinding/array_sequence_test.py
index cb5cbc49d..ad65d58db 100644
--- a/sources/shiboken6/tests/samplebinding/array_sequence_test.py
+++ b/sources/shiboken6/tests/samplebinding/array_sequence_test.py
@@ -14,6 +14,7 @@ from shiboken_paths import init_paths
init_paths()
import sample
+
class ArrayTester(unittest.TestCase):
'''Test case for arrays.'''
@@ -30,5 +31,6 @@ class ArrayTester(unittest.TestCase):
doubleList = [1.2, 2.3, 3.4, 4.5]
self.assertEqual(sample.sumDoubleArray(doubleList), 11.4)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/bug_554_test.py b/sources/shiboken6/tests/samplebinding/bug_554_test.py
index 6c4df6399..a7e7a7210 100644
--- a/sources/shiboken6/tests/samplebinding/bug_554_test.py
+++ b/sources/shiboken6/tests/samplebinding/bug_554_test.py
@@ -11,15 +11,15 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import ObjectType
+
class Bug554:
def crash(self):
class Crasher(ObjectType):
pass
+
if __name__ == '__main__':
bug = Bug554()
bug.crash()
-
-
diff --git a/sources/shiboken6/tests/samplebinding/bug_704_test.py b/sources/shiboken6/tests/samplebinding/bug_704_test.py
index 6de8fa3ea..c470fe723 100644
--- a/sources/shiboken6/tests/samplebinding/bug_704_test.py
+++ b/sources/shiboken6/tests/samplebinding/bug_704_test.py
@@ -25,13 +25,12 @@ def defineNewStyle():
class ObjectTypeTest(unittest.TestCase):
- '''Test cases to avoid declaring Shiboken classes with multiple inheritance from old style classes.'''
+ '''Test cases to avoid declaring Shiboken classes with multiple inheritance
+ from old style classes.'''
def testObjectTypeNewStype(self):
defineNewStyle()
-
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/bytearray_test.py b/sources/shiboken6/tests/samplebinding/bytearray_test.py
index e7c421b96..e51a899fa 100644
--- a/sources/shiboken6/tests/samplebinding/bytearray_test.py
+++ b/sources/shiboken6/tests/samplebinding/bytearray_test.py
@@ -34,7 +34,7 @@ class ByteArrayConcatenationOperatorTest(unittest.TestCase):
def testConcatPythonStringAndByteArray(self):
# Test concatenation of a Python string with a ByteArray, in this order.
- concat_python_string_add_qbytearray_worked = True
+ concat_python_string_add_qbytearray_worked = True # noqa: F841
ba = ByteArray('foo')
result = 'bar\x00' + ba
self.assertEqual(type(result), ByteArray)
@@ -80,14 +80,14 @@ class ByteArrayOperatorAt(unittest.TestCase):
# ByteArray[x] where x is a valid index (reverse order).
string = 'abcdefgh'
obj = ByteArray(string)
- for i in range(len(string)-1, 0, -1):
+ for i in range(len(string) - 1, 0, -1):
self.assertEqual(obj[i], bytes(string[i], "UTF8"))
def testOutOfRange(self):
# ByteArray[x] where x is out of index.
string = '1234567'
obj = ByteArray(string)
- self.assertRaises(IndexError, lambda :obj[len(string)])
+ self.assertRaises(IndexError, lambda: obj[len(string)])
def testNullStrings(self):
ba = ByteArray('\x00')
diff --git a/sources/shiboken6/tests/samplebinding/child_return_test.py b/sources/shiboken6/tests/samplebinding/child_return_test.py
index 97525bcb8..f0ac70626 100644
--- a/sources/shiboken6/tests/samplebinding/child_return_test.py
+++ b/sources/shiboken6/tests/samplebinding/child_return_test.py
@@ -14,7 +14,8 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import ObjectType
+
class ReturnOfChildTest(unittest.TestCase):
'''The BlackBox class has cases of ownership transference between C++ and Python.'''
@@ -37,6 +38,6 @@ class ReturnOfChildTest(unittest.TestCase):
gc.collect()
self.assertRaises(RuntimeError, child.objectName)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/class_fields_test.py b/sources/shiboken6/tests/samplebinding/class_fields_test.py
index 9da25e137..1eeb3d446 100644
--- a/sources/shiboken6/tests/samplebinding/class_fields_test.py
+++ b/sources/shiboken6/tests/samplebinding/class_fields_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import Derived, Point, ObjectType
+
class TestAccessingCppFields(unittest.TestCase):
'''Simple test case for accessing the exposed C++ class fields.'''
@@ -36,7 +37,7 @@ class TestAccessingCppFields(unittest.TestCase):
self.assertEqual(d.primitiveField, int(value))
# attribution with invalid type
- self.assertRaises(TypeError, lambda : setattr(d, 'primitiveField', None))
+ self.assertRaises(TypeError, lambda: setattr(d, 'primitiveField', None))
def testAccessingRenamedFields(self):
'''Reads and writes a renamed field.'''
@@ -72,7 +73,7 @@ class TestAccessingCppFields(unittest.TestCase):
self.assertNotEqual(d.userPrimitiveField, old_value)
# attribution with invalid type
- self.assertRaises(TypeError, lambda : setattr(d, 'userPrimitiveField', None))
+ self.assertRaises(TypeError, lambda: setattr(d, 'userPrimitiveField', None))
def testAccessingValueTypeField(self):
'''Reads and writes a value type (in this case a 'Point') field.'''
@@ -80,7 +81,7 @@ class TestAccessingCppFields(unittest.TestCase):
self.assertEqual(type(d.valueTypeField), Point)
# attribution
- old_value = d.valueTypeField
+ old_value = d.valueTypeField # noqa: F841
new_value = Point(-10, 537)
d.valueTypeField = new_value
self.assertEqual(d.valueTypeField, new_value)
@@ -92,7 +93,7 @@ class TestAccessingCppFields(unittest.TestCase):
self.assertEqual(d.valueTypeField.y(), 20)
# attribution with invalid type
- self.assertRaises(TypeError, lambda : setattr(d, 'valueTypeField', 123))
+ self.assertRaises(TypeError, lambda: setattr(d, 'valueTypeField', 123))
def testAccessingObjectTypeField(self):
'''Reads and writes a object type (in this case an 'ObjectType') field.'''
@@ -111,7 +112,7 @@ class TestAccessingCppFields(unittest.TestCase):
self.assertEqual(d.objectTypeField, value)
# attribution with invalid type
- self.assertRaises(TypeError, lambda : setattr(d, 'objectTypeField', 123))
+ self.assertRaises(TypeError, lambda: setattr(d, 'objectTypeField', 123))
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testRefCountingAccessingObjectTypeField(self):
@@ -155,7 +156,7 @@ class TestAccessingCppFields(unittest.TestCase):
# attribution
old_value = d.bitField
new_value = 1
- d.bitField= new_value
+ d.bitField = new_value
self.assertEqual(d.bitField, new_value)
self.assertNotEqual(d.bitField, old_value)
@@ -165,7 +166,7 @@ class TestAccessingCppFields(unittest.TestCase):
self.assertEqual(d.bitField, int(value))
# attribution with invalid type
- self.assertRaises(TypeError, lambda : setattr(d, 'bitField', None))
+ self.assertRaises(TypeError, lambda: setattr(d, 'bitField', None))
if __name__ == '__main__':
diff --git a/sources/shiboken6/tests/samplebinding/collector_test.py b/sources/shiboken6/tests/samplebinding/collector_test.py
index 376f91f1c..4caebc62a 100644
--- a/sources/shiboken6/tests/samplebinding/collector_test.py
+++ b/sources/shiboken6/tests/samplebinding/collector_test.py
@@ -33,6 +33,7 @@ class CollectorTest(unittest.TestCase):
self.assertEqual(collector.size(), 5)
self.assertEqual(collector.items(), [2, 3, 5, 7, 11])
+
class CollectorExternalOperator(unittest.TestCase):
'''Test cases for external operators of Collector'''
@@ -57,4 +58,3 @@ class CollectorObjectType(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/complex_test.py b/sources/shiboken6/tests/samplebinding/complex_test.py
index 6f0b23b2a..454aff100 100644
--- a/sources/shiboken6/tests/samplebinding/complex_test.py
+++ b/sources/shiboken6/tests/samplebinding/complex_test.py
@@ -16,6 +16,7 @@ init_paths()
import sample
from sample import Point
+
class ComplexTest(unittest.TestCase):
'''Test case for conversions between C++ Complex class to Python complex class'''
@@ -47,11 +48,14 @@ class ComplexTest(unittest.TestCase):
def testUsingTuples(self):
cpx1, cpx2 = (1.2, 3.4), (5.6, 7.8)
- self.assertEqual(sample.sumComplexPair((cpx1, cpx2)), sample.sumComplexPair((complex(*cpx1), complex(*cpx2))))
+ self.assertEqual(sample.sumComplexPair((cpx1, cpx2)),
+ sample.sumComplexPair((complex(*cpx1), complex(*cpx2))))
cpx1, cpx2 = (1, 3), (5, 7)
- self.assertEqual(sample.sumComplexPair((cpx1, cpx2)), sample.sumComplexPair((complex(*cpx1), complex(*cpx2))))
+ self.assertEqual(sample.sumComplexPair((cpx1, cpx2)),
+ sample.sumComplexPair((complex(*cpx1), complex(*cpx2))))
cpx1, cpx2 = (1.2, 3), (5.6, 7)
- self.assertEqual(sample.sumComplexPair((cpx1, cpx2)), sample.sumComplexPair((complex(*cpx1), complex(*cpx2))))
+ self.assertEqual(sample.sumComplexPair((cpx1, cpx2)),
+ sample.sumComplexPair((complex(*cpx1), complex(*cpx2))))
cpx1, cpx2 = (1, 2, 3), (4, 5, 7)
self.assertRaises(TypeError, sample.sumComplexPair, (cpx1, cpx2))
cpx1, cpx2 = ('1', '2'), ('4', '5')
@@ -60,4 +64,3 @@ class ComplexTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/conversion_operator_test.py b/sources/shiboken6/tests/samplebinding/conversion_operator_test.py
index f349ae82b..7e76245b1 100644
--- a/sources/shiboken6/tests/samplebinding/conversion_operator_test.py
+++ b/sources/shiboken6/tests/samplebinding/conversion_operator_test.py
@@ -15,11 +15,13 @@ init_paths()
from sample import Time, StrList
+
class ConversionOperatorTest(unittest.TestCase):
'''Test cases for implicit conversion generated by conversion operator.'''
def testConversionOperator(self):
- '''Time defined an conversion operator for Str, so passing a Time object to a method expecting a Str should work.'''
+ '''Time defined an conversion operator for Str, so passing a Time object
+ to a method expecting a Str should work.'''
t = Time(1, 2, 3)
t_str = t.toString()
sl = StrList()
@@ -30,6 +32,6 @@ class ConversionOperatorTest(unittest.TestCase):
self.assertEqual(len(sl), 1)
self.assertEqual(sl[0], t_str)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/copy_test.py b/sources/shiboken6/tests/samplebinding/copy_test.py
index 0a0533a41..db539d1b9 100644
--- a/sources/shiboken6/tests/samplebinding/copy_test.py
+++ b/sources/shiboken6/tests/samplebinding/copy_test.py
@@ -63,4 +63,3 @@ class PicklingTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/ctorconvrule_test.py b/sources/shiboken6/tests/samplebinding/ctorconvrule_test.py
index 0ad21e35c..5e2695d72 100644
--- a/sources/shiboken6/tests/samplebinding/ctorconvrule_test.py
+++ b/sources/shiboken6/tests/samplebinding/ctorconvrule_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import CtorConvRule
+
class TestCtorConvRule(unittest.TestCase):
'''Simple test case for CtorConvRule'''
@@ -24,6 +25,6 @@ class TestCtorConvRule(unittest.TestCase):
obj = CtorConvRule(value)
self.assertEqual(obj.value(), value + 1)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/cyclic_test.py b/sources/shiboken6/tests/samplebinding/cyclic_test.py
index b72e41b19..4e4ae2603 100644
--- a/sources/shiboken6/tests/samplebinding/cyclic_test.py
+++ b/sources/shiboken6/tests/samplebinding/cyclic_test.py
@@ -16,7 +16,6 @@ from sample import ObjectView
from sample import ObjectModel
-
class ObjTest(unittest.TestCase):
def test_cyclic_dependency_withParent(self):
@@ -37,7 +36,7 @@ class ObjTest(unittest.TestCase):
# turn off automatic garbage collection, to be able to trigger it
# at the 'right' time
gc.disable()
- alive = lambda :sum(isinstance(o, CyclicObject) for o in gc.get_objects() )
+ alive = lambda: sum(isinstance(o, CyclicObject) for o in gc.get_objects()) # noqa: E731
#
# first proof that the wizard is only destructed by the garbage
@@ -70,7 +69,7 @@ class ObjTest(unittest.TestCase):
# turn off automatic garbage collection, to be able to trigger it
# at the 'right' time
gc.disable()
- alive = lambda :sum(isinstance(o, CyclicObject) for o in gc.get_objects() )
+ alive = lambda: sum(isinstance(o, CyclicObject) for o in gc.get_objects()) # noqa: E731
#
# first proof that the wizard is only destructed by the garbage
@@ -85,6 +84,6 @@ class ObjTest(unittest.TestCase):
gc.collect()
self.assertFalse(alive())
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/date_test.py b/sources/shiboken6/tests/samplebinding/date_test.py
index a35861c8c..2b6efcf18 100644
--- a/sources/shiboken6/tests/samplebinding/date_test.py
+++ b/sources/shiboken6/tests/samplebinding/date_test.py
@@ -16,6 +16,7 @@ from datetime import date
from sample import SbkDate
+
class DateConversionTest(unittest.TestCase):
def testConstructorWithDateObject(self):
@@ -32,6 +33,6 @@ class DateConversionTest(unittest.TestCase):
self.assertTrue(cDate.month(), pyDate.month)
self.assertTrue(cDate.year(), pyDate.year)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/decisor_test.py b/sources/shiboken6/tests/samplebinding/decisor_test.py
index 6c7b4482d..0d39c5f96 100644
--- a/sources/shiboken6/tests/samplebinding/decisor_test.py
+++ b/sources/shiboken6/tests/samplebinding/decisor_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import SampleNamespace, Point, ObjectType, ObjectModel
+
class DecisorTest(unittest.TestCase):
'''Test cases for the method overload decisor.'''
@@ -37,11 +38,15 @@ class DecisorTest(unittest.TestCase):
'''Call methods overloads that receive parent and inheritor classes' instances.'''
objecttype = ObjectType()
objectmodel = ObjectModel()
- self.assertEqual(ObjectModel.receivesObjectTypeFamily(objecttype), ObjectModel.ObjectTypeCalled)
- self.assertNotEqual(ObjectModel.receivesObjectTypeFamily(objecttype), ObjectModel.ObjectModelCalled)
- self.assertEqual(ObjectModel.receivesObjectTypeFamily(objectmodel), ObjectModel.ObjectModelCalled)
- self.assertNotEqual(ObjectModel.receivesObjectTypeFamily(objectmodel), ObjectModel.ObjectTypeCalled)
+ self.assertEqual(ObjectModel.receivesObjectTypeFamily(objecttype),
+ ObjectModel.ObjectTypeCalled)
+ self.assertNotEqual(ObjectModel.receivesObjectTypeFamily(objecttype),
+ ObjectModel.ObjectModelCalled)
+ self.assertEqual(ObjectModel.receivesObjectTypeFamily(objectmodel),
+ ObjectModel.ObjectModelCalled)
+ self.assertNotEqual(ObjectModel.receivesObjectTypeFamily(objectmodel),
+ ObjectModel.ObjectTypeCalled)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/delete_test.py b/sources/shiboken6/tests/samplebinding/delete_test.py
index 5a4ee090e..57a792ae2 100644
--- a/sources/shiboken6/tests/samplebinding/delete_test.py
+++ b/sources/shiboken6/tests/samplebinding/delete_test.py
@@ -14,15 +14,15 @@ init_paths()
import sample
from shiboken6 import Shiboken
+
class DeleteTest(unittest.TestCase):
def testNonCppWrapperClassDelete(self):
- """Would segfault when shiboken.delete called on obj not created from
- Python """
+ """Would segfault when shiboken.delete called on obj not created from Python."""
obj = sample.ObjectType()
child = obj.createChild(None)
Shiboken.delete(child)
assert not Shiboken.isValid(child)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/deprecated_test.py b/sources/shiboken6/tests/samplebinding/deprecated_test.py
index 95b07f838..c371df94f 100644
--- a/sources/shiboken6/tests/samplebinding/deprecated_test.py
+++ b/sources/shiboken6/tests/samplebinding/deprecated_test.py
@@ -14,11 +14,13 @@ init_paths()
from sample import ObjectType
+
class TestDeprecatedCall(unittest.TestCase):
def testCallWithError(self):
o = ObjectType()
warnings.simplefilter('error')
self.assertRaises(DeprecationWarning, o.deprecatedFunction)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/derived_test.py b/sources/shiboken6/tests/samplebinding/derived_test.py
index 7db8e5155..346f29136 100644
--- a/sources/shiboken6/tests/samplebinding/derived_test.py
+++ b/sources/shiboken6/tests/samplebinding/derived_test.py
@@ -16,6 +16,7 @@ init_paths()
import sample
from sample import Abstract, Derived, DerivedUsingCt, OverloadedFuncEnum
+
class Deviant(Derived):
def __init__(self):
Derived.__init__(self)
@@ -31,6 +32,16 @@ class Deviant(Derived):
def className(self):
return 'Deviant'
+
+class ImplementVirtualWithOutParameter(Derived):
+ def __init__(self, value):
+ super().__init__()
+ self._value = value
+
+ def virtualWithOutParameter(self):
+ return self._value
+
+
class DerivedTest(unittest.TestCase):
'''Test case for Derived class'''
@@ -40,23 +51,6 @@ class DerivedTest(unittest.TestCase):
'id_', 'pureVirtual', 'unpureVirtual'])
self.assertTrue(inherited_methods.issubset(dir(Derived)))
- @unittest.skipIf(sys.pyside63_option_python_enum, "Makes no sense with strict Enums")
- def testOverloadedMethodCall(self):
- '''Test if the correct overloaded method is being called.'''
- derived = Derived()
-
- result = derived.overloaded(1, 2)
- self.assertEqual(type(result), OverloadedFuncEnum)
- self.assertEqual(result, sample.OverloadedFunc_ii)
-
- result = derived.overloaded(3)
- self.assertEqual(type(result), OverloadedFuncEnum)
- self.assertEqual(result, sample.OverloadedFunc_ii)
-
- result = derived.overloaded(4.4)
- self.assertEqual(type(result), OverloadedFuncEnum)
- self.assertEqual(result, sample.OverloadedFunc_d)
-
def testOtherOverloadedMethodCall(self):
'''Another test to check overloaded method calling, just to double check.'''
derived = Derived()
@@ -74,22 +68,23 @@ class DerivedTest(unittest.TestCase):
derived = Derived()
result = derived.overloaded(1.1, 2.2)
self.assertEqual(type(result), OverloadedFuncEnum)
- if not sys.pyside63_option_python_enum:
- self.assertEqual(result, sample.OverloadedFunc_ii)
def testOverloadedMethodCallWithWrongNumberOfArguments(self):
- '''Test if a call to an overloaded method with the wrong number of arguments raises an exception.'''
+ '''Test if a call to an overloaded method with the wrong number of arguments
+ raises an exception.'''
derived = Derived()
self.assertRaises(TypeError, derived.otherOverloaded, 1, 2, True)
def testReimplementedPureVirtualMethodCall(self):
- '''Test if a Python override of a implemented pure virtual method is correctly called from C++.'''
+ '''Test if a Python override of a implemented pure virtual method is
+ correctly called from C++.'''
d = Deviant()
d.callPureVirtual()
self.assertTrue(d.pure_virtual_called)
def testReimplementedVirtualMethodCall(self):
- '''Test if a Python override of a reimplemented virtual method is correctly called from C++.'''
+ '''Test if a Python override of a reimplemented virtual method is
+ correctly called from C++.'''
d = Deviant()
d.callUnpureVirtual()
self.assertTrue(d.unpure_virtual_called)
@@ -101,7 +96,8 @@ class DerivedTest(unittest.TestCase):
self.assertEqual(d.getClassName(), 'Derived')
def testReimplementedVirtualMethodCallReturningString(self):
- '''Test if a Python override of a reimplemented virtual method is correctly called from C++.'''
+ '''Test if a Python override of a reimplemented virtual method is
+ correctly called from C++.'''
d = Deviant()
self.assertEqual(d.className(), 'Deviant')
self.assertEqual(d.getClassName(), 'Deviant')
@@ -125,7 +121,8 @@ class DerivedTest(unittest.TestCase):
self.assertEqual(Abstract.getObjectId(d), objId)
def testObjectCreationWithParentType(self):
- '''Derived class creates an instance of itself in C++ and returns it as a pointer to its ancestor Abstract.'''
+ '''Derived class creates an instance of itself in C++ and returns it as
+ a pointer to its ancestor Abstract.'''
obj = Derived.createObject()
self.assertEqual(type(obj), Derived)
@@ -134,7 +131,13 @@ class DerivedTest(unittest.TestCase):
obj = DerivedUsingCt(42)
self.assertEqual(obj.value(), 42)
+ def testVirtualWithOutParameter(self):
+ d = Derived()
+ self.assertEqual(d.callVirtualWithOutParameter(), 42)
+
+ d = ImplementVirtualWithOutParameter(1)
+ self.assertEqual(d.callVirtualWithOutParameter(), 1)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/duck_punching_test.py b/sources/shiboken6/tests/samplebinding/duck_punching_test.py
index e1d89e2c0..aa21a0f7e 100644
--- a/sources/shiboken6/tests/samplebinding/duck_punching_test.py
+++ b/sources/shiboken6/tests/samplebinding/duck_punching_test.py
@@ -16,6 +16,7 @@ init_paths()
from sample import VirtualMethods, SimpleFile, Point
+
def MethodTypeCompat(func, instance):
return types.MethodType(func, instance)
@@ -24,10 +25,12 @@ class Duck(VirtualMethods):
def __init__(self):
VirtualMethods.__init__(self)
+
class Monkey(SimpleFile):
def __init__(self, filename):
SimpleFile.__init__(self, filename)
+
class DuckPunchingTest(unittest.TestCase):
'''Test case for duck punching (aka "monkey patching").'''
@@ -56,7 +59,8 @@ class DuckPunchingTest(unittest.TestCase):
result2 = vm.virtualMethod0(pt, val, cpx, b)
self.assertEqual(result1, result2)
- self.assertEqual(result1, VirtualMethods.virtualMethod0(vm, pt, val, cpx, b) * self.multiplier)
+ self.assertEqual(result1,
+ VirtualMethods.virtualMethod0(vm, pt, val, cpx, b) * self.multiplier)
# This is done to decrease the refcount of the vm object
# allowing the object wrapper to be deleted before the
@@ -66,7 +70,8 @@ class DuckPunchingTest(unittest.TestCase):
vm.virtualMethod0 = None
def testMonkeyPatchOnVirtualMethodWithInheritance(self):
- '''Injects new 'virtualMethod0' on an object that inherits from VirtualMethods and makes C++ call it.'''
+ '''Injects new 'virtualMethod0' on an object that inherits from
+ VirtualMethods and makes C++ call it.'''
duck = Duck()
pt, val, cpx, b = Point(1.1, 2.2), 4, complex(3.3, 4.4), True
@@ -85,7 +90,8 @@ class DuckPunchingTest(unittest.TestCase):
result2 = duck.virtualMethod0(pt, val, cpx, b)
self.assertEqual(result1, result2)
- self.assertEqual(result1, VirtualMethods.virtualMethod0(duck, pt, val, cpx, b) * self.multiplier)
+ self.assertEqual(result1,
+ VirtualMethods.virtualMethod0(duck, pt, val, cpx, b) * self.multiplier)
duck.virtualMethod0 = None
@@ -150,4 +156,3 @@ class DuckPunchingTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/echo_test.py b/sources/shiboken6/tests/samplebinding/echo_test.py
index 567d1452a..f1859260e 100644
--- a/sources/shiboken6/tests/samplebinding/echo_test.py
+++ b/sources/shiboken6/tests/samplebinding/echo_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import Echo
+
class TestEcho(unittest.TestCase):
'''Simple test case for Echo.echo'''
@@ -26,7 +27,8 @@ class TestEcho(unittest.TestCase):
def testCallOperator(self):
e = Echo()
- self.assertEqual(e("Hello", 3), "Hello3");
+ self.assertEqual(e("Hello", 3), "Hello3")
+
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/enum_test.py b/sources/shiboken6/tests/samplebinding/enum_test.py
index 90f36a186..276b8d894 100644
--- a/sources/shiboken6/tests/samplebinding/enum_test.py
+++ b/sources/shiboken6/tests/samplebinding/enum_test.py
@@ -13,12 +13,10 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-import shiboken6
# This is needed after the introduction of BUILD_DIR.
import sample
from sample import SampleNamespace, ObjectType, Event
-from shibokensupport.signature import get_signature
def createTempFile():
@@ -29,22 +27,13 @@ def createTempFile():
class EnumTest(unittest.TestCase):
'''Test case for Python representation of C++ enums.'''
- @unittest.skipIf(sys.pyside63_option_python_enum, "test not suitable for Python enum")
- def testEnumRepr(self):
- enum = SampleNamespace.Option(1)
- self.assertEqual(eval(repr(enum)), enum)
-
- enum = SampleNamespace.Option(999)
- self.assertEqual(eval(repr(enum)), enum)
-
def testHashability(self):
self.assertEqual(hash(SampleNamespace.TwoIn), hash(SampleNamespace.TwoOut))
self.assertNotEqual(hash(SampleNamespace.TwoIn), hash(SampleNamespace.OneIn))
def testEnumValuesInsideEnum(self):
'''Enum values should be accessible inside the enum as well as outside.'''
- for value_name in (SampleNamespace.Option.__members__ if sys.pyside63_option_python_enum
- else SampleNamespace.Option.values):
+ for value_name in SampleNamespace.Option.__members__:
enum_item1 = getattr(SampleNamespace.Option, value_name)
enum_item2 = getattr(SampleNamespace, value_name)
self.assertEqual(enum_item1, enum_item2)
@@ -70,7 +59,7 @@ class EnumTest(unittest.TestCase):
def testEnumConstructorWithTooManyParameters(self):
'''Calling the constructor of non-extensible enum with the wrong number of parameters.'''
- self.assertRaises(TypeError, SampleNamespace.InValue, 13, 14)
+ self.assertRaises((TypeError, ValueError), SampleNamespace.InValue, 13, 14)
def testEnumConstructorWithNonNumberParameter(self):
'''Calling the constructor of non-extensible enum with a string.'''
@@ -78,8 +67,10 @@ class EnumTest(unittest.TestCase):
def testEnumItemAsDefaultValueToIntArgument(self):
'''Calls function with an enum item as default value to an int argument.'''
- self.assertEqual(SampleNamespace.enumItemAsDefaultValueToIntArgument(), SampleNamespace.ZeroIn)
- self.assertEqual(SampleNamespace.enumItemAsDefaultValueToIntArgument(SampleNamespace.ZeroOut), SampleNamespace.ZeroOut)
+ self.assertEqual(SampleNamespace.enumItemAsDefaultValueToIntArgument(),
+ SampleNamespace.ZeroIn)
+ self.assertEqual(SampleNamespace.enumItemAsDefaultValueToIntArgument(SampleNamespace.ZeroOut), # noqa E:501
+ SampleNamespace.ZeroOut)
self.assertEqual(SampleNamespace.enumItemAsDefaultValueToIntArgument(123), 123)
def testAnonymousGlobalEnums(self):
@@ -107,54 +98,22 @@ class EnumTest(unittest.TestCase):
event.setEventTypeByConstPtr(Event.BASIC_EVENT)
self.assertEqual(event.eventType(), Event.BASIC_EVENT)
- @unittest.skipIf(sys.pyside63_option_python_enum, "test not suitable for Python enum")
- def testEnumTpPrintImplementation(self):
- '''Without SbkEnum.tp_print 'print' returns the enum represented as an int.'''
- tmpfile = createTempFile()
- print(Event.ANY_EVENT, file=tmpfile)
- tmpfile.seek(0)
- text = tmpfile.read().strip()
- tmpfile.close()
- self.assertEqual(text, str(Event.ANY_EVENT))
- self.assertEqual(text, repr(Event.ANY_EVENT))
-
def testEnumArgumentWithDefaultValue(self):
'''Option enumArgumentWithDefaultValue(Option opt = UnixTime);'''
self.assertEqual(SampleNamespace.enumArgumentWithDefaultValue(), SampleNamespace.UnixTime)
- self.assertEqual(SampleNamespace.enumArgumentWithDefaultValue(SampleNamespace.RandomNumber), SampleNamespace.RandomNumber)
-
- @unittest.skipIf(sys.pyside63_option_python_enum, "test not suitable for Python enum")
- def testSignature(self):
- enum = SampleNamespace.Option(1)
- types = type(enum).mro()
- klass = types[0]
- base = types[1]
- # The class has an empty signature.
-
- self.assertEqual(get_signature(klass), None)
- # The base class must be Enum
- self.assertNotEqual(get_signature(base), None)
- # It contains an int annotation.
- param = get_signature(base).parameters["itemValue"]
- self.assertEqual(param.annotation, int)
+ self.assertEqual(SampleNamespace.enumArgumentWithDefaultValue(SampleNamespace.RandomNumber), # noqa E:501
+ SampleNamespace.RandomNumber)
class MyEvent(Event):
def __init__(self):
- Event.__init__(self, Event.EventType(3 if sys.pyside63_option_python_enum else 999))
+ Event.__init__(self, Event.EventType(3))
class OutOfBoundsTest(unittest.TestCase):
def testValue(self):
e = MyEvent()
- self.assertEqual(repr(e.eventType()), "<EventType.ANY_EVENT: 3>"
- if sys.pyside63_option_python_enum else 'sample.Event.EventType(999)')
-
- @unittest.skipIf(sys.pyside63_option_python_enum, "test not suitable for Python enum")
- def testNoneName(self):
- e = MyEvent()
- t = e.eventType()
- self.assertEqual(t.name, None)
+ self.assertEqual(repr(e.eventType()), "<EventType.ANY_EVENT: 3>")
class EnumOverloadTest(unittest.TestCase):
@@ -177,4 +136,3 @@ class EnumOperators(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py b/sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py
index 1551703a7..42ae23961 100644
--- a/sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py
+++ b/sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py
@@ -14,22 +14,11 @@ init_paths()
import sample
from shiboken_test_helper import objectFullname
-from shiboken6 import Shiboken
-
from shibokensupport.signature import get_signature
class TestEnumFromRemovedNamespace(unittest.TestCase):
- @unittest.skipIf(sys.pyside63_option_python_enum, "Makes no sense with strict Enums")
- def testEnumPromotedToGlobal(self):
- sample.RemovedNamespace1_Enum
- self.assertEqual(sample.RemovedNamespace1_Enum_Value0, 0)
- self.assertEqual(sample.RemovedNamespace1_Enum_Value1, 1)
- sample.RemovedNamespace1_AnonymousEnum_Value0
- sample.RemovedNamespace2_Enum
- sample.RemovedNamespace2_Enum_Value0
-
def testNames(self):
# Test if invisible namespace does not appear on type name
self.assertEqual(objectFullname(sample.RemovedNamespace1_Enum),
@@ -55,9 +44,8 @@ class TestEnumFromRemovedNamespace(unittest.TestCase):
sample.UnremovedNamespace.RemovedNamespace3_AnonymousEnum_Value0
def testNestedFunctionFromRemovedNamespace(self):
- self.assertEqual(sample.UnremovedNamespace.nestedMathSum(1, 2), 3)
+ self.assertEqual(sample.UnremovedNamespace.nestedMathSum(1, 2), 3)
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py b/sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py
index e61656400..8e13d5d46 100644
--- a/sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py
+++ b/sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py
@@ -6,14 +6,12 @@
import os
import sys
-import time
import unittest
from pathlib import Path
sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from random import random
from sample import ObjectType, Event
@@ -41,7 +39,7 @@ class TestEventLoop(unittest.TestCase):
objs = [ObjectType(), NoOverride(), Override()]
evaluated = ObjectType.processEvent(objs,
- Event(Event.BASIC_EVENT))
+ Event(Event.BASIC_EVENT))
self.assertEqual(evaluated, 3)
self.assertTrue(objs[2].called)
diff --git a/sources/shiboken6/tests/samplebinding/event_loop_thread_test.py b/sources/shiboken6/tests/samplebinding/event_loop_thread_test.py
index 2cd1c8d0a..8b854fca6 100644
--- a/sources/shiboken6/tests/samplebinding/event_loop_thread_test.py
+++ b/sources/shiboken6/tests/samplebinding/event_loop_thread_test.py
@@ -64,7 +64,7 @@ class TestEventLoopWithThread(unittest.TestCase):
thread.start()
evaluated = ObjectType.processEvent(objs,
- Event(Event.BASIC_EVENT))
+ Event(Event.BASIC_EVENT))
thread.join()
diff --git a/sources/shiboken6/tests/samplebinding/exception_test.py b/sources/shiboken6/tests/samplebinding/exception_test.py
index 78e583da0..d9e6b377f 100644
--- a/sources/shiboken6/tests/samplebinding/exception_test.py
+++ b/sources/shiboken6/tests/samplebinding/exception_test.py
@@ -13,6 +13,7 @@ init_paths()
from sample import ExceptionTest
+
class CppExceptionTest(unittest.TestCase):
def testVoid(self):
@@ -23,14 +24,14 @@ class CppExceptionTest(unittest.TestCase):
try:
et.voidThrowStdException(True)
- except:
+ except: # noqa: E722
exceptionCount += 1
et.voidThrowInt(False)
try:
et.voidThrowInt(True)
- except:
+ except: # noqa: E722
exceptionCount += 1
self.assertEqual(exceptionCount, 2)
@@ -39,18 +40,18 @@ class CppExceptionTest(unittest.TestCase):
exceptionCount = 0
et = ExceptionTest()
- result = et.intThrowStdException(False);
+ result = et.intThrowStdException(False)
try:
- result = et.intThrowStdException(True);
- except:
+ result = et.intThrowStdException(True)
+ except: # noqa: E722
exceptionCount += 1
- result = et.intThrowInt(False);
+ result = et.intThrowInt(False)
try:
- result = et.intThrowInt(True);
- except:
+ result = et.intThrowInt(True) # noqa: F841
+ except: # noqa: E722
exceptionCount += 1
self.assertEqual(exceptionCount, 2)
@@ -60,8 +61,8 @@ class CppExceptionTest(unittest.TestCase):
when return ownership modifications are generated."""
exceptionCount = 0
try:
- et = ExceptionTest.create(True);
- except:
+ et = ExceptionTest.create(True) # noqa: F841
+ except: # noqa: E722
exceptionCount += 1
self.assertEqual(exceptionCount, 1)
diff --git a/sources/shiboken6/tests/samplebinding/filter_test.py b/sources/shiboken6/tests/samplebinding/filter_test.py
index 86c5fba2a..df805093f 100644
--- a/sources/shiboken6/tests/samplebinding/filter_test.py
+++ b/sources/shiboken6/tests/samplebinding/filter_test.py
@@ -12,6 +12,7 @@ init_paths()
from sample import Data, Intersection, Union
+
class TestFilters(unittest.TestCase):
def testAnd(self):
@@ -23,5 +24,6 @@ class TestFilters(unittest.TestCase):
self.assertEqual(type(inter), Intersection)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/global.h b/sources/shiboken6/tests/samplebinding/global.h
index f73fdd503..64806417a 100644
--- a/sources/shiboken6/tests/samplebinding/global.h
+++ b/sources/shiboken6/tests/samplebinding/global.h
@@ -56,6 +56,7 @@
#include "removednamespaces.h"
#include "sample.h"
#include "samplenamespace.h"
+#include "stdcomplex.h"
#include "simplefile.h"
#include "size.h"
#include "snakecasetest.h"
diff --git a/sources/shiboken6/tests/samplebinding/handleholder_test.py b/sources/shiboken6/tests/samplebinding/handleholder_test.py
index 273915719..af22328c5 100644
--- a/sources/shiboken6/tests/samplebinding/handleholder_test.py
+++ b/sources/shiboken6/tests/samplebinding/handleholder_test.py
@@ -17,6 +17,7 @@ init_paths()
from sample import HandleHolder
+
class HandleHolderTest(unittest.TestCase):
def testCreation(self):
holder = HandleHolder(HandleHolder.createHandle())
@@ -33,5 +34,6 @@ class HandleHolderTest(unittest.TestCase):
holder2 = HandleHolder(holder.handle2())
self.assertTrue(holder.compare2(holder2))
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/hashabletype_test.py b/sources/shiboken6/tests/samplebinding/hashabletype_test.py
index 20d3d2edd..c41f5cc06 100644
--- a/sources/shiboken6/tests/samplebinding/hashabletype_test.py
+++ b/sources/shiboken6/tests/samplebinding/hashabletype_test.py
@@ -13,7 +13,8 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import ObjectType, Str
+
class HashableTest(unittest.TestCase):
@@ -29,6 +30,6 @@ class HashableTest(unittest.TestCase):
h[o] = 2
self.assertTrue(h.get(o), 2)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/ignorederefop_test.py b/sources/shiboken6/tests/samplebinding/ignorederefop_test.py
index 89df035a3..feb78d045 100644
--- a/sources/shiboken6/tests/samplebinding/ignorederefop_test.py
+++ b/sources/shiboken6/tests/samplebinding/ignorederefop_test.py
@@ -9,12 +9,14 @@ from pathlib import Path
sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import Reference
+
class TestLackOfDereferenceOperators (unittest.TestCase):
def testIf(self):
r = Reference()
self.assertFalse(hasattr(r, "__mul__"))
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py b/sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py
index c5c7bc0d1..081666281 100644
--- a/sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py
+++ b/sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py
@@ -27,6 +27,7 @@ if is64bitArchitecture and sys.platform != 'win32':
cLongMin = -9223372036854775808
cLongMax = 9223372036854775807
+
class NumericTester(unittest.TestCase):
'''Helper class for numeric comparison testing'''
diff --git a/sources/shiboken6/tests/samplebinding/implicitconv_test.py b/sources/shiboken6/tests/samplebinding/implicitconv_test.py
index 96cad9c69..ebafe0c52 100644
--- a/sources/shiboken6/tests/samplebinding/implicitconv_test.py
+++ b/sources/shiboken6/tests/samplebinding/implicitconv_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import ImplicitConv, ObjectType
+
class ImplicitConvTest(unittest.TestCase):
'''Test case for implicit conversions'''
@@ -43,4 +44,3 @@ class ImplicitConvTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py b/sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py
index 7ae676102..28d62486a 100644
--- a/sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py
+++ b/sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py
@@ -15,14 +15,16 @@ init_paths()
from sample import SampleNamespace
+
class ScopeAndInheritanceTest(unittest.TestCase):
'''Test cases for finding scope in cases involving inheritance.'''
def testMethodCorrectlyWrapper(self):
'''A method returning a type declared in the scope of the method's
class parent must be found and the method correctly exported.'''
- meth = getattr(SampleNamespace.DerivedFromNamespace, 'methodReturningTypeFromParentScope')
+ meth = getattr(SampleNamespace.DerivedFromNamespace, # noqa: F841
+ 'methodReturningTypeFromParentScope')
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/injectcode_test.py b/sources/shiboken6/tests/samplebinding/injectcode_test.py
index 90225a039..f673a7807 100644
--- a/sources/shiboken6/tests/samplebinding/injectcode_test.py
+++ b/sources/shiboken6/tests/samplebinding/injectcode_test.py
@@ -14,6 +14,7 @@ from shiboken_paths import init_paths
init_paths()
from sample import InjectCode
+
class MyInjectCode(InjectCode):
def __init__(self):
InjectCode.__init__(self)
@@ -22,10 +23,11 @@ class MyInjectCode(InjectCode):
def arrayMethod(self, values):
return self.multiplier * sum(values)
+
class InjectCodeTest(unittest.TestCase):
@unittest.skipIf(hasattr(sys, "pypy_version_info"),
- "PyPy type objects cannot be modified (yet) after creation")
+ "PyPy type objects cannot be modified (yet) after creation")
def testTypeNativeBeginning_TypeTargetBeginning(self):
ic = InjectCode()
self.assertEqual(str(ic), "Hi! I'm the inject code dummy class.")
@@ -71,22 +73,24 @@ class InjectCodeTest(unittest.TestCase):
self.assertEqual(result, sum(values))
def testCallReimplementedVirtualMethodWithArgumentRemovalAndArgumentTypeModification(self):
- '''Calls a reimplemented virtual method that had its first argument removed and the second modified.'''
+ '''Calls a reimplemented virtual method that had its first argument removed
+ and the second modified.'''
ic = MyInjectCode()
values = (1, 2, 3, 4, 5)
result = ic.callArrayMethod(values)
self.assertEqual(result, ic.multiplier * sum(values))
def testUsageOfTypeSystemCheckVariableOnPrimitiveType(self):
- '''When the sequence item is convertible to an integer -1 is returned, or -2 if its not convertible.'''
+ '''When the sequence item is convertible to an integer -1 is returned,
+ or -2 if its not convertible.'''
ic = InjectCode()
values = (1, 2, 3, 4, '5', 6.7)
result = ic.arrayMethod(values)
- fixedValues = [v for v in values if isinstance(v, int)]\
- + [-1 for v in values if isinstance(v, float)]\
- + [-2 for v in values if not isinstance(v, int) and not isinstance(v, float)]
- self.assertEqual(result, sum(fixedValues))
+ ints = [v for v in values if isinstance(v, int)]
+ floats = [-1 for v in values if isinstance(v, float)]
+ other = [-2 for v in values if not isinstance(v, int) and not isinstance(v, float)]
+ self.assertEqual(result, sum(ints + floats + other))
class IntArrayTest(unittest.TestCase):
@@ -110,5 +114,6 @@ class IntArrayTest(unittest.TestCase):
ic = InjectCode()
self.assertEqual(sum([1, 2]) + len([1, 2]), ic.sumArrayAndLength(args))
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/innerclass_test.py b/sources/shiboken6/tests/samplebinding/innerclass_test.py
index f94c57750..721f33483 100644
--- a/sources/shiboken6/tests/samplebinding/innerclass_test.py
+++ b/sources/shiboken6/tests/samplebinding/innerclass_test.py
@@ -13,10 +13,11 @@ init_paths()
from sample import Derived
+
class TestInnerClass(unittest.TestCase):
def testInstaciate(self):
- d = Derived.SomeInnerClass()
+ d = Derived.SomeInnerClass() # noqa: F841
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/intlist_test.py b/sources/shiboken6/tests/samplebinding/intlist_test.py
index 41d2b659a..defa9ca71 100644
--- a/sources/shiboken6/tests/samplebinding/intlist_test.py
+++ b/sources/shiboken6/tests/samplebinding/intlist_test.py
@@ -13,6 +13,7 @@ init_paths()
from sample import IntList
+
class IntListTest(unittest.TestCase):
def testAutoFunctionsToBaseList(self):
@@ -74,5 +75,6 @@ class IntListTest(unittest.TestCase):
self.assertEqual(il[1], int(432.1))
self.assertRaises(TypeError, il.__setitem__, 2, '78')
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/intwrapper_test.py b/sources/shiboken6/tests/samplebinding/intwrapper_test.py
index 21cab6b35..d883adf47 100644
--- a/sources/shiboken6/tests/samplebinding/intwrapper_test.py
+++ b/sources/shiboken6/tests/samplebinding/intwrapper_test.py
@@ -16,8 +16,8 @@ from sample import IntWrapper
class IntWrapperTest(unittest.TestCase):
def testOperators(self):
- ten1 = IntWrapper(10)
- ten2 = IntWrapper(10)
+ ten1 = IntWrapper(10)
+ ten2 = IntWrapper(10)
twenty = IntWrapper(20)
self.assertTrue(ten1 == ten2)
self.assertTrue(ten1 != twenty)
diff --git a/sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py b/sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py
index e3d060430..bb35b2bb1 100644
--- a/sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py
+++ b/sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py
@@ -38,7 +38,7 @@ class ModelWrongReturnTest(unittest.TestCase):
def testWrongTypeReturn(self):
model = ListModelWrong()
view = ObjectView(model)
- self.assertRaises(RuntimeWarning, view.getRawModelData) # calls model.data()
+ self.assertRaises(RuntimeWarning, view.getRawModelData) # calls model.data()
if __name__ == '__main__':
diff --git a/sources/shiboken6/tests/samplebinding/keep_reference_test.py b/sources/shiboken6/tests/samplebinding/keep_reference_test.py
index 6cf416fc4..10591fec6 100644
--- a/sources/shiboken6/tests/samplebinding/keep_reference_test.py
+++ b/sources/shiboken6/tests/samplebinding/keep_reference_test.py
@@ -2,8 +2,6 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-'''Test case for objects that keep references to other object without owning them (e.g. model/view relationships).'''
-
import os
import sys
import unittest
@@ -15,8 +13,10 @@ init_paths()
from sample import ObjectModel, ObjectView
+
class TestKeepReference(unittest.TestCase):
- '''Test case for objects that keep references to other object without owning them (e.g. model/view relationships).'''
+ '''Test case for objects that keep references to other object without
+ owning them (e.g. model/view relationships).'''
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testReferenceCounting(self):
@@ -48,15 +48,16 @@ class TestKeepReference(unittest.TestCase):
self.assertEqual(sys.getrefcount(model), refcount1)
def testReferreedObjectSurvivalAfterContextEnd(self):
- '''Model-like object assigned to a view-like object must survive after get out of context.'''
+ '''Model-like object assigned to a view-like object must survive
+ after get out of context.'''
def createModelAndSetToView(view):
model = ObjectModel()
model.setObjectName('created model')
view.setModel(model)
view = ObjectView()
createModelAndSetToView(view)
- model = view.model()
+ model = view.model() # noqa: F841
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/list_test.py b/sources/shiboken6/tests/samplebinding/list_test.py
index 6eb975b9f..b668bfd90 100644
--- a/sources/shiboken6/tests/samplebinding/list_test.py
+++ b/sources/shiboken6/tests/samplebinding/list_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import ListUser, Point, PointF
+
class ExtendedListUser(ListUser):
def __init__(self):
ListUser.__init__(self)
@@ -24,6 +25,7 @@ class ExtendedListUser(ListUser):
self.create_list_called = True
return [2, 3, 5, 7, 13]
+
class ListConversionTest(unittest.TestCase):
'''Test case for std::list container conversions'''
@@ -69,7 +71,8 @@ class ListConversionTest(unittest.TestCase):
self.assertEqual(result, lst)
def testConversionInBothDirectionsWithSimilarContainer(self):
- '''Test converting a tuple, instead of the expected list, from Python to C++ and back again.'''
+ '''Test converting a tuple, instead of the expected list,
+ from Python to C++ and back again.'''
lu = ListUser()
lst = (3, 5, 7)
lu.setList(lst)
@@ -96,6 +99,6 @@ class ListConversionTest(unittest.TestCase):
self.assertEqual(ListUser.ListOfPointF, ListUser.listOfPoints([PointF()]))
self.assertEqual(ListUser.ListOfPoint, ListUser.listOfPoints([Point()]))
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/lock_test.py b/sources/shiboken6/tests/samplebinding/lock_test.py
index 0657d41b9..acd47634a 100644
--- a/sources/shiboken6/tests/samplebinding/lock_test.py
+++ b/sources/shiboken6/tests/samplebinding/lock_test.py
@@ -63,7 +63,8 @@ class TestLockUnlock(unittest.TestCase):
self.assertTrue(result)
def testReimplementedVirtualBlocker(self):
- '''Same as the basic case but blocker method is a C++ virtual reimplemented in Python and called from C++.'''
+ '''Same as the basic case but blocker method is a C++ virtual reimplemented
+ in Python and called from C++.'''
mybucket = MyBucket()
unlocker = Unlocker(mybucket)
@@ -72,5 +73,6 @@ class TestLockUnlock(unittest.TestCase):
unlocker.join()
self.assertTrue(result)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/map_test.py b/sources/shiboken6/tests/samplebinding/map_test.py
index 5ffed5ede..fa99ad2e7 100644
--- a/sources/shiboken6/tests/samplebinding/map_test.py
+++ b/sources/shiboken6/tests/samplebinding/map_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import MapUser
+
class ExtendedMapUser(MapUser):
def __init__(self):
MapUser.__init__(self)
@@ -22,10 +23,11 @@ class ExtendedMapUser(MapUser):
def createMap(self):
self.create_map_called = True
- return {'two' : (complex(2.2, 2.2), 2),
- 'three' : (complex(3.3, 3.3), 3),
- 'five' : (complex(5.5, 5.5), 5),
- 'seven' : (complex(7.7, 7.7), 7)}
+ return {'two': (complex(2.2, 2.2), 2),
+ 'three': (complex(3.3, 3.3), 3),
+ 'five': (complex(5.5, 5.5), 5),
+ 'seven': (complex(7.7, 7.7), 7)}
+
class MapConversionTest(unittest.TestCase):
'''Test case for std::map container conversions'''
@@ -44,7 +46,7 @@ class MapConversionTest(unittest.TestCase):
def testConversionInBothDirections(self):
'''Test converting a map from Python to C++ and back again.'''
mu = MapUser()
- map_ = {'odds' : [2, 4, 6], 'evens' : [3, 5, 7], 'primes' : [3, 4, 6]}
+ map_ = {'odds': [2, 4, 6], 'evens': [3, 5, 7], 'primes': [3, 4, 6]}
mu.setMap(map_)
result = mu.getMap()
self.assertEqual(result, map_)
@@ -52,9 +54,10 @@ class MapConversionTest(unittest.TestCase):
def testConversionMapIntKeyValueTypeValue(self):
'''C++ signature: MapUser::passMapIntValueType(const std::map<int, const ByteArray>&)'''
mu = MapUser()
- map_ = {0 : 'string'}
+ map_ = {0: 'string'}
result = mu.passMapIntValueType(map_)
self.assertEqual(map_, result)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/metaclass_test.py b/sources/shiboken6/tests/samplebinding/metaclass_test.py
index 787bace70..4d7eeda96 100644
--- a/sources/shiboken6/tests/samplebinding/metaclass_test.py
+++ b/sources/shiboken6/tests/samplebinding/metaclass_test.py
@@ -10,32 +10,40 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import Point
+
class MetaA(type):
pass
+
class A(object):
__metaclass__ = MetaA
+
MetaB = type(Point)
B = Point
+
class MetaC(MetaA, MetaB):
pass
+
+
class C(A, B):
__metaclass__ = MetaC
+
class D(C):
pass
+
class TestMetaClass(unittest.TestCase):
def testIt(self):
- w1 = C() # works
+ w1 = C() # works
w1.setX(1)
w1.setY(2)
- w2 = D() # should work!
+ w2 = D() # should work!
w2.setX(3)
w2.setY(4)
diff --git a/sources/shiboken6/tests/samplebinding/mixed_mi_test.py b/sources/shiboken6/tests/samplebinding/mixed_mi_test.py
index 776605a4d..fa8481600 100644
--- a/sources/shiboken6/tests/samplebinding/mixed_mi_test.py
+++ b/sources/shiboken6/tests/samplebinding/mixed_mi_test.py
@@ -52,5 +52,3 @@ class MixedInheritanceTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
-
diff --git a/sources/shiboken6/tests/samplebinding/modelindex_test.py b/sources/shiboken6/tests/samplebinding/modelindex_test.py
index 725105a9c..e23503eff 100644
--- a/sources/shiboken6/tests/samplebinding/modelindex_test.py
+++ b/sources/shiboken6/tests/samplebinding/modelindex_test.py
@@ -13,6 +13,7 @@ init_paths()
from sample import ModelIndex, ReferentModelIndex, PersistentModelIndex
+
class TestCastOperator(unittest.TestCase):
def testCastOperatorReturningValue(self):
@@ -30,4 +31,3 @@ class TestCastOperator(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/modelview_test.py b/sources/shiboken6/tests/samplebinding/modelview_test.py
index 0b5c657d9..b5663a04e 100644
--- a/sources/shiboken6/tests/samplebinding/modelview_test.py
+++ b/sources/shiboken6/tests/samplebinding/modelview_test.py
@@ -2,7 +2,8 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-'''Test case for objects that keep references to other object without owning them (e.g. model/view relationships).'''
+'''Test case for objects that keep references to other object without owning them
+ (e.g. model/view relationships).'''
import os
import sys
@@ -17,9 +18,11 @@ from sample import ObjectModel, ObjectType, ObjectView
object_name = 'test object'
+
class MyObject(ObjectType):
pass
+
class ListModelKeepsReference(ObjectModel):
def __init__(self, parent=None):
ObjectModel.__init__(self, parent)
@@ -29,6 +32,7 @@ class ListModelKeepsReference(ObjectModel):
def data(self):
return self.obj
+
class ListModelDoesntKeepsReference(ObjectModel):
def data(self):
obj = MyObject()
@@ -55,4 +59,3 @@ class ModelViewTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/modifications_test.py b/sources/shiboken6/tests/samplebinding/modifications_test.py
index d1e70004f..dced14396 100644
--- a/sources/shiboken6/tests/samplebinding/modifications_test.py
+++ b/sources/shiboken6/tests/samplebinding/modifications_test.py
@@ -16,6 +16,7 @@ init_paths()
from sample import Modifications, Point, ByteArray
+
class ExtModifications(Modifications):
def __init__(self):
Modifications.__init__(self)
@@ -41,25 +42,15 @@ class ModificationsTest(unittest.TestCase):
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
- @unittest.skipIf(sys.pyside63_option_python_enum, "Makes no sense with strict Enums")
- def testClassMembersAvailability(self):
- '''Test if Modified class really have the expected members.'''
- expected_members = set(['OverloadedModFunc', 'OverloadedNone',
- 'Overloaded_ibiP', 'Overloaded_ibib',
- 'Overloaded_ibid', 'Overloaded_ibii',
- 'calculateArea', 'doublePlus', 'increment',
- 'multiplyPointCoordsPlusValue', 'name',
- 'pointToPair', 'overloaded', 'power',
- 'timesTen'])
- self.assertTrue(expected_members.issubset(dir(Modifications)))
-
def testRenamedMethodAvailability(self):
- '''Test if Modification class really have renamed the 'className' virtual method to 'name'.'''
+ '''Test if Modification class really have renamed the 'className'
+ virtual method to 'name'.'''
self.assertTrue('className' not in dir(Modifications))
self.assertTrue('name' in dir(Modifications))
def testReimplementationOfRenamedVirtualMethod(self):
- '''Test if class inheriting from Modification class have the reimplementation of renamed virtual method called.'''
+ '''Test if class inheriting from Modification class have the reimplementation
+ of renamed virtual method called.'''
em = ExtModifications()
self.assertEqual(self.mods.name(), 'Modifications')
self.assertEqual(em.name(), 'ExtModifications')
@@ -80,12 +71,14 @@ class ModificationsTest(unittest.TestCase):
self.assertEqual(self.mods.doublePlus(7), 14)
def testDefaultValueRemoval(self):
- '''Test if default value was removed from first argument of Modifications::increment(int).'''
+ '''Test if default value was removed from first argument of
+ Modifications::increment(int).'''
self.assertRaises(TypeError, self.mods.increment)
self.assertEqual(self.mods.increment(7), 8)
def testDefaultValueReplacement(self):
- '''Test if default values for both arguments of Modifications::power(int, int) were modified.'''
+ '''Test if default values for both arguments of Modifications::power(int, int)
+ were modified.'''
# original default values: int power(int base = 1, int exponent = 0);
self.assertNotEqual(self.mods.power(4), 1)
# modified default values: int power(int base = 2, int exponent = 1);
@@ -94,12 +87,14 @@ class ModificationsTest(unittest.TestCase):
self.assertEqual(self.mods.power(5, 3), 5**3)
def testSetNewDefaultValue(self):
- '''Test if default value was correctly set to 10 for first argument of Modifications::timesTen(int).'''
+ '''Test if default value was correctly set to 10 for first argument of
+ Modifications::timesTen(int).'''
self.assertEqual(self.mods.timesTen(7), 70)
self.assertEqual(self.mods.timesTen(), 100)
def testArgumentRemovalAndReturnTypeModificationWithTypesystemTemplates1(self):
- '''Test modifications to method signature and return value using type system templates (case 1).'''
+ '''Test modifications to method signature and return value using type
+ system templates (case 1).'''
result, ok = self.mods.pointToPair(Point(2, 5))
self.assertEqual(type(ok), bool)
self.assertEqual(type(result), tuple)
@@ -110,7 +105,8 @@ class ModificationsTest(unittest.TestCase):
self.assertEqual(result[1], 5.0)
def testArgumentRemovalAndReturnTypeModificationWithTypesystemTemplates2(self):
- '''Test modifications to method signature and return value using type system templates (case 2).'''
+ '''Test modifications to method signature and return value using
+ type system templates (case 2).'''
result, ok = self.mods.multiplyPointCoordsPlusValue(Point(2, 5), 4.1)
self.assertEqual(type(ok), bool)
self.assertEqual(type(result), float)
@@ -124,9 +120,11 @@ class ModificationsTest(unittest.TestCase):
self.assertEqual(self.mods.overloaded(1, True, 2), Modifications.Overloaded_ibii)
# the others weren't modified
self.assertEqual(self.mods.overloaded(1, True, 2, False), Modifications.Overloaded_ibib)
- self.assertEqual(self.mods.overloaded(1, False, 2, Point(3, 4)), Modifications.Overloaded_ibiP)
+ self.assertEqual(self.mods.overloaded(1, False, 2, Point(3, 4)),
+ Modifications.Overloaded_ibiP)
self.assertRaises(TypeError, self.mods.overloaded, 1, True, Point(2, 3), Point(4, 5))
- self.assertEqual(self.mods.over(1, True, Point(2, 3), Point(4, 5)), Modifications.Overloaded_ibPP)
+ self.assertEqual(self.mods.over(1, True, Point(2, 3), Point(4, 5)),
+ Modifications.Overloaded_ibPP)
def testPointArrayModification(self):
points = (Point(1, 1), Point(2, 2))
diff --git a/sources/shiboken6/tests/samplebinding/modified_constructor_test.py b/sources/shiboken6/tests/samplebinding/modified_constructor_test.py
index d4b65a88a..9791a3491 100644
--- a/sources/shiboken6/tests/samplebinding/modified_constructor_test.py
+++ b/sources/shiboken6/tests/samplebinding/modified_constructor_test.py
@@ -4,7 +4,6 @@
'''Tests cases for ConstructorWithModifiedArgument class.'''
-import sys
import os
import sys
import unittest
@@ -14,7 +13,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import ModifiedConstructor
class ConstructorWithModifiedArgumentTest(unittest.TestCase):
@@ -24,6 +23,6 @@ class ConstructorWithModifiedArgumentTest(unittest.TestCase):
sampleClass = ModifiedConstructor("10")
self.assertTrue(sampleClass.retrieveValue(), 10)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py b/sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py
index ae090f8e3..dcb487f1a 100644
--- a/sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py
+++ b/sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py
@@ -16,6 +16,7 @@ init_paths()
from sample import VirtualMethods, Str
+
class ExtendedVirtualMethods(VirtualMethods):
def __init__(self):
VirtualMethods.__init__(self)
@@ -61,7 +62,7 @@ class ExtendedVirtualMethods(VirtualMethods):
self.callMe_called += 1
def getMargins(self):
- return tuple([m*2 for m in VirtualMethods.getMargins(self)])
+ return tuple([m * 2 for m in VirtualMethods.getMargins(self)])
class VirtualMethodsTest(unittest.TestCase):
@@ -185,7 +186,8 @@ class VirtualMethodsTest(unittest.TestCase):
removed_arg_value = 2011
default_value = 3000
result = self.evm.callSum4(a0, removed_arg_value, a1)
- self.assertEqual(result, (a0 - removed_arg_value + a1 + default_value) * self.evm.multiplier)
+ self.assertEqual(result,
+ (a0 - removed_arg_value + a1 + default_value) * self.evm.multiplier)
self.assertTrue(self.evm.sum4_called)
def testOverridenMethodResultModification(self):
@@ -217,15 +219,15 @@ class VirtualMethodsTest(unittest.TestCase):
def testExtendedAllArgumentsRemoved(self):
values = (10, 20, 30, 40)
self.evm.setMargins(*values)
- double = tuple([m*2 for m in values])
+ double = tuple([m * 2 for m in values])
self.assertEqual(self.evm.getMargins(), double)
def testExtendedAllArgumentsRemovedCallVirtual(self):
values = (10, 20, 30, 40)
self.evm.setMargins(*values)
- double = tuple([m*2 for m in values])
+ double = tuple([m * 2 for m in values])
self.assertEqual(self.evm.callGetMargins(), double)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py b/sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py
index e655b8051..fc6b26c3f 100644
--- a/sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py
+++ b/sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py
@@ -13,72 +13,85 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import ObjectType, Point, Str
+
class SimpleUseCase(ObjectType, Str):
def __init__(self, name):
ObjectType.__init__(self)
Str.__init__(self, name)
+
class SimpleUseCaseReverse(Str, ObjectType):
def __init__(self, name):
ObjectType.__init__(self)
Str.__init__(self, name)
+
class SimpleUseCase2(SimpleUseCase):
def __init__(self, name):
SimpleUseCase.__init__(self, name)
+
class ComplexUseCase(SimpleUseCase2, Point):
def __init__(self, name):
SimpleUseCase2.__init__(self, name)
Point.__init__(self)
+
class ComplexUseCaseReverse(Point, SimpleUseCase2):
def __init__(self, name):
SimpleUseCase2.__init__(self, name)
Point.__init__(self)
+
class MultipleCppDerivedTest(unittest.TestCase):
- def testInstanciation(self):
+ def testInstantiation(self):
s = SimpleUseCase("Hi")
self.assertEqual(s, "Hi")
s.setObjectName(s)
self.assertEqual(s.objectName(), "Hi")
- def testInstanciation2(self):
+ def testInstantiation2(self):
s = SimpleUseCase2("Hi")
self.assertEqual(s, "Hi")
s.setObjectName(s)
self.assertEqual(s.objectName(), "Hi")
- def testComplexInstanciation(self):
+ def testComplexInstantiation(self):
c = ComplexUseCase("Hi")
self.assertEqual(c, "Hi")
c.setObjectName(c)
self.assertEqual(c.objectName(), "Hi")
- c.setX(2);
+ c.setX(2)
self.assertEqual(c.x(), 2)
+
class MultipleCppDerivedReverseTest(unittest.TestCase):
- def testInstanciation(self):
+ def testInstantiation(self):
s = SimpleUseCaseReverse("Hi")
self.assertEqual(s, "Hi")
s.setObjectName(s)
self.assertEqual(s.objectName(), "Hi")
- def testInstanciation2(self):
+ def testInstantiation2(self):
s = SimpleUseCase2("Hi")
self.assertEqual(s, "Hi")
s.setObjectName(s)
self.assertEqual(s.objectName(), "Hi")
- def testComplexInstanciation(self):
- c = ComplexUseCaseReverse("Hi")
- c.setObjectName(c)
- self.assertEqual(c.objectName(), "Hi")
- c.setX(2);
- self.assertEqual(c, Point(2, 0))
+ def testComplexInstantiation(self):
+ # PYSIDE-1564: This test can no longer work because of this MRO:
+ # ('ComplexUseCaseReverse', 'Point', 'SimpleUseCase2', 'SimpleUseCase',
+ # 'ObjectType', 'Str', 'Object', 'object')
+ # By multiple inheritance Point would be called first but has no argument.
+ with self.assertRaises(TypeError):
+ c = ComplexUseCaseReverse("Hi") # noqa: F841
+ # c.setObjectName(c)
+ # self.assertEqual(c.objectName(), "Hi")
+ # c.setX(2);
+ # self.assertEqual(c, Point(2, 0))
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/multiple_derived_test.py b/sources/shiboken6/tests/samplebinding/multiple_derived_test.py
index 46e44601d..7497714a8 100644
--- a/sources/shiboken6/tests/samplebinding/multiple_derived_test.py
+++ b/sources/shiboken6/tests/samplebinding/multiple_derived_test.py
@@ -13,17 +13,20 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import Base1, Base2, Base3, Base4, Base5, Base6
+from sample import Base1, Base2
from sample import MDerived1, MDerived2, MDerived3, MDerived4, MDerived5, SonOfMDerived1
+
class ExtMDerived1(MDerived1):
def __init__(self):
MDerived1.__init__(self)
self.multiplier = 20
self.base2Method_called = False
+
def base2Method(self):
return Base2.base2Method(self) * self.multiplier
+
class MultipleDerivedTest(unittest.TestCase):
'''Test cases for multiple inheritance'''
@@ -40,19 +43,22 @@ class MultipleDerivedTest(unittest.TestCase):
self.assertTrue(issubclass(MDerived1, Base2))
def testCallToFunctionWithBase1ArgumentThatCastsBackToMDerived1(self):
- '''MDerived1 is passed as an Base1 argument to a method that returns it casted back to MDerived1.'''
+ '''MDerived1 is passed as an Base1 argument to a method that returns
+ it casted back to MDerived1.'''
a = MDerived1()
b = MDerived1.transformFromBase1(a)
self.assertEqual(a, b)
def testCallToFunctionWithBase2ArgumentThatCastsBackToMDerived1(self):
- '''MDerived1 is passed as an Base2 argument to a method that returns it casted back to MDerived1.'''
+ '''MDerived1 is passed as an Base2 argument to a method that returns
+ it casted back to MDerived1.'''
a = MDerived1()
b = MDerived1.transformFromBase2(a)
self.assertEqual(a, b)
def testPythonClassIsInstance(self):
- '''Python defined class ExtMDerived1 is instance of its parents MDerived1, Base1 and Base2.'''
+ '''Python defined class ExtMDerived1 is instance of its parents
+ MDerived1, Base1 and Base2.'''
a = ExtMDerived1()
self.assertTrue(isinstance(a, ExtMDerived1))
self.assertTrue(isinstance(a, MDerived1))
@@ -60,14 +66,16 @@ class MultipleDerivedTest(unittest.TestCase):
self.assertTrue(isinstance(a, Base2))
def testPythonClassIsSubclass(self):
- '''Python defined class ExtMDerived1 is subclass of its parents MDerived1, Base1 and Base2.'''
+ '''Python defined class ExtMDerived1 is subclass of its parents
+ MDerived1, Base1 and Base2.'''
self.assertTrue(issubclass(ExtMDerived1, MDerived1))
self.assertTrue(issubclass(ExtMDerived1, Base1))
self.assertTrue(issubclass(ExtMDerived1, Base2))
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testCastFromMDerived1ToBases(self):
- '''MDerived1 is casted by C++ to its parents and the binding must return the MDerived1 wrapper.'''
+ '''MDerived1 is casted by C++ to its parents and the binding must return the
+ MDerived1 wrapper.'''
a = MDerived1()
refcnt = sys.getrefcount(a)
b1 = a.castToBase1()
@@ -80,7 +88,8 @@ class MultipleDerivedTest(unittest.TestCase):
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testCastFromExtMDerived1ToMDerived1Bases(self):
- '''Python defined class ExtMDerived1 is casted by C++ to MDerived1 parents and the binding must return the correct ExtMDerived1 instance.'''
+ '''Python defined class ExtMDerived1 is casted by C++ to MDerived1 parents
+ and the binding must return the correct ExtMDerived1 instance.'''
a = ExtMDerived1()
refcnt = sys.getrefcount(a)
b1 = a.castToBase1()
@@ -95,7 +104,8 @@ class MultipleDerivedTest(unittest.TestCase):
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testCastFromSonOfMDerived1ToBases(self):
- '''SonOfMDerived1 is casted by C++ to its parents and the binding must return the SonOfMDerived1 wrapper.'''
+ '''SonOfMDerived1 is casted by C++ to its parents and the binding must return
+ the SonOfMDerived1 wrapper.'''
a = SonOfMDerived1()
refcnt = sys.getrefcount(a)
md1 = a.castToMDerived1()
@@ -116,7 +126,8 @@ class MultipleDerivedTest(unittest.TestCase):
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testCastFromMDerived2ToBases(self):
- '''MDerived2 is casted by C++ to its parents and the binding must return the MDerived2 wrapper.'''
+ '''MDerived2 is casted by C++ to its parents and the binding must
+ return the MDerived2 wrapper.'''
a = MDerived2()
refcnt = sys.getrefcount(a)
b3 = a.castToBase3()
@@ -135,7 +146,8 @@ class MultipleDerivedTest(unittest.TestCase):
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testCastFromMDerived3ToBases(self):
- '''MDerived3 is casted by C++ to its parents and the binding must return the MDerived3 wrapper.'''
+ '''MDerived3 is casted by C++ to its parents and the binding must
+ return the MDerived3 wrapper.'''
a = MDerived3()
refcnt = sys.getrefcount(a)
md1 = a.castToMDerived1()
@@ -166,7 +178,8 @@ class MultipleDerivedTest(unittest.TestCase):
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testCastFromMDerived4ToBases(self):
- '''MDerived4 is casted by C++ to its parents and the binding must return the MDerived4 wrapper.'''
+ '''MDerived4 is casted by C++ to its parents and the binding must
+ return the MDerived4 wrapper.'''
a = MDerived4()
refcnt = sys.getrefcount(a)
b3 = a.castToBase3()
@@ -179,7 +192,8 @@ class MultipleDerivedTest(unittest.TestCase):
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testCastFromMDerived5ToBases(self):
- '''MDerived5 is casted by C++ to its parents and the binding must return the MDerived5 wrapper.'''
+ '''MDerived5 is casted by C++ to its parents and the binding must
+ return the MDerived5 wrapper.'''
a = MDerived5()
refcnt = sys.getrefcount(a)
b3 = a.castToBase3()
@@ -192,7 +206,8 @@ class MultipleDerivedTest(unittest.TestCase):
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testCastFromMDerived3ToBase3(self):
- '''MDerived3 is casted by C++ to Base3 grandparent using both the inherited and reimplement castToBase3 methods.'''
+ '''MDerived3 is casted by C++ to Base3 grandparent using both the inherited
+ and reimplement castToBase3 methods.'''
a = MDerived3()
refcnt = sys.getrefcount(a)
b3_reimplemented = a.castToBase3()
@@ -203,6 +218,6 @@ class MultipleDerivedTest(unittest.TestCase):
self.assertEqual(a, b3_inherited)
self.assertEqual(sys.getrefcount(a), refcnt + 2)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/namespace_test.py b/sources/shiboken6/tests/samplebinding/namespace_test.py
index 2087ced4b..64a6792ac 100644
--- a/sources/shiboken6/tests/samplebinding/namespace_test.py
+++ b/sources/shiboken6/tests/samplebinding/namespace_test.py
@@ -13,11 +13,9 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import SampleNamespace
from shiboken_test_helper import objectFullname
-from shiboken6 import Shiboken
-
from shibokensupport.signature import get_signature
# For tests of invisible namespaces, see
@@ -26,17 +24,17 @@ from shibokensupport.signature import get_signature
class TestVariablesUnderNamespace(unittest.TestCase):
def testIt(self):
- self.assertEqual(SampleNamespace.variableInNamespace, 42)
+ self.assertEqual(SampleNamespace.variableInNamespace, 42)
class TestClassesUnderNamespace(unittest.TestCase):
def testIt(self):
- c1 = SampleNamespace.SomeClass()
- e1 = SampleNamespace.SomeClass.ProtectedEnum()
- c2 = SampleNamespace.SomeClass.SomeInnerClass()
- e2 = SampleNamespace.SomeClass.SomeInnerClass.ProtectedEnum()
- c3 = SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough()
- e3 = SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough.NiceEnum(0)
+ c1 = SampleNamespace.SomeClass() # noqa F841
+ e1 = SampleNamespace.SomeClass.ProtectedEnum() # noqa F841
+ c2 = SampleNamespace.SomeClass.SomeInnerClass() # noqa F841
+ e2 = SampleNamespace.SomeClass.SomeInnerClass.ProtectedEnum() # noqa F841
+ c3 = SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough() # noqa F841
+ e3 = SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough.NiceEnum(0) # noqa F841
def testFunctionAddedOnNamespace(self):
res = SampleNamespace.ImInsideANamespace(2, 2)
@@ -44,25 +42,21 @@ class TestClassesUnderNamespace(unittest.TestCase):
def testTpNames(self):
self.assertEqual(str(SampleNamespace.SomeClass),
- "<class 'sample.SampleNamespace.SomeClass'>")
+ "<class 'sample.SampleNamespace.SomeClass'>")
self.assertEqual(str(SampleNamespace.SomeClass.ProtectedEnum),
- "<enum 'ProtectedEnum'>" if sys.pyside63_option_python_enum else
- "<class 'sample.SampleNamespace.SomeClass.ProtectedEnum'>")
+ "<enum 'ProtectedEnum'>")
self.assertEqual(str(SampleNamespace.SomeClass.SomeInnerClass.ProtectedEnum),
- "<enum 'ProtectedEnum'>" if sys.pyside63_option_python_enum else
- "<class 'sample.SampleNamespace.SomeClass.SomeInnerClass.ProtectedEnum'>")
+ "<enum 'ProtectedEnum'>")
self.assertEqual(str(SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough),
- "<class 'sample.SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough'>")
- self.assertEqual(str(SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough.NiceEnum),
- "<enum 'NiceEnum'>" if sys.pyside63_option_python_enum else
- "<class 'sample.SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough.NiceEnum'>")
+ "<class 'sample.SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough'>") # noqa: E501
+ self.assertEqual(str(SampleNamespace.SomeClass.SomeInnerClass.OkThisIsRecursiveEnough.NiceEnum), # noqa: E501
+ "<enum 'NiceEnum'>")
# Test if enum inside of class is correct represented
- self.assertEqual(objectFullname(get_signature(SampleNamespace.enumInEnumOut).parameters['in_'].annotation),
- "sample.SampleNamespace.InValue")
- self.assertEqual(objectFullname(get_signature(SampleNamespace.enumAsInt).parameters['value'].annotation),
- "sample.SampleNamespace.SomeClass.PublicScopedEnum")
-
+ an = objectFullname(get_signature(SampleNamespace.enumInEnumOut).parameters['in_'].annotation) # noqa: E501
+ self.assertEqual(an, "sample.SampleNamespace.InValue")
+ an = objectFullname(get_signature(SampleNamespace.enumAsInt).parameters['value'].annotation)
+ self.assertEqual(an, "sample.SampleNamespace.SomeClass.PublicScopedEnum")
def testInlineNamespaces(self):
cls = SampleNamespace.ClassWithinInlineNamespace()
diff --git a/sources/shiboken6/tests/samplebinding/newdivision_test.py b/sources/shiboken6/tests/samplebinding/newdivision_test.py
index 6286dcfc9..0e7dfbee1 100644
--- a/sources/shiboken6/tests/samplebinding/newdivision_test.py
+++ b/sources/shiboken6/tests/samplebinding/newdivision_test.py
@@ -10,16 +10,16 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import Point
class TestNewDivision(unittest.TestCase):
def testIt(self):
p = Point(4, 4)
- p2 = p/2
+ p2 = p / 2
self.assertEqual(p2, Point(2, 2))
+
if __name__ == "__main__":
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/nondefaultctor_test.py b/sources/shiboken6/tests/samplebinding/nondefaultctor_test.py
index 3892508ae..bc8d29e50 100644
--- a/sources/shiboken6/tests/samplebinding/nondefaultctor_test.py
+++ b/sources/shiboken6/tests/samplebinding/nondefaultctor_test.py
@@ -15,14 +15,17 @@ init_paths()
from sample import NonDefaultCtor
+
class DerivedNonDefaultCtor (NonDefaultCtor):
def returnMyselfVirtual(self):
- return NonDefaultCtor(self.value()+1)
+ return NonDefaultCtor(self.value() + 1)
+
class AnotherDerivedNonDefaultCtor (NonDefaultCtor):
def __init__(self, some_string):
pass
+
class NonDefaultCtorTest(unittest.TestCase):
def testNonDefaultCtor(self):
@@ -43,8 +46,8 @@ class NonDefaultCtorTest(unittest.TestCase):
self.assertEqual(c.callReturnMyselfVirtual().value(), 4)
def testCtorOverload(self):
- c = AnotherDerivedNonDefaultCtor("testing")
+ c = AnotherDerivedNonDefaultCtor("testing") # noqa: F841
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/nontypetemplate_test.py b/sources/shiboken6/tests/samplebinding/nontypetemplate_test.py
index fa28abc6d..a10547728 100644
--- a/sources/shiboken6/tests/samplebinding/nontypetemplate_test.py
+++ b/sources/shiboken6/tests/samplebinding/nontypetemplate_test.py
@@ -21,6 +21,7 @@ init_paths()
from sample import IntArray2, IntArray3
+
class NonTypeTemplateTest(unittest.TestCase):
def testNonTypeTemplate(self):
@@ -32,7 +33,7 @@ class NonTypeTemplateTest(unittest.TestCase):
def testArrayInitializer(self):
if not hasNumPy:
return
- array3 = IntArray3(numpy.array([1, 2, 3], dtype = 'int32'))
+ array3 = IntArray3(numpy.array([1, 2, 3], dtype='int32'))
self.assertEqual(array3.sum(), 6)
diff --git a/sources/shiboken6/tests/samplebinding/nonzero_test.py b/sources/shiboken6/tests/samplebinding/nonzero_test.py
index d2a30c7ef..7be239fc4 100644
--- a/sources/shiboken6/tests/samplebinding/nonzero_test.py
+++ b/sources/shiboken6/tests/samplebinding/nonzero_test.py
@@ -13,6 +13,7 @@ init_paths()
from sample import Color, Brush
+
class TestNonZeroOperator(unittest.TestCase):
def testColor(self):
"""Color has a Qt-style isNull()"""
diff --git a/sources/shiboken6/tests/samplebinding/numericaltypedef_test.py b/sources/shiboken6/tests/samplebinding/numericaltypedef_test.py
index 9539469a1..f714a4fc8 100644
--- a/sources/shiboken6/tests/samplebinding/numericaltypedef_test.py
+++ b/sources/shiboken6/tests/samplebinding/numericaltypedef_test.py
@@ -13,6 +13,7 @@ init_paths()
from sample import SizeF
+
class NumericalTypedefTest(unittest.TestCase):
def testNumericalTypedefExact(self):
@@ -32,5 +33,6 @@ class NumericalTypedefTest(unittest.TestCase):
self.assertEqual(SizeF.passTypedefOfUnsignedShort(321), 321)
self.assertNotEqual(SizeF.passTypedefOfUnsignedShort(123), 0)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/numpy_test.py b/sources/shiboken6/tests/samplebinding/numpy_test.py
index af1e6d1bf..42094a463 100644
--- a/sources/shiboken6/tests/samplebinding/numpy_test.py
+++ b/sources/shiboken6/tests/samplebinding/numpy_test.py
@@ -8,7 +8,7 @@ try:
if bool(sysconfig.get_config_var('Py_DEBUG')):
sys.exit(0)
import numpy
-except:
+except: # noqa: E722
sys.exit(0)
import os
@@ -21,6 +21,7 @@ from shiboken_paths import init_paths
init_paths()
from sample import PointF
+
class TestNumpyTypes(unittest.TestCase):
def testNumpyConverted(self):
@@ -35,6 +36,6 @@ class TestNumpyTypes(unittest.TestCase):
self.assertAlmostEqual(p.x(), x)
self.assertAlmostEqual(p.y(), y)
+
if __name__ == "__main__":
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/objecttype_test.py b/sources/shiboken6/tests/samplebinding/objecttype_test.py
index 6e90bfb35..ead68ba13 100644
--- a/sources/shiboken6/tests/samplebinding/objecttype_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttype_test.py
@@ -68,7 +68,7 @@ class ObjectTypeTest(unittest.TestCase):
def testNextInFocusChainCycle(self):
parent = ObjectType()
child = ObjectType(parent)
- next_focus = child.nextInFocusChain()
+ next_focus = child.nextInFocusChain() # noqa: F841
Shiboken.invalidate(parent)
@@ -105,5 +105,6 @@ class ObjectTypeTest(unittest.TestCase):
with self.assertRaises(AttributeError):
o.typo
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py b/sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py
index 4e552e887..285e2313b 100644
--- a/sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py
@@ -13,6 +13,7 @@ init_paths()
from sample import ObjectType
+
class NamedArgsTest(unittest.TestCase):
def testOneArgument(self):
@@ -35,18 +36,15 @@ class NamedArgsTest(unittest.TestCase):
o.setObjectNameWithSize(size=6, name="pyside")
self.assertEqual(o.objectName(), "pyside")
-
def testUseDefaultValues(self):
o = ObjectType()
o.setObjectNameWithSize(size=3)
- self.assertEqual(o.objectName(), "<un") # use name='unknown' default argument
+ self.assertEqual(o.objectName(), "<un") # use name='unknown' default argument
o.setObjectSplittedName("")
- self.assertEqual(o.objectName(), "<unknown>") # user prefix='<unk' and suffix='nown>'
-
+ self.assertEqual(o.objectName(), "<unknown>") # user prefix='<unk' and suffix='nown>'
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/objecttypebyvalue_test.py b/sources/shiboken6/tests/samplebinding/objecttypebyvalue_test.py
index 9dd3baf63..8f74af3ab 100644
--- a/sources/shiboken6/tests/samplebinding/objecttypebyvalue_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttypebyvalue_test.py
@@ -10,7 +10,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import ObjectTypeByValue
class ObjectTypeByValueTest (unittest.TestCase):
@@ -22,5 +22,6 @@ class ObjectTypeByValueTest (unittest.TestCase):
# just to make sure it will segfault
obj.prop.protectedValueTypeProperty.setY(2.0)
+
if __name__ == "__main__":
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/objecttypelayout_test.py b/sources/shiboken6/tests/samplebinding/objecttypelayout_test.py
index ea30f103e..677b89281 100644
--- a/sources/shiboken6/tests/samplebinding/objecttypelayout_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttypelayout_test.py
@@ -14,7 +14,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import ObjectType, ObjectTypeLayout
class ObjectTypeLayoutTest(unittest.TestCase):
@@ -22,16 +22,15 @@ class ObjectTypeLayoutTest(unittest.TestCase):
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testOwnershipOverride(self):
- l = ObjectTypeLayout()
+ lt = ObjectTypeLayout()
- o1 = ObjectType(l)
+ o1 = ObjectType(lt)
o1.setObjectName('o1')
self.assertEqual(sys.getrefcount(o1), 3)
- l.takeChild('o1')
+ lt.takeChild('o1')
self.assertEqual(sys.getrefcount(o1), 2)
-
def testSetNullLayout(self):
'''ObjectType.setLayout(0).'''
o2 = ObjectType()
@@ -57,7 +56,7 @@ class ObjectTypeLayoutTest(unittest.TestCase):
self.assertEqual(c3.parent(), None)
p1.setLayout(layout)
- del p1 # This must kill c1, c2 and c3
+ del p1 # This must kill c1, c2 and c3
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
@@ -81,7 +80,7 @@ class ObjectTypeLayoutTest(unittest.TestCase):
self.assertEqual(c3.parent(), None)
p1.setLayout(layout)
- del p1 # This must kill c1, c2 and c3
+ del p1 # This must kill c1, c2 and c3
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
@@ -91,7 +90,8 @@ class ObjectTypeLayoutTest(unittest.TestCase):
self.assertRaises(RuntimeError, layout.objectName)
def testObjectTypeLayoutTransference(self):
- '''Transfer a layout from one ObjectType to another, so that all the items in the layout get reparented.'''
+ '''Transfer a layout from one ObjectType to another, so that all the items in
+ the layout get reparented.'''
p1 = ObjectType()
p2 = ObjectType()
c1 = ObjectType()
@@ -154,7 +154,8 @@ class ObjectTypeLayoutTest(unittest.TestCase):
self.assertRaises(RuntimeError, l2.objectName)
def testObjectTypeLayoutInsideAnotherLayoutAndEveryoneCreatedInCpp(self):
- '''Adds one ObjectTypeLayout to another and sets the parent to an ObjectType. All the objects are created in C++.'''
+ '''Adds one ObjectTypeLayout to another and sets the parent to an ObjectType.
+ All the objects are created in C++.'''
p1 = ObjectType.create()
l1 = ObjectTypeLayout.create()
@@ -192,7 +193,8 @@ class ObjectTypeLayoutTest(unittest.TestCase):
self.assertRaises(RuntimeError, l2.objectName)
def testTransferNestedLayoutsBetweenObjects(self):
- '''Adds one ObjectTypeLayout to another, sets the parent to an ObjectType and then transfer it to another object.'''
+ '''Adds one ObjectTypeLayout to another, sets the parent to an ObjectType
+ and then transfer it to another object.'''
p1 = ObjectType()
p2 = ObjectType()
@@ -243,8 +245,8 @@ class ObjectTypeLayoutTest(unittest.TestCase):
self.assertRaises(RuntimeError, l2.objectName)
def testTransferNestedLayoutsBetweenObjectsAndEveryoneCreatedInCpp(self):
- '''Adds one ObjectTypeLayout to another, sets the parent to an ObjectType and then transfer it to another object.
- All the objects are created in C++.'''
+ '''Adds one ObjectTypeLayout to another, sets the parent to an ObjectType and then
+ transfer it to another object. All the objects are created in C++.'''
p1 = ObjectType.create()
p2 = ObjectType.create()
@@ -294,6 +296,6 @@ class ObjectTypeLayoutTest(unittest.TestCase):
self.assertRaises(RuntimeError, l1.objectName)
self.assertRaises(RuntimeError, l2.objectName)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py b/sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py
index ae5936635..ceeee6c8d 100644
--- a/sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py
@@ -10,7 +10,8 @@ from pathlib import Path
sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import ObjectTypeOperators
+
class ObjectTypeOperatorsTest(unittest.TestCase):
@@ -26,7 +27,7 @@ class ObjectTypeOperatorsTest(unittest.TestCase):
def testPointerOpeators(self):
a = ObjectTypeOperators("a")
- b = ObjectTypeOperators("b")
+ b = ObjectTypeOperators("b") # noqa: F841
self.assertEqual(a + "bc", "abc")
self.assertEqual("bc" + a, "bca")
self.assertEqual("a", a)
@@ -36,5 +37,6 @@ class ObjectTypeOperatorsTest(unittest.TestCase):
a = ObjectTypeOperators("a")
self.assertNotEqual(a, "b")
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py b/sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py
index 68e5edecc..5fa6f824e 100644
--- a/sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py
@@ -12,6 +12,7 @@ from shiboken_paths import init_paths
init_paths()
from sample import ObjectTypeHolder
+
class TestObjectTypeReferenceAsVirtualMethodArgument(unittest.TestCase):
def testBasic(self):
@@ -25,5 +26,6 @@ class TestObjectTypeReferenceAsVirtualMethodArgument(unittest.TestCase):
holder = Holder('TheObjectFromC++')
self.assertEqual(holder.callPassObjectTypeAsReference(), 'ThisIsTheObjectFromC++')
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/oddbool_test.py b/sources/shiboken6/tests/samplebinding/oddbool_test.py
index 466ddba82..87a8cdb1f 100644
--- a/sources/shiboken6/tests/samplebinding/oddbool_test.py
+++ b/sources/shiboken6/tests/samplebinding/oddbool_test.py
@@ -15,11 +15,13 @@ init_paths()
from sample import OddBoolUser, ComparisonTester, SpaceshipComparisonTester
+
class DerivedOddBoolUser (OddBoolUser):
def returnMyselfVirtual(self):
return OddBoolUser()
pass
+
class OddBoolTest(unittest.TestCase):
def testOddBoolUser(self):
@@ -30,13 +32,13 @@ class OddBoolTest(unittest.TestCase):
self.assertEqual(obuTrue.oddBool(), True)
self.assertEqual(obuTrue.callInvertedOddBool(), False)
- self.assertEqual(obuTrue.oddBool() == True, True)
- self.assertEqual(False == obuFalse.oddBool(), True)
- self.assertEqual(obuTrue.oddBool() == obuFalse.oddBool(), False)
+ self.assertTrue(obuTrue.oddBool())
+ self.assertFalse(obuFalse.oddBool())
+ self.assertTrue(obuTrue.oddBool() != obuFalse.oddBool())
- self.assertEqual(obuFalse.oddBool() != True, True)
- self.assertEqual(True != obuFalse.oddBool(), True)
- self.assertEqual(obuTrue.oddBool() != obuFalse.oddBool(), True)
+ self.assertFalse(obuFalse.oddBool())
+ self.assertFalse(obuFalse.oddBool())
+ self.assertTrue(obuTrue.oddBool() != obuFalse.oddBool())
def testVirtuals(self):
dobu = DerivedOddBoolUser()
diff --git a/sources/shiboken6/tests/samplebinding/onlycopyclass_test.py b/sources/shiboken6/tests/samplebinding/onlycopyclass_test.py
index 3bdf431ad..bcb154c52 100644
--- a/sources/shiboken6/tests/samplebinding/onlycopyclass_test.py
+++ b/sources/shiboken6/tests/samplebinding/onlycopyclass_test.py
@@ -13,6 +13,7 @@ init_paths()
from sample import OnlyCopy, FriendOfOnlyCopy
+
class ClassWithOnlyCopyCtorTest(unittest.TestCase):
def testGetOne(self):
obj = FriendOfOnlyCopy.createOnlyCopy(123)
@@ -34,5 +35,6 @@ class ClassWithOnlyCopyCtorTest(unittest.TestCase):
obj = FriendOfOnlyCopy.createOnlyCopy(123)
self.assertEqual(obj.value(), OnlyCopy.getValueFromReference(obj))
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/overflow_test.py b/sources/shiboken6/tests/samplebinding/overflow_test.py
index bb98f313d..84442306a 100644
--- a/sources/shiboken6/tests/samplebinding/overflow_test.py
+++ b/sources/shiboken6/tests/samplebinding/overflow_test.py
@@ -13,7 +13,8 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import (Point, doubleLongLong, doubleShort, doubleUnsignedInt,
+ doubleUnsignedLongLong)
class OverflowTest(unittest.TestCase):
@@ -25,14 +26,16 @@ class OverflowTest(unittest.TestCase):
return super().assertRaises(*args, **kwds)
def testUnsignedInt(self):
- '''C++ function receives an unsigned int argument and raise OverflowError if the value is negative.'''
+ '''C++ function receives an unsigned int argument and raise OverflowError
+ if the value is negative.'''
val = 100
self.assertEqual(doubleUnsignedInt(val), 2 * val)
val *= -1
self.assertRaises(OverflowError, doubleUnsignedInt, val)
def testLongLong(self):
- '''C++ function receives an long long argument and raise OverflowError if the value is negative.'''
+ '''C++ function receives an long long argument and raise OverflowError
+ if the value is negative.'''
val = 100
self.assertEqual(doubleLongLong(val), 2 * val)
val = int(100)
@@ -41,7 +44,8 @@ class OverflowTest(unittest.TestCase):
self.assertRaises(OverflowError, doubleLongLong, val)
def testUnsignedLongLong(self):
- '''C++ function receives an unsigned long long argument and raise OverflowError if the value is negative.'''
+ '''C++ function receives an unsigned long long argument and raise OverflowError
+ if the value is negative.'''
val = 100
self.assertEqual(doubleUnsignedLongLong(val), 2 * val)
val = int(100)
@@ -59,13 +63,13 @@ class OverflowTest(unittest.TestCase):
def testShortOverflow(self):
'''Calls function with short parameter using an overflowing value.'''
doubleShort(-3)
- self.assertRaises(OverflowError, doubleShort, 0xFFFF*-1)
+ self.assertRaises(OverflowError, doubleShort, 0xFFFF * -1)
self.assertRaises(OverflowError, doubleShort, 0xFFFF + 1)
def testOverflowOnCtor(self):
'''Calls object ctor with int parameter using overflowing values.'''
self.assertRaises(OverflowError, Point, 42415335332353253, 42415335332353253)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/overload_sorting_test.py b/sources/shiboken6/tests/samplebinding/overload_sorting_test.py
index 03da96581..060d91510 100644
--- a/sources/shiboken6/tests/samplebinding/overload_sorting_test.py
+++ b/sources/shiboken6/tests/samplebinding/overload_sorting_test.py
@@ -13,11 +13,14 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import (CustomOverloadSequence, ImplicitBase, ImplicitConv,
+ ImplicitTarget, SortedOverload)
+
class Dummy(object):
pass
+
class SimpleOverloadSorting(unittest.TestCase):
def setUp(self):
@@ -63,6 +66,7 @@ class DeepOverloadSorting(unittest.TestCase):
'''Deep Overload - (int, ImplicitBase *)'''
self.assertEqual(self.obj.overloadDeep(1, ImplicitBase()), "ImplicitBase")
+
class EnumOverIntSorting(unittest.TestCase):
def testEnumOverInt(self):
ic = ImplicitConv(ImplicitConv.CtorTwo)
diff --git a/sources/shiboken6/tests/samplebinding/overload_test.py b/sources/shiboken6/tests/samplebinding/overload_test.py
index d6bd90877..62fa8d8d2 100644
--- a/sources/shiboken6/tests/samplebinding/overload_test.py
+++ b/sources/shiboken6/tests/samplebinding/overload_test.py
@@ -21,11 +21,10 @@ def raisesWithErrorMessage(func, arguments, errorType, errorMsg):
try:
func(*arguments)
return False
- except Exception as err:
- if type(err) != TypeError:
- return False
- if not errorMsg in str(err):
- return False
+ except TypeError as err:
+ return errorMsg in str(err)
+ except Exception:
+ return False
return True
@@ -178,12 +177,13 @@ class OverloadTest(unittest.TestCase):
def testAcceptSequencePyObject(self):
# Overload.acceptSequence(void*)
overload = Overload()
+
class Foo(object):
pass
+
foo = Foo()
self.assertEqual(overload.acceptSequence(foo), Overload.Function5)
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py b/sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py
index 199297415..269b97299 100644
--- a/sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py
+++ b/sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py
@@ -39,6 +39,6 @@ class OverloadTest(unittest.TestCase):
overload = Overload()
self.assertEqual(overload.strBufferOverloads(bytes('', "UTF-8"), 0), Overload.Function1)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py b/sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py
index 8a3cdf490..8a55d3ab8 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import Polygon, Point
+
class WrapperValidityOfArgumentsTest(unittest.TestCase):
'''Wrapper validity tests for arguments.'''
@@ -25,17 +26,19 @@ class WrapperValidityOfArgumentsTest(unittest.TestCase):
self.assertRaises(RuntimeError, Polygon.doublePolygonScale, poly)
def testInvalidArgumentToConstructor(self):
- '''Call to constructor using invalidated Python wrapper as argument should raise RuntimeError.'''
+ '''Call to constructor using invalidated Python wrapper as argument
+ should raise RuntimeError.'''
pt = Point(1, 2)
Polygon.stealOwnershipFromPython(pt)
self.assertRaises(RuntimeError, Polygon, pt)
def testInvalidArgumentWithImplicitConversion(self):
- '''Call to method using invalidated Python wrapper to be implicitly converted should raise RuntimeError.'''
+ '''Call to method using invalidated Python wrapper to be implicitly converted
+ should raise RuntimeError.'''
pt = Point(1, 2)
Polygon.stealOwnershipFromPython(pt)
self.assertRaises(RuntimeError, Polygon.doublePolygonScale, pt)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_cpp_test.py b/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_cpp_test.py
index 2c789a72a..25c6fea26 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_cpp_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_cpp_test.py
@@ -30,5 +30,6 @@ class DeleteChildInCpp(unittest.TestCase):
self.assertRaises(RuntimeError, child.objectName)
self.assertEqual(parent.objectName(), 'parent')
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_python_test.py b/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_python_test.py
index b6f5ce235..3ae186815 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_python_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_delete_child_in_python_test.py
@@ -35,5 +35,6 @@ class DeleteChildInPython(unittest.TestCase):
new_child = parent.children()[0]
self.assertEqual(new_child.objectName(), name)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py b/sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py
index 044ef9af6..8f654639c 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py
@@ -33,7 +33,7 @@ class DeleteParentTest(unittest.TestCase):
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
self.assertRaises(RuntimeError, child.objectName)
- self.assertEqual(sys.getrefcount(child), refcount_before-1)
+ self.assertEqual(sys.getrefcount(child), refcount_before - 1)
@unittest.skipUnless(hasattr(sys, "getrefcount"), f"{sys.implementation.name} has no refcount")
def testParentDestructorMultipleChildren(self):
diff --git a/sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py b/sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py
index e51b5555f..37b7591e4 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py
@@ -21,11 +21,13 @@ class ExtObjectType(ObjectType):
ObjectType.__init__(self)
self.type_of_last_event = None
self.last_event = None
+
def event(self, event):
self.last_event = event
self.type_of_last_event = event.eventType()
return True
+
class MyObjectType (ObjectType):
def __init__(self):
super(MyObjectType, self).__init__()
@@ -35,7 +37,7 @@ class MyObjectType (ObjectType):
self.callInvalidateEvent(ev)
try:
ev.eventType()
- except:
+ except: # noqa: E722
self.fail = True
raise
return True
@@ -43,21 +45,25 @@ class MyObjectType (ObjectType):
def invalidateEvent(self, ev):
pass
+
class ExtObjectTypeDerived(ObjectTypeDerived):
def __init__(self):
ObjectTypeDerived.__init__(self)
self.type_of_last_event = None
self.last_event = None
+
def event(self, event):
self.last_event = event
self.type_of_last_event = event.eventType()
return True
+
class OwnershipInvalidateAfterUseTest(unittest.TestCase):
'''Ownership tests for cases of invalidation of Python wrapper after use.'''
def testInvalidateAfterUse(self):
- '''In ObjectType.event(Event*) the wrapper object created for Event must me marked as invalid after the method is called.'''
+ '''In ObjectType.event(Event*) the wrapper object created for Event
+ must me marked as invalid after the method is called.'''
eot = ExtObjectType()
eot.causeEvent(Event.SOME_EVENT)
self.assertEqual(eot.type_of_last_event, Event.SOME_EVENT)
@@ -84,6 +90,6 @@ class OwnershipInvalidateAfterUseTest(unittest.TestCase):
self.assertEqual(eot.type_of_last_event, Event.SOME_EVENT)
self.assertRaises(RuntimeError, eot.last_event.eventType)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py b/sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py
index 868c85931..77b7c576c 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py
@@ -49,6 +49,6 @@ class InvalidateChildTest(unittest.TestCase):
self.assertEqual(child1.objectName(), 'child1')
self.assertRaises(RuntimeError, child2.objectName)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py b/sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py
index 66d6ed5d2..8cbefc30c 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import Point, BlackBox
+
class OwnershipInvalidateNonPolymorphicTest(unittest.TestCase):
'''The BlackBox class has cases of ownership transference between Python and C++.'''
@@ -27,6 +28,6 @@ class OwnershipInvalidateNonPolymorphicTest(unittest.TestCase):
p1_ret = bb.retrievePoint(p1_ticket)
self.assertEqual(p1_ret, Point(10, 20))
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py b/sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py
index 82ecafa7d..c721a212c 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py
@@ -34,7 +34,7 @@ class InvalidateParentTest(unittest.TestCase):
grandchild2.setParent(child2)
bbox = BlackBox()
- bbox.keepObjectType(parent) # Should invalidate the parent
+ bbox.keepObjectType(parent) # Should invalidate the parent
self.assertRaises(RuntimeError, parent.objectName)
# some children still valid they are wrapper classes
@@ -43,6 +43,6 @@ class InvalidateParentTest(unittest.TestCase):
self.assertEqual(grandchild1.objectName(), "grandchild1")
self.assertRaises(RuntimeError, grandchild2.objectName)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py b/sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py
index acacbf461..304223063 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py
@@ -16,6 +16,7 @@ import sys
from sample import ObjectType
+
class ExtObjectType(ObjectType):
def __init__(self):
ObjectType.__init__(self)
@@ -108,4 +109,3 @@ class ReparentingTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/ownership_transference_test.py b/sources/shiboken6/tests/samplebinding/ownership_transference_test.py
index d1eccb4f6..0e9f08b72 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_transference_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_transference_test.py
@@ -16,6 +16,7 @@ init_paths()
from sample import ObjectType, BlackBox
+
class BlackBoxTest(unittest.TestCase):
'''The BlackBox class has cases of ownership transference between C++ and Python.'''
@@ -29,12 +30,13 @@ class BlackBoxTest(unittest.TestCase):
o2.setObjectName('object2')
o2_refcnt = sys.getrefcount(o2)
bb = BlackBox()
- o1_ticket = bb.keepObjectType(o1)
+ o1_ticket = bb.keepObjectType(o1) # noqa: F841
o2_ticket = bb.keepObjectType(o2)
self.assertEqual(set(bb.objects()), set([o1, o2]))
self.assertEqual(str(o1.objectName()), 'object1')
self.assertEqual(str(o2.objectName()), 'object2')
- self.assertEqual(sys.getrefcount(o1), o1_refcnt + 1) # PySide give +1 ref to object with c++ ownership
+ # PySide give +1 ref to object with c++ ownership
+ self.assertEqual(sys.getrefcount(o1), o1_refcnt + 1)
self.assertEqual(sys.getrefcount(o2), o2_refcnt + 1)
o2 = bb.retrieveObjectType(o2_ticket)
self.assertEqual(sys.getrefcount(o2), o2_refcnt)
@@ -48,9 +50,9 @@ class BlackBoxTest(unittest.TestCase):
def testBlackBoxReleasingUnknownObjectType(self):
'''Asks BlackBox to release an unknown ObjectType.'''
o1 = ObjectType()
- o2 = ObjectType()
+ o2 = ObjectType() # noqa: F841
bb = BlackBox()
- o1_ticket = bb.keepObjectType(o1)
+ o1_ticket = bb.keepObjectType(o1) # noqa: F841
o3 = bb.retrieveObjectType(-5)
self.assertEqual(o3, None)
@@ -59,11 +61,11 @@ class BlackBoxTest(unittest.TestCase):
'''Ownership transference using a C++ created object.'''
o1 = ObjectType.create()
o1.setObjectName('object1')
- o1_refcnt = sys.getrefcount(o1)
+ o1_refcnt = sys.getrefcount(o1) # noqa: F841
bb = BlackBox()
- o1_ticket = bb.keepObjectType(o1)
+ o1_ticket = bb.keepObjectType(o1) # noqa: F841
self.assertRaises(RuntimeError, o1.objectName)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/pair_test.py b/sources/shiboken6/tests/samplebinding/pair_test.py
index 278219434..4bd5c697c 100644
--- a/sources/shiboken6/tests/samplebinding/pair_test.py
+++ b/sources/shiboken6/tests/samplebinding/pair_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import PairUser
+
class ExtendedPairUser(PairUser):
def __init__(self):
PairUser.__init__(self)
@@ -24,6 +25,7 @@ class ExtendedPairUser(PairUser):
self.create_pair_called = True
return (7, 13)
+
class PairConversionTest(unittest.TestCase):
'''Test case for std::pair container conversions'''
@@ -48,14 +50,16 @@ class PairConversionTest(unittest.TestCase):
self.assertEqual(cp, (cpx0, cpx1))
def testSumPair(self):
- '''Test method that sums the items of a pair using values of the types expected by C++ (int and double)'''
+ '''Test method that sums the items of a pair using values of the types
+ expected by C++ (int and double)'''
pu = PairUser()
pair = (3, 7.13)
result = pu.sumPair(pair)
self.assertEqual(result, sum(pair))
def testSumPairDifferentTypes(self):
- '''Test method that sums the items of a pair using values of types different from the ones expected by C++ (int and double)'''
+ '''Test method that sums the items of a pair using values of types different
+ from the ones expected by C++ (int and double)'''
pu = PairUser()
pair = (3.3, 7)
result = pu.sumPair(pair)
@@ -71,7 +75,8 @@ class PairConversionTest(unittest.TestCase):
self.assertEqual(result, pair)
def testConversionInBothDirectionsWithSimilarContainer(self):
- '''Test converting a list, instead of the expected tuple, from Python to C++ and the other way around.'''
+ '''Test converting a list, instead of the expected tuple, from Python to C++
+ and the other way around.'''
pu = PairUser()
pair = [3, 5]
pu.setPair(pair)
@@ -79,6 +84,6 @@ class PairConversionTest(unittest.TestCase):
self.assertNotEqual(result, pair)
self.assertEqual(result, tuple(pair))
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/pen_test.py b/sources/shiboken6/tests/samplebinding/pen_test.py
index 88684dc38..106f3bd61 100644
--- a/sources/shiboken6/tests/samplebinding/pen_test.py
+++ b/sources/shiboken6/tests/samplebinding/pen_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import Color, Pen, SampleNamespace
+
class TestPen(unittest.TestCase):
'''Simple test case for Pen.'''
diff --git a/sources/shiboken6/tests/samplebinding/point_test.py b/sources/shiboken6/tests/samplebinding/point_test.py
index 5e7415395..f86c0f423 100644
--- a/sources/shiboken6/tests/samplebinding/point_test.py
+++ b/sources/shiboken6/tests/samplebinding/point_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import Point
+
class PointTest(unittest.TestCase):
'''Test case for Point class, including operator overloads.'''
@@ -92,5 +93,6 @@ class PointTest(unittest.TestCase):
expected = Point((pt1.x() + pt2.x()) / 2.0, (pt1.y() + pt2.y()) / 2.0)
self.assertEqual(pt1.midpoint(pt2), expected)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/pointerholder_test.py b/sources/shiboken6/tests/samplebinding/pointerholder_test.py
index be2faa118..633525a9c 100644
--- a/sources/shiboken6/tests/samplebinding/pointerholder_test.py
+++ b/sources/shiboken6/tests/samplebinding/pointerholder_test.py
@@ -15,8 +15,10 @@ init_paths()
from sample import PointerHolder
+
class TestPointerHolder(unittest.TestCase):
- '''Test cases for a class that holds an arbitraty pointer and is modified to hold an PyObject.'''
+ '''Test cases for a class that holds an arbitraty pointer and
+ is modified to hold an PyObject.'''
def testStoringAndRetrievingPointer(self):
ph = PointerHolder('Hello')
@@ -31,9 +33,9 @@ class TestPointerHolder(unittest.TestCase):
a = (1, 2, 3)
refcnt = sys.getrefcount(a)
ph = PointerHolder(a)
- ptr = ph.pointer()
+ ptr = ph.pointer() # noqa: F841
self.assertEqual(sys.getrefcount(a), refcnt + 1)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py b/sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py
index 64d51d8c4..4da1a89c6 100644
--- a/sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py
+++ b/sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py
@@ -27,7 +27,6 @@ from shiboken_paths import init_paths
init_paths()
from sample import IntArray2, VirtualMethods
-import shiboken6
from shibokensupport.signature import get_signature
import typing
@@ -38,7 +37,7 @@ class PointerPrimitiveTypeTest(unittest.TestCase):
def testArraySignature(self):
# signature="IntArray2(const int*)"
found = False
- for sig in IntArray2.__signature__:
+ for sig in get_signature(IntArray2):
if "data" in sig.parameters:
found = True
break
diff --git a/sources/shiboken6/tests/samplebinding/pointf_test.py b/sources/shiboken6/tests/samplebinding/pointf_test.py
index 53616aecb..91c58eb1d 100644
--- a/sources/shiboken6/tests/samplebinding/pointf_test.py
+++ b/sources/shiboken6/tests/samplebinding/pointf_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import PointF
+
class PointFTest(unittest.TestCase):
'''Test case for PointF class, including operator overloads.'''
@@ -45,5 +46,6 @@ class PointFTest(unittest.TestCase):
expected = PointF((pt1.x() + pt2.x()) / 2.0, (pt1.y() + pt2.y()) / 2.0)
self.assertEqual(pt1.midpoint(pt2), expected)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/primitivereferenceargument_test.py b/sources/shiboken6/tests/samplebinding/primitivereferenceargument_test.py
index 45cf534a6..0b9fe2249 100644
--- a/sources/shiboken6/tests/samplebinding/primitivereferenceargument_test.py
+++ b/sources/shiboken6/tests/samplebinding/primitivereferenceargument_test.py
@@ -12,12 +12,17 @@ from shiboken_paths import init_paths
init_paths()
import sample
+
class PrimitiveReferenceArgumentTest(unittest.TestCase):
def testIntReferenceArgument(self):
'''C++ signature: int acceptIntReference(int&)'''
self.assertEqual(sample.acceptIntReference(123), 123)
+ def testIntReturnPtr(self):
+ '''C++ signature: const int *acceptIntReturnPtr(int x)'''
+ self.assertEqual(sample.acceptIntReturnPtr(123), 123)
+
def testOddBoolReferenceArgument(self):
'''C++ signature: OddBool acceptOddBoolReference(OddBool&)'''
self.assertEqual(sample.acceptOddBoolReference(True), True)
@@ -25,5 +30,6 @@ class PrimitiveReferenceArgumentTest(unittest.TestCase):
self.assertNotEqual(sample.acceptOddBoolReference(True), False)
self.assertNotEqual(sample.acceptOddBoolReference(False), True)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/privatector_test.py b/sources/shiboken6/tests/samplebinding/privatector_test.py
index 235882997..63040388d 100644
--- a/sources/shiboken6/tests/samplebinding/privatector_test.py
+++ b/sources/shiboken6/tests/samplebinding/privatector_test.py
@@ -64,6 +64,6 @@ class PrivateCtorTest(unittest.TestCase):
self.assertEqual(pd3.instanceCalls(), calls + 2)
self.assertEqual(sys.getrefcount(pd3), refcnt)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/privatedtor_test.py b/sources/shiboken6/tests/samplebinding/privatedtor_test.py
index 777a9923b..651f63b15 100644
--- a/sources/shiboken6/tests/samplebinding/privatedtor_test.py
+++ b/sources/shiboken6/tests/samplebinding/privatedtor_test.py
@@ -80,6 +80,6 @@ class PrivateDtorTest(unittest.TestCase):
self.assertLess(abs(before - after), 5)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/protected_test.py b/sources/shiboken6/tests/samplebinding/protected_test.py
index 9538125f5..e4ccf721d 100644
--- a/sources/shiboken6/tests/samplebinding/protected_test.py
+++ b/sources/shiboken6/tests/samplebinding/protected_test.py
@@ -16,42 +16,51 @@ init_paths()
from sample import cacheSize
from sample import ProtectedNonPolymorphic, ProtectedVirtualDestructor
-from sample import ProtectedPolymorphic, ProtectedPolymorphicDaughter, ProtectedPolymorphicGrandDaughter
+from sample import (ProtectedPolymorphic, ProtectedPolymorphicDaughter,
+ ProtectedPolymorphicGrandDaughter)
from sample import createProtectedProperty, ProtectedProperty, ProtectedEnumClass
from sample import PrivateDtor
from sample import Event, ObjectType, Point
+
class ExtendedProtectedPolymorphic(ProtectedPolymorphic):
def __init__(self, name):
ProtectedPolymorphic.__init__(self, name)
self.protectedName_called = False
+
def protectedName(self):
self.protectedName_called = True
self._name = 'Extended' + ProtectedPolymorphic.protectedName(self)
return self._name
+
class ExtendedProtectedPolymorphicDaughter(ProtectedPolymorphicDaughter):
def __init__(self, name):
self.protectedName_called = False
ProtectedPolymorphicDaughter.__init__(self, name)
+
def protectedName(self):
self.protectedName_called = True
self._name = 'ExtendedDaughter' + ProtectedPolymorphicDaughter.protectedName(self)
return self._name
+
class ExtendedProtectedPolymorphicGrandDaughter(ProtectedPolymorphicGrandDaughter):
def __init__(self, name):
self.protectedName_called = False
ProtectedPolymorphicGrandDaughter.__init__(self, name)
+
def protectedName(self):
self.protectedName_called = True
self._name = 'ExtendedGrandDaughter' + ProtectedPolymorphicGrandDaughter.protectedName(self)
return self._name
+
class ExtendedProtectedVirtualDestructor(ProtectedVirtualDestructor):
def __init__(self):
ProtectedVirtualDestructor.__init__(self)
+
class ProtectedNonPolymorphicTest(unittest.TestCase):
'''Test cases for protected method in a class without virtual methods.'''
@@ -81,6 +90,7 @@ class ProtectedNonPolymorphicTest(unittest.TestCase):
self.assertEqual(p.dataTypeName(1), 'integer')
self.assertEqual(p.dataTypeName(Point(1, 2)), 'pointer')
+
class ProtectedPolymorphicTest(unittest.TestCase):
'''Test cases for protected method in a class with virtual methods.'''
@@ -110,6 +120,8 @@ class ProtectedPolymorphicTest(unittest.TestCase):
self.assertTrue(p.protectedName_called)
self.assertEqual(p.protectedName(), name)
self.assertEqual(ProtectedPolymorphic.protectedName(p), original_name)
+
+
class ProtectedPolymorphicDaugherTest(unittest.TestCase):
'''Test cases for protected method in a class inheriting for a class with virtual methods.'''
@@ -153,6 +165,7 @@ class ProtectedPolymorphicGrandDaugherTest(unittest.TestCase):
self.assertEqual(p.protectedName(), name)
self.assertEqual(ProtectedPolymorphicGrandDaughter.protectedName(p), original_name)
+
class ProtectedVirtualDtorTest(unittest.TestCase):
'''Test cases for protected virtual destructor.'''
@@ -200,15 +213,18 @@ class ProtectedVirtualDtorTest(unittest.TestCase):
class ExtendedProtectedEnumClass(ProtectedEnumClass):
def __init__(self):
ProtectedEnumClass.__init__(self)
+
def protectedEnumMethod(self, value):
if value == ProtectedEnumClass.ProtectedItem0:
return ProtectedEnumClass.ProtectedItem1
return ProtectedEnumClass.ProtectedItem0
+
def publicEnumMethod(self, value):
if value == ProtectedEnumClass.PublicItem0:
return ProtectedEnumClass.PublicItem1
return ProtectedEnumClass.PublicItem0
+
class ProtectedEnumTest(unittest.TestCase):
'''Test cases for protected enum.'''
@@ -223,47 +239,66 @@ class ProtectedEnumTest(unittest.TestCase):
self.assertEqual(type(ProtectedEnumClass.ProtectedItem0), ProtectedEnumClass.ProtectedEnum)
- self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem0), ProtectedEnumClass.ProtectedItem0)
- self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem1), ProtectedEnumClass.ProtectedItem1)
-
- self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem0), ProtectedEnumClass.ProtectedItem0)
- self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem1), ProtectedEnumClass.ProtectedItem1)
+ self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem0),
+ ProtectedEnumClass.ProtectedItem0)
+ self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem1),
+ ProtectedEnumClass.ProtectedItem1)
+ self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem0),
+ ProtectedEnumClass.ProtectedItem0)
+ self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem1),
+ ProtectedEnumClass.ProtectedItem1)
def testProtectedMethodWithPublicEnumArgument(self):
'''Calls protected method with public enum argument.'''
obj = ProtectedEnumClass()
- self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem0), ProtectedEnumClass.PublicItem0)
- self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem1), ProtectedEnumClass.PublicItem1)
+ self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem0),
+ ProtectedEnumClass.PublicItem0)
+ self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem1),
+ ProtectedEnumClass.PublicItem1)
- self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem0), ProtectedEnumClass.PublicItem0)
- self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem1), ProtectedEnumClass.PublicItem1)
+ self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem0),
+ ProtectedEnumClass.PublicItem0)
+ self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem1),
+ ProtectedEnumClass.PublicItem1)
def testOverriddenProtectedMethodWithProtectedEnumArgument(self):
'''Calls overridden protected method with protected enum argument.'''
obj = ExtendedProtectedEnumClass()
- self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem0), ProtectedEnumClass.ProtectedItem1)
- self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem1), ProtectedEnumClass.ProtectedItem0)
+ self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem0),
+ ProtectedEnumClass.ProtectedItem1)
+ self.assertEqual(obj.protectedEnumMethod(ProtectedEnumClass.ProtectedItem1),
+ ProtectedEnumClass.ProtectedItem0)
- self.assertEqual(ProtectedEnumClass.protectedEnumMethod(obj, ProtectedEnumClass.ProtectedItem0), ProtectedEnumClass.ProtectedItem0)
- self.assertEqual(ProtectedEnumClass.protectedEnumMethod(obj, ProtectedEnumClass.ProtectedItem1), ProtectedEnumClass.ProtectedItem1)
+ self.assertEqual(ProtectedEnumClass.protectedEnumMethod(obj, ProtectedEnumClass.ProtectedItem0), # noqa: E501
+ ProtectedEnumClass.ProtectedItem0)
+ self.assertEqual(ProtectedEnumClass.protectedEnumMethod(obj,
+ ProtectedEnumClass.ProtectedItem1), ProtectedEnumClass.ProtectedItem1)
- self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem0), ProtectedEnumClass.ProtectedItem1)
- self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem1), ProtectedEnumClass.ProtectedItem0)
+ self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem0),
+ ProtectedEnumClass.ProtectedItem1)
+ self.assertEqual(obj.callProtectedEnumMethod(ProtectedEnumClass.ProtectedItem1),
+ ProtectedEnumClass.ProtectedItem0)
def testOverriddenProtectedMethodWithPublicEnumArgument(self):
'''Calls overridden protected method with public enum argument.'''
obj = ExtendedProtectedEnumClass()
- self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem0), ProtectedEnumClass.PublicItem1)
- self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem1), ProtectedEnumClass.PublicItem0)
+ self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem0),
+ ProtectedEnumClass.PublicItem1)
+ self.assertEqual(obj.publicEnumMethod(ProtectedEnumClass.PublicItem1),
+ ProtectedEnumClass.PublicItem0)
- self.assertEqual(ProtectedEnumClass.publicEnumMethod(obj, ProtectedEnumClass.PublicItem0), ProtectedEnumClass.PublicItem0)
- self.assertEqual(ProtectedEnumClass.publicEnumMethod(obj, ProtectedEnumClass.PublicItem1), ProtectedEnumClass.PublicItem1)
+ self.assertEqual(ProtectedEnumClass.publicEnumMethod(obj, ProtectedEnumClass.PublicItem0),
+ ProtectedEnumClass.PublicItem0)
+ self.assertEqual(ProtectedEnumClass.publicEnumMethod(obj, ProtectedEnumClass.PublicItem1),
+ ProtectedEnumClass.PublicItem1)
- self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem0), ProtectedEnumClass.PublicItem1)
- self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem1), ProtectedEnumClass.PublicItem0)
+ self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem0),
+ ProtectedEnumClass.PublicItem1)
+ self.assertEqual(obj.callPublicEnumMethod(ProtectedEnumClass.PublicItem1),
+ ProtectedEnumClass.PublicItem0)
class ProtectedPropertyTest(unittest.TestCase):
@@ -361,6 +396,6 @@ class PrivateDtorProtectedMethodTest(unittest.TestCase):
self.assertEqual(obj.instanceCalls(), 2)
self.assertEqual(obj.instanceCalls(), obj.protectedInstanceCalls())
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/pstrlist_test.py b/sources/shiboken6/tests/samplebinding/pstrlist_test.py
index a257d5944..d60f9cf35 100644
--- a/sources/shiboken6/tests/samplebinding/pstrlist_test.py
+++ b/sources/shiboken6/tests/samplebinding/pstrlist_test.py
@@ -12,6 +12,7 @@ from shiboken_paths import init_paths
init_paths()
import sample
+
class PStrListTest(unittest.TestCase):
def testPStrList(self):
@@ -26,5 +27,6 @@ class PStrListTest(unittest.TestCase):
lst = sample.createListOfPStr(a, b)
self.assertEqual(lst, [a, b])
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/pystr_test.py b/sources/shiboken6/tests/samplebinding/pystr_test.py
index 3472457e8..ec64c1e31 100644
--- a/sources/shiboken6/tests/samplebinding/pystr_test.py
+++ b/sources/shiboken6/tests/samplebinding/pystr_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import Point
+
class PyStrTest(unittest.TestCase):
'''Test case for definition of __str__ method.'''
@@ -23,6 +24,6 @@ class PyStrTest(unittest.TestCase):
pt = Point(5, 2)
self.assertEqual(str(pt), 'Point(5.0, 2.0)')
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/python_thread_test.py b/sources/shiboken6/tests/samplebinding/python_thread_test.py
index 03a75b824..65398b5c6 100644
--- a/sources/shiboken6/tests/samplebinding/python_thread_test.py
+++ b/sources/shiboken6/tests/samplebinding/python_thread_test.py
@@ -36,7 +36,7 @@ class Producer(threading.Thread):
def run(self):
while self.runs < self.max_runs:
- value = int(random()*10) % 10
+ value = int(random() * 10) % 10
self.bucket.push(value)
self.production_list.append(value)
logging.debug(f'PRODUCER - pushed {value}')
@@ -66,6 +66,7 @@ class Consumer(threading.Thread):
logging.debug('CONSUMER - empty bucket')
time.sleep(0.01)
+
class ProducerConsumer(unittest.TestCase):
'''Basic test case for producer-consumer QThread'''
@@ -91,8 +92,5 @@ class ProducerConsumer(unittest.TestCase):
self.assertEqual(prod.production_list, cons.consumption_list)
-
-
-
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py b/sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py
index f8c7f017d..1d19de941 100644
--- a/sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py
+++ b/sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py
@@ -15,8 +15,10 @@ init_paths()
from sample import countCharacters
+
class ReceiveNullCStringTest(unittest.TestCase):
- '''Test case for a function that could receive a NULL pointer in a '[const] char*' parameter.'''
+ '''Test case for a function that could receive a NULL pointer in a '[const] char*'
+ parameter.'''
def testBasic(self):
'''The test function should be working for the basic cases.'''
@@ -29,6 +31,6 @@ class ReceiveNullCStringTest(unittest.TestCase):
'''The test function returns '-1' when receives a None value instead of a string.'''
self.assertEqual(countCharacters(None), -1)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/reference_test.py b/sources/shiboken6/tests/samplebinding/reference_test.py
index e590a7e4e..1b6dd3a7a 100644
--- a/sources/shiboken6/tests/samplebinding/reference_test.py
+++ b/sources/shiboken6/tests/samplebinding/reference_test.py
@@ -13,7 +13,8 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import Reference, Str
+
class ExtendedReference(Reference):
def __init__(self):
@@ -48,7 +49,7 @@ class ReferenceTest(unittest.TestCase):
def testCantSegFaultWhenReceiveNone(self):
'''do not segfault when receiving None as argument.'''
s = Str()
- self.assertTrue(None == s)
+ self.assertFalse(bool(s))
def testMethodThatReceivesConstReference(self):
'''Test a method that receives a const reference to an object as argument.'''
@@ -57,29 +58,33 @@ class ReferenceTest(unittest.TestCase):
self.assertEqual(Reference.usesConstReference(r), objId)
def testModificationOfReference(self):
- '''Tests if the identity of a reference argument is preserved when passing it to be altered in C++.'''
+ '''Tests if the identity of a reference argument is preserved when passing
+ it to be altered in C++.'''
objId = 123
r1 = Reference(objId)
r1.alterReferenceIdVirtual(r1)
self.assertEqual(r1.objId(), objId * Reference.multiplier())
def testModificationOfReferenceCallingAVirtualIndirectly(self):
- '''Tests if the identity of a reference argument is preserved when passing it to be altered in C++ through a method that calls a virtual method.'''
+ '''Tests if the identity of a reference argument is preserved when passing it
+ to be altered in C++ through a method that calls a virtual method.'''
objId = 123
r1 = Reference(objId)
r1.callAlterReferenceIdVirtual(r1)
self.assertEqual(r1.objId(), objId * Reference.multiplier())
def testModificationOfReferenceCallingAReimplementedVirtualIndirectly(self):
- '''Test if a Python override of a virtual method with a reference parameter called from C++ alters the argument properly.'''
+ '''Test if a Python override of a virtual method with a reference parameter
+ called from C++ alters the argument properly.'''
objId = 123
r = Reference(objId)
er = ExtendedReference()
- result = er.callAlterReferenceIdVirtual(r)
+ result = er.callAlterReferenceIdVirtual(r) # noqa: F841
self.assertEqual(r.objId(), objId * er.multiplier)
def testReimplementedVirtualMethodCallWithReferenceParameter(self):
- '''Test if a Python override of a virtual method with a reference parameter is correctly called from C++.'''
+ '''Test if a Python override of a virtual method with a reference parameter
+ is correctly called from C++.'''
inc = 9
objId = 123
r = Reference(objId)
@@ -88,7 +93,8 @@ class ReferenceTest(unittest.TestCase):
self.assertEqual(result, objId + inc + er.reference_inc)
def testReimplementedVirtualMethodCallWithConstReferenceParameter(self):
- '''Test if a Python override of a virtual method with a const reference parameter is correctly called from C++.'''
+ '''Test if a Python override of a virtual method with a const reference
+ parameter is correctly called from C++.'''
inc = 9
objId = 123
r = Reference(objId)
@@ -96,6 +102,6 @@ class ReferenceTest(unittest.TestCase):
result = er.callUsesConstReferenceVirtual(r, inc)
self.assertEqual(result, objId + inc + er.const_reference_inc)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/referencetopointer_test.py b/sources/shiboken6/tests/samplebinding/referencetopointer_test.py
index 94bb1608b..942c7ea29 100644
--- a/sources/shiboken6/tests/samplebinding/referencetopointer_test.py
+++ b/sources/shiboken6/tests/samplebinding/referencetopointer_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import VirtualMethods, Str
+
class ExtendedVirtualMethods(VirtualMethods):
def __init__(self):
VirtualMethods.__init__(self)
@@ -72,6 +73,6 @@ class ReferenceToPointerTest(unittest.TestCase):
self.assertTrue(ok)
self.assertEqual(string, Str(obj.prefix + 'foo'))
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/renaming_test.py b/sources/shiboken6/tests/samplebinding/renaming_test.py
index b6a9a8fa4..b08438ef3 100644
--- a/sources/shiboken6/tests/samplebinding/renaming_test.py
+++ b/sources/shiboken6/tests/samplebinding/renaming_test.py
@@ -16,8 +16,6 @@ init_paths()
from sample import RenamedValue, RenamedUser
-from shiboken6 import Shiboken
-
from shibokensupport.signature import get_signature
@@ -37,6 +35,5 @@ class RenamingTest(unittest.TestCase):
actual_signature))
-
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/return_null_test.py b/sources/shiboken6/tests/samplebinding/return_null_test.py
index 46d19e9f7..2c4f07c65 100644
--- a/sources/shiboken6/tests/samplebinding/return_null_test.py
+++ b/sources/shiboken6/tests/samplebinding/return_null_test.py
@@ -13,7 +13,9 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import returnNullPrimitivePointer, returnNullValueTypePointer, returnNullObjectTypePointer
+from sample import (returnNullPrimitivePointer, returnNullValueTypePointer,
+ returnNullObjectTypePointer)
+
class ReturnNullTest(unittest.TestCase):
'''Test case for functions that could return a NULL pointer.'''
@@ -33,6 +35,6 @@ class ReturnNullTest(unittest.TestCase):
o = returnNullValueTypePointer()
self.assertEqual(o, None)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/richcompare_test.py b/sources/shiboken6/tests/samplebinding/richcompare_test.py
index e764b41a4..3146d0faf 100644
--- a/sources/shiboken6/tests/samplebinding/richcompare_test.py
+++ b/sources/shiboken6/tests/samplebinding/richcompare_test.py
@@ -11,7 +11,8 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import Expression
+
class TestRichCompare(unittest.TestCase):
@@ -22,5 +23,6 @@ class TestRichCompare(unittest.TestCase):
d = a + c < b + a
self.assertEqual(d.toString(), "((2+(2+3))<(3+2))")
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/sample_test.py b/sources/shiboken6/tests/samplebinding/sample_test.py
index 52abc968f..19b2f708d 100644
--- a/sources/shiboken6/tests/samplebinding/sample_test.py
+++ b/sources/shiboken6/tests/samplebinding/sample_test.py
@@ -15,35 +15,10 @@ init_paths()
import sample
+
class ModuleTest(unittest.TestCase):
'''Test case for module and global functions'''
- @unittest.skipIf(sys.pyside63_option_python_enum, "Makes no sense with strict Enums")
- def testModuleMembers(self):
- '''Test availability of classes, global functions and other members on binding'''
- expected_members = set(['Abstract', 'Derived', 'Point',
- 'ListUser', 'PairUser', 'MapUser',
- 'gimmeComplexList', 'gimmeDouble', 'gimmeInt',
- 'makeCString', 'multiplyPair', 'returnCString',
- 'SampleNamespace', 'transmuteComplexIntoPoint',
- 'transmutePointIntoComplex', 'sumComplexPair',
- 'FirstThing', 'SecondThing', 'ThirdThing',
- 'GlobalEnum', 'NoThing'])
- self.assertTrue(expected_members.issubset(dir(sample)))
-
- @unittest.skipIf(sys.pyside63_option_python_enum, "Makes no sense with strict Enums")
- def testAbstractPrintFormatEnum(self):
- '''Test availability of PrintFormat enum from Abstract class'''
- enum_members = set(['PrintFormat', 'Short', 'Verbose',
- 'OnlyId', 'ClassNameAndId'])
- self.assertTrue(enum_members.issubset(dir(sample.Abstract)))
-
- @unittest.skipIf(sys.pyside63_option_python_enum, "Makes no sense with strict Enums")
- def testSampleNamespaceOptionEnum(self):
- '''Test availability of Option enum from SampleNamespace namespace'''
- enum_members = set(['Option', 'None_', 'RandomNumber', 'UnixTime'])
- self.assertTrue(enum_members.issubset(dir(sample.SampleNamespace)))
-
def testAddedFunctionAtModuleLevel(self):
'''Calls function added to module from type system description.'''
str1 = 'Foo'
@@ -76,7 +51,26 @@ class ModuleTest(unittest.TestCase):
sample.testNullPtrT(None)
self.assertRaises(TypeError, sample.testNullPtrT, 42)
+ def testRValueRefsWithValueTypes(self):
+ """Passing value types by rvalue refs: For value types, nothing should
+ happen since the argument is copied in the call and the copy is
+ moved from."""
+ polygon = sample.Polygon()
+ polygon.addPoint(sample.Point(1, 2))
+ polygon.addPoint(sample.Point(3, 4))
+ point_count = len(polygon.points())
+ self.assertEqual(point_count, sample.takePolygon(polygon))
+
+ def testRValueRefsWithObjectTypes(self):
+ """Passing object types by rvalue refs: The underlying object should
+ be moved from."""
+ o = sample.ObjectType()
+ object_name = "Name"
+ o.setObjectName(object_name)
+ self.assertEqual(len(object_name), sample.takeObjectType(o))
+ # o should be moved from, name is now empty
+ self.assertEqual(len(o.objectName()), 0)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/samplesnippets.cpp b/sources/shiboken6/tests/samplebinding/samplesnippets.cpp
index 12ff7fc1d..43e6b08de 100644
--- a/sources/shiboken6/tests/samplebinding/samplesnippets.cpp
+++ b/sources/shiboken6/tests/samplebinding/samplesnippets.cpp
@@ -18,3 +18,37 @@ static PyObject *Sbk_IntWrapper_add_ints(PyObject * /* self */, PyObject *args)
}
}
// @snippet intwrapper_add_ints
+
+// @snippet stdcomplex_floor
+%PYARG_0 = PyFloat_FromDouble(std::floor(%CPPSELF.abs_value()));
+// @snippet stdcomplex_floor
+
+// @snippet stdcomplex_ceil
+%PYARG_0 = PyFloat_FromDouble(std::ceil(%CPPSELF.abs_value()));
+// @snippet stdcomplex_ceil
+
+// @snippet stdcomplex_abs
+%PYARG_0 = PyFloat_FromDouble(%CPPSELF.abs_value());
+// @snippet stdcomplex_abs
+
+// @snippet stdcomplex_pow
+%RETURN_TYPE %0 = %CPPSELF.pow(%1);
+%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0);
+// @snippet stdcomplex_pow
+
+// @snippet size_char_ct
+// Convert a string "{width}x{height}" specification
+{
+ double width = -1;
+ double height = -1;
+ const std::string s = %1;
+ const auto pos = s.find('x');
+ if (pos != std::string::npos) {
+ std::istringstream wstr(s.substr(0, pos));
+ wstr >> width;
+ std::istringstream hstr(s.substr(pos + 1, s.size() - pos - 1));
+ hstr >> height;
+ }
+ %0 = new %TYPE(width, height);
+}
+// @snippet size_char_ct
diff --git a/sources/shiboken6/tests/samplebinding/simplefile_test.py b/sources/shiboken6/tests/samplebinding/simplefile_test.py
index 1217bd9a8..55c894a35 100644
--- a/sources/shiboken6/tests/samplebinding/simplefile_test.py
+++ b/sources/shiboken6/tests/samplebinding/simplefile_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import SimpleFile
+
class SimpleFileTest(unittest.TestCase):
'''Test cases for SimpleFile class.'''
@@ -54,6 +55,6 @@ class SimpleFileTest(unittest.TestCase):
self.assertRaises(IOError, f.open)
self.assertEqual(f.size(), 0)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/size_test.py b/sources/shiboken6/tests/samplebinding/size_test.py
index 179a961d9..069ce59b3 100644
--- a/sources/shiboken6/tests/samplebinding/size_test.py
+++ b/sources/shiboken6/tests/samplebinding/size_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import Size
+
class PointTest(unittest.TestCase):
'''Test case for Size class, including operator overloads.'''
@@ -94,6 +95,6 @@ class PointTest(unittest.TestCase):
self.assertTrue(s1 > s2)
self.assertFalse(s2 > s1)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py b/sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py
index e176b3347..cf0889299 100644
--- a/sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py
+++ b/sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py
@@ -15,16 +15,20 @@ init_paths()
from sample import SimpleFile
+
class SimpleFile2 (SimpleFile):
def exists(self):
return "Mooo"
+
class SimpleFile3 (SimpleFile):
pass
+
class SimpleFile4 (SimpleFile):
exists = 5
+
class StaticNonStaticMethodsTest(unittest.TestCase):
'''Test cases for overloads involving static and non-static versions of a method.'''
@@ -79,9 +83,9 @@ class StaticNonStaticMethodsTest(unittest.TestCase):
def testDuckPunchingStaticNonStaticMethod(self):
f = SimpleFile(os.fspath(self.existing_filename))
- f.exists = lambda : "Meee"
+ f.exists = lambda: "Meee"
self.assertEqual(f.exists(), "Meee")
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/stdcomplex_test.py b/sources/shiboken6/tests/samplebinding/stdcomplex_test.py
new file mode 100644
index 000000000..0caa9764d
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/stdcomplex_test.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+'''Test cases for StdComplex class'''
+
+import os
+import math
+import sys
+import unittest
+
+from pathlib import Path
+sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
+from shiboken_paths import init_paths
+init_paths()
+
+from sample import StdComplex
+
+
+REAL = 5.0
+IMAG = 2.3
+
+
+class StdComplexTest(unittest.TestCase):
+ '''Test case for StdComplex class, exercising esoteric number
+ protocols (Py_nb_). For standard number protocols, see Point.'''
+
+ def testConversion(self):
+ pt = StdComplex(REAL, IMAG)
+ self.assertEqual(int(pt), int(round(pt.abs_value())))
+ self.assertEqual(float(pt), pt.abs_value())
+
+ def testAbs(self):
+ pt = StdComplex(REAL, IMAG)
+ self.assertEqual(abs(pt), pt.abs_value())
+
+ def testPow(self):
+ '''Compare pow() function to builtin Python type.'''
+ pt = StdComplex(REAL, IMAG)
+ result = pow(pt, StdComplex(2.0, 0))
+ py_pt = complex(REAL, IMAG)
+ py_result = pow(py_pt, complex(2.0, 0))
+ self.assertAlmostEqual(result.real(), py_result.real)
+ self.assertAlmostEqual(result.imag(), py_result.imag)
+
+ def testFloor(self):
+ pt = StdComplex(REAL, IMAG)
+ self.assertEqual(math.floor(pt), math.floor(pt.abs_value()))
+
+ def testCeil(self):
+ pt = StdComplex(REAL, IMAG)
+ self.assertEqual(math.ceil(pt), math.ceil(pt.abs_value()))
+
+ def testPlusOperator(self):
+ '''Test StdComplex class + operator.'''
+ pt1 = StdComplex(REAL, IMAG)
+ pt2 = StdComplex(0.5, 3.2)
+ self.assertEqual(pt1 + pt2, StdComplex(REAL + 0.5, IMAG + 3.2))
+
+ def testEqualOperator(self):
+ '''Test StdComplex class == operator.'''
+ pt1 = StdComplex(REAL, IMAG)
+ pt2 = StdComplex(REAL, IMAG)
+ pt3 = StdComplex(0.5, 3.2)
+ self.assertTrue(pt1 == pt1)
+ self.assertTrue(pt1 == pt2)
+ self.assertFalse(pt1 == pt3)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/str_test.py b/sources/shiboken6/tests/samplebinding/str_test.py
index 97df76452..c06fd6428 100644
--- a/sources/shiboken6/tests/samplebinding/str_test.py
+++ b/sources/shiboken6/tests/samplebinding/str_test.py
@@ -2,7 +2,8 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-'''Test cases for a method that receives a reference to class that is implicitly convertible from a Python native type.'''
+'''Test cases for a method that receives a reference to class that is implicitly
+ convertible from a Python native type.'''
import os
import sys
@@ -15,6 +16,7 @@ init_paths()
from sample import Str
+
class StrTest(unittest.TestCase):
'''Test cases for thr Str class.'''
@@ -31,39 +33,39 @@ class StrTest(unittest.TestCase):
self.assertEqual(str(s1), 'This is Sparta!')
def testPassPythonTypeImplictlyConvertibleToAClassUsedAsReference(self):
- '''Test passing a Python class implicitly convertible to a wrapped class that is expected to be passed as reference.'''
+ '''Test passing a Python class implicitly convertible to a wrapped class
+ that is expected to be passed as reference.'''
s1 = Str('This is %VAR!').arg('Athens')
self.assertEqual(str(s1), 'This is Athens!')
def testSequenceOperators(self):
s1 = Str("abcdef")
- self.assertEqual(len(s1), 6);
- self.assertEqual(len(Str()), 0);
+ self.assertEqual(len(s1), 6)
+ self.assertEqual(len(Str()), 0)
# getitem
- self.assertEqual(s1[0], "a");
- self.assertEqual(s1[1], "b");
- self.assertEqual(s1[2], "c");
- self.assertEqual(s1[3], "d");
- self.assertEqual(s1[4], "e");
- self.assertEqual(s1[5], "f");
- self.assertEqual(s1[-1], "f");
- self.assertEqual(s1[-2], "e");
+ self.assertEqual(s1[0], "a")
+ self.assertEqual(s1[1], "b")
+ self.assertEqual(s1[2], "c")
+ self.assertEqual(s1[3], "d")
+ self.assertEqual(s1[4], "e")
+ self.assertEqual(s1[5], "f")
+ self.assertEqual(s1[-1], "f")
+ self.assertEqual(s1[-2], "e")
self.assertRaises(TypeError, s1.__getitem__, 6)
# setitem
s1[0] = 'A'
s1[1] = 'B'
- self.assertEqual(s1[0], 'A');
- self.assertEqual(s1[1], 'B');
+ self.assertEqual(s1[0], 'A')
+ self.assertEqual(s1[1], 'B')
self.assertRaises(TypeError, s1.__setitem__(6, 67))
def testReverseOperator(self):
s1 = Str("hello")
- n1 = 2
- self.assertEqual(s1+2, "hello2")
- self.assertEqual(2+s1, "2hello")
+ self.assertEqual(s1 + 2, "hello2")
+ self.assertEqual(2 + s1, "2hello")
def testToIntError(self):
self.assertEqual(Str('Z').toInt(), (0, False))
@@ -90,6 +92,6 @@ class StrTest(unittest.TestCase):
self.assertEqual(val, int(str(hexa), 16))
self.assertEqual(hexa.toInt(), (0, False))
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/strlist_test.py b/sources/shiboken6/tests/samplebinding/strlist_test.py
index f768f9c63..2bfb80b67 100644
--- a/sources/shiboken6/tests/samplebinding/strlist_test.py
+++ b/sources/shiboken6/tests/samplebinding/strlist_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import Str, StrList
+
class StrListTest(unittest.TestCase):
'''Test cases for StrList class that inherits from std::list<Str>.'''
@@ -88,5 +89,6 @@ class StrListTest(unittest.TestCase):
self.assertEqual(len(sl), 2)
self.assertEqual(sl, (Str('Foo'), 'Bar'))
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py b/sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py
index f458ad0d2..11279c7ec 100644
--- a/sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py
+++ b/sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py
@@ -14,7 +14,8 @@ init_paths()
from sample import Photon
'''This tests classes that inherit from template classes,
-simulating a situation found in Qt's phonon module.'''
+ simulating a situation found in Qt's phonon module.'''
+
class TemplateInheritingClassTest(unittest.TestCase):
def testClassBasics(self):
@@ -57,5 +58,6 @@ class TemplateInheritingClassTest(unittest.TestCase):
self.assertEqual(obj2, obj2.passPointerThrough(obj2))
self.assertRaises(TypeError, obj1.passPointerThrough, obj2)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/time_test.py b/sources/shiboken6/tests/samplebinding/time_test.py
index 9b32aaaee..6283a6744 100644
--- a/sources/shiboken6/tests/samplebinding/time_test.py
+++ b/sources/shiboken6/tests/samplebinding/time_test.py
@@ -4,7 +4,6 @@
'''Test cases for constructor and method signature decisor on Time class.'''
-import sys
import os
import sys
import unittest
@@ -17,6 +16,7 @@ import datetime
from sample import Time, ImplicitConv, ObjectType
+
class TimeTest(unittest.TestCase):
'''Test cases for constructor and method signature decisor on Time class.
The constructor and one method have these signatures: CTORMETHOD() and
@@ -115,6 +115,6 @@ class TimeTest(unittest.TestCase):
py = datetime.time(12, 32, 5)
self.assertNotEqual(time, py)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/transform_test.py b/sources/shiboken6/tests/samplebinding/transform_test.py
index a938e6af8..7dfd18a4a 100644
--- a/sources/shiboken6/tests/samplebinding/transform_test.py
+++ b/sources/shiboken6/tests/samplebinding/transform_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import Point, applyHomogeneousTransform
+
class TransformTest(unittest.TestCase):
'''Test cases for modifying a function with > 9 arguments.'''
@@ -32,5 +33,6 @@ class TransformTest(unittest.TestCase):
r = applyHomogeneousTransform(p, 1, 0, 0, 0, 1, 0, 0, 0, 0)
self.assertTrue(r is None)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/typeconverters_test.py b/sources/shiboken6/tests/samplebinding/typeconverters_test.py
index 10b7491b1..987ba6dfd 100644
--- a/sources/shiboken6/tests/samplebinding/typeconverters_test.py
+++ b/sources/shiboken6/tests/samplebinding/typeconverters_test.py
@@ -15,6 +15,7 @@ init_paths()
import sample
+
class GetPythonTypeByNameTest(unittest.TestCase):
'''Uses an added function with inject code that uses the libshiboken
@@ -159,12 +160,31 @@ class StringBasedConversionTest(unittest.TestCase):
self.assertTrue(len(result), 1)
self.assertTrue(lst, result[0])
+
+class PrimitiveConversionTest(unittest.TestCase):
+
def testCppPrimitiveType(self):
integers = (12, 34)
result = sample.convertIntegersToCppAndThenToPython(integers[0], integers[1])
for orig, new in zip(integers, result):
self.assertEqual(orig, new)
+ def testLargeIntAsFloat(self):
+ """PYSIDE-2417: When passing an int to a function taking float,
+ a 64bit conversion should be done."""
+ point = sample.PointF(1, 2)
+ large_int = 2**31 + 2
+ point.setX(large_int)
+ self.assertEqual(round(point.x()), large_int)
+
+ def testUnsignedLongLongAsFloat(self):
+ """PYSIDE-2652: When passing an unsigned long long to a function taking float,
+ an unsigned 64bit conversion should be done."""
+ point = sample.PointF(1, 2)
+ large_int = 2**63
+ point.setX(large_int)
+ self.assertEqual(round(point.x()), large_int)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/typedealloc_test.py b/sources/shiboken6/tests/samplebinding/typedealloc_test.py
index 1b47c62bc..ce881e802 100644
--- a/sources/shiboken6/tests/samplebinding/typedealloc_test.py
+++ b/sources/shiboken6/tests/samplebinding/typedealloc_test.py
@@ -33,12 +33,16 @@ class TypeDeallocTest(unittest.TestCase):
def testScopeEnd(self):
ref = None
+
def scope():
+
class Ext(Point):
pass
- o = Ext()
+
+ o = Ext() # noqa: F841
global ref
ref = weakref.ref(Ext, self.callback)
+
scope()
gc.collect()
self.assertTrue(self.called)
@@ -46,7 +50,7 @@ class TypeDeallocTest(unittest.TestCase):
def testDeleteType(self):
class Ext(Point):
pass
- ref = weakref.ref(Ext, self.callback)
+ ref = weakref.ref(Ext, self.callback) # noqa: F841
del Ext
gc.collect()
self.assertTrue(self.called)
@@ -54,4 +58,3 @@ class TypeDeallocTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/typedtordoublefree_test.py b/sources/shiboken6/tests/samplebinding/typedtordoublefree_test.py
index c486f2bcc..ab8e535b5 100644
--- a/sources/shiboken6/tests/samplebinding/typedtordoublefree_test.py
+++ b/sources/shiboken6/tests/samplebinding/typedtordoublefree_test.py
@@ -12,6 +12,7 @@ from shiboken_paths import init_paths
init_paths()
from sample import ObjectType
+
class TestTypeDestructorDoubleFree(unittest.TestCase):
def testTypeDestructorDoubleFree(self):
'''Causes the type destructors of two derived classes to be called.'''
@@ -22,13 +23,16 @@ class TestTypeDestructorDoubleFree(unittest.TestCase):
obj = ExtObj1()
child = ObjectType(parent=obj)
self.assertEqual(obj.takeChild(child), child)
+
class ExtObj2(ObjectType):
def __init__(self):
ObjectType.__init__(self)
+
obj = ExtObj2()
child = ObjectType(parent=obj)
self.assertEqual(obj.takeChild(child), child)
scope()
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
index d7f45d8b6..e315e599e 100644
--- a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
@@ -1,12 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="sample">
- <suppress-warning text="Duplicate type entry: 'sample'" />
- <suppress-warning text="Duplicate type entry: 'SampleNamespace'" />
-
<primitive-type name="ObjectType::Identifier"/>
<primitive-type name="std::nullptr_t"/>
- <primitive-type name="Foo::HANDLE" target-lang-api-name="PyLong"/>
+ <primitive-type name="Foo::SAMPLE_HANDLE" target-lang-api-name="PyLong"/>
<primitive-type name="std::size_t" target-lang-api-name="PyLong">
<conversion-rule>
@@ -74,7 +71,7 @@
</conversion-rule>
</primitive-type>
- <primitive-type name="HANDLE" target-lang-api-name="PyComplex">
+ <primitive-type name="SAMPLE_HANDLE" target-lang-api-name="PyComplex">
<include file-name="handle.h" location="local"/>
<conversion-rule>
<native-to-target>
@@ -400,6 +397,7 @@
<function signature="returnNullValueTypePointer()" />
<function signature="returnNullObjectTypePointer()" />
<function signature="acceptInt(int)" />
+ <function signature="acceptIntReturnPtr(int)"/>
<function signature="acceptUInt(unsigned int)" />
<function signature="acceptLong(long)" />
<function signature="acceptULong(unsigned long)" />
@@ -421,6 +419,8 @@
<function signature="addStdStrings(const std::string&amp;, const std::string&amp;)"/>
<function signature="addStdWStrings(const std::wstring&amp;, const std::wstring&amp;)"/>
<function signature="testNullPtrT(std::nullptr_t)"/>
+ <function signature="takePolygon(Polygon&amp;&amp;)"/>
+ <function signature="takeObjectType(ObjectType&amp;&amp;)"/>
<value-type name="ArrayModifyTest">
<modify-function signature="sumIntArray(int, int*)">
@@ -429,7 +429,7 @@
</value-type>
<value-type name="ClassWithFunctionPointer">
- <suppress-warning text="skipping function 'ClassWithFunctionPointer::callFunctionPointer', unmatched parameter type 'void (*)(void*)'" />
+ <suppress-warning text="^skipping public function 'void ClassWithFunctionPointer::callFunctionPointer.*$" />
</value-type>
<value-type name="IntArray" generate="no"/>
@@ -571,6 +571,14 @@
<modify-function signature="hideFunction(HideType*)" remove="all"/>
<modify-field name="toBeRenamedField" rename="renamedField"/>
<modify-field name="readOnlyField" write="false"/>
+ <modify-function signature="virtualWithOutParameter(int&amp;)const">
+ <inject-code class="shell" position="override">
+ x = virtualWithOutParameterPyOverride(gil, pyOverride.object());
+ return;
+ </inject-code>
+ </modify-function>
+ <add-function signature="virtualWithOutParameterPyOverride()"
+ return-type="int" python-override="true"/>
</object-type>
<object-type name="Derived" polymorphic-id-expression="%1->type() == Derived::TpDerived">
@@ -633,8 +641,8 @@
// CHECKTYPE and ISCONVERTIBLE are used here for test purposes, don't change them.
if (!%CHECKTYPE[ObjectTypeLayout*](layout) &amp;&amp; !%ISCONVERTIBLE[ObjectTypeLayout*](layout))
return;
- // %CHECKTYPE[ObjectTypeLayout*](layout)
- // %ISCONVERTIBLE[ObjectTypeLayout*](layout)
+ /* %CHECKTYPE[ObjectTypeLayout*](layout) */
+ /* %ISCONVERTIBLE[ObjectTypeLayout*](layout) */
ObjectTypeLayout* var;
var = %CONVERTTOCPP[ObjectTypeLayout*](layout);
// TODO-CONVERTER: erase this
@@ -721,7 +729,7 @@
</modify-function>
</object-type>
- <value-type name="ObjectTypeHolder"/>
+ <object-type name="ObjectTypeHolder"/>
<value-type name="OnlyCopy"/>
<value-type name="FriendOfOnlyCopy"/>
@@ -1894,13 +1902,13 @@
</value-type>
<value-type name="Size">
+ <extra-includes>
+ <include file-name="string" location="global"/>
+ <include file-name="sstream" location="global"/>
+ </extra-includes>
<add-function signature="Size(const char*)">
- <inject-code class="target" position="beginning">
- %0 = new %TYPE();
- </inject-code>
- <inject-code class="target" position="end">
- Shiboken::AutoDecRef result(PyObject_CallMethod(%PYSELF, const_cast&lt;char*>("setHeight"), const_cast&lt;char*>("i"), 2));
- </inject-code>
+ <inject-code class="target" position="beginning"
+ file="samplesnippets.cpp" snippet="size_char_ct"/>
</add-function>
</value-type>
<value-type name="SizeF"/>
@@ -2217,14 +2225,14 @@
</add-function>
</value-type>
- <value-type name="SimpleFile">
+ <object-type name="SimpleFile">
<modify-function signature="open()">
<modify-argument index="return">
<remove-argument/>
</modify-argument>
<inject-code class="target" position="end" file="simplefile_glue.cpp"/>
</modify-function>
- </value-type>
+ </object-type>
<value-type name="VoidHolder" />
@@ -2401,6 +2409,31 @@
<object-type name="ObjectTypeByValue" />
+ <value-type name="StdComplex">
+ <extra-includes>
+ <include file-name="cmath" location="global"/>
+ </extra-includes>
+ <!-- PYSIDE-2446: number protocols without a Py_nb_ constant. -->
+ <add-function signature="__floor__()" return-type="double">
+ <inject-code class="target" position="end"
+ file="samplesnippets.cpp" snippet="stdcomplex_floor"/>
+ </add-function>
+ <add-function signature="__ceil__()" return-type="double">
+ <inject-code class="target" position="end"
+ file="samplesnippets.cpp" snippet="stdcomplex_ceil"/>
+ </add-function>
+ <!-- PYSIDE-2446: number protocols with Py_nb_ constants. -->
+ <add-function signature="__abs__()" return-type="double">
+ <inject-code class="target" position="end"
+ file="samplesnippets.cpp" snippet="stdcomplex_abs"/>
+ </add-function>
+ <add-function signature="__pow__(StdComplex@exp@)" return-type="StdComplex">
+ <inject-code class="target" position="end"
+ file="samplesnippets.cpp" snippet="stdcomplex_pow"/>
+ </add-function>
+
+ </value-type>
+
<object-type name="TemplatePtr">
<modify-function signature="dummy(std::list&lt;std::pair&lt;BlackBox *, BlackBox *&gt; &gt; &amp;)" rename="dummy_method" />
</object-type>
@@ -2416,20 +2449,9 @@
<suppress-warning text="horribly broken type '__off64_t'" />
<suppress-warning text="enum '__codecvt_result' does not have a type entry or is not an enum" />
- <suppress-warning text="Pure virtual method &quot;Abstract::hideFunction(HideType*)&quot; must be implement but was completely removed on typesystem." />
- <suppress-warning text="hiding of function 'takeChild' in class 'ObjectType'" />
+ <suppress-warning text="Pure virtual method 'Abstract::hideFunction(HideType*)' must be implemented but was completely removed on type system." />
<suppress-warning text="Shadowing: MDerived2::castToBase3() and MDerived3::castToBase3()" />
- <suppress-warning text="hiding of function 'takeChild' in class 'Bucket'" />
- <suppress-warning text="visibility of function 'publicMethod' modified in class 'MDerived1'" />
- <suppress-warning text="hiding of function 'doNothingInPublic3' in class 'Overload2'" />
- <suppress-warning text="hiding of function 'takeChild' in class 'ObjectModel'" />
- <suppress-warning text="hiding of function 'takeChild' in class 'ObjectView'" />
- <suppress-warning text="visibility of function 'publicMethod' modified in class 'MDerived3'" />
- <suppress-warning text="skipping function 'InjectCode::toStr', unmatched parameter type 'T const&amp;'" />
-
- <suppress-warning text="^skipping function 'std::enable_if.*ComparisonTester::operator[!=]=.*ComparisonTester.*$"/>
-
- <!-- Do not fix this warning, the generator should be able to handle this situation for Object Types. -->
- <suppress-warning text="Argument in position 1 of added function 'SampleNamespace::passReferenceToObjectType(ObjectType * arg__1)', has a type that is not a reference, while the argument in the corresponding position in C++ function 'SampleNamespace::passReferenceToObjectType(const ObjectType &amp; obj, int multiplier)' is a reference." />
+ <suppress-warning text="Visibility of function 'publicMethod' modified in class 'MDerived1'" />
+ <suppress-warning text="^skipping public function 'std::enable_if.*ComparisonTester::operator[!=]=.*ComparisonTester.*$"/>
</typesystem>
diff --git a/sources/shiboken6/tests/samplebinding/typesystypedef_test.py b/sources/shiboken6/tests/samplebinding/typesystypedef_test.py
index 5e54ef6ee..f7f5342ee 100644
--- a/sources/shiboken6/tests/samplebinding/typesystypedef_test.py
+++ b/sources/shiboken6/tests/samplebinding/typesystypedef_test.py
@@ -13,8 +13,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import (ValueWithUnitUser, ValueWithUnitDoubleInch,
- ValueWithUnitDoubleMillimeter)
+from sample import ValueWithUnitUser, ValueWithUnitDoubleInch
class TypeSysTypeDefTest(unittest.TestCase):
diff --git a/sources/shiboken6/tests/samplebinding/unsafe_parent_test.py b/sources/shiboken6/tests/samplebinding/unsafe_parent_test.py
index dbc4097da..2a7e5cac7 100644
--- a/sources/shiboken6/tests/samplebinding/unsafe_parent_test.py
+++ b/sources/shiboken6/tests/samplebinding/unsafe_parent_test.py
@@ -15,6 +15,7 @@ init_paths()
from sample import ObjectType
+
class DerivedObjectType(ObjectType):
def isPython(self):
return True
@@ -22,12 +23,13 @@ class DerivedObjectType(ObjectType):
def createChild(self, parent):
return DerivedObjectType(parent)
+
class ParentTest(unittest.TestCase):
def testUunsafeParent(self):
o = DerivedObjectType()
o.callVirtualCreateChild()
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/useraddedctor_test.py b/sources/shiboken6/tests/samplebinding/useraddedctor_test.py
index 3aee8d6f7..45d4095b6 100644
--- a/sources/shiboken6/tests/samplebinding/useraddedctor_test.py
+++ b/sources/shiboken6/tests/samplebinding/useraddedctor_test.py
@@ -12,14 +12,15 @@ from pathlib import Path
sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import Size
+
class PointTest(unittest.TestCase):
def testUsingSelfOnCtor(self):
# This is a user added ctor and no errors should happen!
- s = Size("oi")
+ s = Size("3x2")
self.assertEqual(s.height(), 2)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/virtualdtor_test.py b/sources/shiboken6/tests/samplebinding/virtualdtor_test.py
index 69c3479c5..6be870269 100644
--- a/sources/shiboken6/tests/samplebinding/virtualdtor_test.py
+++ b/sources/shiboken6/tests/samplebinding/virtualdtor_test.py
@@ -16,10 +16,12 @@ init_paths()
from sample import VirtualDtor
+
class ExtendedVirtualDtor(VirtualDtor):
def __init__(self):
VirtualDtor.__init__(self)
+
class VirtualDtorTest(unittest.TestCase):
'''Test case for virtual destructor.'''
@@ -59,4 +61,3 @@ class VirtualDtorTest(unittest.TestCase):
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/virtualmethods_test.py b/sources/shiboken6/tests/samplebinding/virtualmethods_test.py
index 7be424e26..52dc66c90 100644
--- a/sources/shiboken6/tests/samplebinding/virtualmethods_test.py
+++ b/sources/shiboken6/tests/samplebinding/virtualmethods_test.py
@@ -14,10 +14,11 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import Point, Str, StrList, VirtualDaughter, VirtualMethods
import warnings
+
class ExtendedVirtualMethods(VirtualMethods):
def __init__(self):
VirtualMethods.__init__(self)
@@ -36,6 +37,7 @@ class ExtendedVirtualMethods(VirtualMethods):
# check if recursion is caused by injected code that calls C++.
return VirtualMethods.recursionOnModifiedVirtual(self, arg) + 10
+
class ExtendedVirtualDaughter(VirtualDaughter):
def __init__(self, name):
VirtualDaughter.__init__(self, name)
@@ -45,6 +47,7 @@ class ExtendedVirtualDaughter(VirtualDaughter):
self.grand_daughter_name_called = True
return VirtualDaughter.name(self).prepend('Extended')
+
class ExtendedExtendedVirtualDaughter(ExtendedVirtualDaughter):
def __init__(self, name):
ExtendedVirtualDaughter.__init__(self, name)
@@ -54,6 +57,7 @@ class ExtendedExtendedVirtualDaughter(ExtendedVirtualDaughter):
self.grand_grand_daughter_name_called = True
return ExtendedVirtualDaughter.name(self).prepend('Extended')
+
class VirtualMethodsTest(unittest.TestCase):
'''Test case for virtual methods'''
@@ -66,7 +70,8 @@ class VirtualMethodsTest(unittest.TestCase):
gc.collect()
def testReimplementedVirtualMethod0(self):
- '''Test Python override of a virtual method with various different parameters is correctly called from C++.'''
+ '''Test Python override of a virtual method with various different parameters
+ is correctly called from C++.'''
vm = VirtualMethods()
evm = ExtendedVirtualMethods()
pt = Point(1.1, 2.2)
@@ -120,6 +125,6 @@ class PrettyErrorMessageTest(unittest.TestCase):
obj = ExtendedVirtualMethods()
self.assertRaises(RuntimeWarning, obj.callStrListToStdList, StrList())
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/visibilitychange_test.py b/sources/shiboken6/tests/samplebinding/visibilitychange_test.py
index 1b810e839..becdf7423 100644
--- a/sources/shiboken6/tests/samplebinding/visibilitychange_test.py
+++ b/sources/shiboken6/tests/samplebinding/visibilitychange_test.py
@@ -11,17 +11,17 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import *
+from sample import Base1, MDerived1
+
class VisibilityChangeTest(unittest.TestCase):
def testVisibilityChange(self):
b1 = Base1()
- b1.publicMethod() # ok...
+ b1.publicMethod() # ok...
d1 = MDerived1()
- self.assertRaises(TypeError, d1.publicMethod);
+ self.assertRaises(TypeError, d1.publicMethod)
+
if __name__ == '__main__':
unittest.main()
-
-
diff --git a/sources/shiboken6/tests/samplebinding/voidholder_test.py b/sources/shiboken6/tests/samplebinding/voidholder_test.py
index 63882cc8a..186cb473e 100644
--- a/sources/shiboken6/tests/samplebinding/voidholder_test.py
+++ b/sources/shiboken6/tests/samplebinding/voidholder_test.py
@@ -16,6 +16,7 @@ init_paths()
from sample import VoidHolder, Point
from shiboken6 import Shiboken
+
class VoidHolderTest(unittest.TestCase):
'''Test case for void pointer manipulation.'''
@@ -44,6 +45,6 @@ class VoidHolderTest(unittest.TestCase):
voidholder = VoidHolder()
self.assertEqual(voidholder.voidPointer(), None)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/weakref_test.py b/sources/shiboken6/tests/samplebinding/weakref_test.py
index 317dfb53c..01c6d58d5 100644
--- a/sources/shiboken6/tests/samplebinding/weakref_test.py
+++ b/sources/shiboken6/tests/samplebinding/weakref_test.py
@@ -30,7 +30,7 @@ class WeakrefBasicTest(unittest.TestCase):
def testBasic(self):
'''ObjectType weakref'''
obj = ObjectType()
- ref = weakref.ref(obj, self.cb)
+ ref = weakref.ref(obj, self.cb) # noqa: F841
del obj
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
@@ -39,7 +39,7 @@ class WeakrefBasicTest(unittest.TestCase):
def testPrivateDtor(self):
'''PrivateDtor weakref'''
obj = PrivateDtor.instance()
- ref = weakref.ref(obj, self.cb)
+ ref = weakref.ref(obj, self.cb) # noqa: F841
del obj
# PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
gc.collect()
diff --git a/sources/shiboken6/tests/samplebinding/writableclassdict_test.py b/sources/shiboken6/tests/samplebinding/writableclassdict_test.py
index e3ba10082..dfc962db9 100644
--- a/sources/shiboken6/tests/samplebinding/writableclassdict_test.py
+++ b/sources/shiboken6/tests/samplebinding/writableclassdict_test.py
@@ -13,7 +13,10 @@ init_paths()
from sample import Point
-class ExtPoint(Point): pass
+
+class ExtPoint(Point):
+ pass
+
class TestWritableClassDict(unittest.TestCase):
def testSetattrOnClass(self):
@@ -29,5 +32,6 @@ class TestWritableClassDict(unittest.TestCase):
pt = ExtPoint()
self.assertEqual(pt.bar, 321)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/shibokenmodule/module_test.py b/sources/shiboken6/tests/shibokenmodule/module_test.py
index 9b9a5ad90..9f9f8f5a4 100644
--- a/sources/shiboken6/tests/shibokenmodule/module_test.py
+++ b/sources/shiboken6/tests/shibokenmodule/module_test.py
@@ -7,17 +7,19 @@ import unittest
from pathlib import Path
sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
-from shiboken_paths import init_paths
+from shiboken_paths import init_paths # noqa: E402
init_paths()
-from shiboken6 import Shiboken
-from sample import *
+from shiboken6 import Shiboken # noqa: E402
+from sample import BlackBox, ObjectType, ObjectModel, ObjectView, Point # noqa: E402
+
class MultipleInherited (ObjectType, Point):
def __init__(self):
ObjectType.__init__(self)
Point.__init__(self)
+
class TestShiboken(unittest.TestCase):
def testIsValid(self):
self.assertTrue(Shiboken.isValid(object()))
@@ -43,6 +45,16 @@ class TestShiboken(unittest.TestCase):
self.assertTrue(Shiboken.createdByPython(bb))
bb.disposeObjectType(bb.keepObjectType(obj))
+ def testWrapInstancePreserveId(self):
+ """PYSIDE-31: Verify that wrapInstance() returns the existing wrapper
+ even if a base class type is specified."""
+ v = ObjectView() # inherits ObjectType
+ addresses = Shiboken.getCppPointer(v)
+ self.assertTrue(addresses)
+ address = addresses[0]
+ wrapped = Shiboken.wrapInstance(address, ObjectType)
+ self.assertEqual(id(wrapped), id(v))
+
def testIsOwnedByPython(self):
obj = ObjectType()
self.assertTrue(Shiboken.ownedByPython(obj))
@@ -55,7 +67,7 @@ class TestShiboken(unittest.TestCase):
p = ObjectType()
obj = ObjectType(p)
obj2 = ObjectType(obj)
- obj3 = ObjectType(obj)
+ obj3 = ObjectType(obj) # noqa: F841
self.assertEqual(Shiboken.dump(None), "Ordinary Python type.")
Shiboken.dump(obj)
@@ -69,9 +81,9 @@ class TestShiboken(unittest.TestCase):
# Don't crash even after deleting an object
Shiboken.invalidate(obj)
- Shiboken.dump(obj) # deleted
- Shiboken.dump(p) # child deleted
- Shiboken.dump(obj2) # parent deleted
+ Shiboken.dump(obj) # deleted
+ Shiboken.dump(p) # child deleted
+ Shiboken.dump(obj2) # parent deleted
def testDelete(self):
obj = ObjectType()
diff --git a/sources/shiboken6/tests/smartbinding/CMakeLists.txt b/sources/shiboken6/tests/smartbinding/CMakeLists.txt
index b15967781..c10d7ab6b 100644
--- a/sources/shiboken6/tests/smartbinding/CMakeLists.txt
+++ b/sources/shiboken6/tests/smartbinding/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(smart)
set(smart_TYPESYSTEM
@@ -17,6 +20,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/smart/stdsharedptrtestbench_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/stdsharedptrvirtualmethodtester_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_integer_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_int_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_std_string_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/std_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/std_optional_int_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/std_optional_integer_wrapper.cpp
diff --git a/sources/shiboken6/tests/smartbinding/smart_pointer_test.py b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py
index 1bec3a286..8d4272558 100644
--- a/sources/shiboken6/tests/smartbinding/smart_pointer_test.py
+++ b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py
@@ -262,7 +262,7 @@ class SmartPointerTests(unittest.TestCase):
self.assertTrue(five > four)
self.assertRaises(NotImplementedError,
- lambda : Obj.createNullSharedPtrInteger() == four)
+ lambda: Obj.createNullSharedPtrInteger() == four)
def testSmartPointerObjectComparison(self):
"""Test a pointee class without comparison operators."""
diff --git a/sources/shiboken6/tests/smartbinding/std_optional_test.py b/sources/shiboken6/tests/smartbinding/std_optional_test.py
index be969d0f5..bee573548 100644
--- a/sources/shiboken6/tests/smartbinding/std_optional_test.py
+++ b/sources/shiboken6/tests/smartbinding/std_optional_test.py
@@ -2,7 +2,6 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-import gc
import os
import sys
import unittest
diff --git a/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py b/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py
index b4b9808c6..ddaab43f5 100644
--- a/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py
+++ b/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py
@@ -2,7 +2,6 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-import gc
import os
import sys
import unittest
@@ -28,6 +27,8 @@ class VirtualTester(StdSharedPtrVirtualMethodTester):
class StdSharedPtrTests(unittest.TestCase):
def testInteger(self):
p = StdSharedPtrTestBench.createInteger()
+ # PYSIDE-2462: Ensure Integer's __dir__ entries in the pointer's
+ self.assertTrue("printInteger" in dir(p))
StdSharedPtrTestBench.printInteger(p)
self.assertTrue(p)
call_func_on_ptr(p)
@@ -48,6 +49,15 @@ class StdSharedPtrTests(unittest.TestCase):
self.assertFalse(np)
p = StdSharedPtrTestBench.createInt()
StdSharedPtrTestBench.printInt(p)
+ ip = std.StdIntPtr(42)
+ StdSharedPtrTestBench.printInt(ip)
+
+ def testString(self):
+ np = StdSharedPtrTestBench.createNullString()
+ StdSharedPtrTestBench.printString(np)
+ self.assertFalse(np)
+ p = StdSharedPtrTestBench.createString("bla")
+ StdSharedPtrTestBench.printString(p)
def testVirtuals(self):
"""Test whether code generating virtual function overrides is generated
diff --git a/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py b/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py
index 0f4729413..9c7ef2f01 100644
--- a/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py
+++ b/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py
@@ -2,7 +2,6 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
-import gc
import os
import sys
import unittest
diff --git a/sources/shiboken6/tests/smartbinding/typesystem_smart.xml b/sources/shiboken6/tests/smartbinding/typesystem_smart.xml
index 261d5f15d..e4a1ef8b7 100644
--- a/sources/shiboken6/tests/smartbinding/typesystem_smart.xml
+++ b/sources/shiboken6/tests/smartbinding/typesystem_smart.xml
@@ -50,7 +50,7 @@
value-check-method="operator bool"
ref-count-method="use_count"
reset-method="reset"
- instantiations="Integer,int">
+ instantiations="Integer,int=StdIntPtr,std::string">
<include file-name="memory" location="global"/>
</smart-pointer-type>
diff --git a/sources/shiboken6/tests/test_generator/CMakeLists.txt b/sources/shiboken6/tests/test_generator/CMakeLists.txt
index c6a7ec579..e1d078894 100644
--- a/sources/shiboken6/tests/test_generator/CMakeLists.txt
+++ b/sources/shiboken6/tests/test_generator/CMakeLists.txt
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
cmake_minimum_required(VERSION 3.18)
project(test_generator)
diff --git a/sources/shiboken6/tests/test_generator/run_test.cmake b/sources/shiboken6/tests/test_generator/run_test.cmake
index 34a821d80..37e40b993 100644
--- a/sources/shiboken6/tests/test_generator/run_test.cmake
+++ b/sources/shiboken6/tests/test_generator/run_test.cmake
@@ -1,3 +1,6 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
# The tests are run through this script due to a limitation
# on versions of CMake lesser than 2.8, that prevent setting
# environment variables for tests from working.