aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6')
-rw-r--r--sources/shiboken6/.cmake.conf5
-rw-r--r--sources/shiboken6/ApiExtractor/CMakeLists.txt129
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaargument.cpp49
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaargument.h42
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp2129
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.h93
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp130
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h254
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaenum.cpp200
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaenum.h59
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafield.cpp48
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafield.h38
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.cpp506
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.h165
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.cpp798
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.h181
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang_enums.h56
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h44
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang_typedefs.h43
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetatype.cpp373
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetatype.h78
-rw-r--r--sources/shiboken6/ApiExtractor/addedfunction.cpp216
-rw-r--r--sources/shiboken6/ApiExtractor/addedfunction.h113
-rw-r--r--sources/shiboken6/ApiExtractor/addedfunction_p.h45
-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.cpp751
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractor.h105
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorflags.h18
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorresult.cpp109
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorresult.h88
-rw-r--r--sources/shiboken6/ApiExtractor/arraytypeentry.h28
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp435
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h33
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.cpp131
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.h31
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp53
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangparser.h37
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangutils.cpp133
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangutils.h65
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp221
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/compilersupport.h42
-rw-r--r--sources/shiboken6/ApiExtractor/classdocumentation.cpp381
-rw-r--r--sources/shiboken6/ApiExtractor/classdocumentation.h82
-rw-r--r--sources/shiboken6/ApiExtractor/cmake_uninstall.cmake3
-rw-r--r--sources/shiboken6/ApiExtractor/codesnip.cpp78
-rw-r--r--sources/shiboken6/ApiExtractor/codesnip.h107
-rw-r--r--sources/shiboken6/ApiExtractor/codesniphelpers.cpp51
-rw-r--r--sources/shiboken6/ApiExtractor/codesniphelpers.h29
-rw-r--r--sources/shiboken6/ApiExtractor/complextypeentry.h179
-rw-r--r--sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp41
-rw-r--r--sources/shiboken6/ApiExtractor/conditionalstreamreader.h31
-rw-r--r--sources/shiboken6/ApiExtractor/configurabletypeentry.h28
-rw-r--r--sources/shiboken6/ApiExtractor/constantvaluetypeentry.h23
-rw-r--r--sources/shiboken6/ApiExtractor/containertypeentry.h63
-rw-r--r--sources/shiboken6/ApiExtractor/customconversion.cpp197
-rw-r--r--sources/shiboken6/ApiExtractor/customconversion.h81
-rw-r--r--sources/shiboken6/ApiExtractor/customconversion_typedefs.h14
-rw-r--r--sources/shiboken6/ApiExtractor/customtypenentry.h30
-rw-r--r--sources/shiboken6/ApiExtractor/debughelpers_p.h56
-rw-r--r--sources/shiboken6/ApiExtractor/dependency.h33
-rw-r--r--sources/shiboken6/ApiExtractor/docparser.cpp196
-rw-r--r--sources/shiboken6/ApiExtractor/docparser.h60
-rw-r--r--sources/shiboken6/ApiExtractor/documentation.cpp56
-rw-r--r--sources/shiboken6/ApiExtractor/documentation.h47
-rw-r--r--sources/shiboken6/ApiExtractor/dotview.cpp41
-rw-r--r--sources/shiboken6/ApiExtractor/dotview.h29
-rw-r--r--sources/shiboken6/ApiExtractor/doxygenparser.cpp125
-rw-r--r--sources/shiboken6/ApiExtractor/doxygenparser.h31
-rw-r--r--sources/shiboken6/ApiExtractor/enclosingclassmixin.cpp35
-rw-r--r--sources/shiboken6/ApiExtractor/enclosingclassmixin.h42
-rw-r--r--sources/shiboken6/ApiExtractor/enumtypeentry.h51
-rw-r--r--sources/shiboken6/ApiExtractor/enumvaluetypeentry.h31
-rw-r--r--sources/shiboken6/ApiExtractor/exception.h31
-rw-r--r--sources/shiboken6/ApiExtractor/fileout.cpp77
-rw-r--r--sources/shiboken6/ApiExtractor/fileout.h31
-rw-r--r--sources/shiboken6/ApiExtractor/flagstypeentry.h36
-rw-r--r--sources/shiboken6/ApiExtractor/functiontypeentry.h35
-rw-r--r--sources/shiboken6/ApiExtractor/graph.h29
-rw-r--r--sources/shiboken6/ApiExtractor/header_paths.h34
-rw-r--r--sources/shiboken6/ApiExtractor/icecc.cmake3
-rw-r--r--sources/shiboken6/ApiExtractor/include.cpp79
-rw-r--r--sources/shiboken6/ApiExtractor/include.h78
-rw-r--r--sources/shiboken6/ApiExtractor/messages.cpp499
-rw-r--r--sources/shiboken6/ApiExtractor/messages.h134
-rw-r--r--sources/shiboken6/ApiExtractor/modifications.cpp387
-rw-r--r--sources/shiboken6/ApiExtractor/modifications.h278
-rw-r--r--sources/shiboken6/ApiExtractor/modifications_p.h67
-rw-r--r--sources/shiboken6/ApiExtractor/modifications_typedefs.h25
-rw-r--r--sources/shiboken6/ApiExtractor/namespacetypeentry.h51
-rw-r--r--sources/shiboken6/ApiExtractor/objecttypeentry.h21
-rw-r--r--sources/shiboken6/ApiExtractor/optionsparser.cpp232
-rw-r--r--sources/shiboken6/ApiExtractor/optionsparser.h98
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel.cpp532
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel.h243
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel_enums.h44
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h62
-rw-r--r--sources/shiboken6/ApiExtractor/parser/enumvalue.cpp88
-rw-r--r--sources/shiboken6/ApiExtractor/parser/enumvalue.h49
-rw-r--r--sources/shiboken6/ApiExtractor/parser/typeinfo.cpp168
-rw-r--r--sources/shiboken6/ApiExtractor/parser/typeinfo.h57
-rw-r--r--sources/shiboken6/ApiExtractor/predefined_templates.cpp276
-rw-r--r--sources/shiboken6/ApiExtractor/predefined_templates.h27
-rw-r--r--sources/shiboken6/ApiExtractor/primitivetypeentry.h72
-rw-r--r--sources/shiboken6/ApiExtractor/propertyspec.cpp115
-rw-r--r--sources/shiboken6/ApiExtractor/propertyspec.h49
-rw-r--r--sources/shiboken6/ApiExtractor/pymethoddefentry.cpp53
-rw-r--r--sources/shiboken6/ApiExtractor/pymethoddefentry.h38
-rw-r--r--sources/shiboken6/ApiExtractor/pythontypeentry.h29
-rw-r--r--sources/shiboken6/ApiExtractor/qtcompat.h37
-rw-r--r--sources/shiboken6/ApiExtractor/qtdocparser.cpp460
-rw-r--r--sources/shiboken6/ApiExtractor/qtdocparser.h51
-rw-r--r--sources/shiboken6/ApiExtractor/reporthandler.cpp72
-rw-r--r--sources/shiboken6/ApiExtractor/reporthandler.h33
-rw-r--r--sources/shiboken6/ApiExtractor/smartpointertypeentry.h57
-rw-r--r--sources/shiboken6/ApiExtractor/sourcelocation.cpp29
-rw-r--r--sources/shiboken6/ApiExtractor/sourcelocation.h31
-rw-r--r--sources/shiboken6/ApiExtractor/templateargumententry.h26
-rw-r--r--sources/shiboken6/ApiExtractor/tests/CMakeLists.txt5
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp344
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.h32
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp112
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testabstractmetatype.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp283
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testaddfunction.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp108
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testarrayargument.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp124
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testcodeinjection.h32
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testcontainer.cpp56
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testcontainer.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp119
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testconversionoperator.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp178
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testconversionruletag.h32
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testctorinformation.cpp61
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testctorinformation.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp142
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testdtorinformation.cpp157
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testdtorinformation.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testenum.cpp292
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testenum.h32
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testextrainclude.cpp64
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testextrainclude.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp60
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testfunctiontag.h32
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp95
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testimplicitconversions.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testinserttemplate.cpp62
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testinserttemplate.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp91
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.h32
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp185
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testmodifyfunction.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp41
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testnamespace.cpp66
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testnamespace.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp90
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testnestedtypes.h32
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp71
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.cpp52
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp62
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testrefcounttag.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp45
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testreferencetopointer.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testremovefield.cpp78
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testremovefield.h32
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp49
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testremoveimplconv.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp113
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testresolvetype.cpp286
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testresolvetype.h36
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp101
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testreverseoperators.h32
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testtemplates.cpp243
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testtemplates.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testtoposort.cpp29
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testtoposort.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp62
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testtyperevision.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testutil.h44
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.cpp43
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.h31
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp60
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testvoidarg.h31
-rw-r--r--sources/shiboken6/ApiExtractor/textstream.cpp93
-rw-r--r--sources/shiboken6/ApiExtractor/textstream.h84
-rw-r--r--sources/shiboken6/ApiExtractor/typedatabase.cpp1213
-rw-r--r--sources/shiboken6/ApiExtractor/typedatabase.h193
-rw-r--r--sources/shiboken6/ApiExtractor/typedatabase_p.h25
-rw-r--r--sources/shiboken6/ApiExtractor/typedatabase_typedefs.h54
-rw-r--r--sources/shiboken6/ApiExtractor/typedefentry.h37
-rw-r--r--sources/shiboken6/ApiExtractor/typeparser.cpp85
-rw-r--r--sources/shiboken6/ApiExtractor/typeparser.h31
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.cpp1159
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.h732
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem_enums.h57
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem_typedefs.h111
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp2592
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.h287
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser_p.h297
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemtypeentry.h40
-rw-r--r--sources/shiboken6/ApiExtractor/usingmember.h33
-rw-r--r--sources/shiboken6/ApiExtractor/valuetypeentry.h40
-rw-r--r--sources/shiboken6/ApiExtractor/varargstypeentry.h20
-rw-r--r--sources/shiboken6/ApiExtractor/voidtypeentry.h20
-rw-r--r--sources/shiboken6/ApiExtractor/xmlutils.cpp45
-rw-r--r--sources/shiboken6/ApiExtractor/xmlutils.h36
-rw-r--r--sources/shiboken6/ApiExtractor/xmlutils_libxslt.cpp79
-rw-r--r--sources/shiboken6/ApiExtractor/xmlutils_libxslt.h34
-rw-r--r--sources/shiboken6/ApiExtractor/xmlutils_qt.h34
-rw-r--r--sources/shiboken6/CMakeLists.txt229
-rw-r--r--sources/shiboken6/cmake/FindDocTools.cmake39
-rw-r--r--sources/shiboken6/cmake/ShibokenHelpers.cmake889
-rw-r--r--sources/shiboken6/cmake/ShibokenSetup.cmake192
-rw-r--r--sources/shiboken6/cmake_uninstall.cmake3
-rw-r--r--sources/shiboken6/config.tests/target_python_info/CMakeLists.txt47
-rw-r--r--sources/shiboken6/config.tests/target_qt_info/CMakeLists.txt39
-rw-r--r--sources/shiboken6/config.tests/target_qt_mkspec/CMakeLists.txt25
-rw-r--r--sources/shiboken6/data/CMakeLists.txt19
-rw-r--r--sources/shiboken6/data/Shiboken6Config-spec.cmake.in12
-rw-r--r--sources/shiboken6/data/Shiboken6ToolsConfig.cmake.in7
-rw-r--r--sources/shiboken6/data/shiboken6.pc.in9
-rw-r--r--sources/shiboken6/data/shiboken_helpers.cmake365
-rw-r--r--sources/shiboken6/doc/CMakeLists.txt77
-rw-r--r--sources/shiboken6/doc/_static/css/qt_font.css15
-rw-r--r--sources/shiboken6/doc/_static/css/qt_style.css100
-rw-r--r--sources/shiboken6/doc/_static/qtforpython.png (renamed from sources/shiboken6/doc/_themes/pysidedocs/static/pysidelogo.png)bin4936 -> 4936 bytes
-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/_templates/layout.html2
-rw-r--r--sources/shiboken6/doc/_themes/pysidedocs/searchbox.html12
-rw-r--r--sources/shiboken6/doc/_themes/pysidedocs/static/bg_header.pngbin36012 -> 0 bytes
-rw-r--r--sources/shiboken6/doc/_themes/pysidedocs/static/bg_topo.jpgbin14237 -> 0 bytes
-rw-r--r--sources/shiboken6/doc/_themes/pysidedocs/static/fakebar.pngbin101 -> 0 bytes
-rw-r--r--sources/shiboken6/doc/_themes/pysidedocs/static/logo_python.jpgbin2660 -> 0 bytes
-rw-r--r--sources/shiboken6/doc/_themes/pysidedocs/static/logo_qt.pngbin1032 -> 0 bytes
-rw-r--r--sources/shiboken6/doc/_themes/pysidedocs/static/pyside.css2197
-rw-r--r--sources/shiboken6/doc/_themes/pysidedocs/static/relbar_bg.pngbin130 -> 0 bytes
-rw-r--r--sources/shiboken6/doc/_themes/pysidedocs/theme.conf7
-rw-r--r--sources/shiboken6/doc/_themes/pysidedocs_qthelp/static/pyside.css8
-rw-r--r--sources/shiboken6/doc/conf.py.in81
-rw-r--r--sources/shiboken6/doc/considerations.rst72
-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.rst26
-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.rst118
-rw-r--r--sources/shiboken6/doc/scripts/patch_qhp.py62
-rw-r--r--sources/shiboken6/doc/shiboken-genpyi.rst32
-rw-r--r--sources/shiboken6/doc/shibokengenerator.rst99
-rw-r--r--sources/shiboken6/doc/shibokenmodule.rst70
-rw-r--r--sources/shiboken6/doc/typediscovery.rst145
-rw-r--r--sources/shiboken6/doc/typesystem.rst1
-rw-r--r--sources/shiboken6/doc/typesystem_arguments.rst267
-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.rst263
-rw-r--r--sources/shiboken6/doc/typesystem_conversionrule.rst184
-rw-r--r--sources/shiboken6/doc/typesystem_converters.rst278
-rw-r--r--sources/shiboken6/doc/typesystem_documentation.rst63
-rw-r--r--sources/shiboken6/doc/typesystem_manipulating_objects.rst708
-rw-r--r--sources/shiboken6/doc/typesystem_modify_function.rst66
-rw-r--r--sources/shiboken6/doc/typesystem_ownership.rst192
-rw-r--r--sources/shiboken6/doc/typesystem_solving_compilation.rst98
-rw-r--r--sources/shiboken6/doc/typesystem_specialfunctions.rst22
-rw-r--r--sources/shiboken6/doc/typesystem_specifying_types.rst1084
-rw-r--r--sources/shiboken6/doc/typesystem_templates.rst131
-rw-r--r--sources/shiboken6/doc/typesystem_variables.rst180
-rw-r--r--sources/shiboken6/generator/CMakeLists.txt79
-rw-r--r--sources/shiboken6/generator/_config.py.in1
-rw-r--r--sources/shiboken6/generator/defaultvalue.cpp120
-rw-r--r--sources/shiboken6/generator/defaultvalue.h46
-rw-r--r--sources/shiboken6/generator/generator.cpp658
-rw-r--r--sources/shiboken6/generator/generator.h253
-rw-r--r--sources/shiboken6/generator/generatorcontext.cpp38
-rw-r--r--sources/shiboken6/generator/generatorcontext.h56
-rw-r--r--sources/shiboken6/generator/main.cpp882
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp1489
-rw-r--r--sources/shiboken6/generator/qtdoc/qtdocgenerator.h122
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp809
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinx.h83
-rw-r--r--sources/shiboken6/generator/qtdoc/qtxmltosphinxinterface.h40
-rw-r--r--sources/shiboken6/generator/qtdoc/rstformat.h55
-rw-r--r--sources/shiboken6/generator/shiboken/configurablescope.h33
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.cpp5957
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator.h511
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator_container.cpp203
-rw-r--r--sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp476
-rw-r--r--sources/shiboken6/generator/shiboken/ctypenames.h69
-rw-r--r--sources/shiboken6/generator/shiboken/generatorargument.cpp110
-rw-r--r--sources/shiboken6/generator/shiboken/generatorargument.h60
-rw-r--r--sources/shiboken6/generator/shiboken/generatorstrings.h39
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.cpp960
-rw-r--r--sources/shiboken6/generator/shiboken/headergenerator.h84
-rw-r--r--sources/shiboken6/generator/shiboken/overloaddata.cpp233
-rw-r--r--sources/shiboken6/generator/shiboken/overloaddata.h38
-rw-r--r--sources/shiboken6/generator/shiboken/pytypenames.h56
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.cpp1927
-rw-r--r--sources/shiboken6/generator/shiboken/shibokengenerator.h316
-rw-r--r--sources/shiboken6/generatorrunnermacros.h29
-rw-r--r--sources/shiboken6/generators/shiboken/shiboken.cpp32
-rw-r--r--sources/shiboken6/icecc.cmake3
-rw-r--r--sources/shiboken6/libshiboken/CMakeLists.txt103
-rw-r--r--sources/shiboken6/libshiboken/autodecref.h99
-rw-r--r--sources/shiboken6/libshiboken/basewrapper.cpp785
-rw-r--r--sources/shiboken6/libshiboken/basewrapper.h169
-rw-r--r--sources/shiboken6/libshiboken/basewrapper_p.h178
-rw-r--r--sources/shiboken6/libshiboken/bindingmanager.cpp447
-rw-r--r--sources/shiboken6/libshiboken/bindingmanager.h68
-rw-r--r--sources/shiboken6/libshiboken/bufferprocs_py37.cpp40
-rw-r--r--sources/shiboken6/libshiboken/bufferprocs_py37.h44
-rw-r--r--sources/shiboken6/libshiboken/debugfreehook.cpp44
-rw-r--r--sources/shiboken6/libshiboken/debugfreehook.h40
-rw-r--r--sources/shiboken6/libshiboken/embed/embedding_generator.py73
-rw-r--r--sources/shiboken6/libshiboken/embed/module_collector.py43
-rw-r--r--sources/shiboken6/libshiboken/embed/qt_python_license.txt43
-rw-r--r--sources/shiboken6/libshiboken/embed/signature_bootstrap.py115
-rw-r--r--sources/shiboken6/libshiboken/gilstate.cpp40
-rw-r--r--sources/shiboken6/libshiboken/gilstate.h40
-rw-r--r--sources/shiboken6/libshiboken/helper.cpp372
-rw-r--r--sources/shiboken6/libshiboken/helper.h70
-rw-r--r--sources/shiboken6/libshiboken/pep384_issue33738.cpp121
-rw-r--r--sources/shiboken6/libshiboken/pep384ext.h89
-rw-r--r--sources/shiboken6/libshiboken/pep384impl.cpp516
-rw-r--r--sources/shiboken6/libshiboken/pep384impl.h162
-rw-r--r--sources/shiboken6/libshiboken/pep384impl_doc.rst704
-rw-r--r--sources/shiboken6/libshiboken/pyobjectholder.h86
-rw-r--r--sources/shiboken6/libshiboken/sbkarrayconverter.cpp46
-rw-r--r--sources/shiboken6/libshiboken/sbkarrayconverter.h48
-rw-r--r--sources/shiboken6/libshiboken/sbkarrayconverter_p.h42
-rw-r--r--sources/shiboken6/libshiboken/sbkcontainer.cpp47
-rw-r--r--sources/shiboken6/libshiboken/sbkcontainer.h180
-rw-r--r--sources/shiboken6/libshiboken/sbkconverter.cpp265
-rw-r--r--sources/shiboken6/libshiboken/sbkconverter.h108
-rw-r--r--sources/shiboken6/libshiboken/sbkconverter_p.h70
-rw-r--r--sources/shiboken6/libshiboken/sbkcppstring.cpp45
-rw-r--r--sources/shiboken6/libshiboken/sbkcppstring.h42
-rw-r--r--sources/shiboken6/libshiboken/sbkcpptonumpy.cpp67
-rw-r--r--sources/shiboken6/libshiboken/sbkcpptonumpy.h41
-rw-r--r--sources/shiboken6/libshiboken/sbkenum.cpp977
-rw-r--r--sources/shiboken6/libshiboken/sbkenum.h174
-rw-r--r--sources/shiboken6/libshiboken/sbkenum_p.h52
-rw-r--r--sources/shiboken6/libshiboken/sbkerrors.cpp215
-rw-r--r--sources/shiboken6/libshiboken/sbkerrors.h78
-rw-r--r--sources/shiboken6/libshiboken/sbkfeature_base.cpp445
-rw-r--r--sources/shiboken6/libshiboken/sbkfeature_base.h42
-rw-r--r--sources/shiboken6/libshiboken/sbkmodule.cpp520
-rw-r--r--sources/shiboken6/libshiboken/sbkmodule.h76
-rw-r--r--sources/shiboken6/libshiboken/sbknumpy.cpp57
-rw-r--r--sources/shiboken6/libshiboken/sbknumpyarrayconverter.cpp68
-rw-r--r--sources/shiboken6/libshiboken/sbknumpycheck.h30
-rw-r--r--sources/shiboken6/libshiboken/sbknumpyview.cpp265
-rw-r--r--sources/shiboken6/libshiboken/sbknumpyview.h47
-rw-r--r--sources/shiboken6/libshiboken/sbkpython.h41
-rw-r--r--sources/shiboken6/libshiboken/sbksmartpointer.cpp58
-rw-r--r--sources/shiboken6/libshiboken/sbksmartpointer.h18
-rw-r--r--sources/shiboken6/libshiboken/sbkstaticstrings.cpp54
-rw-r--r--sources/shiboken6/libshiboken/sbkstaticstrings.h51
-rw-r--r--sources/shiboken6/libshiboken/sbkstaticstrings_p.h40
-rw-r--r--sources/shiboken6/libshiboken/sbkstring.cpp104
-rw-r--r--sources/shiboken6/libshiboken/sbkstring.h53
-rw-r--r--sources/shiboken6/libshiboken/sbktypefactory.cpp397
-rw-r--r--sources/shiboken6/libshiboken/sbktypefactory.h54
-rw-r--r--sources/shiboken6/libshiboken/sbkversion.h.in46
-rw-r--r--sources/shiboken6/libshiboken/sbkwindows.h17
-rw-r--r--sources/shiboken6/libshiboken/shiboken.h43
-rw-r--r--sources/shiboken6/libshiboken/shibokenbuffer.cpp40
-rw-r--r--sources/shiboken6/libshiboken/shibokenbuffer.h48
-rw-r--r--sources/shiboken6/libshiboken/shibokenmacros.h40
-rw-r--r--sources/shiboken6/libshiboken/signature.h44
-rw-r--r--sources/shiboken6/libshiboken/signature/signature.cpp200
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_doc.rst376
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_extend.cpp160
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_globals.cpp218
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_helper.cpp122
-rw-r--r--sources/shiboken6/libshiboken/signature/signature_p.h107
-rw-r--r--sources/shiboken6/libshiboken/signature_p.h78
-rw-r--r--sources/shiboken6/libshiboken/threadstatesaver.cpp40
-rw-r--r--sources/shiboken6/libshiboken/threadstatesaver.h40
-rw-r--r--sources/shiboken6/libshiboken/voidptr.cpp145
-rw-r--r--sources/shiboken6/libshiboken/voidptr.h42
-rwxr-xr-xsources/shiboken6/shiboken_tool.py51
-rw-r--r--sources/shiboken6/shiboken_version.py50
-rw-r--r--sources/shiboken6/shibokenmodule/CMakeLists.txt40
-rw-r--r--sources/shiboken6/shibokenmodule/Shiboken.pyi60
-rw-r--r--sources/shiboken6/shibokenmodule/__init__.py.in5
-rw-r--r--sources/shiboken6/shibokenmodule/_config.py.in1
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/__init__.py40
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/feature.py114
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/fix-complaints.py47
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/__init__.py40
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py87
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py44
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py66
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py40
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py117
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py121
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py48
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/loader.py96
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py246
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py168
-rw-r--r--sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/qt_attribution.json2
-rw-r--r--sources/shiboken6/shibokenmodule/nothing.h3
-rw-r--r--sources/shiboken6/shibokenmodule/shibokenmodule.cpp119
-rw-r--r--sources/shiboken6/shibokenmodule/typesystem_shiboken.xml126
-rw-r--r--sources/shiboken6/tests/CMakeLists.txt31
-rw-r--r--sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt14
-rw-r--r--sources/shiboken6/tests/dumpcodemodel/main.cpp104
-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.h53
-rw-r--r--sources/shiboken6/tests/libminimal/listuser.cpp98
-rw-r--r--sources/shiboken6/tests/libminimal/listuser.h49
-rw-r--r--sources/shiboken6/tests/libminimal/minbool.h40
-rw-r--r--sources/shiboken6/tests/libminimal/obj.cpp34
-rw-r--r--sources/shiboken6/tests/libminimal/obj.h35
-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/typedef.cpp29
-rw-r--r--sources/shiboken6/tests/libminimal/typedef.h29
-rw-r--r--sources/shiboken6/tests/libminimal/val.h35
-rw-r--r--sources/shiboken6/tests/libother/CMakeLists.txt17
-rw-r--r--sources/shiboken6/tests/libother/extendsnoimplicitconversion.h32
-rw-r--r--sources/shiboken6/tests/libother/libothermacros.h29
-rw-r--r--sources/shiboken6/tests/libother/number.cpp49
-rw-r--r--sources/shiboken6/tests/libother/number.h33
-rw-r--r--sources/shiboken6/tests/libother/otherderived.cpp45
-rw-r--r--sources/shiboken6/tests/libother/otherderived.h45
-rw-r--r--sources/shiboken6/tests/libother/othermultiplederived.cpp40
-rw-r--r--sources/shiboken6/tests/libother/othermultiplederived.h36
-rw-r--r--sources/shiboken6/tests/libother/otherobjecttype.cpp34
-rw-r--r--sources/shiboken6/tests/libother/otherobjecttype.h37
-rw-r--r--sources/shiboken6/tests/libother/othertypesystypedef.cpp29
-rw-r--r--sources/shiboken6/tests/libother/othertypesystypedef.h29
-rw-r--r--sources/shiboken6/tests/libother/smartptrtester.cpp31
-rw-r--r--sources/shiboken6/tests/libother/smartptrtester.h29
-rw-r--r--sources/shiboken6/tests/libsample/CMakeLists.txt140
-rw-r--r--sources/shiboken6/tests/libsample/abstract.cpp100
-rw-r--r--sources/shiboken6/tests/libsample/abstract.h61
-rw-r--r--sources/shiboken6/tests/libsample/blackbox.cpp100
-rw-r--r--sources/shiboken6/tests/libsample/blackbox.h51
-rw-r--r--sources/shiboken6/tests/libsample/bucket.cpp55
-rw-r--r--sources/shiboken6/tests/libsample/bucket.h35
-rw-r--r--sources/shiboken6/tests/libsample/bytearray.cpp146
-rw-r--r--sources/shiboken6/tests/libsample/bytearray.h95
-rw-r--r--sources/shiboken6/tests/libsample/collector.cpp37
-rw-r--r--sources/shiboken6/tests/libsample/collector.h49
-rw-r--r--sources/shiboken6/tests/libsample/complex.cpp44
-rw-r--r--sources/shiboken6/tests/libsample/complex.h39
-rw-r--r--sources/shiboken6/tests/libsample/ctorconvrule.h35
-rw-r--r--sources/shiboken6/tests/libsample/ctparam.cpp29
-rw-r--r--sources/shiboken6/tests/libsample/ctparam.h29
-rw-r--r--sources/shiboken6/tests/libsample/cvlist.h35
-rw-r--r--sources/shiboken6/tests/libsample/derived.cpp79
-rw-r--r--sources/shiboken6/tests/libsample/derived.h51
-rw-r--r--sources/shiboken6/tests/libsample/derivedusingct.cpp29
-rw-r--r--sources/shiboken6/tests/libsample/derivedusingct.h29
-rw-r--r--sources/shiboken6/tests/libsample/echo.cpp29
-rw-r--r--sources/shiboken6/tests/libsample/echo.h79
-rw-r--r--sources/shiboken6/tests/libsample/exceptiontest.cpp36
-rw-r--r--sources/shiboken6/tests/libsample/exceptiontest.h31
-rw-r--r--sources/shiboken6/tests/libsample/expression.cpp112
-rw-r--r--sources/shiboken6/tests/libsample/expression.h58
-rw-r--r--sources/shiboken6/tests/libsample/filter.cpp51
-rw-r--r--sources/shiboken6/tests/libsample/filter.h57
-rw-r--r--sources/shiboken6/tests/libsample/functions.cpp153
-rw-r--r--sources/shiboken6/tests/libsample/functions.h58
-rw-r--r--sources/shiboken6/tests/libsample/handle.cpp37
-rw-r--r--sources/shiboken6/tests/libsample/handle.h61
-rw-r--r--sources/shiboken6/tests/libsample/implicitconv.cpp53
-rw-r--r--sources/shiboken6/tests/libsample/implicitconv.h55
-rw-r--r--sources/shiboken6/tests/libsample/injectcode.cpp62
-rw-r--r--sources/shiboken6/tests/libsample/injectcode.h55
-rw-r--r--sources/shiboken6/tests/libsample/intwrapper.cpp29
-rw-r--r--sources/shiboken6/tests/libsample/intwrapper.h29
-rw-r--r--sources/shiboken6/tests/libsample/libsamplemacros.h29
-rw-r--r--sources/shiboken6/tests/libsample/list.h71
-rw-r--r--sources/shiboken6/tests/libsample/listuser.cpp66
-rw-r--r--sources/shiboken6/tests/libsample/listuser.h49
-rw-r--r--sources/shiboken6/tests/libsample/main.cpp249
-rw-r--r--sources/shiboken6/tests/libsample/mapuser.cpp71
-rw-r--r--sources/shiboken6/tests/libsample/mapuser.h50
-rw-r--r--sources/shiboken6/tests/libsample/modelindex.h58
-rw-r--r--sources/shiboken6/tests/libsample/modifications.cpp139
-rw-r--r--sources/shiboken6/tests/libsample/modifications.h91
-rw-r--r--sources/shiboken6/tests/libsample/modified_constructor.cpp32
-rw-r--r--sources/shiboken6/tests/libsample/modified_constructor.h33
-rw-r--r--sources/shiboken6/tests/libsample/multiple_derived.cpp62
-rw-r--r--sources/shiboken6/tests/libsample/multiple_derived.h163
-rw-r--r--sources/shiboken6/tests/libsample/noimplicitconversion.h38
-rw-r--r--sources/shiboken6/tests/libsample/nondefaultctor.h43
-rw-r--r--sources/shiboken6/tests/libsample/nontypetemplate.h33
-rw-r--r--sources/shiboken6/tests/libsample/null.h37
-rw-r--r--sources/shiboken6/tests/libsample/objectmodel.cpp44
-rw-r--r--sources/shiboken6/tests/libsample/objectmodel.h43
-rw-r--r--sources/shiboken6/tests/libsample/objecttype.cpp162
-rw-r--r--sources/shiboken6/tests/libsample/objecttype.h126
-rw-r--r--sources/shiboken6/tests/libsample/objecttypebyvalue.h49
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeholder.cpp41
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeholder.h41
-rw-r--r--sources/shiboken6/tests/libsample/objecttypelayout.cpp45
-rw-r--r--sources/shiboken6/tests/libsample/objecttypelayout.h42
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeoperators.cpp41
-rw-r--r--sources/shiboken6/tests/libsample/objecttypeoperators.h51
-rw-r--r--sources/shiboken6/tests/libsample/objectview.cpp42
-rw-r--r--sources/shiboken6/tests/libsample/objectview.h45
-rw-r--r--sources/shiboken6/tests/libsample/oddbool.cpp35
-rw-r--r--sources/shiboken6/tests/libsample/oddbool.h62
-rw-r--r--sources/shiboken6/tests/libsample/onlycopy.cpp59
-rw-r--r--sources/shiboken6/tests/libsample/onlycopy.h47
-rw-r--r--sources/shiboken6/tests/libsample/overload.cpp213
-rw-r--r--sources/shiboken6/tests/libsample/overload.h118
-rw-r--r--sources/shiboken6/tests/libsample/overloadsort.cpp64
-rw-r--r--sources/shiboken6/tests/libsample/overloadsort.h81
-rw-r--r--sources/shiboken6/tests/libsample/pairuser.cpp49
-rw-r--r--sources/shiboken6/tests/libsample/pairuser.h41
-rw-r--r--sources/shiboken6/tests/libsample/pen.cpp49
-rw-r--r--sources/shiboken6/tests/libsample/pen.h40
-rw-r--r--sources/shiboken6/tests/libsample/photon.cpp43
-rw-r--r--sources/shiboken6/tests/libsample/photon.h90
-rw-r--r--sources/shiboken6/tests/libsample/point.cpp108
-rw-r--r--sources/shiboken6/tests/libsample/point.h91
-rw-r--r--sources/shiboken6/tests/libsample/pointerholder.h42
-rw-r--r--sources/shiboken6/tests/libsample/pointf.cpp94
-rw-r--r--sources/shiboken6/tests/libsample/pointf.h81
-rw-r--r--sources/shiboken6/tests/libsample/polygon.cpp54
-rw-r--r--sources/shiboken6/tests/libsample/polygon.h45
-rw-r--r--sources/shiboken6/tests/libsample/privatector.h53
-rw-r--r--sources/shiboken6/tests/libsample/privatedtor.h48
-rw-r--r--sources/shiboken6/tests/libsample/protected.cpp38
-rw-r--r--sources/shiboken6/tests/libsample/protected.h114
-rw-r--r--sources/shiboken6/tests/libsample/rect.h82
-rw-r--r--sources/shiboken6/tests/libsample/reference.cpp65
-rw-r--r--sources/shiboken6/tests/libsample/reference.h73
-rw-r--r--sources/shiboken6/tests/libsample/removednamespaces.h30
-rw-r--r--sources/shiboken6/tests/libsample/renaming.cpp29
-rw-r--r--sources/shiboken6/tests/libsample/renaming.h29
-rw-r--r--sources/shiboken6/tests/libsample/sample.cpp31
-rw-r--r--sources/shiboken6/tests/libsample/sample.h33
-rw-r--r--sources/shiboken6/tests/libsample/samplenamespace.cpp110
-rw-r--r--sources/shiboken6/tests/libsample/samplenamespace.h80
-rw-r--r--sources/shiboken6/tests/libsample/sbkdate.cpp29
-rw-r--r--sources/shiboken6/tests/libsample/sbkdate.h32
-rw-r--r--sources/shiboken6/tests/libsample/simplefile.cpp99
-rw-r--r--sources/shiboken6/tests/libsample/simplefile.h48
-rw-r--r--sources/shiboken6/tests/libsample/size.cpp38
-rw-r--r--sources/shiboken6/tests/libsample/size.h105
-rw-r--r--sources/shiboken6/tests/libsample/snakecasetest.cpp29
-rw-r--r--sources/shiboken6/tests/libsample/snakecasetest.h29
-rw-r--r--sources/shiboken6/tests/libsample/sometime.cpp58
-rw-r--r--sources/shiboken6/tests/libsample/sometime.h56
-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.cpp124
-rw-r--r--sources/shiboken6/tests/libsample/str.h62
-rw-r--r--sources/shiboken6/tests/libsample/strlist.cpp35
-rw-r--r--sources/shiboken6/tests/libsample/strlist.h62
-rw-r--r--sources/shiboken6/tests/libsample/templateptr.cpp33
-rw-r--r--sources/shiboken6/tests/libsample/templateptr.h38
-rw-r--r--sources/shiboken6/tests/libsample/transform.cpp65
-rw-r--r--sources/shiboken6/tests/libsample/transform.h43
-rw-r--r--sources/shiboken6/tests/libsample/typesystypedef.cpp29
-rw-r--r--sources/shiboken6/tests/libsample/typesystypedef.h29
-rw-r--r--sources/shiboken6/tests/libsample/valueandvirtual.h42
-rw-r--r--sources/shiboken6/tests/libsample/virtualmethods.cpp43
-rw-r--r--sources/shiboken6/tests/libsample/virtualmethods.h71
-rw-r--r--sources/shiboken6/tests/libsample/voidholder.h46
-rw-r--r--sources/shiboken6/tests/libsmart/CMakeLists.txt14
-rw-r--r--sources/shiboken6/tests/libsmart/libsmartmacros.h29
-rw-r--r--sources/shiboken6/tests/libsmart/smart.cpp157
-rw-r--r--sources/shiboken6/tests/libsmart/smart.h33
-rw-r--r--sources/shiboken6/tests/libsmart/smart_integer.h69
-rw-r--r--sources/shiboken6/tests/libsmart/smart_obj.h47
-rw-r--r--sources/shiboken6/tests/libsmart/smart_registry.h35
-rw-r--r--sources/shiboken6/tests/libsmart/smart_sharedptr.h56
-rw-r--r--sources/shiboken6/tests/libsmart/smart_test.h13
-rw-r--r--sources/shiboken6/tests/libsmart/stdoptionaltestbench.cpp58
-rw-r--r--sources/shiboken6/tests/libsmart/stdoptionaltestbench.h30
-rw-r--r--sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp106
-rw-r--r--sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h49
-rw-r--r--sources/shiboken6/tests/libsmart/stduniqueptrtestbench.cpp133
-rw-r--r--sources/shiboken6/tests/libsmart/stduniqueptrtestbench.h50
-rw-r--r--sources/shiboken6/tests/minimalbinding/CMakeLists.txt23
-rw-r--r--sources/shiboken6/tests/minimalbinding/brace_pattern_test.py49
-rw-r--r--sources/shiboken6/tests/minimalbinding/containeruser_test.py44
-rw-r--r--sources/shiboken6/tests/minimalbinding/global.h31
-rw-r--r--sources/shiboken6/tests/minimalbinding/listuser_test.py92
-rw-r--r--sources/shiboken6/tests/minimalbinding/minbool_test.py53
-rw-r--r--sources/shiboken6/tests/minimalbinding/minimal-binding.txt.in1
-rw-r--r--sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject10
-rw-r--r--sources/shiboken6/tests/minimalbinding/obj_test.py33
-rw-r--r--sources/shiboken6/tests/minimalbinding/spanuser_test.py42
-rw-r--r--sources/shiboken6/tests/minimalbinding/typedef_test.py85
-rw-r--r--sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml85
-rw-r--r--sources/shiboken6/tests/minimalbinding/val_test.py32
-rw-r--r--sources/shiboken6/tests/otherbinding/CMakeLists.txt21
-rw-r--r--sources/shiboken6/tests/otherbinding/collector_external_operator_test.py34
-rw-r--r--sources/shiboken6/tests/otherbinding/conversion_operator_for_class_without_implicit_conversions_test.py59
-rw-r--r--sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py34
-rw-r--r--sources/shiboken6/tests/otherbinding/global.h29
-rw-r--r--sources/shiboken6/tests/otherbinding/module_reload_test.py33
-rw-r--r--sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py44
-rw-r--r--sources/shiboken6/tests/otherbinding/objtypehashes_test.py34
-rw-r--r--sources/shiboken6/tests/otherbinding/other-binding.txt.in2
-rw-r--r--sources/shiboken6/tests/otherbinding/otherbinding.pyproject17
-rw-r--r--sources/shiboken6/tests/otherbinding/otherderived_test.py49
-rw-r--r--sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py34
-rw-r--r--sources/shiboken6/tests/otherbinding/signature_test.py43
-rw-r--r--sources/shiboken6/tests/otherbinding/smartptr_test.py33
-rw-r--r--sources/shiboken6/tests/otherbinding/star_import_test.py99
-rw-r--r--sources/shiboken6/tests/otherbinding/test_module_template.py44
-rw-r--r--sources/shiboken6/tests/otherbinding/typediscovery_test.py58
-rw-r--r--sources/shiboken6/tests/otherbinding/typesystem_other.xml4
-rw-r--r--sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py33
-rw-r--r--sources/shiboken6/tests/otherbinding/wrongctor_test.py41
-rw-r--r--sources/shiboken6/tests/qtxmltosphinx/CMakeLists.txt32
-rw-r--r--sources/shiboken6/tests/qtxmltosphinx/main.cpp115
-rw-r--r--sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt5
-rw-r--r--sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp650
-rw-r--r--sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h32
-rw-r--r--sources/shiboken6/tests/samplebinding/CMakeLists.txt25
-rw-r--r--sources/shiboken6/tests/samplebinding/__del___test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/abstract_test.py42
-rw-r--r--sources/shiboken6/tests/samplebinding/addedfunction_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/argumentmodifications_test.py49
-rw-r--r--sources/shiboken6/tests/samplebinding/array_numpy_test.py40
-rw-r--r--sources/shiboken6/tests/samplebinding/array_sequence_test.py32
-rw-r--r--sources/shiboken6/tests/samplebinding/bug_554_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/bug_704_test.py36
-rw-r--r--sources/shiboken6/tests/samplebinding/bytearray_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/child_return_test.py41
-rw-r--r--sources/shiboken6/tests/samplebinding/class_fields_test.py46
-rw-r--r--sources/shiboken6/tests/samplebinding/collector_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/complex_test.py42
-rw-r--r--sources/shiboken6/tests/samplebinding/conversion_operator_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/copy_test.py32
-rw-r--r--sources/shiboken6/tests/samplebinding/ctorconvrule_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/cyclic_test.py51
-rw-r--r--sources/shiboken6/tests/samplebinding/date_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/decisor_test.py46
-rw-r--r--sources/shiboken6/tests/samplebinding/delete_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/deprecated_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/derived_test.py82
-rw-r--r--sources/shiboken6/tests/samplebinding/duck_punching_test.py44
-rw-r--r--sources/shiboken6/tests/samplebinding/echo_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/enum_test.py92
-rw-r--r--sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py47
-rw-r--r--sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/event_loop_thread_test.py32
-rw-r--r--sources/shiboken6/tests/samplebinding/exception_test.py58
-rw-r--r--sources/shiboken6/tests/samplebinding/filter_test.py31
-rw-r--r--sources/shiboken6/tests/samplebinding/global.h30
-rw-r--r--sources/shiboken6/tests/samplebinding/handleholder_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/hashabletype_test.py36
-rw-r--r--sources/shiboken6/tests/samplebinding/ignorederefop_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/implicitconv_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/injectcode_test.py50
-rw-r--r--sources/shiboken6/tests/samplebinding/innerclass_test.py36
-rw-r--r--sources/shiboken6/tests/samplebinding/intlist_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/intwrapper_test.py40
-rw-r--r--sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/keep_reference_test.py44
-rw-r--r--sources/shiboken6/tests/samplebinding/list_test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/lock_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/map_test.py46
-rw-r--r--sources/shiboken6/tests/samplebinding/metaclass_test.py43
-rw-r--r--sources/shiboken6/tests/samplebinding/mi_virtual_methods_test.py31
-rw-r--r--sources/shiboken6/tests/samplebinding/mixed_mi_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/modelindex_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/modelview_test.py40
-rw-r--r--sources/shiboken6/tests/samplebinding/modifications_test.py73
-rw-r--r--sources/shiboken6/tests/samplebinding/modified_constructor_test.py36
-rw-r--r--sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py46
-rw-r--r--sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py70
-rw-r--r--sources/shiboken6/tests/samplebinding/multiple_derived_test.py74
-rw-r--r--sources/shiboken6/tests/samplebinding/namespace_test.py73
-rw-r--r--sources/shiboken6/tests/samplebinding/newdivision_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/nondefaultctor_test.py40
-rw-r--r--sources/shiboken6/tests/samplebinding/nontypetemplate_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/nonzero_test.py32
-rw-r--r--sources/shiboken6/tests/samplebinding/numericaltypedef_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/numpy_test.py36
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttype_test.py39
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py39
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypebyvalue_test.py32
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypelayout_test.py76
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/oddbool_test.py60
-rw-r--r--sources/shiboken6/tests/samplebinding/onlycopyclass_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/overflow_test.py52
-rw-r--r--sources/shiboken6/tests/samplebinding/overload_sorting_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/overload_test.py43
-rw-r--r--sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py40
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_delete_child_in_cpp_test.py32
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_delete_child_in_python_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py40
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py43
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/ownership_transference_test.py50
-rw-r--r--sources/shiboken6/tests/samplebinding/pair_test.py44
-rw-r--r--sources/shiboken6/tests/samplebinding/pen_test.py32
-rw-r--r--sources/shiboken6/tests/samplebinding/point_test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/pointerholder_test.py39
-rw-r--r--sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py39
-rw-r--r--sources/shiboken6/tests/samplebinding/pointf_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/primitivereferenceargument_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/privatector_test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/privatedtor_test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/protected_test.py141
-rw-r--r--sources/shiboken6/tests/samplebinding/pstrlist_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/pystr_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/python_thread_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/reference_test.py55
-rw-r--r--sources/shiboken6/tests/samplebinding/referencetopointer_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/renaming_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/return_null_test.py37
-rw-r--r--sources/shiboken6/tests/samplebinding/richcompare_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/sample-binding.txt.in1
-rw-r--r--sources/shiboken6/tests/samplebinding/sample_test.py85
-rw-r--r--sources/shiboken6/tests/samplebinding/samplebinding.pyproject131
-rw-r--r--sources/shiboken6/tests/samplebinding/samplesnippets.cpp54
-rw-r--r--sources/shiboken6/tests/samplebinding/simplefile_glue.cpp29
-rw-r--r--sources/shiboken6/tests/samplebinding/simplefile_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/size_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/snakecase_test.py31
-rw-r--r--sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py39
-rw-r--r--sources/shiboken6/tests/samplebinding/stdcomplex_test.py71
-rw-r--r--sources/shiboken6/tests/samplebinding/str_test.py71
-rw-r--r--sources/shiboken6/tests/samplebinding/strlist_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/time_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/transform_test.py33
-rw-r--r--sources/shiboken6/tests/samplebinding/typeconverters_test.py51
-rw-r--r--sources/shiboken6/tests/samplebinding/typedealloc_test.py42
-rw-r--r--sources/shiboken6/tests/samplebinding/typedtordoublefree_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/typesystem_sample.xml243
-rw-r--r--sources/shiboken6/tests/samplebinding/typesystypedef_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/unsafe_parent_test.py35
-rw-r--r--sources/shiboken6/tests/samplebinding/useraddedctor_test.py38
-rw-r--r--sources/shiboken6/tests/samplebinding/virtualdtor_test.py41
-rw-r--r--sources/shiboken6/tests/samplebinding/virtualmethods_test.py45
-rw-r--r--sources/shiboken6/tests/samplebinding/visibilitychange_test.py41
-rw-r--r--sources/shiboken6/tests/samplebinding/voidholder_test.py34
-rw-r--r--sources/shiboken6/tests/samplebinding/weakref_test.py40
-rw-r--r--sources/shiboken6/tests/samplebinding/writableclassdict_test.py37
-rw-r--r--sources/shiboken6/tests/shiboken_paths.py29
-rw-r--r--sources/shiboken6/tests/shiboken_test_helper.py31
-rw-r--r--sources/shiboken6/tests/shibokenmodule/module_test.py55
-rw-r--r--sources/shiboken6/tests/smartbinding/CMakeLists.txt37
-rw-r--r--sources/shiboken6/tests/smartbinding/global.h29
-rw-r--r--sources/shiboken6/tests/smartbinding/smart-binding.txt.in1
-rw-r--r--sources/shiboken6/tests/smartbinding/smart_pointer_test.py189
-rw-r--r--sources/shiboken6/tests/smartbinding/smartbinding.pyproject7
-rw-r--r--sources/shiboken6/tests/smartbinding/std_optional_test.py69
-rw-r--r--sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py87
-rw-r--r--sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py94
-rw-r--r--sources/shiboken6/tests/smartbinding/typesystem_smart.xml60
-rw-r--r--sources/shiboken6/tests/test_generator/CMakeLists.txt5
-rw-r--r--sources/shiboken6/tests/test_generator/dummygenerator.cpp29
-rw-r--r--sources/shiboken6/tests/test_generator/dummygenerator.h29
-rw-r--r--sources/shiboken6/tests/test_generator/dummygentest.cpp34
-rw-r--r--sources/shiboken6/tests/test_generator/dummygentest.h29
-rw-r--r--sources/shiboken6/tests/test_generator/main.cpp29
-rw-r--r--sources/shiboken6/tests/test_generator/run_test.cmake3
788 files changed, 45311 insertions, 44521 deletions
diff --git a/sources/shiboken6/.cmake.conf b/sources/shiboken6/.cmake.conf
new file mode 100644
index 000000000..ecc0a433d
--- /dev/null
+++ b/sources/shiboken6/.cmake.conf
@@ -0,0 +1,5 @@
+set(shiboken_MAJOR_VERSION "6")
+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 37f929531..7aa2fbd11 100644
--- a/sources/shiboken6/ApiExtractor/CMakeLists.txt
+++ b/sources/shiboken6/ApiExtractor/CMakeLists.txt
@@ -1,52 +1,88 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(apiextractor)
-cmake_minimum_required(VERSION 3.16)
-cmake_policy(VERSION 3.16)
+cmake_minimum_required(VERSION 3.18)
+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
-codesniphelpers.cpp
-conditionalstreamreader.cpp
-documentation.cpp
-dotview.cpp
-enclosingclassmixin.cpp
-fileout.cpp
-messages.cpp
-modifications.cpp
-propertyspec.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(Qt${QT_MAJOR_VERSION}Xml 6.0)
find_package(LibXml2 2.6.32)
find_package(LibXslt 1.1.19)
@@ -58,7 +94,7 @@ endif()
if(NOT HAS_LIBXSLT)
set(DISABLE_DOCSTRINGS TRUE)
message(WARNING
- "Documentation will not be built due to missing dependency (no Qt5XmlPatterns found).")
+ "Documentation will not be built due to missing dependency (libxslt not found).")
endif()
# Export to parent scope so that generator/CMakeLists.txt gets it
@@ -69,7 +105,7 @@ target_include_directories(apiextractor PRIVATE ${CLANG_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/parser)
-target_link_libraries(apiextractor PUBLIC Qt${QT_MAJOR_VERSION}::Core)
+target_link_libraries(apiextractor PUBLIC Qt::Core)
target_link_libraries(apiextractor PRIVATE libclang)
if (HAS_LIBXSLT)
@@ -82,17 +118,20 @@ 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 PRIVATE CMAKE_CXX_COMPILER="${CMAKE_CXX_COMPILER}")
+target_compile_definitions(apiextractor
+ PRIVATE CMAKE_CXX_COMPILER="${CMAKE_CXX_COMPILER}"
+ PRIVATE QT_LEAN_HEADERS=1)
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE)
if (BUILD_TESTS)
- find_package(Qt${QT_MAJOR_VERSION}Test 6.0 REQUIRED)
+ find_package(Qt6 REQUIRED COMPONENTS Test)
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests)
enable_testing()
add_subdirectory(tests)
diff --git a/sources/shiboken6/ApiExtractor/abstractmetaargument.cpp b/sources/shiboken6/ApiExtractor/abstractmetaargument.cpp
index 81c6a2273..05cebe10a 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetaargument.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetaargument.cpp
@@ -1,37 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "abstractmetaargument.h"
+#include "abstractmetatype.h"
#include "documentation.h"
+#include "qtcompat.h"
+
#include <QtCore/QDebug>
#include <QtCore/QSharedData>
+using namespace Qt::StringLiterals;
+
class AbstractMetaArgumentData : public QSharedData
{
public:
@@ -58,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
{
@@ -78,6 +58,11 @@ const AbstractMetaType &AbstractMetaArgument::modifiedType() const
return d->m_modifiedType;
}
+bool AbstractMetaArgument::isTypeModified() const
+{
+ return modifiedType() != type();
+}
+
bool AbstractMetaArgument::isModifiedRemoved() const
{
return d->m_modifiedRemoved;
@@ -168,9 +153,9 @@ bool AbstractMetaArgument::hasModifiedDefaultValueExpression() const
QString AbstractMetaArgumentData::toString() const
{
- QString result = m_type.name() + QLatin1Char(' ') + m_name;
+ QString result = m_type.name() + u' ' + m_name;
if (!m_expression.isEmpty())
- result += QLatin1String(" = ") + m_expression;
+ result += u" = "_s + m_expression;
return result;
}
@@ -206,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 fb8ae0fb2..38402e369 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetaargument.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetaargument.h
@@ -1,43 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ABSTRACTMETAARGUMENT_H
#define ABSTRACTMETAARGUMENT_H
-#include "abstractmetalang_typedefs.h"
-#include "abstractmetatype.h"
-#include "typesystem_enums.h"
-#include "typesystem_typedefs.h"
-
#include <QtCore/QSharedDataPointer>
QT_FORWARD_DECLARE_CLASS(QDebug)
+class AbstractMetaType;
class AbstractMetaArgumentData;
class Documentation;
@@ -48,15 +19,14 @@ 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);
void setModifiedType(const AbstractMetaType &type);
const AbstractMetaType &modifiedType() const;
- bool isTypeModified() const { return modifiedType() != type(); }
+ bool isTypeModified() const;
bool isModifiedRemoved() const;
void setModifiedRemoved(bool v);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
index 92ffe054d..f07fb96c6 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
@@ -1,43 +1,34 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "abstractmetabuilder_p.h"
+#include "abstractmetaargument.h"
#include "abstractmetaenum.h"
#include "abstractmetafield.h"
#include "abstractmetafunction.h"
+#include "abstractmetatype.h"
+#include "addedfunction.h"
#include "graph.h"
+#include "debughelpers_p.h"
#include "exception.h"
#include "messages.h"
#include "propertyspec.h"
#include "reporthandler.h"
#include "sourcelocation.h"
#include "typedatabase.h"
-#include "typesystem.h"
+#include "enumtypeentry.h"
+#include "enumvaluetypeentry.h"
+#include "arraytypeentry.h"
+#include "constantvaluetypeentry.h"
+#include "containertypeentry.h"
+#include "flagstypeentry.h"
+#include "functiontypeentry.h"
+#include "namespacetypeentry.h"
+#include "primitivetypeentry.h"
+#include "smartpointertypeentry.h"
+#include "templateargumententry.h"
+#include "typedefentry.h"
+#include "typesystemtypeentry.h"
#include "usingmember.h"
#include "parser/codemodel.h"
@@ -46,10 +37,13 @@
#include <clangparser/clangutils.h>
#include <clangparser/compilersupport.h>
+#include "qtcompat.h"
+
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
+#include <QtCore/QMetaObject>
#include <QtCore/QQueue>
#include <QtCore/QRegularExpression>
#include <QtCore/QTemporaryFile>
@@ -59,11 +53,11 @@
#include <algorithm>
#include <memory>
-static inline QString colonColon() { return QStringLiteral("::"); }
+using namespace Qt::StringLiterals;
static QString stripTemplateArgs(const QString &name)
{
- int pos = name.indexOf(QLatin1Char('<'));
+ const auto pos = name.indexOf(u'<');
return pos < 0 ? name : name.left(pos);
}
@@ -73,18 +67,37 @@ static void fixArgumentIndexes(AbstractMetaArgumentList *list)
(*list)[i].setArgumentIndex(i);
}
-bool AbstractMetaBuilderPrivate::m_useGlobalHeader = false;
+bool operator<(const RejectEntry &re1, const RejectEntry &re2)
+{
+ return re1.reason != re2.reason
+ ? (re1.reason < re2.reason) : (re1.sortkey < re2.sortkey);
+}
-AbstractMetaBuilderPrivate::AbstractMetaBuilderPrivate() :
- m_logDirectory(QLatin1String(".") + QDir::separator())
+QTextStream &operator<<(QTextStream &str, const RejectEntry &re)
+{
+ str << re.signature;
+ if (!re.message.isEmpty())
+ str << ": " << re.message;
+ return str;
+}
+
+static void applyCachedFunctionModifications(const AbstractMetaFunctionPtr &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());
+ }
}
-AbstractMetaBuilderPrivate::~AbstractMetaBuilderPrivate()
+bool AbstractMetaBuilderPrivate::m_useGlobalHeader = false;
+bool AbstractMetaBuilderPrivate::m_codeModelTestMode = false;
+
+AbstractMetaBuilderPrivate::AbstractMetaBuilderPrivate() :
+ m_logDirectory(u"."_s + QDir::separator())
{
- qDeleteAll(m_templates);
- qDeleteAll(m_smartPointers);
- qDeleteAll(m_metaClasses);
}
AbstractMetaBuilder::AbstractMetaBuilder() : d(new AbstractMetaBuilderPrivate)
@@ -102,16 +115,37 @@ const AbstractMetaClassList &AbstractMetaBuilder::classes() const
return d->m_metaClasses;
}
+AbstractMetaClassList AbstractMetaBuilder::takeClasses()
+{
+ AbstractMetaClassList result;
+ qSwap(result, d->m_metaClasses);
+ return result;
+}
+
const AbstractMetaClassList &AbstractMetaBuilder::templates() const
{
return d->m_templates;
}
+AbstractMetaClassList AbstractMetaBuilder::takeTemplates()
+{
+ AbstractMetaClassList result;
+ qSwap(result, d->m_templates);
+ return result;
+}
+
const AbstractMetaClassList &AbstractMetaBuilder::smartPointers() const
{
return d->m_smartPointers;
}
+AbstractMetaClassList AbstractMetaBuilder::takeSmartPointers()
+{
+ AbstractMetaClassList result;
+ qSwap(result, d->m_smartPointers);
+ return result;
+}
+
const AbstractMetaFunctionCList &AbstractMetaBuilder::globalFunctions() const
{
return d->m_globalFunctions;
@@ -122,36 +156,41 @@ const AbstractMetaEnumList &AbstractMetaBuilder::globalEnums() const
return d->m_globalEnums;
}
-const QHash<const TypeEntry *, AbstractMetaEnum> &AbstractMetaBuilder::typeEntryToEnumsHash() const
+const QHash<TypeEntryCPtr, AbstractMetaEnum> &AbstractMetaBuilder::typeEntryToEnumsHash() const
{
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) {
- const TypeEntry *entry = it.value();
+ TypeEntryCPtr entry = it.value();
if (!entry)
continue;
if (!entry->isComplex() || !entry->generateCode())
continue;
- auto centry = static_cast<const ComplexTypeEntry *>(entry);
+ auto centry = std::static_pointer_cast<const ComplexTypeEntry>(entry);
if (!centry->generateCode())
continue;
FunctionModificationList modifications = centry->functionModifications();
- for (const FunctionModification &modification : qAsConst(modifications)) {
+ for (const FunctionModification &modification : std::as_const(modifications)) {
QString signature = modification.signature();
QString name = signature.trimmed();
- name.truncate(name.indexOf(QLatin1Char('(')));
+ name.truncate(name.indexOf(u'('));
- AbstractMetaClass *clazz = AbstractMetaClass::findClass(m_metaClasses, centry);
+ const auto clazz = AbstractMetaClass::findClass(m_metaClasses, centry);
if (!clazz)
continue;
@@ -159,13 +198,14 @@ void AbstractMetaBuilderPrivate::checkFunctionModifications()
QStringList possibleSignatures;
for (const auto &function : clazz->functions()) {
if (function->implementingClass() == clazz
- && modification.matches(function->minimalSignature())) {
+ && modification.matches(function->modificationSignatures())) {
found = true;
break;
}
if (function->originalName() == name) {
- possibleSignatures.append(function->minimalSignature() + QLatin1String(" in ")
+ const QString signatures = function->modificationSignatures().join(u'/');
+ possibleSignatures.append(signatures + u" in "_s
+ function->implementingClass()->name());
}
}
@@ -180,14 +220,14 @@ 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;
- const TypeEntry *entry = type->typeEntry();
+ TypeEntryCPtr entry = type->typeEntry();
if (entry && entry->isComplex())
returned = AbstractMetaClass::findClass(m_metaClasses, entry);
return returned;
@@ -197,18 +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) {
- if (AbstractMetaClass *cls = argumentToClass(arguments.at(0), currentClass))
- cls->setHasHashFunction(true);
+ if (arguments.size() >= 1) { // (Class, Hash seed).
+ if (AbstractMetaClassPtr cls = argumentToClass(arguments.at(0), currentClass))
+ cls->setHashFunction(function_item->name());
}
}
void AbstractMetaBuilderPrivate::registerToStringCapabilityIn(const NamespaceModelItem &nsItem)
{
- const FunctionList &streamOps = nsItem->findFunctions(QLatin1String("operator<<"));
+ const FunctionList &streamOps = nsItem->findFunctions("operator<<");
for (const FunctionModelItem &item : streamOps)
registerToStringCapability(item, nullptr);
for (const NamespaceModelItem &ni : nsItem->namespaces())
@@ -220,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() == QLatin1String("QDebug")) {
+ 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()));
}
@@ -235,27 +277,27 @@ void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelI
}
void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelItem &item,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
if (item->accessPolicy() != Access::Public)
return;
- ArgumentList arguments = item->arguments();
+ const ArgumentList &itemArguments = item->arguments();
bool firstArgumentIsSelf = true;
bool unaryOperator = false;
- auto baseoperandClass = argumentToClass(arguments.at(0), currentClass);
+ auto baseoperandClass = argumentToClass(itemArguments.at(0), currentClass);
- if (arguments.size() == 1) {
+ if (itemArguments.size() == 1) {
unaryOperator = true;
} else if (!baseoperandClass
|| !baseoperandClass->typeEntry()->generateCode()) {
- baseoperandClass = argumentToClass(arguments.at(1), currentClass);
+ baseoperandClass = argumentToClass(itemArguments.at(1), currentClass);
firstArgumentIsSelf = false;
} else {
auto type = translateType(item->type(), currentClass);
- const TypeEntry *retType = type.has_value() ? type->typeEntry() : nullptr;
- AbstractMetaClass *otherArgClass = argumentToClass(arguments.at(1), currentClass);
+ const auto retType = type.has_value() ? type->typeEntry() : TypeEntryCPtr{};
+ const auto otherArgClass = argumentToClass(itemArguments.at(1), currentClass);
if (otherArgClass && retType
&& (retType->isValue() || retType->isObject())
&& retType != baseoperandClass->typeEntry()
@@ -264,43 +306,60 @@ void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelIte
firstArgumentIsSelf = false;
}
}
+ if (!baseoperandClass) {
+ rejectFunction(item, currentClass, AbstractMetaBuilder::UnmatchedOperator,
+ u"base operand class not found."_s);
+ return;
+ }
- if (baseoperandClass) {
- AbstractMetaFunction *metaFunction = traverseFunction(item, baseoperandClass);
- if (metaFunction) {
- // Strip away first argument, since that is the containing object
- AbstractMetaArgumentList arguments = metaFunction->arguments();
- if (firstArgumentIsSelf || unaryOperator) {
- AbstractMetaArgument first = arguments.takeFirst();
- fixArgumentIndexes(&arguments);
- if (!unaryOperator && first.type().indirections())
- metaFunction->setPointerOperator(true);
- metaFunction->setArguments(arguments);
- } else {
- // If the operator method is not unary and the first operator is
- // not of the same type of its owning class we suppose that it
- // must be an reverse operator (e.g. CLASS::operator(TYPE, CLASS)).
- // All operator overloads that operate over a class are already
- // being added as member functions of that class by the API Extractor.
- AbstractMetaArgument last = arguments.takeLast();
- if (last.type().indirections())
- metaFunction->setPointerOperator(true);
-
- metaFunction->setArguments(arguments);
- metaFunction->setReverseOperator(true);
- }
- metaFunction->setAccess(Access::Public);
- setupFunctionDefaults(metaFunction, baseoperandClass);
- baseoperandClass->addFunction(AbstractMetaFunctionCPtr(metaFunction));
- Q_ASSERT(!metaFunction->wasPrivate());
- } else {
- delete metaFunction;
- }
+ if (item->isSpaceshipOperator() && !item->isDeleted()) {
+ AbstractMetaClass::addSynthesizedComparisonOperators(baseoperandClass);
+ return;
}
+
+ auto metaFunction = traverseFunction(item, baseoperandClass);
+ if (metaFunction == nullptr)
+ return;
+
+ auto flags = metaFunction->flags();
+ // Strip away first argument, since that is the containing object
+ AbstractMetaArgumentList arguments = metaFunction->arguments();
+ if (firstArgumentIsSelf || unaryOperator) {
+ AbstractMetaArgument first = arguments.takeFirst();
+ fixArgumentIndexes(&arguments);
+ if (!unaryOperator && first.type().indirections())
+ metaFunction->setPointerOperator(true);
+ metaFunction->setArguments(arguments);
+ flags.setFlag(AbstractMetaFunction::Flag::OperatorLeadingClassArgumentRemoved);
+ if (first.type().passByValue())
+ flags.setFlag(AbstractMetaFunction::Flag::OperatorClassArgumentByValue);
+ } else {
+ // If the operator method is not unary and the first operator is
+ // not of the same type of its owning class we suppose that it
+ // must be an reverse operator (e.g. CLASS::operator(TYPE, CLASS)).
+ // All operator overloads that operate over a class are already
+ // being added as member functions of that class by the API Extractor.
+ AbstractMetaArgument last = arguments.takeLast();
+ if (last.type().indirections())
+ metaFunction->setPointerOperator(true);
+ metaFunction->setArguments(arguments);
+ metaFunction->setReverseOperator(true);
+ flags.setFlag(AbstractMetaFunction::Flag::OperatorTrailingClassArgumentRemoved);
+ if (last.type().passByValue())
+ flags.setFlag(AbstractMetaFunction::Flag::OperatorClassArgumentByValue);
+ }
+ metaFunction->setFlags(flags);
+ metaFunction->setAccess(Access::Public);
+ AbstractMetaClass::addFunction(baseoperandClass, metaFunction);
+ if (!metaFunction->arguments().isEmpty()) {
+ const auto include = metaFunction->arguments().constFirst().type().typeEntry()->include();
+ baseoperandClass->typeEntry()->addArgumentInclude(include);
+ }
+ Q_ASSERT(!metaFunction->wasPrivate());
}
bool AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem &item,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
ArgumentList itemArguments = item->arguments();
if (itemArguments.size() != 2 || item->accessPolicy() != Access::Public)
@@ -312,7 +371,7 @@ bool AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem
if (streamedClass == nullptr)
return false;
- AbstractMetaFunction *streamFunction = traverseFunction(item, streamedClass);
+ auto streamFunction = traverseFunction(item, streamedClass);
if (!streamFunction)
return false;
@@ -327,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();
@@ -343,19 +401,19 @@ bool AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem
funcClass = streamClass;
}
- setupFunctionDefaults(streamFunction, funcClass);
- funcClass->addFunction(AbstractMetaFunctionCPtr(streamFunction));
+ AbstractMetaClass::addFunction(funcClass, streamFunction);
+ auto funcTe = funcClass->typeEntry();
if (funcClass == streamClass)
- funcClass->typeEntry()->addExtraInclude(streamedClass->typeEntry()->include());
+ funcTe->addArgumentInclude(streamedClass->typeEntry()->include());
else
- funcClass->typeEntry()->addExtraInclude(streamClass->typeEntry()->include());
+ funcTe->addArgumentInclude(streamClass->typeEntry()->include());
return true;
}
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)
@@ -368,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, QStringLiteral("QObject"))) {
- if (auto qMetaObjectClass = AbstractMetaClass::findClass(m_metaClasses, QStringLiteral("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;
@@ -378,7 +436,7 @@ void AbstractMetaBuilderPrivate::sortLists()
}
m_metaClasses = classesTopologicalSorted(m_metaClasses, additionalDependencies);
- for (AbstractMetaClass *cls : qAsConst(m_metaClasses))
+ for (const auto &cls : std::as_const(m_metaClasses))
cls->sortFunctions();
// Ensure that indexes are in alphabetical order, roughly, except
@@ -395,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();
@@ -403,15 +461,15 @@ 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 int diagnosticsCount = diagnostics.size()) {
+ if (const auto diagnosticsCount = diagnostics.size()) {
QDebug d = qWarning();
d.nospace();
d.noquote();
d << "Clang: " << diagnosticsCount << " diagnostic messages:\n";
- for (int i = 0; i < diagnosticsCount; ++i)
+ for (qsizetype i = 0; i < diagnosticsCount; ++i)
d << " " << diagnostics.at(i) << '\n';
}
return result;
@@ -422,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;
@@ -433,7 +491,8 @@ static QStringList functionCandidates(const AbstractMetaFunctionCList &list,
return result;
}
-void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
+void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
+ ApiExtractorFlags flags)
{
const TypeDatabase *types = TypeDatabase::instance();
@@ -442,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()) {
@@ -463,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();
@@ -489,32 +548,31 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
// Global functions
const FunctionList &functions = dom->functions();
for (const FunctionModelItem &func : functions) {
- if (func->accessPolicy() != Access::Public || func->name().startsWith(QLatin1String("operator")))
+ if (func->accessPolicy() != Access::Public || func->name().startsWith(u"operator"))
continue;
- FunctionTypeEntry *funcEntry = types->findFunctionType(func->name());
+ FunctionTypeEntryPtr funcEntry = types->findFunctionType(func->name());
if (!funcEntry || !funcEntry->generateCode())
continue;
- AbstractMetaFunction *metaFunc = traverseFunction(func, nullptr);
- if (!metaFunc)
+ auto metaFuncPtr = traverseFunction(func, nullptr);
+ if (!metaFuncPtr)
continue;
- AbstractMetaFunctionCPtr metaFuncPtr(metaFunc);
- if (!funcEntry->hasSignature(metaFunc->minimalSignature()))
+ if (!funcEntry->hasSignature(metaFuncPtr->minimalSignature()))
continue;
- metaFunc->setTypeEntry(funcEntry);
- applyFunctionModifications(metaFunc);
- metaFunc->applyTypeModifications();
+ metaFuncPtr->setTypeEntry(funcEntry);
+ applyFunctionModifications(metaFuncPtr);
+ metaFuncPtr->applyTypeModifications();
setInclude(funcEntry, func->fileName());
m_globalFunctions << metaFuncPtr;
}
- ReportHandler::startProgress("Fixing class inheritance...");
- for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) {
+ ReportHandler::startProgress("Fixed class inheritance.");
+ for (const auto &cls : std::as_const(m_metaClasses)) {
if (cls->needsInheritanceSetup()) {
setupInheritance(cls);
traverseUsingMembers(cls);
@@ -526,26 +584,28 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
}
}
- ReportHandler::startProgress("Detecting inconsistencies in class model...");
- for (AbstractMetaClass *cls : qAsConst(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 vco = AbstractMetaClass::determineValueTypeWithCopyConstructorOnly(cls);
+ const bool avoidProtectedHack = flags.testFlag(ApiExtractorFlag::AvoidProtectedHack);
+ const bool vco =
+ AbstractMetaClass::determineValueTypeWithCopyConstructorOnly(cls, avoidProtectedHack);
cls->setValueTypeWithCopyConstructorOnly(vco);
cls->typeEntry()->setValueTypeWithCopyConstructorOnly(vco);
}
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) {
- TypeEntry *entry = it.value();
+ const TypeEntryPtr &entry = it.value();
if (!entry->isPrimitive()) {
if ((entry->isValue() || entry->isObject())
&& !types->shouldDropTypeEntry(entry->qualifiedCppName())
@@ -555,11 +615,11 @@ 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 = static_cast<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;
- for (const auto &func : qAsConst(m_globalFunctions)) {
+ for (const auto &func : std::as_const(m_globalFunctions)) {
if (signature == func->minimalSignature()) {
ok = true;
break;
@@ -573,9 +633,9 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
}
}
} else if (entry->isEnum() && entry->generateCode()) {
- auto enumEntry = static_cast<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()
@@ -592,7 +652,7 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
}
{
- const FunctionList &hashFunctions = dom->findFunctions(QLatin1String("qHash"));
+ const FunctionList &hashFunctions = dom->findFunctions("qHash");
for (const FunctionModelItem &item : hashFunctions)
registerHashFunction(item, nullptr);
}
@@ -615,16 +675,15 @@ 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 : qAsConst(m_metaClasses)) {
+ for (const auto &cls : std::as_const(m_metaClasses)) {
// setupEquals(cls);
// setupComparable(cls);
- setupClonable(cls);
setupExternalConversion(cls);
// sort all inner classes topologically
@@ -634,6 +693,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
cls->setInnerClasses(classesTopologicalSorted(cls->innerClasses()));
}
+ fixSmartPointers();
+
dumpLog();
sortLists();
@@ -646,25 +707,29 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
throw Exception(errorMessage);
}
- m_itemToClass.clear();
- m_classToItem.clear();
- m_typeSystemTypeDefs.clear();
+ if (!m_codeModelTestMode) {
+ m_itemToClass.clear();
+ m_classToItem.clear();
+ m_typeSystemTypeDefs.clear();
+ m_scopes.clear();
+ }
ReportHandler::endProgress();
}
bool AbstractMetaBuilder::build(const QByteArrayList &arguments,
+ ApiExtractorFlags apiExtractorFlags,
bool addCompilerSupportArguments,
LanguageLevel level,
unsigned clangFlags)
{
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();
- d->traverseDom(dom);
+ qCDebug(lcShiboken) << dom.get();
+ d->traverseDom(dom, apiExtractorFlags);
return true;
}
@@ -676,7 +741,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);
@@ -690,23 +755,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;
}
@@ -716,22 +785,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());
@@ -740,11 +809,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());
}
}
@@ -752,20 +821,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.get()); // Add for enum lookup.
+ m_itemToClass.insert(ni.get(), mjc);
}
}
@@ -779,16 +850,16 @@ 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);
- TypeEntry *typeEntry = nullptr;
- const TypeEntry *enclosingTypeEntry = enclosing ? enclosing->typeEntry() : nullptr;
+ TypeEntryPtr typeEntry;
+ const auto enclosingTypeEntry = enclosing ? enclosing->typeEntry() : TypeEntryCPtr{};
if (enumItem->accessPolicy() == Access::Private) {
- typeEntry = new EnumTypeEntry(enumItem->qualifiedName().constLast(),
- QVersionNumber(0, 0), enclosingTypeEntry);
+ typeEntry.reset(new EnumTypeEntry(enumItem->qualifiedName().constLast(),
+ QVersionNumber(0, 0), enclosingTypeEntry));
TypeDatabase::instance()->addType(typeEntry);
} else if (enumItem->enumKind() != AnonymousEnum) {
typeEntry = TypeDatabase::instance()->findType(qualifiedName);
@@ -798,7 +869,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;
@@ -815,65 +886,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 = static_cast<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.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) {
- auto 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);
@@ -885,9 +966,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());
@@ -896,16 +999,16 @@ 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
// we store the aliased type on the alias
// TypeEntry
- PrimitiveTypeEntry *ptype = types->findPrimitiveType(className);
+ const auto ptype = types->findPrimitiveType(className);
const auto &targetNames = typeDef->type().qualifiedName();
- PrimitiveTypeEntry *pTarget = targetNames.size() == 1
- ? types->findPrimitiveType(targetNames.constFirst()) : nullptr;
+ const auto pTarget = targetNames.size() == 1
+ ? types->findPrimitiveType(targetNames.constFirst()) : PrimitiveTypeEntryPtr{};
if (ptype) {
ptype->setReferencedTypeEntry(pTarget);
return nullptr;
@@ -913,9 +1016,10 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelIt
// It is a (nested?) global typedef to a primitive type
// (like size_t = unsigned)? Add it to the type DB.
- if (pTarget && pTarget->basicReferencedNonBuiltinTypeEntry()->isCppPrimitive()
+ if (pTarget && isCppPrimitive(basicReferencedNonBuiltinTypeEntry(pTarget))
&& currentClass == nullptr) {
- auto *pte = new PrimitiveTypeEntry(className, {}, nullptr);
+ auto pte = std::make_shared<PrimitiveTypeEntry>(className, QVersionNumber{},
+ TypeEntryCPtr{});
pte->setReferencedTypeEntry(pTarget);
pte->setBuiltIn(true);
types->addType(pte);
@@ -923,11 +1027,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelIt
}
// If we haven't specified anything for the typedef, then we don't care
- ComplexTypeEntry *type = types->findComplexType(fullClassName);
+ auto type = types->findComplexType(fullClassName);
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()));
@@ -946,8 +1050,8 @@ void AbstractMetaBuilderPrivate::traverseTypesystemTypedefs()
{
const auto &entries = TypeDatabase::instance()->typedefEntries();
for (auto it = entries.begin(), end = entries.end(); it != end; ++it) {
- TypedefEntry *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()));
@@ -973,9 +1077,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;
@@ -983,20 +1087,24 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
// we have inner an class
if (currentClass) {
fullClassName = stripTemplateArgs(currentClass->typeEntry()->qualifiedCppName())
- + colonColon() + fullClassName;
+ + u"::"_s + fullClassName;
}
- ComplexTypeEntry *type = TypeDatabase::instance()->findComplexType(fullClassName);
+ const auto type = TypeDatabase::instance()->findComplexType(fullClassName);
AbstractMetaBuilder::RejectReason reason = AbstractMetaBuilder::NoReason;
if (TypeDatabase::instance()->isClassRejected(fullClassName)) {
reason = AbstractMetaBuilder::GenerationDisabled;
} else if (!type) {
- TypeEntry *te = TypeDatabase::instance()->findType(fullClassName);
- if (te && !te->isComplex())
+ TypeEntryPtr te = TypeDatabase::instance()->findType(fullClassName);
+ if (te && !te->isComplex()) {
reason = AbstractMetaBuilder::RedefinedToNotClass;
- else
+ // Set the default include file name
+ if (!te->include().isValid())
+ setInclude(te, classItem->fileName());
+ } else {
reason = AbstractMetaBuilder::NotInTypeSystem;
+ }
} else if (type->codeGeneration() == TypeEntry::GenerateNothing) {
reason = AbstractMetaBuilder::GenerationDisabled;
}
@@ -1005,11 +1113,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)
@@ -1018,6 +1126,9 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
if (classItem->isFinal())
*metaClass += AbstractMetaClass::FinalCppClass;
+ if (classItem->classType() == CodeModel::Struct)
+ *metaClass += AbstractMetaClass::Struct;
+
QStringList baseClassNames;
const QList<_ClassModelItem::BaseClass> &baseClasses = classItem->baseClasses();
for (const _ClassModelItem::BaseClass &baseClass : baseClasses) {
@@ -1031,21 +1142,22 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
if (ReportHandler::isDebug(ReportHandler::MediumDebug)) {
const QString message = type->isContainer()
- ? u"container: '"_qs + fullClassName + u'\''
- : u"class: '"_qs + metaClass->fullName() + u'\'';
+ ? u"container: '"_s + fullClassName + u'\''
+ : u"class: '"_s + metaClass->fullName() + u'\'';
qCInfo(lcShiboken, "%s", qPrintable(message));
}
TemplateParameterList template_parameters = classItem->templateParameters();
- TypeEntries template_args;
+ TypeEntryCList template_args;
template_args.clear();
- auto argumentParent = metaClass->typeEntry()->typeSystemTypeEntry();
- for (int i = 0; i < template_parameters.size(); ++i) {
+ 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(param_type);
+ template_args.append(TypeEntryCPtr(param_type));
}
metaClass->setTemplateArguments(template_args);
@@ -1057,11 +1169,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());
}
}
@@ -1071,10 +1183,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());
}
}
@@ -1086,7 +1198,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
}
void AbstractMetaBuilderPrivate::traverseScopeMembers(const ScopeModelItem &item,
- AbstractMetaClass *metaClass)
+ const AbstractMetaClassPtr &metaClass)
{
// Classes/Namespace members
traverseFields(item, metaClass);
@@ -1100,28 +1212,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});
@@ -1135,7 +1244,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;
@@ -1150,18 +1259,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();
@@ -1175,8 +1284,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 {};
}
@@ -1189,7 +1299,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)));
@@ -1224,7 +1334,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) {
@@ -1237,37 +1347,22 @@ void AbstractMetaBuilderPrivate::traverseFields(const ScopeModelItem &scope_item
}
}
-void AbstractMetaBuilderPrivate::setupFunctionDefaults(AbstractMetaFunction *metaFunction,
- AbstractMetaClass *metaClass)
-{
- // Set the default value of the declaring class. This may be changed
- // in fixFunctions later on
- metaFunction->setDeclaringClass(metaClass);
-
- // Some of the queries below depend on the implementing class being set
- // to function properly. Such as function modifications
- metaFunction->setImplementingClass(metaClass);
-
- if (metaFunction->name() == QLatin1String("operator_equal"))
- metaClass->setHasEqualsOperator(true);
-}
-
-void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaFunction *metaFunction)
+void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(const AbstractMetaFunctionPtr &metaFunction)
{
if (!metaFunction->isConversionOperator())
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();
- if (castTo.endsWith(QLatin1Char('&')))
+ if (castTo.endsWith(u'&'))
castTo.chop(1);
- if (castTo.startsWith(QLatin1String("const ")))
+ if (castTo.startsWith(u"const "))
castTo.remove(0, 6);
- TypeEntry *retType = types->findType(castTo);
+ TypeEntryPtr retType = types->findType(castTo);
if (!retType)
return;
@@ -1276,19 +1371,25 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF
metaFunction->setType(metaType);
}
-AbstractMetaFunctionRawPtrList
+AbstractMetaFunctionList
AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem,
AbstractMetaClass::Attributes *constructorAttributes,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
*constructorAttributes = {};
- AbstractMetaFunctionRawPtrList result;
+ AbstractMetaFunctionList result;
const FunctionList &scopeFunctionList = scopeItem->functions();
result.reserve(scopeFunctionList.size());
+ const bool isNamespace = currentClass->isNamespace();
for (const FunctionModelItem &function : scopeFunctionList) {
- if (AbstractMetaFunction *metaFunction = traverseFunction(function, currentClass)) {
+ if (isNamespace && function->isOperator()) {
+ traverseOperatorFunction(function, currentClass);
+ } else if (function->isSpaceshipOperator() && !function->isDeleted()) {
+ if (currentClass)
+ AbstractMetaClass::addSynthesizedComparisonOperators(currentClass);
+ } else if (auto metaFunction = traverseFunction(function, currentClass)) {
result.append(metaFunction);
- } else if (function->functionType() == CodeModel::Constructor) {
+ } else if (!function->isDeleted() && function->functionType() == CodeModel::Constructor) {
auto arguments = function->arguments();
*constructorAttributes |= AbstractMetaClass::HasRejectedConstructor;
if (arguments.isEmpty() || arguments.constFirst()->defaultValue())
@@ -1298,17 +1399,17 @@ 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 =
+ const AbstractMetaFunctionList functions =
classFunctionList(scopeItem, &constructorAttributes, metaClass);
metaClass->setAttributes(metaClass->attributes() | constructorAttributes);
- for (AbstractMetaFunction *metaFunction : functions) {
+ for (const auto &metaFunction : functions) {
if (metaClass->isNamespace())
- *metaFunction += AbstractMetaFunction::Static;
+ metaFunction->setCppAttribute(FunctionAttribute::Static);
const auto propertyFunction = metaClass->searchPropertyFunction(metaFunction->name());
if (propertyFunction.index >= 0) {
@@ -1341,50 +1442,44 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
metaFunction->setPropertySpecIndex(propertyFunction.index);
}
break;
+ case AbstractMetaClass::PropertyFunction::Notify:
+ if (metaFunction->isSignal()) {
+ *metaFunction += AbstractMetaFunction::PropertyNotify;
+ metaFunction->setPropertySpecIndex(propertyFunction.index);
+ }
}
}
- 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)) {
- setupFunctionDefaults(metaFunction, metaClass);
-
- if (metaFunction->isSignal() && metaClass->hasSignal(metaFunction))
- qCWarning(lcShiboken, "%s", qPrintable(msgSignalOverloaded(metaClass, metaFunction)));
+ if (metaFunction->isSignal() && metaClass->hasSignal(metaFunction.get()))
+ qCWarning(lcShiboken, "%s", qPrintable(msgSignalOverloaded(metaClass,
+ metaFunction.get())));
if (metaFunction->isConversionOperator())
fixReturnTypeOfConversionOperator(metaFunction);
- metaClass->addFunction(AbstractMetaFunctionCPtr(metaFunction));
+ AbstractMetaClass::addFunction(metaClass, metaFunction);
applyFunctionModifications(metaFunction);
} else if (metaFunction->isDestructor()) {
metaClass->setHasPrivateDestructor(metaFunction->isPrivate());
metaClass->setHasProtectedDestructor(metaFunction->isProtected());
metaClass->setHasVirtualDestructor(metaFunction->isVirtual());
}
- if (!metaFunction->ownerClass()) {
- delete metaFunction;
- metaFunction = nullptr;
- }
}
fillAddedFunctions(metaClass);
}
-void AbstractMetaBuilderPrivate::fillAddedFunctions(AbstractMetaClass *metaClass)
+void AbstractMetaBuilderPrivate::fillAddedFunctions(const AbstractMetaClassPtr &metaClass)
{
// Add the functions added by the typesystem
QString errorMessage;
@@ -1397,12 +1492,12 @@ void AbstractMetaBuilderPrivate::fillAddedFunctions(AbstractMetaClass *metaClass
QString AbstractMetaBuilder::getSnakeCaseName(const QString &name)
{
- const int size = name.size();
+ const auto size = name.size();
if (size < 3)
return name;
QString result;
result.reserve(size + 4);
- for (int i = 0; i < size; ++i) {
+ for (qsizetype i = 0; i < size; ++i) {
const QChar c = name.at(i);
if (c.isUpper()) {
if (i > 0) {
@@ -1440,7 +1535,7 @@ QStringList AbstractMetaBuilder::definitionNames(const QString &name,
return result;
}
-void AbstractMetaBuilderPrivate::applyFunctionModifications(AbstractMetaFunction *func)
+void AbstractMetaBuilderPrivate::applyFunctionModifications(const AbstractMetaFunctionPtr &func)
{
AbstractMetaFunction& funcRef = *func;
for (const FunctionModification &mod : func->modifications(func->implementingClass())) {
@@ -1448,26 +1543,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;
@@ -1477,13 +1563,15 @@ bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
QStringList baseClasses = metaClass->baseClassNames();
// we only support our own containers and ONLY if there is only one baseclass
- if (baseClasses.size() == 1 && baseClasses.constFirst().contains(QLatin1Char('<'))) {
+ if (baseClasses.size() == 1 && baseClasses.constFirst().contains(u'<')) {
TypeInfo info;
- ComplexTypeEntry* baseContainerType;
- AbstractMetaClass* templ = findTemplateClass(baseClasses.constFirst(), metaClass, &info, &baseContainerType);
+ ComplexTypeEntryPtr 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;
}
@@ -1500,15 +1588,15 @@ 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;
}
- TypeDatabase* types = TypeDatabase::instance();
+ auto *types = TypeDatabase::instance();
- for (const auto &baseClassName : baseClasses) {
+ for (const auto &baseClassName : baseClasses) {
if (!types->isClassRejected(baseClassName)) {
auto typeEntry = types->findType(baseClassName);
if (typeEntry == nullptr || !typeEntry->isComplex()) {
@@ -1537,7 +1625,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));
}
@@ -1547,7 +1635,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();
@@ -1585,17 +1673,16 @@ static AbstractMetaFunction::FunctionType functionTypeFromName(const QString &);
bool AbstractMetaBuilderPrivate::traverseAddedGlobalFunction(const AddedFunctionPtr &addedFunc,
QString *errorMessage)
{
- AbstractMetaFunction *metaFunction =
- traverseAddedFunctionHelper(addedFunc, nullptr, errorMessage);
+ auto metaFunction = traverseAddedFunctionHelper(addedFunc, nullptr, errorMessage);
if (metaFunction == nullptr)
return false;
- m_globalFunctions << AbstractMetaFunctionCPtr(metaFunction);
+ m_globalFunctions << metaFunction;
return true;
}
-AbstractMetaFunction *
+AbstractMetaFunctionPtr
AbstractMetaBuilderPrivate::traverseAddedFunctionHelper(const AddedFunctionPtr &addedFunc,
- AbstractMetaClass *metaClass /* = nullptr */,
+ const AbstractMetaClassPtr &metaClass /* = {} */,
QString *errorMessage)
{
auto returnType = translateType(addedFunc->returnType(), metaClass, {}, errorMessage);
@@ -1604,16 +1691,16 @@ AbstractMetaFunction *
msgAddedFunctionInvalidReturnType(addedFunc->name(),
addedFunc->returnType().qualifiedName(),
*errorMessage, metaClass);
- return nullptr;
+ return {};
}
- auto metaFunction = new AbstractMetaFunction(addedFunc);
+ auto metaFunction = std::make_shared<AbstractMetaFunction>(addedFunc);
metaFunction->setType(returnType.value());
metaFunction->setFunctionType(functionTypeFromName(addedFunc->name()));
const auto &args = addedFunc->arguments();
- qsizetype argCount = args.count();
+ qsizetype argCount = args.size();
// Check "foo(void)"
if (argCount == 1 && args.constFirst().typeInfo.isVoid())
argCount = 0;
@@ -1625,8 +1712,7 @@ AbstractMetaFunction *
msgAddedFunctionInvalidArgType(addedFunc->name(),
arg.typeInfo.qualifiedName(), i + 1,
*errorMessage, metaClass);
- delete metaFunction;
- return nullptr;
+ return {};
}
type->decideUsagePattern();
@@ -1664,7 +1750,8 @@ AbstractMetaFunction *
// Find the correct default values
const FunctionModificationList functionMods = metaFunction->modifications(metaClass);
- for (int i = 0; i < metaArguments.size(); ++i) {
+ applyCachedFunctionModifications(metaFunction, functionMods);
+ for (qsizetype i = 0; i < metaArguments.size(); ++i) {
AbstractMetaArgument &metaArg = metaArguments[i];
// use replace-default-expression for set default value
@@ -1679,21 +1766,20 @@ AbstractMetaFunction *
}
bool AbstractMetaBuilderPrivate::traverseAddedMemberFunction(const AddedFunctionPtr &addedFunc,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
QString *errorMessage)
{
- AbstractMetaFunction *metaFunction =
- traverseAddedFunctionHelper(addedFunc, metaClass, errorMessage);
+ auto metaFunction = traverseAddedFunctionHelper(addedFunc, metaClass, errorMessage);
if (metaFunction == nullptr)
return false;
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) {
- const TypeEntry *te = fargs.constFirst().type().typeEntry();
+ const auto te = fargs.constFirst().type().typeEntry();
if (te->isCustom())
metaFunction->setExplicit(true);
if (te->name() == metaFunction->name())
@@ -1703,12 +1789,13 @@ bool AbstractMetaBuilderPrivate::traverseAddedMemberFunction(const AddedFunction
metaFunction->setDeclaringClass(metaClass);
metaFunction->setImplementingClass(metaClass);
- metaClass->addFunction(AbstractMetaFunctionCPtr(metaFunction));
+ AbstractMetaClass::addFunction(metaClass, metaFunction);
metaClass->setHasNonPrivateConstructor(true);
return true;
}
-void AbstractMetaBuilderPrivate::fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods)
+void AbstractMetaBuilderPrivate::fixArgumentNames(const AbstractMetaFunctionPtr &func,
+ const FunctionModificationList &mods)
{
AbstractMetaArgumentList &arguments = func->arguments();
@@ -1719,9 +1806,9 @@ void AbstractMetaBuilderPrivate::fixArgumentNames(AbstractMetaFunction *func, co
}
}
- for (int i = 0, size = arguments.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = arguments.size(); i < size; ++i) {
if (arguments.at(i).name().isEmpty())
- arguments[i].setName(QLatin1String("arg__") + QString::number(i + 1), false);
+ arguments[i].setName(u"arg__"_s + QString::number(i + 1), false);
}
}
@@ -1731,15 +1818,15 @@ static QString functionSignature(const FunctionModelItem &functionItem)
const ArgumentList &arguments = functionItem->arguments();
for (const ArgumentModelItem &arg : arguments)
args << arg->type().toString();
- return functionItem->name() + QLatin1Char('(') + args.join(QLatin1Char(',')) + QLatin1Char(')');
+ return functionItem->name() + u'(' + args.join(u',') + u')';
}
static inline QString qualifiedFunctionSignatureWithType(const FunctionModelItem &functionItem,
const QString &className = QString())
{
- QString result = functionItem->type().toString() + QLatin1Char(' ');
+ QString result = functionItem->type().toString() + u' ';
if (!className.isEmpty())
- result += className + colonColon();
+ result += className + u"::"_s;
result += functionSignature(functionItem);
return result;
}
@@ -1827,7 +1914,7 @@ static AbstractMetaFunction::FunctionType functionTypeFromName(const QString &na
// Apply the <array> modifications of the arguments
static bool applyArrayArgumentModifications(const FunctionModificationList &functionMods,
- AbstractMetaFunction *func,
+ const AbstractMetaFunctionPtr &func,
QString *errorMessage)
{
for (const FunctionModification &mod : functionMods) {
@@ -1836,7 +1923,7 @@ static bool applyArrayArgumentModifications(const FunctionModificationList &func
const int i = argMod.index() - 1;
if (i < 0 || i >= func->arguments().size()) {
*errorMessage = msgCannotSetArrayUsage(func->minimalSignature(), i,
- QLatin1String("Index out of range."));
+ u"Index out of range."_s);
return false;
}
auto t = func->arguments().at(i).type();
@@ -1851,11 +1938,51 @@ static bool applyArrayArgumentModifications(const FunctionModificationList &func
return true;
}
-AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem,
- AbstractMetaClass *currentClass)
+// 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});
+}
+
+AbstractMetaFunctionPtr
+ AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem,
+ const AbstractMetaClassPtr &currentClass)
+{
+ const auto *tdb = TypeDatabase::instance();
+
if (!functionItem->templateParameters().isEmpty())
- return nullptr;
+ return {};
if (functionItem->isDeleted()) {
switch (functionItem->functionType()) {
@@ -1869,87 +1996,76 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
default:
break;
}
- return nullptr;
+ return {};
}
- QString functionName = functionItem->name();
- QString className;
- if (currentClass) {
+ const QString &functionName = functionItem->name();
+ const QString className = currentClass != nullptr ?
+ currentClass->typeEntry()->qualifiedCppName() : QString{};
+
+ if (m_apiExtractorFlags.testFlag(ApiExtractorFlag::UsePySideExtensions)) {
+ // Skip enum helpers generated by Q_ENUM
+ if ((currentClass == nullptr || currentClass->isNamespace())
+ && (functionName == u"qt_getEnumMetaObject" || functionName == u"qt_getEnumName")) {
+ return {};
+ }
+
// Clang: Skip qt_metacast(), qt_metacall(), expanded from Q_OBJECT
// and overridden metaObject(), QGADGET helpers
- if (functionName == QLatin1String("qt_check_for_QGADGET_macro")
- || functionName.startsWith(QLatin1String("qt_meta"))) {
- return nullptr;
+ if (currentClass != nullptr) {
+ if (functionName == u"qt_check_for_QGADGET_macro"
+ || functionName.startsWith(u"qt_meta")) {
+ return {};
+ }
+ if (functionName == u"metaObject" && className != u"QObject")
+ return {};
}
- className = currentClass->typeEntry()->qualifiedCppName();
- if (functionName == QLatin1String("metaObject") && className != QLatin1String("QObject"))
- return nullptr;
- }
-
- // Store original signature with unresolved typedefs for message/log purposes
- const QString originalQualifiedSignatureWithReturn =
- qualifiedFunctionSignatureWithType(functionItem, className);
+ } // PySide extensions
QString rejectReason;
- if (TypeDatabase::instance()->isFunctionRejected(className, functionName, &rejectReason)) {
- m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled);
- return nullptr;
+ if (tdb->isFunctionRejected(className, functionName, &rejectReason)) {
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, rejectReason);
+ return {};
}
- 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));
}
- return nullptr;
+ return {};
}
if (functionItem->isFriend())
- return nullptr;
+ return {};
- 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 + QLatin1String(" is deprecated."),
- AbstractMetaBuilder::GenerationDisabled);
- return nullptr;
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, u" is deprecated."_s);
+ return {};
}
- auto *metaFunction = new AbstractMetaFunction;
+ AbstractMetaFunction::Flags flags;
+ auto metaFunction = std::make_shared<AbstractMetaFunction>(functionName);
+ metaFunction->setCppAttributes(cppAttributes);
+ const QByteArray cSignature = signature.toUtf8();
+ const QString unresolvedSignature =
+ QString::fromUtf8(QMetaObject::normalizedSignature(cSignature.constData()));
+ metaFunction->setUnresolvedSignature(unresolvedSignature);
+ 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());
- metaFunction->setName(functionName);
- metaFunction->setOriginalName(functionItem->name());
-
- 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());
@@ -1959,27 +2075,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);
- delete metaFunction;
- return nullptr;
+ if (tdb->isReturnTypeRejected(className, returnType.toString(), &rejectReason)) {
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, rejectReason);
+ return {};
}
- 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);
- delete metaFunction;
- return nullptr;
+ qPrintable(msgSkippingFunction(functionItem, signature, reason)));
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::UnmatchedReturnType, reason);
+ return {};
}
metaFunction->setType(type.value());
@@ -1988,43 +2107,56 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
}
ArgumentList arguments = functionItem->arguments();
+ // Add private signals for documentation purposes
+ if (!arguments.isEmpty()
+ && m_apiExtractorFlags.testFlag(ApiExtractorFlag::UsePySideExtensions)
+ && functionItem->functionType() == CodeModel::Signal
+ && arguments.constLast()->type().qualifiedName().constLast() == u"QPrivateSignal") {
+ flags.setFlag(AbstractMetaFunction::Flag::PrivateSignal);
+ arguments.removeLast();
+ }
if (arguments.size() == 1) {
ArgumentModelItem arg = arguments.at(0);
TypeInfo type = arg->type();
- if (type.qualifiedName().constFirst() == QLatin1String("void") && type.indirections() == 0)
+ if (type.qualifiedName().constFirst() == u"void" && type.indirections() == 0)
arguments.pop_front();
}
- for (int i = 0; i < arguments.size(); ++i) {
+ 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);
- delete metaFunction;
- return nullptr;
+ if (tdb->isArgumentTypeRejected(className, arg->type().toString(), &rejectReason)) {
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, rejectReason);
+ return {};
}
- 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
- + QLatin1String(": ") + reason;
- m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedArgumentType);
- delete metaFunction;
- return nullptr;
+ qPrintable(msgSkippingFunction(functionItem, signature, reason)));
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::UnmatchedArgumentType, reason);
+ return {};
}
auto metaType = metaTypeO.value();
@@ -2033,10 +2165,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;
@@ -2049,23 +2179,18 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
AbstractMetaArgumentList &metaArguments = metaFunction->arguments();
const FunctionModificationList functionMods = currentClass
- ? AbstractMetaFunction::findClassModifications(metaFunction, currentClass)
- : AbstractMetaFunction::findGlobalModifications(metaFunction);
+ ? AbstractMetaFunction::findClassModifications(metaFunction.get(), currentClass)
+ : AbstractMetaFunction::findGlobalModifications(metaFunction.get());
- for (const FunctionModification &mod : functionMods) {
- if (mod.exceptionHandling() != TypeSystem::ExceptionHandling::Unspecified)
- metaFunction->setExceptionHandlingModification(mod.exceptionHandling());
- else if (mod.allowThread() != TypeSystem::AllowThread::Unspecified)
- metaFunction->setAllowThreadModification(mod.allowThread());
- }
+ applyCachedFunctionModifications(metaFunction, functionMods);
// Find the correct default values
- for (int i = 0, size = metaArguments.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = metaArguments.size(); i < size; ++i) {
const ArgumentModelItem &arg = arguments.at(i);
AbstractMetaArgument &metaArg = metaArguments[i];
const QString originalDefaultExpression =
- fixDefaultValue(arg, metaArg.type(), currentClass, i);
+ fixDefaultValue(arg->defaultValueExpression(), metaArg.type(), currentClass);
metaArg.setOriginalDefaultValueExpression(originalDefaultExpression);
metaArg.setDefaultValueExpression(originalDefaultExpression);
@@ -2080,7 +2205,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
&& metaFunction->argumentName(i + 1, false, currentClass).isEmpty()) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnnamedArgumentDefaultExpression(currentClass, i + 1,
- className, metaFunction)));
+ className, metaFunction.get())));
}
}
@@ -2098,7 +2223,7 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
if (currentClass && metaFunction->arguments().size() == 1) {
const AbstractMetaType &argType = metaFunction->arguments().constFirst().type();
if (argType.typeEntry() == currentClass->typeEntry() && argType.indirections() == 0) {
- if (metaFunction->name() == QLatin1String("operator=")) {
+ if (metaFunction->name() == u"operator=") {
switch (argType.referenceType()) {
case NoReference:
metaFunction->setFunctionType(AbstractMetaFunction::AssignmentOperatorFunction);
@@ -2114,35 +2239,39 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
}
}
}
+ metaFunction->setFlags(flags);
return metaFunction;
}
-static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaClass, const QString& qualifiedName)
+static TypeEntryCPtr findTypeEntryUsingContext(const AbstractMetaClassCPtr &metaClass,
+ const QString& qualifiedName)
{
- const TypeEntry* type = nullptr;
- QStringList context = metaClass->qualifiedCppName().split(colonColon());
+ TypeEntryCPtr type;
+ 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;
}
// Helper for findTypeEntries/translateTypeStatic()
-TypeEntries AbstractMetaBuilderPrivate::findTypeEntriesHelper(const QString &qualifiedName,
- const QString &name,
- const AbstractMetaClass *currentClass,
- AbstractMetaBuilderPrivate *d)
+TypeEntryCList AbstractMetaBuilderPrivate::findTypeEntriesHelper(const QString &qualifiedName,
+ const QString &name,
+ 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 AbstractMetaClassList &baseClasses = d->getBaseClasses(currentClass);
- for (const AbstractMetaClass *cls : baseClasses) {
+ const auto &baseClasses = d->getBaseClasses(currentClass);
+ for (const auto &cls : baseClasses) {
if (auto type = findTypeEntryUsingContext(cls, qualifiedName))
return {type};
}
@@ -2166,7 +2295,7 @@ TypeEntries AbstractMetaBuilderPrivate::findTypeEntriesHelper(const QString &qua
// of the parameters.
if (currentClass) {
const auto &template_args = currentClass->templateArguments();
- for (const TypeEntry *te : template_args) {
+ for (const auto &te : template_args) {
if (te->name() == qualifiedName)
return {te};
}
@@ -2176,13 +2305,15 @@ TypeEntries AbstractMetaBuilderPrivate::findTypeEntriesHelper(const QString &qua
// Helper for translateTypeStatic() that calls findTypeEntriesHelper()
// and does some error checking.
-TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualifiedName,
- const QString &name,
- const AbstractMetaClass *currentClass,
- AbstractMetaBuilderPrivate *d,
- QString *errorMessage)
-{
- TypeEntries types = findTypeEntriesHelper(qualifiedName, name, currentClass, d);
+TypeEntryCList AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualifiedName,
+ const QString &name,
+ TranslateTypeFlags flags,
+ const AbstractMetaClassCPtr &currentClass,
+ AbstractMetaBuilderPrivate *d,
+ QString *errorMessage)
+{
+ TypeEntryCList types = findTypeEntriesHelper(qualifiedName, name, flags,
+ currentClass, d);
if (types.isEmpty()) {
if (errorMessage != nullptr)
*errorMessage = msgCannotFindTypeEntry(qualifiedName);
@@ -2192,9 +2323,11 @@ TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualified
// Resolve entries added by metabuilder (for example, "GLenum") to match
// the signatures for modifications.
for (qsizetype i = 0, size = types.size(); i < size; ++i) {
- const auto *e = types.at(i);
- if (e->isPrimitive())
- types[i] = e->asPrimitive()->basicReferencedNonBuiltinTypeEntry();
+ const auto &e = types.at(i);
+ if (e->isPrimitive()) {
+ const auto pte = std::static_pointer_cast<const PrimitiveTypeEntry>(e);
+ types[i] = basicReferencedNonBuiltinTypeEntry(pte);
+ }
}
if (types.size() == 1)
@@ -2202,7 +2335,7 @@ TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualified
const auto typeEntryType = types.constFirst()->type();
const bool sameType = std::all_of(types.cbegin() + 1, types.cend(),
- [typeEntryType](const TypeEntry *e) {
+ [typeEntryType](const TypeEntryCPtr &e) {
return e->type() == typeEntryType;
});
@@ -2225,10 +2358,10 @@ TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualified
// 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;
@@ -2236,9 +2369,194 @@ const AbstractMetaClass *AbstractMetaBuilderPrivate::resolveTypeSystemTypeDef(co
return nullptr;
}
+// The below helpers and AbstractMetaBuilderPrivate::fixSmartPointers()
+// synthesize missing smart pointer functions and classes. For example for
+// std::shared_ptr, the full class declaration or base classes from
+// internal, compiler-dependent STL implementation headers might not be exposed
+// to the parser unless those headers are specified as <system-include>.
+
+static void synthesizeWarning(const AbstractMetaFunctionCPtr &f)
+{
+ qCWarning(lcShiboken, "Synthesizing \"%s\"...",
+ qPrintable(f->classQualifiedSignature()));
+}
+
+static AbstractMetaFunctionPtr
+ addMethod(const AbstractMetaClassPtr &s, const AbstractMetaType &returnType,
+ const QString &name, bool isConst = true)
+{
+ auto function = std::make_shared<AbstractMetaFunction>(name);
+ function->setType(returnType);
+ AbstractMetaClass::addFunction(s, function);
+ function->setConstant(isConst);
+ synthesizeWarning(function);
+ return function;
+}
+
+static AbstractMetaFunctionPtr
+ addMethod(const AbstractMetaClassPtr &s, const QString &returnTypeName,
+ const QString &name, bool isConst = true)
+{
+ auto typeEntry = TypeDatabase::instance()->findPrimitiveType(returnTypeName);
+ 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 AbstractMetaClassCPtr &s,
+ const SmartPointerTypeEntryCPtr &ste)
+{
+ AbstractMetaType type(s->templateArguments().constFirst());
+ if (ste->smartPointerType() != TypeSystem::SmartPointerType::ValueHandle)
+ type.addIndirection();
+ type.decideUsagePattern();
+ return type;
+}
+
+// Create the pointee argument of a smart pointer constructor or reset()
+static AbstractMetaArgument pointeeArgument(const AbstractMetaClassCPtr &s,
+ const SmartPointerTypeEntryCPtr &ste)
+{
+ AbstractMetaArgument pointee;
+ pointee.setType(instantiationType(s, ste));
+ pointee.setName(u"pointee"_s);
+ return pointee;
+}
+
+// Add the smart pointer constructors. For MSVC, (when not specifying
+// <system-header>), clang only sees the default constructor.
+static void fixSmartPointerConstructors(const AbstractMetaClassPtr &s,
+ const SmartPointerTypeEntryCPtr &ste)
+{
+ const auto ctors = s->queryFunctions(FunctionQueryOption::Constructors);
+ bool seenDefaultConstructor = false;
+ bool seenParameter = false;
+ for (const auto &ctor : ctors) {
+ if (ctor->arguments().isEmpty())
+ seenDefaultConstructor = true;
+ else
+ seenParameter = true;
+ }
+
+ if (!seenParameter) {
+ auto constructor = std::make_shared<AbstractMetaFunction>(s->name());
+ constructor->setFunctionType(AbstractMetaFunction::ConstructorFunction);
+ constructor->addArgument(pointeeArgument(s, ste));
+ AbstractMetaClass::addFunction(s, constructor);
+ synthesizeWarning(constructor);
+ }
+
+ if (!seenDefaultConstructor) {
+ auto constructor = std::make_shared<AbstractMetaFunction>(s->name());
+ constructor->setFunctionType(AbstractMetaFunction::ConstructorFunction);
+ AbstractMetaClass::addFunction(s, constructor);
+ synthesizeWarning(constructor);
+ }
+}
+
+// Similarly, add the smart pointer reset() functions
+static void fixSmartPointerReset(const AbstractMetaClassPtr &s,
+ const SmartPointerTypeEntryCPtr &ste)
+{
+ const QString resetMethodName = ste->resetMethod();
+ const auto functions = s->findFunctions(resetMethodName);
+ bool seenParameterLess = false;
+ bool seenParameter = false;
+ for (const auto &function : functions) {
+ if (function->arguments().isEmpty())
+ seenParameterLess = true;
+ else
+ seenParameter = true;
+ }
+
+ if (!seenParameter) {
+ auto f = std::make_shared<AbstractMetaFunction>(resetMethodName);
+ f->addArgument(pointeeArgument(s, ste));
+ AbstractMetaClass::addFunction(s, f);
+ synthesizeWarning(f);
+ }
+
+ if (!seenParameterLess) {
+ auto f = std::make_shared<AbstractMetaFunction>(resetMethodName);
+ AbstractMetaClass::addFunction(s, f);
+ synthesizeWarning(f);
+ }
+}
+
+// Add the relevant missing smart pointer functions.
+static void fixSmartPointerClass(const AbstractMetaClassPtr &s,
+ const SmartPointerTypeEntryCPtr &ste)
+{
+ fixSmartPointerConstructors(s, ste);
+
+ if (!ste->resetMethod().isEmpty())
+ fixSmartPointerReset(s, ste);
+
+ const QString getterName = ste->getter();
+ if (!s->findFunction(getterName))
+ addMethod(s, instantiationType(s, ste), getterName);
+
+ const QString refCountName = ste->refCountMethodName();
+ if (!refCountName.isEmpty() && !s->findFunction(refCountName))
+ addMethod(s, u"int"_s, refCountName);
+
+ const QString valueCheckMethod = ste->valueCheckMethod();
+ 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))
+ addMethod(s, u"bool"_s, nullCheckMethod);
+}
+
+// Create a missing smart pointer class
+static AbstractMetaClassPtr createSmartPointerClass(const SmartPointerTypeEntryCPtr &ste,
+ const AbstractMetaClassList &allClasses)
+{
+ 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()) {
+ const auto enclosing = AbstractMetaClass::findClass(allClasses, enclosingTe);
+ if (!enclosing)
+ throw Exception(msgEnclosingClassNotFound(ste));
+ result->setEnclosingClass(enclosing);
+ auto inner = enclosing->innerClasses();
+ inner.append(std::const_pointer_cast<const AbstractMetaClass>(result));
+ enclosing->setInnerClasses(inner);
+ }
+ return result;
+}
+
+void AbstractMetaBuilderPrivate::fixSmartPointers()
+{
+ const auto smartPointerTypes = TypeDatabase::instance()->smartPointerTypes();
+ for (const auto &ste : smartPointerTypes) {
+ const auto smartPointerClass =
+ AbstractMetaClass::findClass(m_smartPointers, ste);
+ if (smartPointerClass) {
+ fixSmartPointerClass(std::const_pointer_cast<AbstractMetaClass>(smartPointerClass),
+ ste);
+ } else {
+ qCWarning(lcShiboken, "Synthesizing smart pointer \"%s\"...",
+ qPrintable(ste->qualifiedCppName()));
+ m_smartPointers.append(createSmartPointerClass(ste, m_metaClasses));
+ }
+ }
+}
+
std::optional<AbstractMetaType>
AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei,
- const AbstractMetaClass *currentClass,
+ const AbstractMetaClassCPtr &currentClass,
TranslateTypeFlags flags,
QString *errorMessage)
{
@@ -2251,9 +2569,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)
@@ -2280,10 +2605,10 @@ std::optional<AbstractMetaType>
// the global scope when they are referenced from inside a namespace.
// This is a work around to fix this bug since fixing it in resolveType
// seemed non-trivial
- int i = d ? d->m_scopes.size() - 1 : -1;
+ 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;
}
@@ -2291,7 +2616,7 @@ std::optional<AbstractMetaType>
if (typeInfo.isFunctionPointer()) {
if (errorMessageIn)
- *errorMessageIn = msgUnableToTranslateType(_typei, QLatin1String("Unsupported function pointer."));
+ *errorMessageIn = msgUnableToTranslateType(_typei, u"Unsupported function pointer."_s);
return {};
}
@@ -2307,7 +2632,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
@@ -2331,13 +2656,13 @@ std::optional<AbstractMetaType>
auto elementType = translateTypeStatic(newInfo, currentClass, d, flags, &errorMessage);
if (!elementType.has_value()) {
if (errorMessageIn) {
- errorMessage.prepend(QLatin1String("Unable to translate array element: "));
+ errorMessage.prepend(u"Unable to translate array element: "_s);
*errorMessageIn = msgUnableToTranslateType(_typei, errorMessage);
}
return {};
}
- for (int i = typeInfo.arrayElements().size() - 1; i >= 0; --i) {
+ for (auto i = typeInfo.arrayElements().size() - 1; i >= 0; --i) {
AbstractMetaType arrayType;
arrayType.setArrayElementType(elementType.value());
const QString &arrayElement = typeInfo.arrayElements().at(i);
@@ -2350,8 +2675,9 @@ std::optional<AbstractMetaType>
arrayType.setArrayElementCount(int(elems));
}
auto elementTypeEntry = elementType->typeEntry();
- arrayType.setTypeEntry(new ArrayTypeEntry(elementTypeEntry, elementTypeEntry->version(),
- elementTypeEntry->parent()));
+ auto at = std::make_shared<ArrayTypeEntry>(elementTypeEntry, elementTypeEntry->version(),
+ elementTypeEntry->parent());
+ arrayType.setTypeEntry(at);
arrayType.decideUsagePattern();
elementType = arrayType;
@@ -2362,7 +2688,7 @@ std::optional<AbstractMetaType>
QStringList qualifierList = typeInfo.qualifiedName();
if (qualifierList.isEmpty()) {
- errorMessage = msgUnableToTranslateType(_typei, QLatin1String("horribly broken type"));
+ errorMessage = msgUnableToTranslateType(_typei, u"horribly broken type"_s);
if (errorMessageIn)
*errorMessageIn = errorMessage;
else
@@ -2370,23 +2696,32 @@ 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)
- if (qualifiedName == QLatin1String("QFlags")) {
+ if (qualifiedName == u"QFlags") {
qualifiedName = typeInfo.toString();
typeInfo.clearInstantiations();
}
- const TypeEntries 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);
return {};
}
- const TypeEntry *type = types.constFirst();
+ TypeEntryCPtr type = types.constFirst();
const TypeEntry::Type typeEntryType = type->type();
AbstractMetaType metaType;
@@ -2397,15 +2732,18 @@ std::optional<AbstractMetaType>
metaType.setOriginalTypeDescription(_typei.toString());
const auto &templateArguments = typeInfo.instantiations();
- for (int t = 0, size = templateArguments.size(); t < size; ++t) {
+ 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)) {
- TypeDatabase::instance()->addConstantValueTypeEntry(value, type->typeSystemTypeEntry());
+ auto module = typeSystemTypeEntry(type);
+ TypeDatabase::instance()->addConstantValueTypeEntry(value, module);
targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage);
}
}
@@ -2431,8 +2769,8 @@ std::optional<AbstractMetaType>
type = instantiationType;
} else {
auto it = std::find_if(types.cbegin(), types.cend(),
- [instantiationType](const TypeEntry *e) {
- auto smartPtr = static_cast<const SmartPointerTypeEntry *>(e);
+ [instantiationType](const TypeEntryCPtr &e) {
+ auto smartPtr = std::static_pointer_cast<const SmartPointerTypeEntry>(e);
return smartPtr->matchesInstantiation(instantiationType);
});
if (it == types.cend()) {
@@ -2466,7 +2804,7 @@ std::optional<AbstractMetaType>
std::optional<AbstractMetaType>
AbstractMetaBuilder::translateType(const TypeInfo &_typei,
- AbstractMetaClass *currentClass,
+ const AbstractMetaClassPtr &currentClass,
TranslateTypeFlags flags,
QString *errorMessage)
{
@@ -2477,7 +2815,7 @@ std::optional<AbstractMetaType>
std::optional<AbstractMetaType>
AbstractMetaBuilder::translateType(const QString &t,
- AbstractMetaClass *currentClass,
+ const AbstractMetaClassPtr &currentClass,
TranslateTypeFlags flags,
QString *errorMessageIn)
{
@@ -2500,14 +2838,14 @@ qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringV
if (ok)
return value;
- if (stringValue == QLatin1String("true") || stringValue == QLatin1String("false")) {
+ if (stringValue == u"true" || stringValue == u"false") {
ok = true;
- return (stringValue == QLatin1String("true"));
+ return (stringValue == u"true");
}
// 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;
@@ -2520,7 +2858,7 @@ qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringV
return enumValue->value().value();
}
- for (const AbstractMetaEnum &metaEnum : qAsConst(m_globalEnums)) {
+ for (const AbstractMetaEnum &metaEnum : std::as_const(m_globalEnums)) {
auto ev = metaEnum.findEnumValue(stringValue);
if (ev.has_value()) {
ok = true;
@@ -2532,111 +2870,163 @@ qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringV
return 0;
}
+// Return whether candidate is some underqualified specification of qualifiedType
+// ("B::C" should be qualified to "A::B::C")
+static bool isUnderQualifiedSpec(QStringView qualifiedType, QStringView candidate)
+{
+ const auto candidateSize = candidate.size();
+ const auto qualifiedTypeSize = qualifiedType.size();
+ return candidateSize < qualifiedTypeSize
+ && qualifiedType.endsWith(candidate)
+ && qualifiedType.at(qualifiedTypeSize - candidateSize - 1) == u':';
+}
+
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);
}
-QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &item,
- const AbstractMetaType &type,
- const AbstractMetaClass *implementingClass,
- int /* argumentIndex */) const
+void AbstractMetaBuilder::setCodeModelTestMode(bool b)
{
- QString expr = item->defaultValueExpression();
- if (expr.isEmpty() || expr == u"{}" || expr == u"nullptr" || expr == u"NULL")
- return expr;
+ AbstractMetaBuilderPrivate::m_codeModelTestMode = b;
+}
+
+// Helper to fix a simple default value (field or enum reference) in a
+// class context.
+QString AbstractMetaBuilderPrivate::fixSimpleDefaultValue(QStringView expr,
+ const AbstractMetaClassCPtr &klass) const
+{
+ const QString field = qualifyStaticField(klass, expr);
+ if (!field.isEmpty())
+ return field;
+ const auto cit = m_classToItem.constFind(klass);
+ if (cit == m_classToItem.cend())
+ return {};
+ auto *scope = dynamic_cast<const _ScopeModelItem *>(cit.value());
+ if (!scope)
+ return {};
+ if (auto enumValue = scope->findEnumByValue(expr))
+ return enumValue.qualifiedName;
+ return {};
+}
+
+// see TestResolveType::testFixDefaultArguments()
+QString AbstractMetaBuilderPrivate::fixDefaultValue(QString expr, const AbstractMetaType &type,
+ const AbstractMetaClassCPtr &implementingClass) const
+{
expr.replace(u'\n', u' '); // breaks signature parser
- if (type.isPrimitive()) {
- if (type.name() == QLatin1String("boolean")) {
- if (expr != QLatin1String("false") && expr != QLatin1String("true")) {
- bool ok = false;
- int number = expr.toInt(&ok);
- if (ok && number)
- expr = QLatin1String("true");
- else
- expr = QLatin1String("false");
- }
- } else {
- // This can be an enum or flag so I need to delay the
- // translation until all namespaces are completely
- // processed. This is done in figureOutEnumValues()
- }
- } else if (type.isFlags() || type.isEnum()) {
- expr = fixEnumDefault(type, expr);
- } else if (type.isContainer() && expr.contains(QLatin1Char('<'))) {
- static const QRegularExpression typeRegEx(QStringLiteral("[^<]*<(.*)>"));
- Q_ASSERT(typeRegEx.isValid());
- const QRegularExpressionMatch typeMatch = typeRegEx.match(type.minimalSignature());
- static const QRegularExpression defaultRegEx(QLatin1String("([^<]*<).*(>[^>]*)"));
- Q_ASSERT(defaultRegEx.isValid());
- const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr);
- if (typeMatch.hasMatch() && defaultMatch.hasMatch())
- expr = defaultMatch.captured(1) + typeMatch.captured(1) + defaultMatch.captured(2);
+ if (AbstractMetaBuilder::dontFixDefaultValue(expr))
+ return expr;
+
+ if (type.isFlags() || type.isEnum()) {
+ 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>()"
+ if (type.instantiations().size() != 1)
+ return expr; // Only simple types are handled, not QMap<int, int>.
+ auto innerTypeEntry = type.instantiations().constFirst().typeEntry();
+ if (!innerTypeEntry->isComplex())
+ return expr;
+ const QString &qualifiedInnerTypeName = innerTypeEntry->qualifiedCppName();
+ if (!qualifiedInnerTypeName.contains(u"::")) // Nothing to qualify here
+ return expr;
+ const auto openPos = expr.indexOf(u'<');
+ const auto closingPos = expr.lastIndexOf(u'>');
+ if (openPos == -1 || closingPos == -1)
+ return expr;
+ const auto innerPos = openPos + 1;
+ const auto innerLen = closingPos - innerPos;
+ const auto innerType = QStringView{expr}.mid(innerPos, innerLen).trimmed();
+ if (isUnderQualifiedSpec(qualifiedInnerTypeName, innerType))
+ expr.replace(innerPos, innerLen, qualifiedInnerTypeName);
} else {
- // Here the default value is supposed to be a constructor,
- // a class field, or a constructor receiving a class field
- static const QRegularExpression defaultRegEx(QStringLiteral("([^\\(]*\\(|)([^\\)]*)(\\)|)"));
- Q_ASSERT(defaultRegEx.isValid());
- const QRegularExpressionMatch defaultMatch = defaultRegEx.match(expr);
- QString defaultValueCtorName = defaultMatch.hasMatch() ? defaultMatch.captured(1) : QString();
- if (defaultValueCtorName.endsWith(QLatin1Char('(')))
- defaultValueCtorName.chop(1);
-
- // Fix the scope for constructor using the already resolved argument
- // type as a reference. The following regular expression extracts any
- // use of namespaces/scopes from the type string.
- static const QRegularExpression
- typeRegEx(QLatin1String(R"(^(?:const[\s]+|)([\w:]*::|)([A-Za-z_]\w*)\s*[&\*]?$)"));
- Q_ASSERT(typeRegEx.isValid());
- const QRegularExpressionMatch typeMatch = typeRegEx.match(type.minimalSignature());
-
- QString typeNamespace = typeMatch.hasMatch() ? typeMatch.captured(1) : QString();
- QString typeCtorName = typeMatch.hasMatch() ? typeMatch.captured(2) : QString();
- if (!typeNamespace.isEmpty() && defaultValueCtorName == typeCtorName)
- expr.prepend(typeNamespace);
-
- // Fix scope if the parameter is a field of the current class
- if (implementingClass) {
- const AbstractMetaFieldList &fields = implementingClass->fields();
- for (const AbstractMetaField &field : fields) {
- if (defaultMatch.hasMatch() && defaultMatch.captured(2) == field.name()) {
- expr = defaultMatch.captured(1) + implementingClass->name()
- + colonColon() + defaultMatch.captured(2) + defaultMatch.captured(3);
- break;
- }
+ // Here the default value is supposed to be a constructor, a class field,
+ // a constructor receiving a static class field or an enum. Consider
+ // class QSqlDatabase { ...
+ // static const char *defaultConnection;
+ // QSqlDatabase(const QString &connection = QLatin1String(defaultConnection))
+ // -> = QLatin1String(QSqlDatabase::defaultConnection)
+ // static void foo(QSqlDatabase db = QSqlDatabase(defaultConnection));
+ // -> = QSqlDatabase(QSqlDatabase::defaultConnection)
+ //
+ // Enum values from the class as defaults of int and others types (via
+ // implicit conversion) are handled here as well:
+ // class QStyleOption { ...
+ // enum StyleOptionType { Type = SO_Default };
+ // QStyleOption(..., int type = SO_Default);
+ // -> = QStyleOption::StyleOptionType::SO_Default
+
+ // Is this a single field or an enum?
+ if (isQualifiedCppIdentifier(expr)) {
+ const QString fixed = fixSimpleDefaultValue(expr, implementingClass);
+ return fixed.isEmpty() ? expr : fixed;
+ }
+
+ // Is this sth like "QLatin1String(field)", "Class(Field)", "Class()"?
+ const auto parenPos = expr.indexOf(u'(');
+ if (parenPos == -1 || !expr.endsWith(u')'))
+ return expr;
+ // Is the term within parentheses a class field or enum?
+ const auto innerLength = expr.size() - parenPos - 2;
+ if (innerLength > 0) { // Not some function call "defaultFunc()"
+ const auto inner = QStringView{expr}.mid(parenPos + 1, innerLength);
+ if (isQualifiedCppIdentifier(inner)
+ && !AbstractMetaBuilder::dontFixDefaultValue(inner)) {
+ const QString replacement = fixSimpleDefaultValue(inner, implementingClass);
+ if (!replacement.isEmpty() && replacement != inner)
+ expr.replace(parenPos + 1, innerLength, replacement);
}
}
+ // Is this a class constructor "Class(Field)"? Expand it.
+ const auto te = type.typeEntry();
+ if (!te->isComplex())
+ return expr;
+ const QString &qualifiedTypeName = te->qualifiedCppName();
+ if (!qualifiedTypeName.contains(u"::")) // Nothing to qualify here
+ return expr;
+ const auto className = QStringView{expr}.left(parenPos);
+ if (isUnderQualifiedSpec(qualifiedTypeName, className))
+ expr.replace(0, className.size(), qualifiedTypeName);
}
return expr;
}
+QString AbstractMetaBuilder::fixDefaultValue(const QString &expr, const AbstractMetaType &type,
+ const AbstractMetaClassCPtr &c) const
+{
+ return d->fixDefaultValue(expr, type, c);
+}
+
bool AbstractMetaBuilderPrivate::isEnum(const FileModelItem &dom, const QStringList& qualified_name)
{
CodeModelItem item = dom->model()->findItem(qualified_name, dom);
return item && item->kind() == _EnumModelItem::__node_kind;
}
-AbstractMetaClass* AbstractMetaBuilderPrivate::findTemplateClass(const QString &name,
- const AbstractMetaClass *context,
- TypeInfo *info,
- ComplexTypeEntry **baseContainerType) const
+AbstractMetaClassPtr
+ AbstractMetaBuilderPrivate::findTemplateClass(const QString &name,
+ const AbstractMetaClassCPtr &context,
+ TypeInfo *info,
+ ComplexTypeEntryPtr *baseContainerType) const
{
if (baseContainerType)
- *baseContainerType = nullptr;
- TypeDatabase* types = TypeDatabase::instance();
+ 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 (int i = scope.size(); i >= 0; --i) {
- QString prefix = i > 0 ? QStringList(scope.mid(0, i)).join(colonColon()) + colonColon() : QString();
+ for (auto i = scope.size(); i >= 0; --i) {
+ 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;
@@ -2645,8 +3035,8 @@ AbstractMetaClass* AbstractMetaBuilderPrivate::findTemplateClass(const QString &
if (info)
*info = parsed;
- AbstractMetaClass *templ = nullptr;
- for (AbstractMetaClass *c : qAsConst(m_templates)) {
+ AbstractMetaClassPtr templ;
+ for (const auto &c : std::as_const(m_templates)) {
if (c->typeEntry()->name() == qualifiedName) {
templ = c;
break;
@@ -2666,19 +3056,18 @@ AbstractMetaClass* AbstractMetaBuilderPrivate::findTemplateClass(const QString &
return nullptr;
}
-AbstractMetaClassList AbstractMetaBuilderPrivate::getBaseClasses(const AbstractMetaClass *metaClass) const
+AbstractMetaClassCList
+ AbstractMetaBuilderPrivate::getBaseClasses(const AbstractMetaClassCPtr &metaClass) const
{
// Shortcut if inheritance has already been set up
if (metaClass->inheritanceDone() || !metaClass->needsInheritanceSetup())
return metaClass->baseClasses();
- AbstractMetaClassList baseClasses;
+ AbstractMetaClassCList baseClasses;
const QStringList &baseClassNames = metaClass->baseClassNames();
for (const QString& parent : baseClassNames) {
- AbstractMetaClass *cls = nullptr;
- if (parent.contains(QLatin1Char('<')))
- 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;
@@ -2698,7 +3087,7 @@ std::optional<AbstractMetaType>
returned.setOriginalTemplateType(metaType);
if (returned.typeEntry()->isTemplateArgument()) {
- const auto *tae = static_cast<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.
@@ -2716,7 +3105,7 @@ std::optional<AbstractMetaType>
if (returned.hasInstantiations()) {
AbstractMetaTypeList instantiations = returned.instantiations();
- for (int i = 0; i < instantiations.count(); ++i) {
+ for (qsizetype i = 0; i < instantiations.size(); ++i) {
auto ins = inheritTemplateType(templateTypes, instantiations.at(i));
if (!ins.has_value())
return {};
@@ -2728,84 +3117,236 @@ std::optional<AbstractMetaType>
return returned;
}
-bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
- const AbstractMetaClass *templateClass,
+AbstractMetaClassPtr
+ AbstractMetaBuilder::inheritTemplateClass(const ComplexTypeEntryPtr &te,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes)
+{
+ auto result = std::make_shared<AbstractMetaClass>();
+ result->setTypeDef(true);
+
+ result->setTypeEntry(te);
+ if (!AbstractMetaBuilderPrivate::inheritTemplate(result, templateClass,
+ templateTypes)) {
+ return {};
+ }
+ AbstractMetaBuilderPrivate::inheritTemplateFunctions(result);
+ return result;
+}
+
+
+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();
- TypeEntry *t = nullptr;
- // 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 = subclass->typeEntry()->typeSystemTypeEntry();
- 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 : qAsConst(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(const AbstractMetaClassPtr &subclass,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes)
+{
subclass->setTemplateBaseClass(templateClass);
subclass->setTemplateBaseClassInstantiations(templateTypes);
subclass->setBaseClass(templateClass->baseClass());
return true;
}
-static bool inheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
- const AbstractMetaFunctionCList &existingSubclassFuncs,
- const AbstractMetaClass *subclass,
- const AbstractMetaClass *templateBaseClass)
+AbstractMetaFunctionPtr
+ AbstractMetaBuilderPrivate::inheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes)
+{
+ AbstractMetaFunctionPtr f(function->copy());
+ f->setArguments(AbstractMetaArgumentList());
+ f->setFlags(f->flags() | AbstractMetaFunction::Flag::InheritedFromTemplate);
+
+ if (!function->isVoid()) {
+ auto returnType = inheritTemplateType(templateTypes, function->type());
+ if (!returnType.has_value())
+ return {};
+ f->setType(returnType.value());
+ }
+
+ const AbstractMetaArgumentList &arguments = function->arguments();
+ for (const AbstractMetaArgument &argument : arguments) {
+ auto argType = inheritTemplateType(templateTypes, argument.type());
+ if (!argType.has_value())
+ return {};
+ AbstractMetaArgument arg = argument;
+ arg.setType(argType.value());
+ f->addArgument(arg);
+ }
+
+ return f;
+}
+
+AbstractMetaFunctionPtr
+ AbstractMetaBuilder::inheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes)
+{
+ return AbstractMetaBuilderPrivate::inheritTemplateFunction(function, templateTypes);
+}
+
+AbstractMetaFunctionPtr
+ AbstractMetaBuilderPrivate::inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass)
+{
+ AbstractMetaFunctionPtr f = inheritTemplateFunction(function, templateTypes);
+ if (!f)
+ return {};
+
+ // There is no base class in the target language to inherit from here, so
+ // the template instantiation is the class that implements the function.
+ f->setImplementingClass(subclass);
+
+ // We also set it as the declaring class, since the superclass is
+ // supposed to disappear. This allows us to make certain function modifications
+ // on the inherited functions.
+ f->setDeclaringClass(subclass);
+
+ if (f->isConstructor()) {
+ f->setName(subclass->name());
+ f->setOriginalName(subclass->name());
+ }
+
+ ComplexTypeEntryPtr te = subclass->typeEntry();
+ const FunctionModificationList mods = function->modifications(templateClass);
+
+ for (auto mod : mods) {
+ mod.setSignature(f->minimalSignature());
+
+// If we ever need it... Below is the code to do
+// substitution of the template instantation type inside
+// injected code..
+#if 0
+ if (mod.modifiers & Modification::CodeInjection) {
+ for (int j = 0; j < template_types.size(); ++j) {
+ CodeSnip &snip = mod.snips.last();
+ QString code = snip.code();
+ code.replace(QString::fromLatin1("$$QT_TEMPLATE_%1$$").arg(j),
+ template_types.at(j)->typeEntry()->qualifiedCppName());
+ snip.codeList.clear();
+ snip.addCode(code);
+ }
+ }
+#endif
+ te->addFunctionModification(mod);
+ }
+
+ QString errorMessage;
+ if (!applyArrayArgumentModifications(f->modifications(subclass), f,
+ &errorMessage)) {
+ qCWarning(lcShiboken, "While specializing %s (%s): %s",
+ qPrintable(subclass->name()), qPrintable(templateClass->name()),
+ qPrintable(errorMessage));
+ }
+ return f;
+}
+
+AbstractMetaFunctionPtr
+ AbstractMetaBuilder::inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass)
+{
+ return AbstractMetaBuilderPrivate::inheritTemplateMember(function, templateTypes,
+ templateClass, subclass);
+}
+
+static bool doInheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaFunctionCList &existingSubclassFuncs,
+ 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
// declares it via "using").
if (function->isModifiedRemoved())
return false;
+ if (function->isConstructor() && !subclass->isTypeDef())
+ return false;
return AbstractMetaFunction::find(existingSubclassFuncs, function->name()) == nullptr
|| subclass->isUsingMember(templateBaseClass, function->name(), Access::Protected);
}
-void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *subclass)
+void AbstractMetaBuilderPrivate::inheritTemplateFunctions(const AbstractMetaClassPtr &subclass)
{
- QString errorMessage;
auto templateClass = subclass->templateBaseClass();
if (subclass->isTypeDef()) {
- subclass->setHasCloneOperator(templateClass->hasCloneOperator());
- subclass->setHasEqualsOperator(templateClass->hasEqualsOperator());
- subclass->setHasHashFunction(templateClass->hasHashFunction());
+ subclass->setHashFunction(templateClass->hashFunction());
subclass->setHasNonPrivateConstructor(templateClass->hasNonPrivateConstructor());
subclass->setHasPrivateDestructor(templateClass->hasPrivateDestructor());
subclass->setHasProtectedDestructor(templateClass->hasProtectedDestructor());
@@ -2817,82 +3358,13 @@ void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *sub
subclass->functions(); // Take copy
const auto &templateClassFunctions = templateClass->functions();
for (const auto &function : templateClassFunctions) {
- if (!inheritTemplateFunction(function, existingSubclassFuncs,
- subclass, templateClass)) {
- continue;
- }
-
- std::unique_ptr<AbstractMetaFunction> f(function->copy());
- f->setArguments(AbstractMetaArgumentList());
-
- if (!function->isVoid()) {
- auto returnType = inheritTemplateType(templateTypes, function->type());
- if (!returnType.has_value())
- continue;
- f->setType(returnType.value());
- }
-
- const AbstractMetaArgumentList &arguments = function->arguments();
- for (const AbstractMetaArgument &argument : arguments) {
- auto argType = inheritTemplateType(templateTypes, argument.type());
- if (!argType.has_value())
- break;
- AbstractMetaArgument arg = argument;
- arg.setType(argType.value());
- f->addArgument(arg);
- }
-
- if (f->arguments().size() < function->arguments().size())
- continue;
-
- // There is no base class in the target language to inherit from here, so
- // the template instantiation is the class that implements the function.
- f->setImplementingClass(subclass);
-
- // We also set it as the declaring class, since the superclass is
- // supposed to disappear. This allows us to make certain function modifications
- // on the inherited functions.
- f->setDeclaringClass(subclass);
-
- if (f->isConstructor()) {
- if (!subclass->isTypeDef())
- continue;
- f->setName(subclass->name());
- f->setOriginalName(subclass->name());
+ if (doInheritTemplateFunction(function, existingSubclassFuncs,
+ templateClass, subclass)) {
+ AbstractMetaFunctionCPtr f = inheritTemplateMember(function, templateTypes,
+ templateClass, subclass);
+ if (f)
+ AbstractMetaClass::addFunction(subclass, f);
}
-
- ComplexTypeEntry* te = subclass->typeEntry();
- FunctionModificationList mods = function->modifications(templateClass);
- for (int i = 0; i < mods.size(); ++i) {
- FunctionModification mod = mods.at(i);
- mod.setSignature(f->minimalSignature());
-
- // If we ever need it... Below is the code to do
- // substitution of the template instantation type inside
- // injected code..
-#if 0
- if (mod.modifiers & Modification::CodeInjection) {
- for (int j = 0; j < template_types.size(); ++j) {
- CodeSnip &snip = mod.snips.last();
- QString code = snip.code();
- code.replace(QString::fromLatin1("$$QT_TEMPLATE_%1$$").arg(j),
- template_types.at(j)->typeEntry()->qualifiedCppName());
- snip.codeList.clear();
- snip.addCode(code);
- }
- }
-#endif
- te->addFunctionModification(mod);
- }
-
-
- if (!applyArrayArgumentModifications(f->modifications(subclass), f.get(),
- &errorMessage)) {
- qCWarning(lcShiboken, "While specializing %s (%s): %s",
- qPrintable(subclass->name()), qPrintable(templateClass->name()),
- qPrintable(errorMessage));
- }
- subclass->addFunction(AbstractMetaFunctionCPtr(f.release()));
}
// Take copy
@@ -2901,8 +3373,7 @@ void AbstractMetaBuilderPrivate::inheritTemplateFunctions(AbstractMetaClass *sub
for (const AbstractMetaField &field : templateClassFields) {
// If the field is modified or the instantiation has a field named
// the same as an existing field we have shadowing, so we need to skip it.
- if (field.isModifiedRemoved(TypeSystem::All)
- || field.isStatic()
+ if (field.isModifiedRemoved() || field.isStatic()
|| AbstractMetaField::find(existingSubclassFields, field.name()).has_value()) {
continue;
}
@@ -2917,7 +3388,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();
@@ -2928,7 +3399,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;
@@ -2957,63 +3428,35 @@ void AbstractMetaBuilderPrivate::parseQ_Properties(AbstractMetaClass *metaClass,
}
}
-static AbstractMetaFunctionCPtr findCopyCtor(AbstractMetaClass* cls)
-{
- for (const auto &f : cls->functions()) {
- const AbstractMetaFunction::FunctionType t = f->functionType();
- if (t == AbstractMetaFunction::CopyConstructorFunction || t == AbstractMetaFunction::AssignmentOperatorFunction)
- return f;
- }
- return {};
-}
-
-void AbstractMetaBuilderPrivate::setupClonable(AbstractMetaClass *cls)
-{
- bool result = true;
-
- // find copy ctor for the current class
- auto copyCtor = findCopyCtor(cls);
- if (!copyCtor.isNull()) { // if exists a copy ctor in this class
- result = copyCtor->isPublic();
- } else { // else... lets find one in the parent class
- QQueue<AbstractMetaClass*> baseClasses;
- if (cls->baseClass())
- baseClasses.enqueue(cls->baseClass());
-
- while (!baseClasses.isEmpty()) {
- AbstractMetaClass* currentClass = baseClasses.dequeue();
- if (currentClass->baseClass())
- baseClasses.enqueue(currentClass->baseClass());
-
- copyCtor = findCopyCtor(currentClass);
- if (copyCtor) {
- result = copyCtor->isPublic();
- break;
- }
- }
- }
- cls->setHasCloneOperator(result);
-}
-
-void AbstractMetaBuilderPrivate::setupExternalConversion(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);
}
- const AbstractMetaClassList &innerClasses = cls->innerClasses();
- for (AbstractMetaClass *innerClass : 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)));
@@ -3022,70 +3465,37 @@ static void writeRejectLogFile(const QString &name,
QTextStream s(&f);
-
- for (int reason = 0; reason < AbstractMetaBuilder::NoReason; ++reason) {
- s << QString(72, QLatin1Char('*')) << Qt::endl;
- 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;
+ 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 << 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;
- }
-
- s << QString(72, QLatin1Char('*')) << Qt::endl << Qt::endl;
+ s << " - " << e << '\n';
}
-
}
void AbstractMetaBuilderPrivate::dumpLog() const
{
- writeRejectLogFile(m_logDirectory + QLatin1String("mjb_rejected_classes.log"), m_rejectedClasses);
- writeRejectLogFile(m_logDirectory + QLatin1String("mjb_rejected_enums.log"), m_rejectedEnums);
- writeRejectLogFile(m_logDirectory + QLatin1String("mjb_rejected_functions.log"), m_rejectedFunctions);
- writeRejectLogFile(m_logDirectory + QLatin1String("mjb_rejected_fields.log"), m_rejectedFields);
+ writeRejectLogFile(m_logDirectory + u"mjb_rejected_classes.log"_s, m_rejectedClasses);
+ writeRejectLogFile(m_logDirectory + u"mjb_rejected_enums.log"_s, m_rejectedEnums);
+ writeRejectLogFile(m_logDirectory + u"mjb_rejected_functions.log"_s, m_rejectedFunctions);
+ writeRejectLogFile(m_logDirectory + u"mjb_rejected_fields.log"_s, m_rejectedFields);
}
-using ClassGraph = Graph<AbstractMetaClass *>;
-
-// Add a dependency of the class associated with typeEntry on clazz
-static bool addClassDependency(const AbstractMetaClassList &classList,
- const TypeEntry *typeEntry,
- AbstractMetaClass *clazz,
- ClassGraph *graph)
+// Topological sorting of classes. Templates for use with
+// AbstractMetaClassList/AbstractMetaClassCList.
+// Add a dependency of the class associated with typeEntry on clazz.
+template <class MetaClass>
+static bool addClassDependency(const QList<std::shared_ptr<MetaClass> > &classList,
+ const TypeEntryCPtr &typeEntry,
+ std::shared_ptr<MetaClass> clazz,
+ Graph<std::shared_ptr<MetaClass> > *graph)
{
if (!typeEntry->isComplex() || typeEntry == clazz->typeEntry())
return false;
@@ -3095,10 +3505,12 @@ static bool addClassDependency(const AbstractMetaClassList &classList,
return graph->addEdge(c, clazz);
}
-AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const AbstractMetaClassList &classList,
- const Dependencies &additionalDependencies)
+template <class MetaClass>
+static QList<std::shared_ptr<MetaClass> >
+ topologicalSortHelper(const QList<std::shared_ptr<MetaClass> > &classList,
+ const Dependencies &additionalDependencies)
{
- ClassGraph 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)) {
@@ -3108,14 +3520,14 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const
}
}
- for (AbstractMetaClass *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(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();
@@ -3141,24 +3553,44 @@ AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const
const auto result = graph.topologicalSort();
if (!result.isValid() && graph.nodeCount()) {
- QTemporaryFile tempFile(QDir::tempPath() + QLatin1String("/cyclic_depXXXXXX.dot"));
+ 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));
}
return result.result;
}
+AbstractMetaClassList
+ AbstractMetaBuilderPrivate::classesTopologicalSorted(const AbstractMetaClassList &classList,
+ const Dependencies &additionalDependencies)
+{
+ return topologicalSortHelper(classList, additionalDependencies);
+}
+
+AbstractMetaClassCList
+ AbstractMetaBuilderPrivate::classesTopologicalSorted(const AbstractMetaClassCList &classList,
+ const Dependencies &additionalDependencies)
+{
+ return topologicalSortHelper(classList, additionalDependencies);
+}
+
void AbstractMetaBuilderPrivate::pushScope(const NamespaceModelItem &item)
{
// For purposes of type lookup, join all namespaces of the same name
@@ -3172,8 +3604,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);
@@ -3206,13 +3638,18 @@ void AbstractMetaBuilder::setSkipDeprecated(bool value)
d->m_skipDeprecated = value;
}
+void AbstractMetaBuilder::setApiExtractorFlags(ApiExtractorFlags flags)
+{
+ d->m_apiExtractorFlags = flags;
+}
+
// PYSIDE-975: When receiving an absolute path name from the code model, try
// to resolve it against the include paths set on shiboken in order to recreate
// relative paths like #include <foo/bar.h>.
static inline bool isFileSystemSlash(QChar c)
{
- return c == QLatin1Char('/') || c == QLatin1Char('\\');
+ return c == u'/' || c == u'\\';
}
static bool matchHeader(const QString &headerPath, const QString &fileName)
@@ -3222,13 +3659,13 @@ static bool matchHeader(const QString &headerPath, const QString &fileName)
#else
static const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
#endif
- const int pathSize = headerPath.size();
+ const auto pathSize = headerPath.size();
return fileName.size() > pathSize
&& isFileSystemSlash(fileName.at(pathSize))
&& fileName.startsWith(headerPath, caseSensitivity);
}
-void AbstractMetaBuilderPrivate::setInclude(TypeEntry *te, const QString &path) const
+void AbstractMetaBuilderPrivate::setInclude(const TypeEntryPtr &te, const QString &path) const
{
auto it = m_resolveIncludeHash.find(path);
if (it == m_resolveIncludeHash.end()) {
@@ -3276,9 +3713,9 @@ void AbstractMetaBuilder::formatDebug(QDebug &debug) const
debug << "m_globalHeader=" << d->m_globalHeaders;
debugFormatSequence(debug, "globalEnums", d->m_globalEnums, "\n");
debugFormatSequence(debug, "globalFunctions", d->m_globalFunctions, "\n");
- if (const int scopeCount = d->m_scopes.size()) {
+ if (const auto scopeCount = d->m_scopes.size()) {
debug << "\n scopes[" << scopeCount << "]=(";
- for (int i = 0; i < scopeCount; ++i) {
+ for (qsizetype i = 0; i < scopeCount; ++i) {
if (i)
debug << ", ";
_CodeModelItem::formatKind(debug, d->m_scopes.at(i)->kind());
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
index 022c29cdd..20261ed3c 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder.h
@@ -1,41 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ABSTRACTMETABUILDER_H
#define ABSTRACTMETABUILDER_H
#include "abstractmetalang_typedefs.h"
+#include "apiextractorflags.h"
#include "header_paths.h"
#include "typesystem_enums.h"
+#include "typesystem_typedefs.h"
#include "clangparser/compilersupport.h"
-#include <QFileInfoList>
+#include <QtCore/QFileInfoList>
#include <optional>
@@ -45,19 +22,22 @@ class AbstractMetaBuilderPrivate;
class AbstractMetaClass;
class AbstractMetaType;
class AbstractMetaEnumValue;
+class ComplexTypeEntry;
class TypeInfo;
class TypeEntry;
class AbstractMetaBuilder
{
public:
+ Q_DISABLE_COPY_MOVE(AbstractMetaBuilder)
+
enum RejectReason {
NotInTypeSystem,
GenerationDisabled,
RedefinedToNotClass,
UnmatchedArgumentType,
UnmatchedReturnType,
- ApiIncompatible,
+ UnmatchedOperator,
Deprecated,
NoReason
};
@@ -66,13 +46,18 @@ public:
virtual ~AbstractMetaBuilder();
const AbstractMetaClassList &classes() const;
+ AbstractMetaClassList takeClasses();
const AbstractMetaClassList &templates() const;
+ AbstractMetaClassList takeTemplates();
const AbstractMetaClassList &smartPointers() const;
+ AbstractMetaClassList takeSmartPointers();
const AbstractMetaFunctionCList &globalFunctions() const;
const AbstractMetaEnumList &globalEnums() const;
- const QHash<const TypeEntry *, AbstractMetaEnum> &typeEntryToEnumsHash() const;
+ const QHash<TypeEntryCPtr, AbstractMetaEnum> &typeEntryToEnumsHash() const;
+ const QMultiHash<QString, QString> &typedefTargetToName() const;
bool build(const QByteArrayList &arguments,
+ ApiExtractorFlags apiExtractorFlags = {},
bool addCompilerSupportArguments = true,
LanguageLevel level = LanguageLevel::Default,
unsigned clangFlags = 0);
@@ -90,30 +75,64 @@ public:
void setSkipDeprecated(bool value);
+ 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.
+ /// \param function Function
+ /// \param templateTypes Instantiation types
+ /// \return Specialized copy of the function
+ static AbstractMetaFunctionPtr
+ inheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes);
+
+ static AbstractMetaClassPtr
+ inheritTemplateClass(const ComplexTypeEntryPtr &te,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes);
+
+ /// Performs a template specialization of the member function.
+ /// \param function Member function
+ /// \param templateTypes Instantiation types
+ /// \param templateClass Template class
+ /// \param subclass Specialized class
+ /// \return Specialized copy of the function
+ static AbstractMetaFunctionPtr
+ inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes,
+ 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,
- QStringView value);
- static QString searchForEnumScope(const AbstractMetaClass *metaClass,
+ static QString resolveScopePrefix(const AbstractMetaClassCPtr &scope,
QStringView value);
+ static bool dontFixDefaultValue(QStringView expr);
+
// For testing purposes
- QString fixEnumDefault(const AbstractMetaType &type, const QString &expr) const;
+ QString fixDefaultValue(const QString &expr, const AbstractMetaType &type,
+ const AbstractMetaClassCPtr &) const;
+ QString fixEnumDefault(const AbstractMetaType &type, const QString &expr,
+ const AbstractMetaClassCPtr & = {}) const;
+
+ static void setCodeModelTestMode(bool b);
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp
index 068c67241..68eef737a 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp
@@ -1,36 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "abstractmetabuilder.h"
#include "abstractmetabuilder_p.h"
#include "abstractmetaenum.h"
+#include "abstractmetafield.h"
#include "abstractmetalang.h"
-#include "typesystem.h"
+#include "enumtypeentry.h"
+#include "flagstypeentry.h"
+
+using namespace Qt::StringLiterals;
using QStringViewList = QList<QStringView>;
@@ -42,7 +21,7 @@ static QString resolveScopePrefixHelper(const QStringViewList &scopeList,
{
QString name;
for (qsizetype i = scopeList.size() - 1 ; i >= 0; --i) {
- const QString prefix = scopeList.at(i).toString() + u"::"_qs;
+ const QString prefix = scopeList.at(i).toString() + u"::"_s;
if (value.startsWith(prefix))
name.clear();
else
@@ -51,14 +30,14 @@ static QString resolveScopePrefixHelper(const QStringViewList &scopeList,
return name;
}
-QString AbstractMetaBuilder::resolveScopePrefix(const AbstractMetaClass *scope,
+QString AbstractMetaBuilder::resolveScopePrefix(const AbstractMetaClassCPtr &scope,
QStringView value)
{
if (!scope)
return {};
const QString &qualifiedCppName = scope->qualifiedCppName();
const QStringViewList scopeList =
- QStringView{qualifiedCppName}.split(u"::"_qs, Qt::SkipEmptyParts);
+ QStringView{qualifiedCppName}.split(u"::"_s, Qt::SkipEmptyParts);
return resolveScopePrefixHelper(scopeList, value);
}
@@ -66,46 +45,27 @@ 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();
const QString &enumName = metaEnum.name();
QStringViewList parts =
- QStringView{qualifiedCppName}.split(u"::"_qs, Qt::SkipEmptyParts);
+ QStringView{qualifiedCppName}.split(u"::"_s, Qt::SkipEmptyParts);
// Append the type (as required for enum classes) unless it is an anonymous enum.
if (!metaEnum.isAnonymous())
parts.append(QStringView{enumName});
return resolveScopePrefixHelper(parts, value);
}
-// Return the scope for fully qualifying an enumeration value from
-// an unknown enum in the class scope including trailing "::".
-QString AbstractMetaBuilder::searchForEnumScope(const AbstractMetaClass *metaClass,
- QStringView value)
-{
- if (!metaClass)
- return QString();
- for (const AbstractMetaEnum &metaEnum : metaClass->enums()) {
- auto v = metaEnum.findEnumValue(value);
- if (v.has_value())
- return resolveEnumValueScopePrefix(metaEnum, value);
- }
- // PYSIDE-331: We need to also search the base classes.
- QString ret = searchForEnumScope(metaClass->enclosingClass(), value);
- if (ret.isEmpty())
- ret = searchForEnumScope(metaClass->baseClass(), value);
- return ret;
-}
-
-static bool isQualifiedCppIdentifier(QStringView e)
+bool AbstractMetaBuilderPrivate::isQualifiedCppIdentifier(QStringView e)
{
return !e.isEmpty() && e.at(0).isLetter()
&& std::all_of(e.cbegin() + 1, e.cend(),
[](QChar c) { return c.isLetterOrNumber() || c == u'_' || c == u':'; });
}
-static bool isNumericConstant(const QStringView expr)
+static bool isIntegerConstant(const QStringView expr)
{
bool isNumber;
auto n = expr.toInt(&isNumber, /* guess base: 0x or decimal */ 0);
@@ -113,25 +73,38 @@ static bool isNumericConstant(const QStringView expr)
return isNumber;
}
+static bool isFloatConstant(const QStringView expr)
+{
+ bool isNumber;
+ auto d = expr.toDouble(&isNumber);
+ Q_UNUSED(d);
+ return isNumber;
+}
+
// Fix an enum default value: Add the enum/flag scope or fully qualified name
// 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 (isNumericConstant(expr))
+ if (isIntegerConstant(expr))
return expr;
- const auto *typeEntry = type.typeEntry();
- const EnumTypeEntry *enumTypeEntry = nullptr;
- const FlagsTypeEntry *flagsTypeEntry = nullptr;
+ const QString field = qualifyStaticField(klass, expr);
+ if (!field.isEmpty())
+ return field;
+
+ const auto typeEntry = type.typeEntry();
+ EnumTypeEntryCPtr enumTypeEntry;
+ FlagsTypeEntryCPtr flagsTypeEntry;
if (typeEntry->isFlags()) {
- flagsTypeEntry = static_cast<const FlagsTypeEntry *>(typeEntry);
+ flagsTypeEntry = std::static_pointer_cast<const FlagsTypeEntry>(typeEntry);
enumTypeEntry = flagsTypeEntry->originator();
} else {
Q_ASSERT(typeEntry->isEnum());
- enumTypeEntry = static_cast<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"::"))
@@ -163,7 +136,7 @@ QString AbstractMetaBuilderPrivate::fixEnumDefault(const AbstractMetaType &type,
: QStringView{result};
// Quick check for number "Options(0x4)"
- if (isNumericConstant(innerExpression))
+ if (isIntegerConstant(innerExpression))
return result;
// Quick check for single enum value "Options(Option1)"
@@ -187,14 +160,43 @@ QString AbstractMetaBuilderPrivate::fixEnumDefault(const AbstractMetaType &type,
for (const auto &tokenIn : tokens) {
const auto token = tokenIn.trimmed();
QString qualified = token.toString();
- if (!isNumericConstant(token) && isQualifiedCppIdentifier(token))
+ if (!isIntegerConstant(token) && isQualifiedCppIdentifier(token))
qualified.prepend(resolveEnumValueScopePrefix(metaEnum, token));
qualifiedTokens.append(qualified);
}
- const QString qualifiedExpression = qualifiedTokens.join(u" | "_qs);
+ const QString qualifiedExpression = qualifiedTokens.join(u" | "_s);
if (!typeCast)
return qualifiedExpression;
result.replace(parenPos + 1, innerExpression.size(), qualifiedExpression);
return result;
}
+
+bool AbstractMetaBuilder::dontFixDefaultValue(QStringView expr)
+{
+ return expr.isEmpty() || expr == u"{}" || expr == u"nullptr"
+ || expr == u"NULL" || expr == u"true" || expr == u"false"
+ || (expr.startsWith(u'{') && expr.startsWith(u'}')) // initializer list
+ || (expr.startsWith(u'[') && expr.startsWith(u']')) // array
+ || expr.startsWith(u"Qt::") // Qt namespace constant
+ || isIntegerConstant(expr) || isFloatConstant(expr);
+}
+
+QString AbstractMetaBuilderPrivate::qualifyStaticField(const AbstractMetaClassCPtr &c,
+ QStringView field)
+{
+ if (!c || c->fields().isEmpty())
+ return {};
+ // If there is a scope, ensure it matches the class
+ const auto lastQualifier = field.lastIndexOf(u"::");
+ if (lastQualifier != -1
+ && !c->qualifiedCppName().endsWith(field.left(lastQualifier))) {
+ return {};
+ }
+ const auto fieldName = lastQualifier != -1
+ ? field.mid(lastQualifier + 2) : field;
+ const auto fieldOpt = c->findField(fieldName);
+ if (!fieldOpt.has_value() || !fieldOpt.value().isStatic())
+ return {};
+ return AbstractMetaBuilder::resolveScopePrefix(c, field) + field.toString();
+}
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
index a52b4bf9d..4e337339e 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ABSTRACTMETABUILDER_P_H
#define ABSTRACTMETABUILDER_P_H
@@ -35,24 +10,38 @@
#include "abstractmetalang.h"
#include "abstractmetatype.h"
#include "include.h"
-#include "modifications.h"
#include "typeparser.h"
+#include "modifications_typedefs.h"
+#include "typesystem_typedefs.h"
-#include <QSet>
-#include <QFileInfo>
-#include <QList>
+#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;
@@ -60,74 +49,90 @@ public:
Q_DISABLE_COPY(AbstractMetaBuilderPrivate)
AbstractMetaBuilderPrivate();
- ~AbstractMetaBuilderPrivate();
static FileModelItem buildDom(QByteArrayList arguments,
bool addCompilerSupportArguments,
LanguageLevel level,
unsigned clangFlags);
- void traverseDom(const FileModelItem &dom);
+ void traverseDom(const FileModelItem &dom, ApiExtractorFlags flags);
void dumpLog() const;
- static AbstractMetaClassList classesTopologicalSorted(const AbstractMetaClassList &classList,
- const Dependencies &additionalDependencies = {});
+
+ static AbstractMetaClassList
+ classesTopologicalSorted(const AbstractMetaClassList &classList,
+ const Dependencies &additionalDependencies = {});
+ static AbstractMetaClassCList
+ classesTopologicalSorted(const AbstractMetaClassCList &classList,
+ const Dependencies &additionalDependencies = {});
+
NamespaceModelItem popScope() { return m_scopes.takeLast(); }
void pushScope(const NamespaceModelItem &item);
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);
- static void applyFunctionModifications(AbstractMetaFunction *func);
- void traverseFields(const ScopeModelItem &item, AbstractMetaClass *parent);
+ AbstractMetaFunctionList classFunctionList(const ScopeModelItem &scopeItem,
+ AbstractMetaClass::Attributes *constructorAttributes,
+ const AbstractMetaClassPtr &currentClass);
+ void traverseFunctions(const ScopeModelItem& item,
+ const AbstractMetaClassPtr &parent);
+ static void applyFunctionModifications(const AbstractMetaFunctionPtr &func);
+ 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);
- AbstractMetaFunction *traverseAddedFunctionHelper(const AddedFunctionPtr &addedFunc,
- AbstractMetaClass *metaClass,
- QString *errorMessage);
+ const AbstractMetaClassPtr &currentClass);
+ AbstractMetaFunctionPtr
+ traverseAddedFunctionHelper(const AddedFunctionPtr &addedFunc,
+ 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);
+ AbstractMetaFunctionPtr
+ 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
@@ -139,49 +144,68 @@ public:
* said class.
* \param metaFunction conversion operator function to be fixed.
*/
- static void fixReturnTypeOfConversionOperator(AbstractMetaFunction *metaFunction);
-
- void parseQ_Properties(AbstractMetaClass *metaClass, const QStringList &declarations);
- void setupEquals(AbstractMetaClass *metaClass);
- void setupComparable(AbstractMetaClass *metaClass);
- static void setupClonable(AbstractMetaClass *cls);
- void setupExternalConversion(AbstractMetaClass *cls);
- static void setupFunctionDefaults(AbstractMetaFunction *metaFunction,
- AbstractMetaClass *metaClass);
-
- QString fixDefaultValue(const ArgumentModelItem &item,
- const AbstractMetaType &type,
- const AbstractMetaClass *,
- int argumentIndex) const;
- QString fixEnumDefault(const AbstractMetaType &type, const QString &expr) const;
+ static void fixReturnTypeOfConversionOperator(const AbstractMetaFunctionPtr &metaFunction);
+
+ 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 AbstractMetaClassCPtr &) const;
+ QString fixSimpleDefaultValue(QStringView expr,
+ const AbstractMetaClassCPtr &klass) 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 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 TypeEntries findTypeEntriesHelper(const QString &qualifiedName, const QString &name,
- const AbstractMetaClass *currentClass = nullptr,
- AbstractMetaBuilderPrivate *d = nullptr);
- static TypeEntries findTypeEntries(const QString &qualifiedName, const QString &name,
- const AbstractMetaClass *currentClass = nullptr,
- AbstractMetaBuilderPrivate *d = nullptr,
- QString *errorMessage = nullptr);
+ static TypeEntryCList findTypeEntriesHelper(const QString &qualifiedName, const QString &name,
+ TranslateTypeFlags flags = {},
+ const AbstractMetaClassCPtr &currentClass = {},
+ AbstractMetaBuilderPrivate *d = nullptr);
+ static TypeEntryCList findTypeEntries(const QString &qualifiedName, const QString &name,
+ 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,
- ComplexTypeEntry **baseContainerType = Q_NULLPTR) const;
- AbstractMetaClassList getBaseClasses(const AbstractMetaClass *metaClass) const;
+ AbstractMetaClassPtr findTemplateClass(const QString& name, const AbstractMetaClassCPtr &context,
+ TypeInfo *info = nullptr,
+ ComplexTypeEntryPtr *baseContainerType = nullptr) 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);
- void inheritTemplateFunctions(AbstractMetaClass *subclass);
- std::optional<AbstractMetaType>
+ static bool inheritTemplate(const AbstractMetaClassPtr &subclass,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes);
+
+ static AbstractMetaFunctionPtr
+ inheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes);
+
+ static AbstractMetaFunctionPtr
+ inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass);
+
+ static void inheritTemplateFunctions(const AbstractMetaClassPtr &subclass);
+ static std::optional<AbstractMetaType>
inheritTemplateType(const AbstractMetaTypeList &templateTypes,
const AbstractMetaType &metaType);
@@ -189,29 +213,32 @@ public:
static bool isEnum(const FileModelItem &dom, const QStringList &qualifiedName);
void sortLists();
- void setInclude(TypeEntry *te, const QString &path) const;
- static void fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods);
+ void setInclude(const TypeEntryPtr &te, const QString &path) const;
+ static void fixArgumentNames(const AbstractMetaFunctionPtr &func,
+ const FunctionModificationList &mods);
+
+ void fillAddedFunctions(const AbstractMetaClassPtr &metaClass);
+ AbstractMetaClassCPtr resolveTypeSystemTypeDef(const AbstractMetaType &t) const;
- void fillAddedFunctions(AbstractMetaClass *metaClass);
- const AbstractMetaClass *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<const TypeEntry *, AbstractMetaEnum> m_enums;
+ QHash<TypeEntryCPtr, AbstractMetaEnum> m_enums;
QList<NamespaceModelItem> m_scopes;
@@ -219,9 +246,12 @@ 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;
static bool m_useGlobalHeader;
+ static bool m_codeModelTestMode;
};
#endif // ABSTRACTMETBUILDER_P_H
diff --git a/sources/shiboken6/ApiExtractor/abstractmetaenum.cpp b/sources/shiboken6/ApiExtractor/abstractmetaenum.cpp
index ad64e58b9..780170c22 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetaenum.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetaenum.cpp
@@ -1,39 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "abstractmetaenum.h"
#include "abstractmetalang.h"
#include "documentation.h"
-#include "typesystem.h"
+#include "enumtypeentry.h"
#include "parser/enumvalue.h"
+#include "qtcompat.h"
+
#include <QtCore/QDebug>
+#include <algorithm>
+
+using namespace Qt::StringLiterals;
+
class AbstractMetaEnumValueData : public QSharedData
{
public:
@@ -41,6 +22,7 @@ public:
QString m_stringValue;
EnumValue m_value;
Documentation m_doc;
+ bool m_deprecated = false;
};
AbstractMetaEnumValue::AbstractMetaEnumValue() :
@@ -50,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
@@ -87,6 +69,17 @@ void AbstractMetaEnumValue::setName(const QString &name)
d->m_name = name;
}
+bool AbstractMetaEnumValue::isDeprecated() const
+{
+ return d->m_deprecated;
+}
+
+void AbstractMetaEnumValue::setDeprecated(bool deprecated)
+{
+ if (d->m_deprecated != deprecated)
+ d->m_deprecated = deprecated;
+}
+
Documentation AbstractMetaEnumValue::documentation() const
{
return d->m_doc;
@@ -103,29 +96,67 @@ void AbstractMetaEnumValue::setDocumentation(const Documentation &doc)
class AbstractMetaEnumData : public QSharedData
{
public:
- AbstractMetaEnumData() : m_hasQenumsDeclaration(false), m_signed(true)
+ AbstractMetaEnumData() : m_deprecated(false),
+ m_hasQenumsDeclaration(false), m_signed(true)
{
}
+ int unsignedUsedBits() const;
+ int signedUsedBits() const;
+
AbstractMetaEnumValueList m_enumValues;
- EnumTypeEntry *m_typeEntry = nullptr;
+ EnumTypeEntryCPtr m_typeEntry;
Documentation m_doc;
+ QString m_underlyingType;
EnumKind m_enumKind = CEnum;
Access m_access = Access::Public;
+ uint m_deprecated : 1;
uint m_hasQenumsDeclaration : 1;
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
@@ -133,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;
@@ -154,7 +195,7 @@ std::optional<AbstractMetaEnumValue>
{
if (isAnonymous())
return findMatchingEnumValue(d->m_enumValues, value);
- const int sepPos = value.indexOf(QLatin1String("::"));
+ const int sepPos = value.indexOf(u"::");
if (sepPos == -1)
return findMatchingEnumValue(d->m_enumValues, value);
if (name() == value.left(sepPos))
@@ -170,7 +211,7 @@ QString AbstractMetaEnum::name() const
QString AbstractMetaEnum::qualifiedCppName() const
{
return enclosingClass()
- ? enclosingClass()->qualifiedCppName() + QLatin1String("::") + name()
+ ? enclosingClass()->qualifiedCppName() + u"::"_s + name()
: name();
}
@@ -185,6 +226,36 @@ void AbstractMetaEnum::setAccess(Access a)
d->m_access = a;
}
+bool AbstractMetaEnum::isDeprecated() const
+{
+ return d->m_deprecated;
+}
+
+void AbstractMetaEnum::setDeprecated(bool deprecated)
+{
+ if (d->m_deprecated != deprecated)
+ d->m_deprecated = deprecated;
+}
+
+static bool isDeprecatedValue(const AbstractMetaEnumValue &v)
+{
+ return v.isDeprecated();
+};
+
+bool AbstractMetaEnum::hasDeprecatedValues() const
+{
+ return std::any_of(d->m_enumValues.cbegin(), d->m_enumValues.cend(),
+ isDeprecatedValue);
+}
+
+AbstractMetaEnumValueList AbstractMetaEnum::deprecatedValues() const
+{
+ AbstractMetaEnumValueList result;
+ std::copy_if(d->m_enumValues.cbegin(), d->m_enumValues.cend(),
+ std::back_inserter(result), isDeprecatedValue);
+ return result;
+}
+
const Documentation &AbstractMetaEnum::documentation() const
{
return d->m_doc;
@@ -208,7 +279,7 @@ QString AbstractMetaEnum::package() const
QString AbstractMetaEnum::fullName() const
{
- return package() + QLatin1Char('.') + qualifier() + QLatin1Char('.') + name();
+ return package() + u'.' + qualifier() + u'.' + name();
}
EnumKind AbstractMetaEnum::enumKind() const
@@ -238,12 +309,12 @@ void AbstractMetaEnum::setHasQEnumsDeclaration(bool on)
d->m_hasQenumsDeclaration = on;
}
-EnumTypeEntry *AbstractMetaEnum::typeEntry() const
+EnumTypeEntryCPtr AbstractMetaEnum::typeEntry() const
{
return d->m_typeEntry;
}
-void AbstractMetaEnum::setTypeEntry(EnumTypeEntry *entry)
+void AbstractMetaEnum::setTypeEntry(const EnumTypeEntryCPtr &entry)
{
if (d->m_typeEntry != entry)
d->m_typeEntry = entry;
@@ -260,14 +331,39 @@ 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)
{
- const QString &name = v.stringValue();
- if (!name.isEmpty())
- d << name << '=';
- d << v.value();
+ d << v.name() << '=';
+ if (forceHex)
+ v.value().formatDebugHex(d);
+ else
+ v.value().formatDebug(d);
+ if (v.isDeprecated())
+ d << " (deprecated)";
}
QDebug operator<<(QDebug d, const AbstractMetaEnumValue &v)
@@ -283,15 +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 << " \"" << e.underlyingType() << '"';
if (!e.isSigned())
- d << " (unsigned) ";
- d << '[';
+ d << " (unsigned)";
+ d << " [";
const AbstractMetaEnumValueList &values = e.values();
- for (int i = 0, count = values.size(); i < count; ++i) {
+ 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));
+ d << ", ";
+ formatMetaEnumValue(d, values.at(i), hasFlags);
}
d << ']';
}
diff --git a/sources/shiboken6/ApiExtractor/abstractmetaenum.h b/sources/shiboken6/ApiExtractor/abstractmetaenum.h
index 2cf949f15..03d7a3082 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetaenum.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetaenum.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ABSTRACTMETAENUM_H
#define ABSTRACTMETAENUM_H
@@ -32,6 +7,7 @@
#include "abstractmetalang_typedefs.h"
#include "enclosingclassmixin.h"
#include "parser/codemodel_enums.h"
+#include "typesystem_typedefs.h"
#include <QtCore/QSharedDataPointer>
#include <QtCore/QString>
@@ -52,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;
@@ -65,9 +41,14 @@ public:
QString name() const;
void setName(const QString &name);
+ bool isDeprecated() const;
+ void setDeprecated(bool deprecated);
+
Documentation documentation() const;
void setDocumentation(const Documentation& doc);
+ int usedBits() const;
+
private:
QSharedDataPointer<AbstractMetaEnumValueData> d;
};
@@ -78,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;
@@ -95,6 +77,11 @@ public:
bool isPrivate() const { return access() == Access::Private; }
bool isProtected() const { return access() == Access::Protected; }
+ bool isDeprecated() const;
+ void setDeprecated(bool deprecated);
+ bool hasDeprecatedValues() const;
+ AbstractMetaEnumValueList deprecatedValues() const;
+
const Documentation &documentation() const;
void setDocumentation(const Documentation& doc);
@@ -113,12 +100,18 @@ public:
bool hasQEnumsDeclaration() const;
void setHasQEnumsDeclaration(bool on);
- EnumTypeEntry *typeEntry() const;
- void setTypeEntry(EnumTypeEntry *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 45ea5601a..27a76d04d 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafield.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetafield.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "abstractmetafield.h"
#include "abstractmetabuilder.h"
@@ -32,11 +7,16 @@
#include "abstractmetatype.h"
#include "documentation.h"
#include "modifications.h"
-#include "typesystem.h"
+#include "complextypeentry.h"
+#include "typesystemtypeentry.h"
#include "parser/codemodel.h"
+#include "qtcompat.h"
+
#include <QtCore/QDebug>
+using namespace Qt::StringLiterals;
+
class AbstractMetaFieldData : public QSharedData
{
public:
@@ -56,15 +36,15 @@ 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);
std::optional<AbstractMetaField>
AbstractMetaField::find(const AbstractMetaFieldList &haystack,
- const QString &needle)
+ QStringView needle)
{
for (const auto &f : haystack) {
if (f.name() == needle)
@@ -76,7 +56,7 @@ std::optional<AbstractMetaField>
/*******************************************************************************
* Indicates that this field has a modification that removes it
*/
-bool AbstractMetaField::isModifiedRemoved(int types) const
+bool AbstractMetaField::isModifiedRemoved() const
{
const FieldModificationList &mods = modifications();
for (const FieldModification &mod : mods) {
@@ -143,7 +123,7 @@ void AbstractMetaField::setStatic(bool s)
QString AbstractMetaField::qualifiedCppName() const
{
- return enclosingClass()->qualifiedCppName() + QLatin1String("::")
+ return enclosingClass()->qualifiedCppName() + u"::"_s
+ originalName();
}
@@ -222,7 +202,7 @@ TypeSystem::SnakeCase AbstractMetaField::snakeCase() const
auto typeEntry = enclosingClass()->typeEntry();
const auto snakeCase = typeEntry->snakeCase();
return snakeCase != TypeSystem::SnakeCase::Unspecified
- ? snakeCase : typeEntry->typeSystemTypeEntry()->snakeCase();
+ ? snakeCase : typeSystemTypeEntry(typeEntry)->snakeCase();
}
FieldModificationList AbstractMetaField::modifications() const
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafield.h b/sources/shiboken6/ApiExtractor/abstractmetafield.h
index 794cce462..0fa858791 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafield.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetafield.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ABSTRACTMETAFIELD_H
#define ABSTRACTMETAFIELD_H
@@ -32,6 +7,7 @@
#include "abstractmetalang_typedefs.h"
#include "parser/codemodel_enums.h"
#include "typesystem_enums.h"
+#include "modifications_typedefs.h"
#include "typesystem_typedefs.h"
#include "enclosingclassmixin.h"
@@ -50,13 +26,13 @@ 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;
- bool isModifiedRemoved(int types = TypeSystem::All) const;
+ bool isModifiedRemoved() const;
bool generateOpaqueContainer() const;
const AbstractMetaType &type() const;
@@ -95,7 +71,7 @@ public:
TypeSystem::SnakeCase snakeCase() const;
static std::optional<AbstractMetaField>
- find(const AbstractMetaFieldList &haystack, const QString &needle);
+ find(const AbstractMetaFieldList &haystack, QStringView needle);
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
index 4264eda3c..11a02f154 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
@@ -1,55 +1,42 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "abstractmetafunction.h"
+#include "abstractmetaargument.h"
#include "abstractmetabuilder.h"
#include "abstractmetalang.h"
#include "abstractmetalang_helpers.h"
#include "abstractmetatype.h"
+#include "addedfunction.h"
#include <codemodel.h>
#include "documentation.h"
#include "exception.h"
#include "messages.h"
+#include "codesnip.h"
#include "modifications.h"
-#include "propertyspec.h"
#include "reporthandler.h"
#include "sourcelocation.h"
#include "typedatabase.h"
-#include "typesystem.h"
+#include "complextypeentry.h"
+#include "containertypeentry.h"
+#include "functiontypeentry.h"
+#include "primitivetypeentry.h"
+#include "typesystemtypeentry.h"
+
+#include "qtcompat.h"
#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;
};
@@ -61,7 +48,6 @@ public:
AbstractMetaFunctionPrivate()
: m_constant(false),
m_reverse(false),
- m_explicit(false),
m_pointerOperator(false),
m_isCallOperator(false)
{
@@ -74,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);
@@ -85,23 +71,25 @@ public:
mutable QString m_cachedMinimalSignature;
mutable QString m_cachedSignature;
mutable QString m_cachedModifiedName;
+ QString m_unresolvedSignature;
- FunctionTypeEntry* m_typeEntry = nullptr;
+ FunctionTypeEntryPtr m_typeEntry;
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;
@@ -112,13 +100,17 @@ public:
TypeSystem::ExceptionHandling m_exceptionHandlingModification = TypeSystem::ExceptionHandling::Unspecified;
};
-AbstractMetaFunction::AbstractMetaFunction(const AddedFunctionPtr &addedFunc) :
+AbstractMetaFunction::AbstractMetaFunction(const QString &name) :
AbstractMetaFunction()
{
+ d->m_originalName = d->m_name = name;
+}
+
+AbstractMetaFunction::AbstractMetaFunction(const AddedFunctionPtr &addedFunc) :
+ AbstractMetaFunction(addedFunc->name())
+{
d->m_addedFunction = addedFunc;
setConstant(addedFunc->isConstant());
- setName(addedFunc->name());
- setOriginalName(addedFunc->name());
switch (addedFunc->access()) {
case AddedFunction::Protected:
setAccess(Access::Protected);
@@ -127,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);
@@ -222,20 +214,19 @@ 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
{
if (d->m_type.typeUsagePattern() != AbstractMetaType::PrimitivePattern)
return false;
- const auto *pte = d->m_type.typeEntry()->asPrimitive();
- return pte->basicReferencedTypeEntry()->name() == u"bool";
+ return basicReferencedTypeEntry(d->m_type.typeEntry())->name() == u"bool";
}
bool AbstractMetaFunction::isOperatorBool() const
@@ -270,12 +261,37 @@ 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;
+}
+
+void AbstractMetaFunction::setFlags(Flags f)
+{
+ d->m_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())
@@ -285,6 +301,17 @@ bool AbstractMetaFunction::isModifiedRemoved(const AbstractMetaClass *cls) const
return false;
}
+bool AbstractMetaFunction::isModifiedFinal(AbstractMetaClassCPtr cls) const
+{
+ if (!isInGlobalScope() && cls == nullptr)
+ cls = d->m_implementingClass;
+ for (const auto &mod : modifications(cls)) {
+ if (mod.modifiers().testFlag(FunctionModification::Final))
+ return true;
+ }
+ return false;
+}
+
bool AbstractMetaFunction::isVoid() const
{
return d->m_type.isVoid();
@@ -300,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;
}
@@ -329,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
@@ -360,10 +387,10 @@ AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const Abstra
maxArguments = arguments();
}
- int minCount = minArguments.size();
- int maxCount = maxArguments.size();
+ const auto minCount = minArguments.size();
+ const auto maxCount = maxArguments.size();
bool same = true;
- for (int i = 0; i < maxCount; ++i) {
+ for (qsizetype i = 0; i < maxCount; ++i) {
if (i < minCount) {
const AbstractMetaArgument &min_arg = minArguments.at(i);
const AbstractMetaArgument &max_arg = maxArguments.at(i);
@@ -414,6 +441,11 @@ 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());
cpy->setOriginalName(originalName());
@@ -450,35 +482,50 @@ 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:
return false;
default:
+ if (!isWhiteListed())
+ 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()
- && !isModifiedRemoved();
+ // 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();
}
-QStringList AbstractMetaFunction::introspectionCompatibleSignatures(const QStringList &resolvedArguments) const
+bool AbstractMetaFunction::isWhiteListed() const
{
- AbstractMetaArgumentList arguments = this->arguments();
- if (arguments.size() == resolvedArguments.size()) {
- QString signature = name() + QLatin1Char('(') + resolvedArguments.join(QLatin1Char(',')) + QLatin1Char(')');
- return QStringList(TypeDatabase::normalizedSignature(signature));
- }
- QStringList returned;
-
- const AbstractMetaArgument &argument = arguments.at(resolvedArguments.size());
- QStringList minimalTypeSignature = argument.type().minimalSignature().split(QLatin1String("::"));
- for (int i = 0; i < minimalTypeSignature.size(); ++i) {
- returned += introspectionCompatibleSignatures(QStringList(resolvedArguments)
- << QStringList(minimalTypeSignature.mid(minimalTypeSignature.size() - i - 1)).join(QLatin1String("::")));
+ switch (d->m_functionType) {
+ case NormalFunction:
+ case SignalFunction:
+ case SlotFunction:
+ if (auto dc = declaringClass()) {
+ const QSet<QString> &whiteList = dc->typeEntry()->generateFunctions();
+ return whiteList.isEmpty() || whiteList.contains(d->m_name)
+ || whiteList.contains(minimalSignature());
+ }
+ break;
+ default:
+ break;
}
-
- return returned;
+ return true;
}
QString AbstractMetaFunctionPrivate::signature() const
@@ -486,22 +533,22 @@ QString AbstractMetaFunctionPrivate::signature() const
if (m_cachedSignature.isEmpty()) {
m_cachedSignature = m_originalName;
- m_cachedSignature += QLatin1Char('(');
+ m_cachedSignature += u'(';
- for (int i = 0; i < m_arguments.count(); ++i) {
+ for (qsizetype i = 0; i < m_arguments.size(); ++i) {
const AbstractMetaArgument &a = m_arguments.at(i);
const AbstractMetaType &t = a.type();
if (i > 0)
- m_cachedSignature += QLatin1String(", ");
+ m_cachedSignature += u", "_s;
m_cachedSignature += t.cppSignature();
// We need to have the argument names in the qdoc files
- m_cachedSignature += QLatin1Char(' ');
+ m_cachedSignature += u' ';
m_cachedSignature += a.name();
}
- m_cachedSignature += QLatin1Char(')');
+ m_cachedSignature += u')';
if (m_constant)
- m_cachedSignature += QLatin1String(" const");
+ m_cachedSignature += u" const"_s;
}
return m_cachedSignature;
}
@@ -511,6 +558,25 @@ QString AbstractMetaFunction::signature() const
return d->signature();
}
+QString AbstractMetaFunction::classQualifiedSignature() const
+{
+ QString result;
+ if (d->m_implementingClass)
+ result += d->m_implementingClass->qualifiedCppName() + u"::"_s;
+ result += signature();
+ return result;
+}
+
+QString AbstractMetaFunction::unresolvedSignature() const
+{
+ return d->m_unresolvedSignature;
+}
+
+void AbstractMetaFunction::setUnresolvedSignature(const QString &s)
+{
+ d->m_unresolvedSignature = s;
+}
+
bool AbstractMetaFunction::isConstant() const
{
return d->m_constant;
@@ -523,18 +589,23 @@ 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
{
int count = 0;
- for (int i = 0, size = d->m_arguments.size(); i < size; ++i && ++count) {
+ for (qsizetype i = 0, size = d->m_arguments.size(); i < size; ++i && ++count) {
const auto &arg = d->m_arguments.at(i);
if (arg.isModifiedRemoved())
--count;
@@ -545,8 +616,20 @@ int AbstractMetaFunction::actualMinimumArgumentCount() const
return count;
}
+int AbstractMetaFunction::actualArgumentIndex(int index) const
+{
+ if (index < 0 || index >= int(d->m_arguments.size()))
+ throw Exception(msgArgumentIndexOutOfRange(this, index));
+ int result = 0;
+ for (int i = 0; i < index; ++i) {
+ if (!d->m_arguments.at(i).isModifiedRemoved())
+ ++result;
+ }
+ return result;
+}
+
// 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;
@@ -561,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()) {
@@ -590,6 +673,11 @@ QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int
return QString();
}
+bool AbstractMetaFunction::hasConversionRule(TypeSystem::Language language, int idx) const
+{
+ return !conversionRule(language, idx).isEmpty();
+}
+
// FIXME If we remove a arg. in the method at the base class, it will not reflect here.
bool AbstractMetaFunction::argumentRemoved(int key) const
{
@@ -605,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;
}
@@ -651,13 +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
{
- 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
@@ -702,6 +800,24 @@ void AbstractMetaFunction::setFunctionType(AbstractMetaFunction::FunctionType ty
d->m_functionType = type;
}
+std::optional<AbstractMetaFunction::ComparisonOperatorType>
+AbstractMetaFunction::comparisonOperatorType() const
+{
+ if (d->m_functionType != ComparisonOperator)
+ return {};
+ static const QHash<QString, ComparisonOperatorType> mapping = {
+ {u"operator=="_s, OperatorEqual},
+ {u"operator!="_s, OperatorNotEqual},
+ {u"operator<"_s, OperatorLess},
+ {u"operator<="_s, OperatorLessEqual},
+ {u"operator>"_s, OperatorGreater},
+ {u"operator>="_s, OperatorGreaterEqual}
+ };
+ const auto it = mapping.constFind(originalName());
+ Q_ASSERT(it != mapping.constEnd());
+ return it.value();
+}
+
// Auto-detect whether a function should be wrapped into
// Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS, that is, temporarily release
// the GIL (global interpreter lock). Doing so is required for any thread-wait
@@ -711,8 +827,13 @@ void AbstractMetaFunction::setFunctionType(AbstractMetaFunction::FunctionType ty
bool AbstractMetaFunction::autoDetectAllowThread() const
{
// Disallow for simple getter functions.
- const bool maybeGetter = d->m_constant != 0 && !isVoid() && d->m_arguments.isEmpty();
- return !maybeGetter;
+ return !maybeAccessor();
+}
+
+bool AbstractMetaFunction::maybeAccessor() const
+{
+ return d->m_functionType == NormalFunction && d->m_class != nullptr
+ && d->m_constant != 0 && !isVoid() && d->m_arguments.isEmpty();
}
SourceLocation AbstractMetaFunction::sourceLocation() const
@@ -725,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;
}
@@ -763,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()) {
@@ -782,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
@@ -871,22 +997,24 @@ QString AbstractMetaFunction::pyiTypeReplaced(int argumentIndex) const
QString AbstractMetaFunctionPrivate::formatMinimalSignature(const AbstractMetaFunction *q,
bool comment) const
{
- QString result = m_originalName + QLatin1Char('(');
- for (int i = 0; i < m_arguments.count(); ++i) {
+ 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 += QLatin1Char(',');
+ 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 += QLatin1Char(')');
+ result += u')';
if (m_constant)
- result += QLatin1String("const");
+ result += u"const"_s;
result = TypeDatabase::normalizedSignature(result);
if (comment && !q->isVoid()) {
- result += u"->"_qs;
+ result += u"->"_s;
result += q->isTypeModified()
? q->modifiedTypeName() : q->type().minimalSignature();
}
@@ -900,6 +1028,14 @@ QString AbstractMetaFunction::minimalSignature() const
return d->m_cachedMinimalSignature;
}
+QStringList AbstractMetaFunction::modificationSignatures() const
+{
+ QStringList result{minimalSignature()};
+ if (d->m_unresolvedSignature != result.constFirst())
+ result.append(d->m_unresolvedSignature);
+ return result;
+}
+
QString AbstractMetaFunction::signatureComment() const
{
return d->formatMinimalSignature(this, true);
@@ -908,25 +1044,28 @@ 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))
- result += QLatin1String("virtual ");
+ 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;
result += minimalSignature();
if (isOverride)
- result += QLatin1String(" override");
+ result += u" override"_s;
if (isFinal)
- result += QLatin1String(" final");
+ result += u" final"_s;
return result;
}
FunctionModificationList AbstractMetaFunction::findClassModifications(const AbstractMetaFunction *f,
- const AbstractMetaClass *implementor)
+ AbstractMetaClassCPtr implementor)
{
- const QString signature = f->minimalSignature();
+ const auto signatures = f->modificationSignatures();
FunctionModificationList mods;
while (implementor) {
- mods += implementor->typeEntry()->functionModifications(signature);
+ mods += implementor->typeEntry()->functionModifications(signatures);
if ((implementor == implementor->baseClass()) ||
(implementor == f->implementingClass() && !mods.isEmpty())) {
break;
@@ -938,15 +1077,16 @@ FunctionModificationList AbstractMetaFunction::findClassModifications(const Abst
FunctionModificationList AbstractMetaFunction::findGlobalModifications(const AbstractMetaFunction *f)
{
- return TypeDatabase::instance()->functionModifications(f->minimalSignature());
+ auto *td = TypeDatabase::instance();
+ return td->globalFunctionModifications(f->modificationSignatures());
}
const FunctionModificationList &
AbstractMetaFunctionPrivate::modifications(const AbstractMetaFunction *q,
- const AbstractMetaClass *implementor) const
+ const AbstractMetaClassCPtr &implementor) const
{
- if (!m_addedFunction.isNull())
- return m_addedFunction->modifications;
+ if (m_addedFunction)
+ return m_addedFunction->modifications();
for (const auto &ce : m_modificationCache) {
if (ce.klass == implementor)
return ce.modifications;
@@ -960,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);
}
@@ -972,9 +1112,15 @@ void AbstractMetaFunction::clearModificationsCache()
d->m_modificationCache.clear();
}
+const DocModificationList AbstractMetaFunction::addedFunctionDocModifications() const
+{
+ 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();
}
@@ -989,19 +1135,30 @@ void AbstractMetaFunction::setPropertySpecIndex(int i)
d->m_propertySpecIndex = i;
}
-FunctionTypeEntry *AbstractMetaFunction::typeEntry() const
+FunctionTypeEntryPtr AbstractMetaFunction::typeEntry() const
{
return d->m_typeEntry;
}
-void AbstractMetaFunction::setTypeEntry(FunctionTypeEntry *typeEntry)
+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 == QLatin1String("operator()");
+ return d->m_name == u"operator()";
}
bool AbstractMetaFunction::hasInjectedCode() const
@@ -1082,7 +1239,7 @@ bool AbstractMetaFunction::hasSignatureModifications() const
bool AbstractMetaFunction::isConversionOperator(const QString &funcName)
{
- return funcName.startsWith(QLatin1String("operator "));
+ return funcName.startsWith(u"operator ");
}
ExceptionSpecification AbstractMetaFunction::exceptionSpecification() const
@@ -1095,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;
}
@@ -1153,11 +1310,11 @@ bool AbstractMetaFunction::isOperatorOverload(const QString &funcName)
if (isConversionOperator(funcName))
return true;
- static const QRegularExpression opRegEx(QLatin1String("^operator([+\\-\\*/%=&\\|\\^\\<>!][=]?"
+ static const QRegularExpression opRegEx(u"^operator([+\\-\\*/%=&\\|\\^\\<>!][=]?"
"|\\+\\+|\\-\\-|&&|\\|\\||<<[=]?|>>[=]?|~"
"|\\[\\]|\\s+delete\\[?\\]?"
"|\\(\\)"
- "|\\s+new\\[?\\]?)$"));
+ "|\\s+new\\[?\\]?)$"_s);
Q_ASSERT(opRegEx.isValid());
return opRegEx.match(funcName).hasMatch();
}
@@ -1184,22 +1341,27 @@ bool AbstractMetaFunction::isComparisonOperator() const
return d->m_functionType == ComparisonOperator;
}
+bool AbstractMetaFunction::isSymmetricalComparisonOperator() const
+{
+ if (d->m_functionType != ComparisonOperator || d->m_class == nullptr)
+ return false;
+ AbstractMetaType classType(d->m_class->typeEntry());
+ classType.decideUsagePattern();
+ return std::all_of(d->m_arguments.constBegin(), d->m_arguments.constEnd(),
+ [classType](const AbstractMetaArgument &a) {
+ return a.type().isEquivalent(classType);});
+}
+
bool AbstractMetaFunction::isIncDecrementOperator() const
{
return d->m_functionType == IncrementOperator
|| d->m_functionType == DecrementOperator;
}
-
bool AbstractMetaFunction::isLogicalOperator() const
{
return d->m_functionType == LogicalOperator;
}
-bool AbstractMetaFunction::isSubscriptOperator() const
-{
- return d->m_functionType == SubscriptOperator;
-}
-
bool AbstractMetaFunction::isAssignmentOperator() const
{
return d->m_functionType == AssignmentOperatorFunction
@@ -1249,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
@@ -1274,7 +1436,7 @@ QString AbstractMetaFunction::modifiedName() const
AbstractMetaFunctionCPtr
AbstractMetaFunction::find(const AbstractMetaFunctionCList &haystack,
- const QString &needle)
+ QAnyStringView needle)
{
for (const auto &f : haystack) {
if (f->name() == needle)
@@ -1312,6 +1474,8 @@ bool AbstractMetaFunction::matches(OperatorQueryOptions query) const
break;
case AbstractMetaFunction::ComparisonOperator:
result = query.testFlag(OperatorQueryOption::ComparisonOp);
+ if (!result && query.testFlag(OperatorQueryOption::SymmetricalComparisonOp))
+ result = isSymmetricalComparisonOperator();
break;
default:
break;
@@ -1370,17 +1534,14 @@ 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 : d->m_typeEntry->typeSystemTypeEntry()->snakeCase();
- }
+ if (d->m_typeEntry) // Global function
+ return typeSystemTypeEntry(d->m_typeEntry)->snakeCase();
if (d->m_class) {
auto typeEntry = d->m_class->typeEntry();
const auto snakeCase = typeEntry->snakeCase();
return snakeCase != TypeSystem::SnakeCase::Unspecified
- ? snakeCase : typeEntry->typeSystemTypeEntry()->snakeCase();
+ ? snakeCase : typeSystemTypeEntry(typeEntry)->snakeCase();
}
return TypeSystem::SnakeCase::Disabled;
}
@@ -1394,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);
@@ -1404,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);
}
@@ -1434,6 +1595,38 @@ bool AbstractMetaFunction::isVisibilityModifiedToPrivate() const
return false;
}
+struct ComparisonOperator
+{
+ const char *cppOperator;
+ const char *pythonOpCode;
+};
+
+using ComparisonOperatorMapping =
+ QHash<AbstractMetaFunction::ComparisonOperatorType, ComparisonOperator>;
+
+static const ComparisonOperatorMapping &comparisonOperatorMapping()
+{
+ static const ComparisonOperatorMapping result = {
+ {AbstractMetaFunction::OperatorEqual, {"==", "Py_EQ"}},
+ {AbstractMetaFunction::OperatorNotEqual, {"!=", "Py_NE"}},
+ {AbstractMetaFunction::OperatorLess, {"<", "Py_LT"}},
+ {AbstractMetaFunction::OperatorLessEqual, {"<=", "Py_LE"}},
+ {AbstractMetaFunction::OperatorGreater, {">", "Py_GT"}},
+ {AbstractMetaFunction::OperatorGreaterEqual, {">=", "Py_GE"}}
+ };
+ return result;
+}
+
+const char * AbstractMetaFunction::pythonRichCompareOpCode(ComparisonOperatorType ct)
+{
+ return comparisonOperatorMapping().value(ct).pythonOpCode;
+}
+
+const char * AbstractMetaFunction::cppComparisonOperator(ComparisonOperatorType ct)
+{
+ return comparisonOperatorMapping().value(ct).cppOperator;
+}
+
#ifndef QT_NO_DEBUG_STREAM
void AbstractMetaFunction::formatDebugBrief(QDebug &debug) const
{
@@ -1459,12 +1652,15 @@ void AbstractMetaFunction::formatDebugVerbose(QDebug &debug) const
if (d->m_exceptionHandlingModification != TypeSystem::ExceptionHandling::Unspecified)
debug << " exeption-mod " << int(d->m_exceptionHandlingModification);
debug << '(';
- for (int i = 0, count = d->m_arguments.size(); i < count; ++i) {
+ for (qsizetype i = 0, count = d->m_arguments.size(); i < count; ++i) {
if (i)
debug << ", ";
debug << d->m_arguments.at(i);
}
- debug << "), signature=\"" << minimalSignature() << '"';
+ const QString signature = minimalSignature();
+ debug << "), signature=\"" << signature << '"';
+ if (signature != d->m_unresolvedSignature)
+ debug << ", unresolvedSignature=\"" << d->m_unresolvedSignature << '"';
if (d->m_constant)
debug << " [const]";
if (d->m_reverse)
@@ -1473,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 1cbae5ed6..e252e439d 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafunction.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.h
@@ -1,42 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ABSTRACTMETAFUNCTION_H
#define ABSTRACTMETAFUNCTION_H
#include "abstractmetalang_enums.h"
#include "abstractmetalang_typedefs.h"
-#include "abstractmetaargument.h"
#include "typesystem_enums.h"
+#include "modifications_typedefs.h"
#include "typesystem_typedefs.h"
+#include "parser/codemodel_enums.h"
+#include <QtCore/QMetaObject>
#include <QtCore/QScopedPointer>
+#include <optional>
+
QT_FORWARD_DECLARE_CLASS(QDebug)
QT_FORWARD_DECLARE_CLASS(QRegularExpression)
@@ -53,6 +32,8 @@ class AbstractMetaFunction
{
Q_GADGET
public:
+ Q_DISABLE_COPY_MOVE(AbstractMetaFunction)
+
enum FunctionType {
ConstructorFunction,
CopyConstructorFunction,
@@ -84,6 +65,12 @@ public:
};
Q_ENUM(FunctionType)
+ enum ComparisonOperatorType {
+ OperatorEqual, OperatorNotEqual, OperatorLess, OperatorLessEqual,
+ OperatorGreater, OperatorGreaterEqual
+ };
+ Q_ENUM(ComparisonOperatorType)
+
enum CompareResultFlag {
EqualName = 0x00000001,
EqualArguments = 0x00000002,
@@ -105,29 +92,18 @@ public:
enum Attribute {
None = 0x00000000,
- Friendly = 0x00000001,
-
- Abstract = 0x00000002,
- Static = 0x00000004,
ClassMethod = 0x00000008,
- FinalInTargetLang = 0x00000010,
-
GetterFunction = 0x00000020,
SetterFunction = 0x00000040,
PropertyReader = 0x00000100,
PropertyWriter = 0x00000200,
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
};
Q_DECLARE_FLAGS(Attributes, Attribute)
Q_FLAG(Attribute)
@@ -138,17 +114,33 @@ public:
void operator+=(Attribute attribute);
void operator-=(Attribute attribute);
- bool isFinalInTargetLang() const;
+ 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,
+ OperatorTrailingClassArgumentRemoved = 0x2,
+ OperatorClassArgumentByValue = 0x4, // The removed class argument was passed by value
+ InheritedFromTemplate = 0x8, // Inherited from a template in metabuilder
+ HiddenFriend = 0x10,
+ PrivateSignal = 0x20 // Private Qt signal (cannot emit from client code)
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
+ Flags flags() const;
+ void setFlags(Flags f);
+
bool isAbstract() const;
bool isClassMethod() const;
bool isStatic() const;
- bool isInvokable() const;
bool isPropertyReader() const;
bool isPropertyWriter() const;
bool isPropertyResetter() const;
- bool isFriendly() const;
AbstractMetaFunction();
+ explicit AbstractMetaFunction(const QString &name);
explicit AbstractMetaFunction(const AddedFunctionPtr &addedFunc);
~AbstractMetaFunction();
@@ -210,9 +202,11 @@ public:
bool isArithmeticOperator() const;
bool isBitwiseOperator() const; // Includes shift operator
bool isComparisonOperator() const;
+ /// Returns whether this is a comparison accepting owner class
+ /// (bool operator==(QByteArray,QByteArray) but not bool operator==(QByteArray,const char *)
+ bool isSymmetricalComparisonOperator() const;
bool isIncDecrementOperator() const;
bool isLogicalOperator() const;
- bool isSubscriptOperator() const;
bool isAssignmentOperator() const; // Assignment or move assignment
bool isGetter() const;
/// Returns whether it is a Qt-style isNull() method suitable for nb_bool
@@ -233,12 +227,15 @@ public:
QString modifiedName() const;
QString minimalSignature() const;
+ /// List of signatures matched for modifications
+ QStringList modificationSignatures() const;
// Signature with replaced argument types and return type for overload
// decisor comment.
QString signatureComment() const;
QString debugSignature() const; // including virtual/override/final, etc., for debugging only.
- bool isModifiedRemoved(const AbstractMetaClass *cls = nullptr) const;
+ bool isModifiedRemoved(AbstractMetaClassCPtr cls = {}) const;
+ bool isModifiedFinal(AbstractMetaClassCPtr cls = {}) const;
bool isVoid() const;
@@ -246,25 +243,27 @@ 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();
void setArguments(const AbstractMetaArgumentList &arguments);
void addArgument(const AbstractMetaArgument &argument);
int actualMinimumArgumentCount() const;
+ // Return the argument index accounting for the isModifiedRemoved arguments [0..n-1]
+ int actualArgumentIndex(int index) const;
bool isDeprecated() const;
bool isDestructor() const { return functionType() == DestructorFunction; }
@@ -276,20 +275,32 @@ public:
bool isSignal() const { return functionType() == SignalFunction; }
bool isSlot() const { return functionType() == SlotFunction; }
bool isEmptyFunction() const { return functionType() == EmptyFunction; }
+ bool maybeAccessor() const;
FunctionType functionType() const;
void setFunctionType(FunctionType type);
+ std::optional<ComparisonOperatorType> comparisonOperatorType() const;
+
bool usesRValueReferences() const;
bool generateBinding() const;
+ // Returns whether the function is contained in the positive list of the
+ // type entry if one is specified.
+ bool isWhiteListed() const;
- QStringList introspectionCompatibleSignatures(const QStringList &resolvedArguments = QStringList()) const;
QString signature() const;
+ /// Return a signature qualified by class name, for error reporting.
+ QString classQualifiedSignature() const;
+
+ /// Signature with unresolved typedefs as seen by the code parser
+ QString unresolvedSignature() const;
+ void setUnresolvedSignature(const QString &);
bool isConstant() const;
void setConstant(bool constant);
/// 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;
@@ -302,11 +313,14 @@ public:
AbstractMetaFunction *copy() const;
QString conversionRule(TypeSystem::Language language, int idx) const;
- QList<ReferenceCount> referenceCounts(const AbstractMetaClass *cls, int idx = -2) const;
- ArgumentOwner argumentOwner(const AbstractMetaClass *cls, int idx) const;
+ bool hasConversionRule(TypeSystem::Language language, 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(); }
@@ -346,29 +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);
- FunctionTypeEntry* typeEntry() const;
+ FunctionTypeEntryPtr typeEntry() const;
+ void setTypeEntry(const FunctionTypeEntryPtr &typeEntry);
- void setTypeEntry(FunctionTypeEntry* typeEntry);
+ QString targetLangPackage() const;
bool isCallOperator() const;
static AbstractMetaFunctionCPtr
- find(const AbstractMetaFunctionCList &haystack, const QString &needle);
+ find(const AbstractMetaFunctionCList &haystack, QAnyStringView needle);
bool matches(OperatorQueryOptions) const;
@@ -414,6 +431,9 @@ public:
SourceLocation sourceLocation() const;
void setSourceLocation(const SourceLocation &sourceLocation);
+ static const char *pythonRichCompareOpCode(ComparisonOperatorType ct);
+ static const char *cppComparisonOperator(ComparisonOperatorType ct);
+
private:
template <class Predicate>
bool traverseCodeSnips(Predicate predicate,
@@ -424,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
@@ -444,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);
@@ -464,15 +474,12 @@ inline bool AbstractMetaFunction::isPropertyResetter() const
return attributes().testFlag(PropertyResetter);
}
-inline bool AbstractMetaFunction::isFriendly() const
-{
- return attributes().testFlag(Friendly);
-}
-
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaFunction::CompareResult)
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaFunction::Attributes);
+Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaFunction::Flags);
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const AbstractMetaFunction *af);
#endif
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
index 9e6b3d44e..fb49cc9d0 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang.cpp
@@ -1,36 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// 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"
#include "abstractmetafunction.h"
+#include "abstractmetatype.h"
#include "abstractmetafield.h"
+#include "parser/codemodel.h"
#include "documentation.h"
#include "messages.h"
#include "modifications.h"
@@ -38,13 +17,18 @@
#include "reporthandler.h"
#include "sourcelocation.h"
#include "typedatabase.h"
-#include "typesystem.h"
+#include "enumtypeentry.h"
+#include "namespacetypeentry.h"
#include "usingmember.h"
+#include "qtcompat.h"
+
#include <QtCore/QDebug>
#include <algorithm>
+using namespace Qt::StringLiterals;
+
bool function_sorter(const AbstractMetaFunctionCPtr &a, const AbstractMetaFunctionCPtr &b)
{
return a->signature() < b->signature();
@@ -66,9 +50,6 @@ public:
m_hasPrivateDestructor(false),
m_hasProtectedDestructor(false),
m_hasVirtualDestructor(false),
- m_hasHashFunction(false),
- m_hasEqualsOperator(false),
- m_hasCloneOperator(false),
m_isTypeDef(false),
m_hasToStringCapability(false),
m_valueTypeWithCopyConstructorOnly(false),
@@ -76,20 +57,23 @@ public:
{
}
- ~AbstractMetaClassPrivate()
- {
- qDeleteAll(m_templateArgs);
- }
-
void addFunction(const AbstractMetaFunctionCPtr &function);
+ static AbstractMetaFunction *
+ createFunction(const QString &name, AbstractMetaFunction::FunctionType t,
+ Access access, const AbstractMetaArgumentList &arguments,
+ 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;
uint m_hasVirtuals : 1;
uint m_isPolymorphic : 1;
@@ -103,9 +87,6 @@ public:
uint m_hasPrivateDestructor : 1;
uint m_hasProtectedDestructor : 1;
uint m_hasVirtualDestructor : 1;
- uint m_hasHashFunction : 1;
- uint m_hasEqualsOperator : 1;
- uint m_hasCloneOperator : 1;
uint m_isTypeDef : 1;
uint m_hasToStringCapability : 1;
uint m_valueTypeWithCopyConstructorOnly : 1;
@@ -113,24 +94,26 @@ public:
Documentation m_doc;
- const AbstractMetaClass *m_enclosingClass = nullptr;
- AbstractMetaClass *m_defaultSuperclass = nullptr;
- AbstractMetaClassList m_baseClasses; // Real base classes after setting up inheritance
+ 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;
- AbstractMetaClassList m_innerClasses;
+ AbstractMetaClassCList m_innerClasses;
+ QString m_hashFunction;
AbstractMetaFunctionCList m_externalConversionOperators;
QStringList m_baseClassNames; // Base class names from C++, including rejected
- TypeEntries m_templateArgs;
- ComplexTypeEntry *m_typeEntry = nullptr;
+ TypeEntryCList m_templateArgs;
+ ComplexTypeEntryPtr m_typeEntry;
SourceLocation m_sourceLocation;
UsingMembers m_usingMembers;
@@ -195,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::Constructors
- | default_flags | public_flags);
-
- // Final functions
- returned += queryFunctions(FunctionQueryOption::FinalInTargetLangFunctions
- | FunctionQueryOption::NonStaticFunctions
- | default_flags | public_flags);
+ AbstractMetaFunctionCList returned = queryFunctions(FunctionQueryOption::AnyConstructor
+ | 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);
@@ -227,7 +197,7 @@ AbstractMetaFunctionCList AbstractMetaClass::functionsInTargetLang() const
AbstractMetaFunctionCList AbstractMetaClass::implicitConversions() const
{
- if (!hasCloneOperator() && !hasExternalConversionOperators())
+ if (!isCopyConstructible() && !hasExternalConversionOperators())
return {};
AbstractMetaFunctionCList returned;
@@ -239,7 +209,6 @@ AbstractMetaFunctionCList AbstractMetaClass::implicitConversions() const
for (const auto &f : list) {
if ((f->actualMinimumArgumentCount() == 1 || f->arguments().size() == 1 || f->isConversionOperator())
&& !f->isExplicit()
- && f->functionType() != AbstractMetaFunction::CopyConstructorFunction
&& !f->usesRValueReferences()
&& !f->isModifiedRemoved()
&& f->wasPublic()) {
@@ -337,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;
}
@@ -355,48 +324,29 @@ const AbstractMetaFunctionCList &AbstractMetaClass::functions() const
return d->m_functions;
}
-void AbstractMetaClass::setFunctions(const AbstractMetaFunctionCList &functions)
-{
- d->m_functions = functions;
-
- // Functions must be sorted by name before next loop
- sortFunctions();
-
- for (const auto &f : qAsConst(d->m_functions)) {
- qSharedPointerConstCast<AbstractMetaFunction>(f)->setOwnerClass(this);
- if (!f->isPublic())
- d->m_hasNonpublic = true;
- }
-}
-
-bool AbstractMetaClass::hasDefaultToStringFunction() const
+const AbstractMetaFunctionCList &AbstractMetaClass::userAddedPythonOverrides() const
{
- const auto &funcs = queryFunctionsByName(QLatin1String("toString"));
- for (const auto &f : funcs) {
- if (!f->actualMinimumArgumentCount())
- return true;
- }
- return false;
+ return d->m_userAddedPythonOverrides;
}
-bool AbstractMetaClass::hasEqualsOperator() const
+void AbstractMetaClassPrivate::sortFunctions()
{
- return d->m_hasEqualsOperator;
+ std::sort(m_functions.begin(), m_functions.end(), function_sorter);
}
-void AbstractMetaClass::setHasEqualsOperator(bool on)
+void AbstractMetaClassPrivate::setFunctions(const AbstractMetaFunctionCList &functions,
+ const AbstractMetaClassCPtr &q)
{
- d->m_hasEqualsOperator = on;
-}
+ m_functions = functions;
-bool AbstractMetaClass::hasCloneOperator() const
-{
- return d->m_hasCloneOperator;
-}
+ // Functions must be sorted by name before next loop
+ sortFunctions();
-void AbstractMetaClass::setHasCloneOperator(bool on)
-{
- d->m_hasCloneOperator = on;
+ for (const auto &f : std::as_const(m_functions)) {
+ std::const_pointer_cast<AbstractMetaFunction>(f)->setOwnerClass(q);
+ if (!f->isPublic())
+ m_hasNonpublic = true;
+ }
}
const QList<QPropertySpec> &AbstractMetaClass::propertySpecs() const
@@ -409,9 +359,16 @@ void AbstractMetaClass::addPropertySpec(const QPropertySpec &spec)
d->m_propertySpecs << spec;
}
+void AbstractMetaClass::setPropertyDocumentation(const QString &name, const Documentation &doc)
+{
+ const auto index = d->indexOfProperty(name);
+ if (index >= 0)
+ d->m_propertySpecs[index].setDocumentation(doc);
+}
+
void AbstractMetaClassPrivate::addFunction(const AbstractMetaFunctionCPtr &function)
{
- Q_ASSERT(!function->signature().startsWith(QLatin1Char('(')));
+ Q_ASSERT(!function->signature().startsWith(u'('));
if (!function->isDestructor())
m_functions << function;
@@ -421,12 +378,31 @@ void AbstractMetaClassPrivate::addFunction(const AbstractMetaFunctionCPtr &funct
m_hasVirtuals |= function->isVirtual();
m_isPolymorphic |= m_hasVirtuals;
m_hasNonpublic |= !function->isPublic();
+ m_hasNonPrivateConstructor |= !function->isPrivate()
+ && function->functionType() == AbstractMetaFunction::ConstructorFunction;
}
-void AbstractMetaClass::addFunction(const AbstractMetaFunctionCPtr &function)
+void AbstractMetaClass::addFunction(const AbstractMetaClassPtr &klass,
+ const AbstractMetaFunctionCPtr &function)
{
- qSharedPointerConstCast<AbstractMetaFunction>(function)->setOwnerClass(this);
- d->addFunction(function);
+ 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(klass);
+
+ // Some of the queries below depend on the implementing class being set
+ // to function properly. Such as function modifications
+ nonConstF->setImplementingClass(klass);
+
+ 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
@@ -464,32 +440,32 @@ QString AbstractMetaClass::baseClassName() const
}
// Attribute "default-superclass"
-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;
}
-AbstractMetaClass *AbstractMetaClass::baseClass() const
+AbstractMetaClassCPtr AbstractMetaClass::baseClass() const
{
return d->m_baseClasses.value(0, nullptr);
}
-const AbstractMetaClassList &AbstractMetaClass::baseClasses() const
+const AbstractMetaClassCList &AbstractMetaClass::baseClasses() const
{
Q_ASSERT(inheritanceDone() || !needsInheritanceSetup());
return d->m_baseClasses;
}
// base classes including "defaultSuperclass".
-AbstractMetaClassList AbstractMetaClass::typeSystemBaseClasses() const
+AbstractMetaClassCList AbstractMetaClass::typeSystemBaseClasses() const
{
- AbstractMetaClassList result = d->m_baseClasses;
- if (d->m_defaultSuperclass != nullptr) {
+ AbstractMetaClassCList result = d->m_baseClasses;
+ if (d->m_defaultSuperclass) {
result.removeAll(d->m_defaultSuperclass);
result.prepend(d->m_defaultSuperclass);
}
@@ -497,25 +473,25 @@ AbstractMetaClassList AbstractMetaClass::typeSystemBaseClasses() const
}
// Recursive list of all base classes including defaultSuperclass
-AbstractMetaClassList AbstractMetaClass::allTypeSystemAncestors() const
+AbstractMetaClassCList AbstractMetaClass::allTypeSystemAncestors() const
{
- AbstractMetaClassList result;
- const AbstractMetaClassList baseClasses = typeSystemBaseClasses();
- for (AbstractMetaClass *base : baseClasses) {
+ AbstractMetaClassCList result;
+ const auto baseClasses = typeSystemBaseClasses();
+ for (const auto &base : baseClasses) {
result.append(base);
result.append(base->allTypeSystemAncestors());
}
return result;
}
-void AbstractMetaClass::addBaseClass(AbstractMetaClass *baseClass)
+void AbstractMetaClass::addBaseClass(const AbstractMetaClassCPtr &baseClass)
{
Q_ASSERT(baseClass);
d->m_baseClasses.append(baseClass);
d->m_isPolymorphic |= baseClass->isPolymorphic();
}
-void AbstractMetaClass::setBaseClass(AbstractMetaClass *baseClass)
+void AbstractMetaClass::setBaseClass(const AbstractMetaClassCPtr &baseClass)
{
if (baseClass) {
d->m_baseClasses.prepend(baseClass);
@@ -523,27 +499,27 @@ void AbstractMetaClass::setBaseClass(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;
}
-const AbstractMetaClassList &AbstractMetaClass::innerClasses() const
+const AbstractMetaClassCList &AbstractMetaClass::innerClasses() const
{
return d->m_innerClasses;
}
-void AbstractMetaClass::addInnerClass(AbstractMetaClass *cl)
+void AbstractMetaClass::addInnerClass(const AbstractMetaClassPtr &cl)
{
d->m_innerClasses << cl;
}
-void AbstractMetaClass::setInnerClasses(const AbstractMetaClassList &innerClasses)
+void AbstractMetaClass::setInnerClasses(const AbstractMetaClassCList &innerClasses)
{
d->m_innerClasses = innerClasses;
}
@@ -566,9 +542,19 @@ bool AbstractMetaClass::isInvisibleNamespace() const
&& !NamespaceTypeEntry::isVisibleScope(d->m_typeEntry);
}
+bool AbstractMetaClass::isInlineNamespace() const
+{
+ bool result = false;
+ if (d->m_typeEntry->isNamespace()) {
+ const auto nte = std::static_pointer_cast<const NamespaceTypeEntry>(d->m_typeEntry);
+ result = nte->isInlineNamespace();
+ }
+ return result;
+}
+
bool AbstractMetaClass::isQtNamespace() const
{
- return isNamespace() && name() == QLatin1String("Qt");
+ return isNamespace() && name() == u"Qt";
}
QString AbstractMetaClass::qualifiedCppName() const
@@ -578,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(const QString &functionName) const
+AbstractMetaFunctionCPtr AbstractMetaClass::findFunction(QAnyStringView functionName) const
{
return AbstractMetaFunction::find(d->m_functions, functionName);
}
-AbstractMetaFunctionCList AbstractMetaClass::findFunctions(const QString &functionName) const
+AbstractMetaFunctionCList AbstractMetaClass::findFunctions(QAnyStringView functionName) const
{
AbstractMetaFunctionCList result;
std::copy_if(d->m_functions.cbegin(), d->m_functions.cend(),
@@ -619,15 +605,6 @@ AbstractMetaFunctionCPtr AbstractMetaClass::findQtIsNullMethod() const
return *it;
}
-bool AbstractMetaClass::hasProtectedFunctions() const
-{
- for (const auto &func : d->m_functions) {
- if (func->isProtected())
- return true;
- }
- return false;
-}
-
bool AbstractMetaClass::hasProtectedFields() const
{
for (const AbstractMetaField &field : d->m_fields) {
@@ -637,17 +614,12 @@ bool AbstractMetaClass::hasProtectedFields() const
return false;
}
-bool AbstractMetaClass::hasProtectedMembers() const
-{
- return hasProtectedFields() || hasProtectedFunctions();
-}
-
-const TypeEntries &AbstractMetaClass::templateArguments() const
+const TypeEntryCList &AbstractMetaClass::templateArguments() const
{
return d->m_templateArgs;
}
-void AbstractMetaClass::setTemplateArguments(const TypeEntries &args)
+void AbstractMetaClass::setTemplateArguments(const TypeEntryCList &args)
{
d->m_templateArgs = args;
}
@@ -662,36 +634,41 @@ void AbstractMetaClass::setBaseClassNames(const QStringList &names)
d->m_baseClassNames = names;
}
-const ComplexTypeEntry *AbstractMetaClass::typeEntry() const
+ComplexTypeEntryCPtr AbstractMetaClass::typeEntry() const
{
return d->m_typeEntry;
}
-ComplexTypeEntry *AbstractMetaClass::typeEntry()
+ComplexTypeEntryPtr AbstractMetaClass::typeEntry()
{
return d->m_typeEntry;
}
-void AbstractMetaClass::setTypeEntry(ComplexTypeEntry *type)
+void AbstractMetaClass::setTypeEntry(const ComplexTypeEntryPtr &type)
{
d->m_typeEntry = type;
}
-void AbstractMetaClass::setHasHashFunction(bool on)
+QString AbstractMetaClass::hashFunction() const
{
- d->m_hasHashFunction = on;
+ return d->m_hashFunction;
+}
+
+void AbstractMetaClass::setHashFunction(const QString &f)
+{
+ d->m_hashFunction = f;
}
bool AbstractMetaClass::hasHashFunction() const
{
- return d->m_hasHashFunction;
+ return !d->m_hashFunction.isEmpty();
}
// Search whether a functions is a property setter/getter/reset
AbstractMetaClass::PropertyFunctionSearchResult
AbstractMetaClass::searchPropertyFunction(const QString &name) const
{
- for (int i = 0, size = d->m_propertySpecs.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = d->m_propertySpecs.size(); i < size; ++i) {
const auto &propertySpec = d->m_propertySpecs.at(i);
if (name == propertySpec.read())
return PropertyFunctionSearchResult{i, PropertyFunction::Read};
@@ -699,6 +676,8 @@ AbstractMetaClass::PropertyFunctionSearchResult
return PropertyFunctionSearchResult{i, PropertyFunction::Write};
if (name == propertySpec.reset())
return PropertyFunctionSearchResult{i, PropertyFunction::Reset};
+ if (name == propertySpec.notify())
+ return PropertyFunctionSearchResult{i, PropertyFunction::Notify};
}
return PropertyFunctionSearchResult{-1, PropertyFunction::Read};
}
@@ -706,10 +685,9 @@ AbstractMetaClass::PropertyFunctionSearchResult
std::optional<QPropertySpec>
AbstractMetaClass::propertySpecByName(const QString &name) const
{
- for (const auto &propertySpec : d->m_propertySpecs) {
- if (name == propertySpec.name())
- return propertySpec;
- }
+ const auto index = d->indexOfProperty(name);
+ if (index >= 0)
+ return d->m_propertySpecs.at(index);
return {};
}
@@ -791,7 +769,16 @@ bool AbstractMetaClass::deleteInMainThread() const
bool AbstractMetaClassPrivate::hasConstructors() const
{
return AbstractMetaClass::queryFirstFunction(m_functions,
- FunctionQueryOption::Constructors) != nullptr;
+ FunctionQueryOption::AnyConstructor) != nullptr;
+}
+
+qsizetype AbstractMetaClassPrivate::indexOfProperty(const QString &name) const
+{
+ for (qsizetype i = 0; i < m_propertySpecs.size(); ++i) {
+ if (m_propertySpecs.at(i).name() == name)
+ return i;
+ }
+ return -1;
}
bool AbstractMetaClass::hasConstructors() const
@@ -816,51 +803,95 @@ 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 = new AbstractMetaFunction;
- f->setType(AbstractMetaType::createVoid());
- f->setOriginalName(q->name());
- f->setName(q->name());
- f->setOwnerClass(q);
- f->setFunctionType(t);
- f->setArguments(arguments);
- f->setDeclaringClass(q);
- f->setAccess(access);
+ 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->setImplementingClass(q);
-
+ 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 *
+ AbstractMetaClassPrivate::createFunction(const QString &name,
+ AbstractMetaFunction::FunctionType t,
+ Access access,
+ const AbstractMetaArgumentList &arguments,
+ const AbstractMetaType &returnType,
+ const AbstractMetaClassPtr &q)
+{
+ auto *f = new AbstractMetaFunction(name);
+ f->setType(returnType);
+ f->setOwnerClass(q);
+ f->setFunctionType(t);
+ f->setArguments(arguments);
+ f->setDeclaringClass(q);
+ f->setAccess(access);
+ f->setImplementingClass(q);
+ return f;
+}
+
+static AbstractMetaType boolType()
+{
+ auto boolType = TypeDatabase::instance()->findType(u"bool"_s);
+ Q_ASSERT(boolType);
+ AbstractMetaType result(boolType);
+ result.decideUsagePattern();
+ return result;
+}
+
+// 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(const AbstractMetaClassPtr &c)
+{
+ static const auto returnType = boolType();
+
+ AbstractMetaType selfType(c->typeEntry());
+ selfType.setConstant(true);
+ selfType.setReferenceType(LValueReference);
+ selfType.decideUsagePattern();
+ AbstractMetaArgument selfArgument;
+ selfArgument.setType(selfType);
+ selfArgument.setName(u"rhs"_s);
+ AbstractMetaArgumentList arguments(1, selfArgument);
+
+ static const char *operators[]
+ = {"operator==", "operator!=", "operator<", "operator<=", "operator>", "operator>="};
+ for (auto *op : operators) {
+ auto *f = AbstractMetaClassPrivate::createFunction(QLatin1StringView(op),
+ AbstractMetaFunction::ComparisonOperator,
+ Access::Public, arguments,
+ returnType, c);
+ c->d->addFunction(AbstractMetaFunctionCPtr(f));
+ }
}
bool AbstractMetaClass::hasNonPrivateConstructor() const
@@ -953,6 +984,8 @@ bool AbstractMetaClass::isDefaultConstructible() const
// (non-ref or not const value).
static bool defaultConstructibleField(const AbstractMetaField &f)
{
+ if (f.isStatic())
+ return true;
const auto &type = f.type();
return type.referenceType() == NoReference
&& !(type.indirections() == 0 && type.isConstant()); // no const values
@@ -963,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();
});
}
@@ -971,6 +1004,7 @@ bool AbstractMetaClass::isImplicitlyDefaultConstructible() const
static bool canAddDefaultConstructorHelper(const AbstractMetaClass *cls)
{
return !cls->isNamespace()
+ && !cls->hasDeletedDefaultConstructor()
&& !cls->attributes().testFlag(AbstractMetaClass::HasRejectedConstructor)
&& !cls->hasPrivateDestructor();
}
@@ -997,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();
});
}
@@ -1012,6 +1046,21 @@ bool AbstractMetaClass::canAddDefaultCopyConstructor() const
return isImplicitlyCopyConstructible();
}
+static bool classHasParentManagement(const AbstractMetaClassCPtr &c)
+{
+ const auto flags = c->typeEntry()->typeFlags();
+ return flags.testFlag(ComplexTypeEntry::ParentManagement);
+}
+
+TypeEntryCPtr parentManagementEntry(const AbstractMetaClassCPtr &klass)
+{
+ if (klass->typeEntry()->isObject()) {
+ if (auto c = recurseClassHierarchy(klass, classHasParentManagement))
+ return c->typeEntry();
+ }
+ return nullptr;
+}
+
bool AbstractMetaClass::generateExceptionHandling() const
{
return queryFirstFunction(d->m_functions, FunctionQueryOption::Visible
@@ -1076,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
{
@@ -1087,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
{
@@ -1118,35 +1167,32 @@ 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;
if (query.testFlag(FunctionQueryOption::Signals) && (!f->isSignal()))
return false;
- if (query.testFlag(FunctionQueryOption::Constructors)
+ if (query.testFlag(FunctionQueryOption::AnyConstructor)
&& (!f->isConstructor() || f->ownerClass() != f->implementingClass())) {
return false;
}
+ if (query.testFlag(FunctionQueryOption::Constructors)
+ && (f->functionType() != AbstractMetaFunction::ConstructorFunction
+ || f->ownerClass() != f->implementingClass())) {
+ return false;
+ }
+
if (query.testFlag(FunctionQueryOption::CopyConstructor)
&& (!f->isCopyConstructor() || f->ownerClass() != f->implementingClass())) {
return false;
@@ -1193,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;
@@ -1203,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 {};
@@ -1230,7 +1276,7 @@ AbstractMetaFunctionCList AbstractMetaClass::cppSignalFunctions() const
}
std::optional<AbstractMetaField>
- AbstractMetaClass::findField(const QString &name) const
+ AbstractMetaClass::findField(QStringView name) const
{
return AbstractMetaField::find(d->m_fields, name);
}
@@ -1271,7 +1317,7 @@ std::optional<AbstractMetaEnum>
std::optional<AbstractMetaEnumValue>
AbstractMetaClass::findEnumValue(const QString &enumValueName) const
{
- for (const AbstractMetaEnum &e : qAsConst(d->m_enums)) {
+ for (const AbstractMetaEnum &e : std::as_const(d->m_enums)) {
auto v = e.findEnumValue(enumValueName);
if (v.has_value())
return v;
@@ -1293,7 +1339,7 @@ void AbstractMetaClass::getEnumsToBeGenerated(AbstractMetaEnumList *enumList) co
void AbstractMetaClass::getEnumsFromInvisibleNamespacesToBeGenerated(AbstractMetaEnumList *enumList) const
{
if (isNamespace()) {
- invisibleNamespaceRecursion([enumList](AbstractMetaClass *c) {
+ invisibleNamespaceRecursion([enumList](const AbstractMetaClassCPtr &c) {
c->getEnumsToBeGenerated(enumList);
});
}
@@ -1302,7 +1348,7 @@ void AbstractMetaClass::getEnumsFromInvisibleNamespacesToBeGenerated(AbstractMet
void AbstractMetaClass::getFunctionsFromInvisibleNamespacesToBeGenerated(AbstractMetaFunctionCList *funcList) const
{
if (isNamespace()) {
- invisibleNamespaceRecursion([funcList](AbstractMetaClass *c) {
+ invisibleNamespaceRecursion([funcList](const AbstractMetaClassCPtr &c) {
funcList->append(c->functions());
});
}
@@ -1310,19 +1356,19 @@ void AbstractMetaClass::getFunctionsFromInvisibleNamespacesToBeGenerated(Abstrac
QString AbstractMetaClass::fullName() const
{
- return package() + QLatin1Char('.') + d->m_typeEntry->targetLangName();
+ 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);
- const TypeEntry *entry = type.typeEntry();
- if (entry && entry->isComplex()) {
- const auto *centry = static_cast<const ComplexTypeEntry *>(entry);
- ComplexTypeEntry *class_entry = metaClass->typeEntry();
- if (class_entry && centry->include().isValid())
- class_entry->addExtraInclude(centry->include());
+ const auto entry = type.typeEntry();
+
+ if (entry && entry->include().isValid()) {
+ const auto class_entry = metaClass->typeEntry();
+ class_entry->addArgumentInclude(entry->include());
}
if (type.hasInstantiations()) {
@@ -1331,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);
@@ -1339,8 +1385,12 @@ static void addExtraIncludesForFunction(AbstractMetaClass *metaClass,
addExtraIncludeForType(metaClass, meta_function->type());
const AbstractMetaArgumentList &arguments = meta_function->arguments();
- for (const AbstractMetaArgument &argument : arguments)
- addExtraIncludeForType(metaClass, argument.type());
+ for (const AbstractMetaArgument &argument : arguments) {
+ const auto &type = argument.type();
+ addExtraIncludeForType(metaClass, type);
+ if (argument.modifiedType() != type)
+ addExtraIncludeForType(metaClass, argument.modifiedType());
+ }
}
static bool addSuperFunction(const AbstractMetaFunctionCPtr &f)
@@ -1362,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.
@@ -1371,14 +1421,13 @@ 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.
const auto ctors = superClass->queryFunctions(FunctionQueryOption::Constructors);
for (const auto &ctor : ctors) {
- if (ctor->functionType() == AbstractMetaFunction::ConstructorFunction
- && !ctor->isPrivate()) {
+ if (!ctor->isPrivate()) {
addConstructor(AbstractMetaFunction::ConstructorFunction,
ctor->access(), ctor->arguments(), q);
}
@@ -1387,50 +1436,61 @@ 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 : qAsConst(funcs)) {
+ 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 superClass : d->m_baseClasses) {
- 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;
QSet<AbstractMetaFunctionCPtr> funcsToAdd;
- for (const auto &sf : qAsConst(superFuncs)) {
+ for (const auto &sf : std::as_const(superFuncs)) {
if (sf->isModifiedRemoved())
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
@@ -1441,43 +1501,25 @@ void AbstractMetaClass::fixFunctions()
// we generally don't care about private functions, but we have to get the ones that are
// virtual in case they override abstract functions.
bool add = addSuperFunction(sf);
- for (const auto &cf : qAsConst(nonRemovedFuncs)) {
- AbstractMetaFunctionPtr f(qSharedPointerConstCast<AbstractMetaFunction>(cf));
- const AbstractMetaFunction::CompareResult cmp = cf->compareTo(sf.data());
+ for (const auto &cf : std::as_const(nonRemovedFuncs)) {
+ 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
@@ -1489,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) {
@@ -1553,7 +1564,7 @@ void AbstractMetaClass::fixFunctions()
funcsToAdd << sf;
}
- for (const auto &f : qAsConst(funcsToAdd)) {
+ for (const auto &f : std::as_const(funcsToAdd)) {
AbstractMetaFunction *copy = f->copy();
(*copy) += AbstractMetaFunction::AddedMethod;
funcs.append(AbstractMetaFunctionCPtr(copy));
@@ -1563,9 +1574,9 @@ void AbstractMetaClass::fixFunctions()
bool hasPrivateConstructors = false;
bool hasPublicConstructors = false;
// Apply modifications after the declaring class has been set
- for (const auto &func : qAsConst(funcs)) {
- auto ncFunc = qSharedPointerConstCast<AbstractMetaFunction>(func);
- for (const auto &mod : func->modifications(this)) {
+ for (const auto &func : std::as_const(funcs)) {
+ auto ncFunc = std::const_pointer_cast<AbstractMetaFunction>(func);
+ for (const auto &mod : func->modifications(klass)) {
if (mod.isRenameModifier())
ncFunc->setName(mod.renamedToName());
}
@@ -1573,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()) {
@@ -1587,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
@@ -1604,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;
@@ -1626,26 +1638,6 @@ bool AbstractMetaClass::inheritanceDone() const
* Other stuff...
*/
-
-std::optional<AbstractMetaEnum>
- AbstractMetaClass::findEnum(const AbstractMetaClassList &classes,
- const EnumTypeEntry *entry)
-{
- Q_ASSERT(entry->isEnum());
-
- auto scopeEntry = entry->parent();
- AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes, scopeEntry);
- if (!metaClass) {
- qCWarning(lcShiboken, "%s", qPrintable(msgClassOfEnumNotFound(entry)));
- return {};
- }
-
- QString qualifiedName = entry->qualifiedCppName();
- const int pos = qualifiedName.lastIndexOf(QLatin1String("::"));
- const QString enumName = pos > 0 ? qualifiedName.mid(pos + 2) : qualifiedName;
- return metaClass->findEnum(enumName);
-}
-
std::optional<AbstractMetaEnumValue>
AbstractMetaClass::findEnumValue(const AbstractMetaClassList &classes,
const QString &name)
@@ -1655,11 +1647,11 @@ std::optional<AbstractMetaEnumValue>
if (lst.size() > 1) {
const auto &prefixName = lst.at(0);
const auto &enumName = lst.at(1);
- if (AbstractMetaClass *cl = findClass(classes, prefixName.toString()))
+ 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;
@@ -1673,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, const QString &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;
@@ -1691,7 +1683,7 @@ static It findClassHelper(It begin, It end, const QString &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) {
@@ -1702,32 +1694,32 @@ static It findClassHelper(It begin, It end, const QString &name)
return end;
}
-AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &classes,
- const QString &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,
- const QString &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 TypeEntry *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,
- const TypeEntry *typeEntry)
+AbstractMetaClassCPtr AbstractMetaClass::findClass(const AbstractMetaClassCList &classes,
+ const TypeEntryCPtr &typeEntry)
{
for (auto c : classes) {
if (c->typeEntry() == typeEntry)
@@ -1737,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;
});
}
@@ -1787,7 +1780,7 @@ bool AbstractMetaClass::isCopyable() const
return false;
auto copyable = d->m_typeEntry->copyable();
return copyable == ComplexTypeEntry::CopyableSet
- || (copyable == ComplexTypeEntry::Unknown && hasCloneOperator());
+ || (copyable == ComplexTypeEntry::Unknown && isCopyConstructible());
}
bool AbstractMetaClass::isValueTypeWithCopyConstructorOnly() const
@@ -1800,19 +1793,22 @@ void AbstractMetaClass::setValueTypeWithCopyConstructorOnly(bool v)
d->m_valueTypeWithCopyConstructorOnly = v;
}
-bool AbstractMetaClass::determineValueTypeWithCopyConstructorOnly(const AbstractMetaClass *c)
+bool AbstractMetaClass::determineValueTypeWithCopyConstructorOnly(const AbstractMetaClassCPtr &c,
+ bool avoidProtectedHack)
{
if (!c->typeEntry()->isValue())
return false;
if (c->attributes().testFlag(AbstractMetaClass::HasRejectedDefaultConstructor))
return false;
- const auto ctors = c->queryFunctions(FunctionQueryOption::Constructors);
+ const auto ctors = c->queryFunctions(FunctionQueryOption::AnyConstructor);
bool copyConstructorFound = false;
for (const auto &ctor : ctors) {
switch (ctor->functionType()) {
case AbstractMetaFunction::ConstructorFunction:
- return false;
+ if (!ctor->isPrivate() && (ctor->isPublic() || !avoidProtectedHack))
+ return false;
+ break;
case AbstractMetaFunction::CopyConstructorFunction:
copyConstructorFound = true;
break;
@@ -1833,8 +1829,8 @@ void AbstractMetaClass::format(QDebug &debug) const
if (debug.verbosity() > 2)
debug << static_cast<const void *>(this) << ", ";
debug << '"' << qualifiedCppName();
- if (const int count = d->m_templateArgs.size()) {
- for (int i = 0; i < count; ++i)
+ if (const auto count = d->m_templateArgs.size()) {
+ for (qsizetype i = 0; i < count; ++i)
debug << (i ? ',' : '<') << d->m_templateArgs.at(i)->qualifiedCppName();
debug << '>';
}
@@ -1845,9 +1841,25 @@ void AbstractMetaClass::format(QDebug &debug) const
debug << " [final]";
if (attributes().testFlag(AbstractMetaClass::Deprecated))
debug << " [deprecated]";
+
+ if (d->m_hasPrivateConstructor)
+ debug << " [private constructor]";
+ if (d->m_hasDeletedDefaultConstructor)
+ debug << " [deleted default constructor]";
+ if (d->m_hasDeletedCopyConstructor)
+ debug << " [deleted copy constructor]";
+ if (d->m_hasPrivateDestructor)
+ debug << " [private destructor]";
+ if (d->m_hasProtectedDestructor)
+ debug << " [protected destructor]";
+ if (d->m_hasVirtualDestructor)
+ debug << " [virtual destructor]";
+ if (d->m_valueTypeWithCopyConstructorOnly)
+ debug << " [value type with copy constructor only]";
+
if (!d->m_baseClasses.isEmpty()) {
debug << ", inherits ";
- for (auto b : d->m_baseClasses)
+ for (const auto &b : d->m_baseClasses)
debug << " \"" << b->name() << '"';
}
@@ -1862,13 +1874,13 @@ void AbstractMetaClass::format(QDebug &debug) const
if (auto templateBase = templateBaseClass()) {
const auto &instantiatedTypes = templateBaseClassInstantiations();
debug << ", instantiates \"" << templateBase->name();
- for (int i = 0, count = instantiatedTypes.size(); i < count; ++i)
+ for (qsizetype i = 0, count = instantiatedTypes.size(); i < count; ++i)
debug << (i ? ',' : '<') << instantiatedTypes.at(i).name();
debug << ">\"";
}
- if (const int count = d->m_propertySpecs.size()) {
+ if (const auto count = d->m_propertySpecs.size()) {
debug << ", properties (" << count << "): [";
- for (int i = 0; i < count; ++i) {
+ for (qsizetype i = 0; i < count; ++i) {
if (i)
debug << ", ";
d->m_propertySpecs.at(i).formatDebug(debug);
@@ -1882,18 +1894,18 @@ void AbstractMetaClass::formatMembers(QDebug &debug) const
if (!d->m_enums.isEmpty())
debug << ", enums[" << d->m_enums.size() << "]=" << d->m_enums;
if (!d->m_functions.isEmpty()) {
- const int count = d->m_functions.size();
+ const auto count = d->m_functions.size();
debug << ", functions=[" << count << "](";
- for (int i = 0; i < count; ++i) {
+ for (qsizetype i = 0; i < count; ++i) {
if (i)
debug << ", ";
d->m_functions.at(i)->formatDebugBrief(debug);
}
debug << ')';
}
- if (const int count = d->m_fields.size()) {
+ if (const auto count = d->m_fields.size()) {
debug << ", fields=[" << count << "](";
- for (int i = 0; i < count; ++i) {
+ for (qsizetype i = 0; i < count; ++i) {
if (i)
debug << ", ";
d->m_fields.at(i).formatDebug(debug);
@@ -1912,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);
@@ -1922,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 cc7fd7cec..3dc876690 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ABSTRACTMETALANG_H
#define ABSTRACTMETALANG_H
@@ -32,7 +7,6 @@
#include "abstractmetalang_enums.h"
#include "abstractmetalang_typedefs.h"
#include "enclosingclassmixin.h"
-#include "typesystem_enums.h"
#include "typesystem_typedefs.h"
#include <QtCore/qobjectdefs.h>
@@ -73,7 +47,8 @@ public:
HasRejectedDefaultConstructor = 0x00000020,
FinalCppClass = 0x00000100,
- Deprecated = 0x00000200
+ Deprecated = 0x00000200,
+ Struct = 0x00000400
};
Q_DECLARE_FLAGS(Attributes, Attribute)
Q_FLAG(Attribute)
@@ -91,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(const QString& functionName) const;
- AbstractMetaFunctionCList findFunctions(const QString& 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;
@@ -106,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);
@@ -138,13 +115,15 @@ public:
bool isImplicitlyCopyConstructible() const;
bool canAddDefaultCopyConstructor() const;
+ static void addSynthesizedComparisonOperators(const AbstractMetaClassPtr &c);
+
bool generateExceptionHandling() const;
CppWrapper cppWrapper() const;
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;
@@ -182,7 +161,7 @@ public:
void addField(const AbstractMetaField &field);
bool hasStaticFields() const;
- std::optional<AbstractMetaField> findField(const QString &name) const;
+ std::optional<AbstractMetaField> findField(QStringView name) const;
const AbstractMetaEnumList &enums() const;
AbstractMetaEnumList &enums();
@@ -209,42 +188,40 @@ public:
QString baseClassName() const;
- AbstractMetaClass *defaultSuperclass() const; // Attribute "default-superclass"
- void setDefaultSuperclass(AbstractMetaClass *s);
+ AbstractMetaClassCPtr defaultSuperclass() const; // Attribute "default-superclass"
+ void setDefaultSuperclass(const AbstractMetaClassPtr &s);
- AbstractMetaClass *baseClass() const;
- const AbstractMetaClassList &baseClasses() const;
+ AbstractMetaClassCPtr baseClass() const;
+ const AbstractMetaClassCList &baseClasses() const;
// base classes including defaultSuperclass
- AbstractMetaClassList typeSystemBaseClasses() const;
+ AbstractMetaClassCList typeSystemBaseClasses() const;
// Recursive list of all base classes including defaultSuperclass
- AbstractMetaClassList allTypeSystemAncestors() const;
+ AbstractMetaClassCList allTypeSystemAncestors() const;
- void addBaseClass(AbstractMetaClass *base_class);
- void setBaseClass(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 AbstractMetaClassList &innerClasses() const;
- void addInnerClass(AbstractMetaClass* cl);
- void setInnerClasses(const AbstractMetaClassList &innerClasses);
+ const AbstractMetaClassCList &innerClasses() const;
+ void addInnerClass(const AbstractMetaClassPtr &cl);
+ void setInnerClasses(const AbstractMetaClassCList &innerClasses);
QString package() const;
bool isNamespace() const;
bool isInvisibleNamespace() const;
+ bool isInlineNamespace() const;
- bool isQObject() const { return inheritsFrom(u"QObject"_qs); }
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.
@@ -253,60 +230,46 @@ public:
bool isPolymorphic() const;
/**
- * Tells if this class has one or more functions that are protected.
- * \return true if the class has protected functions.
- */
- bool hasProtectedFunctions() const;
-
- /**
* Tells if this class has one or more fields (member variables) that are protected.
* \return true if the class has protected fields.
*/
bool hasProtectedFields() const;
- /**
- * Tells if this class has one or more members (functions or fields) that are protected.
- * \return true if the class has protected members.
- */
- bool hasProtectedMembers() const;
-
- const TypeEntries &templateArguments() const;
- void setTemplateArguments(const TypeEntries &);
+ const TypeEntryCList &templateArguments() const;
+ void setTemplateArguments(const TypeEntryCList &);
// only valid during metabuilder's run
const QStringList &baseClassNames() const;
void setBaseClassNames(const QStringList &names);
- const ComplexTypeEntry *typeEntry() const;
- ComplexTypeEntry *typeEntry();
- void setTypeEntry(ComplexTypeEntry *type);
+ ComplexTypeEntryCPtr typeEntry() const;
+ ComplexTypeEntryPtr typeEntry();
+ void setTypeEntry(const ComplexTypeEntryPtr &type);
- void setHasHashFunction(bool on);
+ /// Returns the global hash function as found by the code parser
+ QString hashFunction() const;
+ void setHashFunction(const QString &);
+ /// Returns whether the class has a qHash() overload. Currently unused,
+ /// specified in type system.
bool hasHashFunction() const;
- bool hasDefaultToStringFunction() const;
-
- bool hasEqualsOperator() const;
- void setHasEqualsOperator(bool on);
-
- bool hasCloneOperator() const;
- void setHasCloneOperator(bool on);
-
const QList<QPropertySpec> &propertySpecs() const;
void addPropertySpec(const QPropertySpec &spec);
+ void setPropertyDocumentation(const QString &name, const Documentation &doc);
// Helpers to search whether a functions is a property setter/getter/reset
enum class PropertyFunction
{
Read,
Write,
- Reset
+ Reset,
+ Notify
};
struct PropertyFunctionSearchResult
{
- int index;
+ qsizetype index;
PropertyFunction function;
};
@@ -324,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;
@@ -349,28 +312,27 @@ public:
bool isCopyable() const;
bool isValueTypeWithCopyConstructorOnly() const;
void setValueTypeWithCopyConstructorOnly(bool v);
- static bool determineValueTypeWithCopyConstructorOnly(const AbstractMetaClass *c);
-
- static AbstractMetaClass *findClass(const AbstractMetaClassList &classes,
- const QString &name);
- static const AbstractMetaClass *findClass(const AbstractMetaClassCList &classes,
- const QString &name);
- static AbstractMetaClass *findClass(const AbstractMetaClassList &classes,
- const TypeEntry* typeEntry);
- static const AbstractMetaClass *findClass(const AbstractMetaClassCList &classes,
- const TypeEntry* typeEntry);
- const AbstractMetaClass *findBaseClass(const QString &qualifiedName) const;
+ static bool determineValueTypeWithCopyConstructorOnly(const AbstractMetaClassCPtr &c,
+ bool avoidProtectedHack);
+
+ 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 AbstractMetaClassCPtr findClass(const AbstractMetaClassCList &classes,
+ const TypeEntryCPtr &typeEntry);
+ AbstractMetaClassCPtr findBaseClass(const QString &qualifiedName) const;
static std::optional<AbstractMetaEnumValue> findEnumValue(const AbstractMetaClassList &classes,
const QString &string);
- static std::optional<AbstractMetaEnum> findEnum(const AbstractMetaClassList &classes,
- const EnumTypeEntry *entry);
SourceLocation sourceLocation() const;
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;
@@ -382,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);
@@ -401,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);
@@ -409,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 c78e84320..9047c6bcd 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang_enums.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ABSTRACTMETALANG_ENUMS_H
#define ABSTRACTMETALANG_ENUMS_H
@@ -32,21 +7,19 @@
#include <QtCore/QFlags>
enum class FunctionQueryOption {
- Constructors = 0x0000001, // Only constructors
- CopyConstructor = 0x0000002, // Only copy constructors
+ AnyConstructor = 0x0000001, // Any constructor (copy/move)
+ 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,
@@ -58,14 +31,17 @@ Q_DECLARE_FLAGS(FunctionQueryOptions, FunctionQueryOption)
Q_DECLARE_OPERATORS_FOR_FLAGS(FunctionQueryOptions)
enum class OperatorQueryOption {
- ArithmeticOp = 0x01, // Arithmetic: +, -, *, /, %, +=, -=, *=, /=, %=, unary+, unary-
- IncDecrementOp = 0x02, // ++, --
- BitwiseOp = 0x04, // Bitwise: <<, <<=, >>, >>=, ~, &, &=, |, |=, ^, ^=
- ComparisonOp = 0x08, // Comparison: <, <=, >, >=, !=, ==
- LogicalOp = 0x10, // Logical: !, &&, ||
- ConversionOp = 0x20, // Conversion: operator [const] TYPE()
- SubscriptionOp = 0x40, // Subscription: []
- AssignmentOp = 0x80 // Assignment: =
+ ArithmeticOp = 0x01, // Arithmetic: +, -, *, /, %, +=, -=, *=, /=, %=, unary+, unary-
+ IncDecrementOp = 0x02, // ++, --
+ BitwiseOp = 0x04, // Bitwise: <<, <<=, >>, >>=, ~, &, &=, |, |=, ^, ^=
+ ComparisonOp = 0x08, // Comparison: <, <=, >, >=, !=, ==
+ // Comparing to instances of owner class: <, <=, >, >=, !=, ==
+ // (bool operator==(QByteArray,QByteArray) but not bool operator==(QByteArray,const char *)
+ SymmetricalComparisonOp = 0x10,
+ LogicalOp = 0x20, // Logical: !, &&, ||
+ ConversionOp = 0x40, // Conversion: operator [const] TYPE()
+ SubscriptionOp = 0x80, // Subscription: []
+ AssignmentOp = 0x100 // Assignment: =
};
Q_DECLARE_FLAGS(OperatorQueryOptions, OperatorQueryOption)
diff --git a/sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h b/sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h
index afe5c954a..2a053ceaf 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang_helpers.h
@@ -1,49 +1,27 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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;
@@ -51,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 cdfcdab1e..27321ca2d 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetalang_typedefs.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetalang_typedefs.h
@@ -1,37 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ABSTRACTMETALANG_TYPEDEFS_H
#define ABSTRACTMETALANG_TYPEDEFS_H
-#include <QtCore/QSharedPointer>
#include <QtCore/QList>
+#include <memory>
+
class AbstractMetaClass;
class AbstractMetaField;
class AbstractMetaArgument;
@@ -41,17 +17,20 @@ 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>;
using AbstractMetaFunctionRawPtrList = QList<AbstractMetaFunction *>;
using AbstractMetaFunctionCList = QList<AbstractMetaFunctionCPtr>;
+using AbstractMetaFunctionList = QList<AbstractMetaFunctionPtr>;
using AbstractMetaTypeList = QList<AbstractMetaType>;
using UsingMembers = QList<UsingMember>;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
index 80ab1828d..3ec07509d 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
@@ -1,38 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "abstractmetatype.h"
#include "abstractmetabuilder.h"
#include "abstractmetalang.h"
#include "messages.h"
#include "typedatabase.h"
-#include "typesystem.h"
-#include "parser/codemodel.h"
+#include "containertypeentry.h"
+#include "enumtypeentry.h"
+#include "flagstypeentry.h"
+
+#include "qtcompat.h"
+#include "typeinfo.h"
#ifndef QT_NO_DEBUG_STREAM
# include <QtCore/QDebug>
@@ -40,26 +19,29 @@
#include <QtCore/QHash>
#include <QtCore/QSharedData>
-#include <QtCore/QSharedPointer>
#include <QtCore/QStack>
-using AbstractMetaTypeCPtr = QSharedPointer<const AbstractMetaType>;
+#include <memory>
+
+using namespace Qt::StringLiterals;
+
+using AbstractMetaTypeCPtr = std::shared_ptr<const AbstractMetaType>;
const QSet<QString> &AbstractMetaType::cppFloatTypes()
{
- static const QSet<QString> result{u"double"_qs, u"float"_qs};
+ static const QSet<QString> result{u"double"_s, u"float"_s};
return result;
}
const QSet<QString> &AbstractMetaType::cppSignedCharTypes()
{
- static const QSet<QString> result{u"char"_qs, u"signed char"_qs};
+ static const QSet<QString> result{u"char"_s, u"signed char"_s};
return result;
}
const QSet<QString> &AbstractMetaType::cppUnsignedCharTypes()
{
- static const QSet<QString> result{u"unsigned char"_qs};
+ static const QSet<QString> result{u"unsigned char"_s};
return result;
}
@@ -73,14 +55,14 @@ const QSet<QString> &AbstractMetaType::cppSignedIntTypes()
{
static QSet<QString> result;
if (result.isEmpty()) {
- result = {u"char"_qs, u"signed char"_qs, u"short"_qs, u"short int"_qs,
- u"signed short"_qs, u"signed short int"_qs,
- u"int"_qs, u"signed int"_qs,
- u"long"_qs, u"long int"_qs,
- u"signed long"_qs, u"signed long int"_qs,
- u"long long"_qs, u"long long int"_qs,
- u"signed long long int"_qs,
- u"ptrdiff_t"_qs};
+ result = {u"char"_s, u"signed char"_s, u"short"_s, u"short int"_s,
+ u"signed short"_s, u"signed short int"_s,
+ u"int"_s, u"signed int"_s,
+ u"long"_s, u"long int"_s,
+ u"signed long"_s, u"signed long int"_s,
+ u"long long"_s, u"long long int"_s,
+ u"signed long long int"_s,
+ u"ptrdiff_t"_s};
result |= cppSignedCharTypes();
}
return result;
@@ -90,12 +72,12 @@ const QSet<QString> &AbstractMetaType::cppUnsignedIntTypes()
{
static QSet<QString> result;
if (result.isEmpty()) {
- result = {u"unsigned short"_qs, u"unsigned short int"_qs,
- u"unsigned"_qs, u"unsigned int"_qs,
- u"unsigned long"_qs, u"unsigned long int"_qs,
- u"unsigned long long"_qs,
- u"unsigned long long int"_qs,
- u"size_t"_qs};
+ result = {u"unsigned short"_s, u"unsigned short int"_s,
+ u"unsigned"_s, u"unsigned int"_s,
+ u"unsigned long"_s, u"unsigned long int"_s,
+ u"unsigned long long"_s,
+ u"unsigned long long int"_s,
+ u"size_t"_s};
result |= cppUnsignedCharTypes();
}
return result;
@@ -107,7 +89,7 @@ const QSet<QString> &AbstractMetaType::cppIntegralTypes()
if (result.isEmpty()) {
result |= cppSignedIntTypes();
result |= cppUnsignedIntTypes();
- result.insert(u"bool"_qs);
+ result.insert(u"bool"_s);
}
return result;
}
@@ -118,7 +100,7 @@ const QSet<QString> &AbstractMetaType::cppPrimitiveTypes()
if (result.isEmpty()) {
result |= cppIntegralTypes();
result |= cppFloatTypes();
- result.insert(u"wchar_t"_qs);
+ result.insert(u"wchar_t"_s);
}
return result;
}
@@ -126,7 +108,7 @@ const QSet<QString> &AbstractMetaType::cppPrimitiveTypes()
class AbstractMetaTypeData : public QSharedData
{
public:
- AbstractMetaTypeData(const TypeEntry *t);
+ AbstractMetaTypeData(const TypeEntryCPtr &t);
int actualIndirections() const;
bool passByConstRef() const;
@@ -135,11 +117,14 @@ public:
bool hasTemplateChildren() const;
QString formatSignature(bool minimal) const;
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;
- const TypeEntry *m_typeEntry;
+ TypeEntryCPtr m_typeEntry;
AbstractMetaTypeList m_instantiations;
mutable QString m_cachedCppSignature;
mutable QString m_cachedPythonSignature;
@@ -161,7 +146,7 @@ public:
AbstractMetaTypeList m_children;
};
-AbstractMetaTypeData::AbstractMetaTypeData(const TypeEntry *t) :
+AbstractMetaTypeData::AbstractMetaTypeData(const TypeEntryCPtr &t) :
m_typeEntry(t),
m_constant(false),
m_volatile(false),
@@ -170,7 +155,16 @@ AbstractMetaTypeData::AbstractMetaTypeData(const TypeEntry *t) :
{
}
-AbstractMetaType::AbstractMetaType(const TypeEntry *t) : d(new AbstractMetaTypeData(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))
{
Q_ASSERT(t);
}
@@ -184,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;
@@ -237,16 +231,21 @@ 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)
{
if (d->m_pattern == AbstractMetaType::NativePointerAsArrayPattern) {
- *errorMessage = QLatin1String("<array> modification already applied.");
+ *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;
@@ -270,12 +269,12 @@ bool AbstractMetaType::applyArrayModification(QString *errorMessage)
return true;
}
-const TypeEntry *AbstractMetaType::typeEntry() const
+TypeEntryCPtr AbstractMetaType::typeEntry() const
{
return d->m_typeEntry;
}
-void AbstractMetaType::setTypeEntry(const TypeEntry *type)
+void AbstractMetaType::setTypeEntry(const TypeEntryCPtr &type)
{
if (d->m_typeEntry != type)
d->m_typeEntry = type;
@@ -294,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
@@ -329,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;
@@ -357,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;
@@ -435,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();
@@ -527,6 +543,7 @@ void AbstractMetaType::decideUsagePattern()
pattern = ObjectPattern;
}
setTypeUsagePattern(pattern);
+ Q_ASSERT(pattern != ContainerPattern || !d->m_instantiations.isEmpty());
}
bool AbstractMetaTypeData::hasTemplateChildren() const
@@ -553,10 +570,33 @@ bool AbstractMetaType::hasTemplateChildren() const
static inline QString formatArraySize(int e)
{
QString result;
- result += QLatin1Char('[');
+ result += u'[';
if (e >= 0)
result += QString::number(e);
- result += QLatin1Char(']');
+ result += u']';
+ 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;
}
@@ -564,13 +604,13 @@ QString AbstractMetaTypeData::formatSignature(bool minimal) const
{
QString result;
if (m_constant)
- result += QLatin1String("const ");
+ result += u"const "_s;
if (m_volatile)
- result += QLatin1String("volatile ");
+ result += u"volatile "_s;
if (m_pattern == AbstractMetaType::ArrayPattern) {
// Build nested array dimensions a[2][3] in correct order
result += m_arrayElementType->minimalSignature();
- const int arrayPos = result.indexOf(QLatin1Char('['));
+ const int arrayPos = result.indexOf(u'[');
if (arrayPos != -1)
result.insert(arrayPos, formatArraySize(m_arrayElementCount));
else
@@ -579,29 +619,30 @@ QString AbstractMetaTypeData::formatSignature(bool minimal) const
result += m_typeEntry->qualifiedCppName();
}
if (!m_instantiations.isEmpty()) {
- result += QLatin1Char('<');
+ result += u'<';
if (minimal)
- result += QLatin1Char(' ');
- for (int i = 0, size = m_instantiations.size(); i < size; ++i) {
+ result += u' ';
+ const auto size = stripDefaultTemplateArgs(m_typeEntry, m_instantiations);
+ for (qsizetype i = 0; i < size; ++i) {
if (i > 0)
- result += QLatin1Char(',');
+ result += u',';
result += m_instantiations.at(i).minimalSignature();
}
- result += QLatin1String(" >");
+ result += u'>';
}
if (!minimal && (!m_indirections.isEmpty() || m_referenceType != NoReference))
- result += QLatin1Char(' ');
+ result += u' ';
for (Indirection i : m_indirections)
result += TypeInfo::indirectionKeyword(i);
switch (m_referenceType) {
case NoReference:
break;
case LValueReference:
- result += QLatin1Char('&');
+ result += u'&';
break;
case RValueReference:
- result += QLatin1String("&&");
+ result += u"&&"_s;
break;
}
return result;
@@ -627,7 +668,7 @@ QString AbstractMetaTypeData::formatPythonSignature() const
*/
QString result;
if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern)
- result += QLatin1String("array ");
+ result += u"array "_s;
// We no longer use the "const" qualifier for heuristics. Instead,
// NativePointerAsArrayPattern indicates when we have <array> in XML.
// if (m_typeEntry->isPrimitive() && isConstant())
@@ -635,12 +676,12 @@ QString AbstractMetaTypeData::formatPythonSignature() const
if (!m_typeEntry->isPrimitive() && !m_typeEntry->isSmartPointer()) {
const QString package = m_typeEntry->targetLangPackage();
if (!package.isEmpty())
- result += package + QLatin1Char('.');
+ result += package + u'.';
}
if (m_pattern == AbstractMetaType::ArrayPattern) {
// Build nested array dimensions a[2][3] in correct order
result += m_arrayElementType->formatPythonSignature();
- const int arrayPos = result.indexOf(QLatin1Char('['));
+ const int arrayPos = result.indexOf(u'[');
if (arrayPos != -1)
result.insert(arrayPos, formatArraySize(m_arrayElementCount));
else
@@ -649,22 +690,24 @@ QString AbstractMetaTypeData::formatPythonSignature() const
result += m_typeEntry->targetLangName();
}
if (!m_instantiations.isEmpty()) {
- result += QLatin1Char('[');
- for (int i = 0, size = m_instantiations.size(); i < size; ++i) {
+ result += u'[';
+ for (qsizetype i = 0, size = m_instantiations.size(); i < size; ++i) {
if (i > 0)
- result += QLatin1String(", ");
+ result += u", "_s;
result += m_instantiations.at(i).formatPythonSignature();
}
- result += QLatin1Char(']');
+ result += u']';
}
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();
- result.replace(QLatin1String("::"), QLatin1String("."));
+ // 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;
}
@@ -675,7 +718,7 @@ QString AbstractMetaType::formatPythonSignature() const
bool AbstractMetaType::isCppPrimitive() const
{
- return d->m_pattern == PrimitivePattern && d->m_typeEntry->isCppPrimitive();
+ return d->m_pattern == PrimitivePattern && ::isCppPrimitive(d->m_typeEntry);
}
bool AbstractMetaType::isConstant() const
@@ -706,12 +749,12 @@ 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::equals(const AbstractMetaTypeData &rhs) const
+bool AbstractMetaTypeData::isEquivalent(const AbstractMetaTypeData &rhs) const
{
if (m_typeEntry != rhs.m_typeEntry
|| m_indirections != rhs.m_indirections
@@ -719,11 +762,6 @@ bool AbstractMetaTypeData::equals(const AbstractMetaTypeData &rhs) const
return false;
}
- if (m_constant != rhs.m_constant || m_volatile != rhs.m_volatile
- || m_referenceType != rhs.m_referenceType) {
- return false;
- }
-
if (!equalsCPtr(m_arrayElementType, rhs.m_arrayElementType))
return false;
@@ -735,19 +773,30 @@ bool AbstractMetaTypeData::equals(const AbstractMetaTypeData &rhs) const
return true;
}
-bool AbstractMetaType::equals(const AbstractMetaType &rhs) const
+bool AbstractMetaTypeData::equals(const AbstractMetaTypeData &rhs) const
+{
+ return m_constant == rhs.m_constant && m_volatile == rhs.m_volatile
+ && m_referenceType == rhs.m_referenceType && isEquivalent(rhs);
+}
+
+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
+{
+ return d->isEquivalent(*rhs.d);
}
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));
}
@@ -755,7 +804,7 @@ AbstractMetaType AbstractMetaType::createVoid()
{
static QScopedPointer<AbstractMetaType> metaType;
if (metaType.isNull()) {
- static const TypeEntry *voidTypeEntry = TypeDatabase::instance()->findType(QLatin1String("void"));
+ static TypeEntryCPtr voidTypeEntry = TypeDatabase::instance()->findType(u"void"_s);
Q_ASSERT(voidTypeEntry);
metaType.reset(new AbstractMetaType(voidTypeEntry));
metaType->decideUsagePattern();
@@ -765,7 +814,23 @@ AbstractMetaType AbstractMetaType::createVoid()
void AbstractMetaType::dereference(QString *type)
{
- type->prepend(u"(*"_qs);
+ type->prepend(u"(*"_s);
+ type->append(u')');
+}
+
+QString AbstractMetaType::dereferencePrefix(qsizetype n)
+{
+ const QChar c = n > 0 ? u'*' : u'&';
+ return QString(qAbs(n), c);
+}
+
+void AbstractMetaType::applyDereference(QString *type, qsizetype n)
+{
+ if (n == 0)
+ return;
+
+ type->prepend(dereferencePrefix(n));
+ type->prepend(u'(');
type->append(u')');
}
@@ -791,6 +856,11 @@ bool AbstractMetaType::isObjectType() const
return d->m_typeEntry->isObject();
}
+bool AbstractMetaType::isUniquePointer() const
+{
+ return isSmartPointer() && d->m_typeEntry->isUniquePointer();
+}
+
bool AbstractMetaType::isPointer() const
{
return !d->m_indirections.isEmpty()
@@ -807,19 +877,19 @@ bool AbstractMetaType::isCString() const
{
return isNativePointer()
&& d->m_indirections.size() == 1
- && name() == QLatin1String("char");
+ && name() == u"char";
}
bool AbstractMetaType::isVoidPointer() const
{
return isNativePointer()
&& d->m_indirections.size() == 1
- && name() == QLatin1String("void");
+ && name() == u"void";
}
bool AbstractMetaType::isUserPrimitive() const
{
- return d->m_indirections.isEmpty() && d->m_typeEntry->isUserPrimitive();
+ return d->m_indirections.isEmpty() && ::isUserPrimitive(d->m_typeEntry);
}
bool AbstractMetaType::isObjectTypeUsedAsValueType() const
@@ -841,20 +911,12 @@ bool AbstractMetaType::isPointerToWrapperType() const
bool AbstractMetaType::isWrapperPassedByReference() const
{
return d->m_referenceType == LValueReference && isWrapperType()
- && !isPointer();
-}
-
-bool AbstractMetaType::shouldDereferenceArgument() const
-{
- return isWrapperPassedByReference()
- || valueTypeWithCopyConstructorOnlyPassed()
- || isObjectTypeUsedAsValueType()
- || generateOpaqueContainer();
+ && !isPointer();
}
bool AbstractMetaType::isCppIntegralPrimitive() const
{
- return d->m_typeEntry->isCppIntegralPrimitive();
+ return ::isCppIntegralPrimitive(d->m_typeEntry);
}
bool AbstractMetaType::isExtendedCppPrimitive() const
@@ -863,14 +925,14 @@ bool AbstractMetaType::isExtendedCppPrimitive() const
return true;
if (!d->m_indirections.isEmpty())
return false;
- return d->m_typeEntry->isExtendedCppPrimitive();
+ return ::isExtendedCppPrimitive(d->m_typeEntry);
}
bool AbstractMetaType::isValueTypeWithCopyConstructorOnly() const
{
bool result = false;
if (d->m_typeEntry->isComplex()) {
- const auto *cte = static_cast<const ComplexTypeEntry *>(d->m_typeEntry);
+ const auto cte = std::static_pointer_cast<const ComplexTypeEntry>(d->m_typeEntry);
result = cte->isValueTypeWithCopyConstructorOnly();
}
return result;
@@ -887,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();
- if (typeSignature.startsWith(QLatin1String("::")))
+ 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);
@@ -903,30 +969,28 @@ 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();
}
-AbstractMetaType AbstractMetaType::fromTypeEntry(const TypeEntry *typeEntry)
+AbstractMetaType AbstractMetaType::fromTypeEntry(const TypeEntryCPtr &typeEntry)
{
QString typeName = typeEntry->qualifiedCppName();
- if (typeName.startsWith(QLatin1String("::")))
+ if (typeName.startsWith(u"::"))
typeName.remove(0, 2);
auto &cache = *metaTypeFromStringCache();
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());
}
@@ -934,39 +998,39 @@ AbstractMetaType AbstractMetaType::fromAbstractMetaClass(const AbstractMetaClass
template <class Predicate> // Predicate(containerTypeEntry, signature)
bool AbstractMetaTypeData::generateOpaqueContainer(Predicate pred) const
{
- if (m_pattern != AbstractMetaType::ContainerPattern)
+ // Allow for passing containers by pointer as well.
+ if (!m_typeEntry->isContainer())
return false;
- auto *containerTypeEntry = static_cast<const ContainerTypeEntry *>(m_typeEntry);
- auto kind = containerTypeEntry->containerKind();
- if (kind != ContainerTypeEntry::ListContainer)
+ if (m_indirections.size() > 1)
return false;
- const auto &instantation = m_instantiations.constFirst();
- if (instantation.referenceType() != NoReference)
+ auto containerTypeEntry = std::static_pointer_cast<const ContainerTypeEntry>(m_typeEntry);
+ auto kind = containerTypeEntry->containerKind();
+ 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 ContainerTypeEntry *t,
- const QString &signature)
+static bool opaqueContainerPredicate(const ContainerTypeEntryCPtr &t,
+ const QStringList &instantiations)
{
- return t->generateOpaqueContainer(signature);
+ return t->generateOpaqueContainer(instantiations);
}
bool AbstractMetaType::generateOpaqueContainer() const
@@ -979,8 +1043,9 @@ bool AbstractMetaType::generateOpaqueContainer() const
// (cf AbstractMetaFunction::generateOpaqueContainerReturn())
bool AbstractMetaType::generateOpaqueContainerForGetter(const QString &modifiedType) const
{
- auto predicate = [&modifiedType](const ContainerTypeEntry *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);
}
@@ -1004,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]";
@@ -1015,9 +1080,9 @@ void AbstractMetaType::formatDebug(QDebug &debug) const
<< "\", arrayElementCount=" << arrayElementCount();
}
const auto &instantiations = this->instantiations();
- if (const int instantiationsSize = instantiations.size()) {
+ if (const auto instantiationsSize = instantiations.size()) {
debug << ", instantiations[" << instantiationsSize << "]=<";
- for (int i = 0; i < instantiationsSize; ++i) {
+ for (qsizetype i = 0; i < instantiationsSize; ++i) {
if (i)
debug << ", ";
instantiations.at(i).formatDebug(debug);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.h b/sources/shiboken6/ApiExtractor/abstractmetatype.h
index e06535799..8a1ecdf20 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetatype.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetatype.h
@@ -1,38 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ABSTRACTMETATYPE_H
#define ABSTRACTMETATYPE_H
+#include "abstractmetalang_enums.h"
#include "abstractmetalang_typedefs.h"
#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>
@@ -70,11 +49,11 @@ public:
Q_ENUM(TypeUsagePattern)
AbstractMetaType();
- explicit AbstractMetaType(const TypeEntry *t);
+ 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;
@@ -90,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); }
@@ -126,6 +106,7 @@ public:
// returns true if the type was used as a smart pointer
bool isSmartPointer() const { return typeUsagePattern() == SmartPointerPattern; }
+ bool isUniquePointer() const;
// returns true if the type was used as a flag
bool isFlags() const { return typeUsagePattern() == FlagsPattern; }
@@ -140,6 +121,7 @@ public:
bool passByConstRef() const;
bool passByValue() const;
+ bool useStdMove() const;
ReferenceType referenceType() const;
void setReferenceType(ReferenceType ref);
@@ -163,14 +145,17 @@ public:
AbstractMetaTypeList nestedArrayTypes() const;
+ /// Strip const/indirections/reference from the type
+ AbstractMetaType plainType() const;
+
QString cppSignature() const;
QString pythonSignature() const;
bool applyArrayModification(QString *errorMessage);
- const TypeEntry *typeEntry() const;
- void setTypeEntry(const TypeEntry *type);
+ TypeEntryCPtr typeEntry() const;
+ void setTypeEntry(const TypeEntryCPtr &type);
void setOriginalTypeDescription(const QString &otd);
QString originalTypeDescription() const;
@@ -187,7 +172,8 @@ 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;
// View on: Type to use for function argument conversion, fex
// std::string_view -> std::string for foo(std::string_view);
@@ -202,13 +188,16 @@ 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 TypeEntry *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()
+ static QString dereferencePrefix(qsizetype n); // Return the prefix **/& as as required
+ static void applyDereference(QString *type, qsizetype n);
static bool stripDereference(QString *type); // "(*foo)" -> "foo"
// Query functions for generators
@@ -233,9 +222,6 @@ public:
bool isPointerToWrapperType() const;
/// Wrapper type passed by reference
bool isWrapperPassedByReference() const;
- /// Checks if the meta type of an argument should be dereferenced by the Python
- /// method wrapper passing it to C++.
- bool shouldDereferenceArgument() const;
/// Returns true if the type is a C++ integral primitive,
/// i.e. bool, char, int, long, and their unsigned counterparts.
bool isCppIntegralPrimitive() const;
@@ -268,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;
@@ -276,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
new file mode 100644
index 000000000..9d95b734c
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/addedfunction.cpp
@@ -0,0 +1,216 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "addedfunction.h"
+#include "addedfunction_p.h"
+#include "typeparser.h"
+
+#include <QtCore/QDebug>
+
+using namespace Qt::StringLiterals;
+
+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 {
+
+QDebug operator<<(QDebug d, const Argument &a)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "Argument(type=\"" << a.type << '"';
+ if (!a.name.isEmpty())
+ d << ", name=\"" << a.name << '"';
+ if (!a.defaultValue.isEmpty())
+ d << ", defaultValue=\"" << a.defaultValue << '"';
+ d << ')';
+ return d;
+}
+
+// Helper for finding the end of a function parameter, observing
+// nested template parameters or lists.
+static qsizetype parameterTokenEnd(qsizetype startPos, QStringView paramString)
+{
+ const auto end = paramString.size();
+ int nestingLevel = 0;
+ for (qsizetype p = startPos; p < end; ++p) {
+ switch (paramString.at(p).toLatin1()) {
+ case ',':
+ if (nestingLevel == 0)
+ return p;
+ break;
+ case '<': // templates
+ case '{': // initializer lists of default values
+ case '(': // initialization, function pointers
+ case '[': // array dimensions
+ ++nestingLevel;
+ break;
+ case '>':
+ case '}':
+ case ')':
+ case ']':
+ --nestingLevel;
+ break;
+ }
+ }
+ return end;
+}
+
+// Split a function parameter list into string tokens containing one
+// parameters (including default value, etc).
+static QList<QStringView> splitParameterTokens(QStringView paramString)
+{
+ QList<QStringView> result;
+ qsizetype startPos = 0;
+ for ( ; startPos < paramString.size(); ) {
+ const auto end = parameterTokenEnd(startPos, paramString);
+ result.append(paramString.mid(startPos, end - startPos).trimmed());
+ startPos = end + 1;
+ }
+ return result;
+}
+
+// Split a function parameter list
+Arguments splitParameters(QStringView paramString, QString *errorMessage)
+{
+ Arguments result;
+ const QList<QStringView> tokens = splitParameterTokens(paramString);
+
+ for (const auto &t : tokens) {
+ Argument argument;
+ // Check defaultValue, "int @b@=5"
+ const auto equalPos = t.lastIndexOf(u'=');
+ if (equalPos != -1) {
+ const int defaultValuePos = equalPos + 1;
+ argument.defaultValue =
+ t.mid(defaultValuePos, t.size() - defaultValuePos).trimmed().toString();
+ }
+ QString typeString = (equalPos != -1 ? t.left(equalPos) : t).trimmed().toString();
+ // Check @name@
+ const auto atPos = typeString.indexOf(u'@');
+ if (atPos != -1) {
+ const int namePos = atPos + 1;
+ const int nameEndPos = typeString.indexOf(u'@', namePos);
+ if (nameEndPos == -1) {
+ if (errorMessage != nullptr) {
+ *errorMessage = u"Mismatched @ in \""_s
+ + paramString.toString() + u'"';
+ }
+ return {};
+ }
+ argument.name = typeString.mid(namePos, nameEndPos - namePos).trimmed();
+ typeString.remove(atPos, nameEndPos - atPos + 1);
+ }
+ argument.type = typeString.trimmed();
+ result.append(argument);
+ }
+
+ return result;
+}
+
+} // namespace AddedFunctionParser
+
+AddedFunction::AddedFunction(const QString &name, const QList<Argument> &arguments,
+ const TypeInfo &returnType) :
+ m_name(name),
+ m_arguments(arguments),
+ m_returnType(returnType)
+{
+}
+
+AddedFunction::AddedFunctionPtr
+ AddedFunction::createAddedFunction(const QString &signatureIn, const QString &returnTypeIn,
+ QString *errorMessage)
+
+{
+ errorMessage->clear();
+
+ QList<Argument> arguments;
+ const TypeInfo returnType = returnTypeIn.isEmpty()
+ ? TypeInfo::voidType()
+ : TypeParser::parse(returnTypeIn, errorMessage);
+ if (!errorMessage->isEmpty())
+ return {};
+
+ QStringView signature = QStringView{signatureIn}.trimmed();
+
+ // Skip past "operator()(...)"
+ 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 auto closingParenPos = signature.lastIndexOf(u')');
+ if (closingParenPos < 0) {
+ *errorMessage = u"Missing closing parenthesis"_s;
+ return {};
+ }
+
+ // Check for "foo() const"
+ bool isConst = false;
+ const auto signatureLength = signature.length();
+ const auto qualifierLength = signatureLength - closingParenPos - 1;
+ if (qualifierLength >= 5
+ && signature.right(qualifierLength).contains(u"const")) {
+ isConst = true;
+ }
+
+ const auto paramString = signature.mid(openParenPos + 1, closingParenPos - openParenPos - 1);
+ const auto params = AddedFunctionParser::splitParameters(paramString, errorMessage);
+ if (params.isEmpty() && !errorMessage->isEmpty())
+ return {};
+ for (const auto &p : params) {
+ TypeInfo type = p.type == u"..."
+ ? TypeInfo::varArgsType() : TypeParser::parse(p.type, errorMessage);
+ if (!errorMessage->isEmpty()) {
+ errorMessage->prepend(u"Unable to parse added function "_s + signatureIn
+ + u": "_s);
+ return {};
+ }
+ arguments.append({type, p.name, p.defaultValue});
+ }
+
+ auto result = std::make_shared<AddedFunction>(name, arguments, returnType);
+ result->setConstant(isConst);
+ return result;
+}
+
+QDebug operator<<(QDebug d, const AddedFunction::Argument &a)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "Argument(";
+ d << a.typeInfo;
+ if (!a.name.isEmpty())
+ d << ' ' << a.name;
+ if (!a.defaultValue.isEmpty())
+ d << " = " << a.defaultValue;
+ d << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, const AddedFunction &af)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << "AddedFunction(";
+ if (af.access() == AddedFunction::Protected)
+ d << "protected";
+ if (af.isStatic())
+ d << " static";
+ d << af.returnType() << ' ' << af.name() << '(' << af.arguments() << ')';
+ if (af.isConstant())
+ d << " const";
+ if (af.isDeclaration())
+ d << " [declaration]";
+ return d;
+}
diff --git a/sources/shiboken6/ApiExtractor/addedfunction.h b/sources/shiboken6/ApiExtractor/addedfunction.h
new file mode 100644
index 000000000..b8d189b7a
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/addedfunction.h
@@ -0,0 +1,113 @@
+// 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 ADDEDFUNCTION_H
+#define ADDEDFUNCTION_H
+
+#include "modifications.h"
+#include "parser/typeinfo.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+
+#include <memory>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+
+/// \internal
+/// Struct used to store information about functions added by the typesystem.
+/// This info will be used later to create a fake AbstractMetaFunction which
+/// will be inserted into the right AbstractMetaClass.
+struct AddedFunction
+{
+ using AddedFunctionPtr = std::shared_ptr<AddedFunction>;
+
+ /// Function access types.
+ enum Access {
+ Protected = 0x1,
+ Public = 0x2
+ };
+
+ struct Argument
+ {
+ TypeInfo typeInfo;
+ QString name;
+ QString defaultValue;
+ };
+
+ /// Creates a new AddedFunction with a signature and a return type.
+ explicit AddedFunction(const QString &name, const QList<Argument> &arguments,
+ const TypeInfo &returnType);
+
+ static AddedFunctionPtr createAddedFunction(const QString &signatureIn,
+ const QString &returnTypeIn,
+ QString *errorMessage);
+
+ AddedFunction() = default;
+
+ /// Returns the function name.
+ QString name() const { return m_name; }
+
+ /// Set the function access type.
+ void setAccess(Access access) { m_access = access; }
+
+ /// Returns the function access type.
+ Access access() const { return m_access; }
+
+ /// Returns the function return type.
+ const TypeInfo &returnType() const { return m_returnType; }
+
+ /// Returns a list of argument type infos.
+ const QList<Argument> &arguments() const { return m_arguments; }
+
+ /// Returns true if this is a constant method.
+ bool isConstant() const { return m_isConst; }
+ void setConstant(bool c) { m_isConst = c; };
+
+ /// Set this method static.
+ void setStatic(bool value) { m_isStatic = value; }
+
+ /// Set this method as a classmethod.
+ void setClassMethod(bool value) { m_isClassMethod = value; }
+
+ /// Returns true if this is a static method.
+ bool isStatic() const { return m_isStatic; }
+
+ /// Returns true if this is a class method.
+ bool isClassMethod() const { return m_isClassMethod; }
+
+ 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; }
+
+ const DocModificationList &docModifications() const { return m_docModifications; }
+ 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);
+QDebug operator<<(QDebug d, const AddedFunction &af);
+
+#endif // ADDEDFUNCTION_H
diff --git a/sources/shiboken6/ApiExtractor/addedfunction_p.h b/sources/shiboken6/ApiExtractor/addedfunction_p.h
new file mode 100644
index 000000000..40b69a5df
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/addedfunction_p.h
@@ -0,0 +1,45 @@
+// 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 ADDEDFUNCTION_P_H
+#define ADDEDFUNCTION_P_H
+
+#include <QtCore/QtCompare>
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QStringView>
+
+QT_BEGIN_NAMESPACE
+class QDebug;
+QT_END_NAMESPACE
+
+// Helpers to split a parameter list of <add-function>, <declare-function>
+// in a separate header for testing purposes
+
+namespace AddedFunctionParser {
+
+struct Argument
+{
+ 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>;
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const Argument &a);
+#endif
+
+Arguments splitParameters(QStringView paramString, QString *errorMessage = nullptr);
+
+} // namespace AddedFunctionParser
+
+#endif // MODIFICATIONS_P_H
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 cee8bbdcd..786cd0783 100644
--- a/sources/shiboken6/ApiExtractor/apiextractor.cpp
+++ b/sources/shiboken6/ApiExtractor/apiextractor.cpp
@@ -1,156 +1,314 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "apiextractor.h"
#include "apiextractorresult.h"
+#include "abstractmetaargument.h"
+#include "abstractmetabuilder.h"
+#include "abstractmetaenum.h"
+#include "abstractmetafield.h"
+#include "abstractmetafunction.h"
#include "abstractmetalang.h"
+#include "codesnip.h"
+#include "exception.h"
+#include "messages.h"
+#include "modifications.h"
+#include "optionsparser.h"
+#include "reporthandler.h"
+#include "typedatabase.h"
+#include "customconversion.h"
+#include "containertypeentry.h"
+#include "primitivetypeentry.h"
+#include "smartpointertypeentry.h"
+#include "typedefentry.h"
+#include "namespacetypeentry.h"
+#include "typesystemtypeentry.h"
+
+#include "qtcompat.h"
+
+#include <QtCore/QDir>
+#include <QtCore/QDebug>
+#include <QtCore/QTemporaryFile>
-#include <QDir>
-#include <QDebug>
-#include <QTemporaryFile>
#include <algorithm>
#include <iostream>
#include <iterator>
-#include "reporthandler.h"
-#include "typesystem.h"
-#include "fileout.h"
-#include "abstractmetabuilder.h"
-#include "abstractmetaenum.h"
-#include "typedatabase.h"
-#include "typesystem.h"
+using namespace Qt::StringLiterals;
-#include <algorithm>
-#include <iterator>
+struct InstantiationCollectContext
+{
+ AbstractMetaTypeList instantiatedContainers;
+ InstantiatedSmartPointers instantiatedSmartPointers;
+ QStringList instantiatedContainersNames;
+};
-ApiExtractor::ApiExtractor()
+struct ApiExtractorOptions
{
- // Environment TYPESYSTEMPATH
- QString envTypesystemPaths = QFile::decodeName(qgetenv("TYPESYSTEMPATH"));
- if (!envTypesystemPaths.isEmpty())
- TypeDatabase::instance()->addTypesystemPath(envTypesystemPaths);
+ 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')';
}
-ApiExtractor::~ApiExtractor()
+QList<OptionDescription> ApiExtractor::options()
{
- delete m_builder;
+ 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()},
+ };
}
-void ApiExtractor::addTypesystemSearchPath (const QString& path)
+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)
{
- TypeDatabase::instance()->addTypesystemPath(path);
+ 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 ApiExtractor::addTypesystemSearchPath(const QStringList& paths)
+void ApiExtractorOptionsParser::parseIncludePathOption(const QStringList &values,
+ HeaderType headerType)
{
- for (const QString &path : paths)
- addTypesystemSearchPath(path);
+ for (const auto &value : values)
+ parseIncludePathOption(value, headerType);
}
-void ApiExtractor::setTypesystemKeywords(const QStringList &keywords)
+void ApiExtractorOptionsParser::setLanguageLevel(const QString &value)
{
- TypeDatabase::instance()->setTypesystemKeywords(keywords);
+ 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;
}
-void ApiExtractor::addIncludePath(const HeaderPath& path)
+bool ApiExtractorOptionsParser::handleBoolOption(const QString &key, OptionSource source)
{
- m_includePaths << path;
+ 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;
}
-void ApiExtractor::addIncludePath(const HeaderPaths& paths)
+bool ApiExtractorOptionsParser::handleOption(const QString &key, const QString &value,
+ OptionSource source)
{
- m_includePaths << paths;
+ 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;
}
-void ApiExtractor::setLogDirectory(const QString& logDir)
+std::shared_ptr<OptionsParser> ApiExtractor::createOptionsParser()
{
- m_logDirectory = logDir;
+ return std::make_shared<ApiExtractorOptionsParser>(d);
}
-void ApiExtractor::setCppFileNames(const QFileInfoList &cppFileName)
+struct ApiExtractorPrivate : public ApiExtractorOptions
+{
+ bool runHelper(ApiExtractorFlags flags);
+
+ static QString getSimplifiedContainerTypeName(const AbstractMetaType &type);
+ void addInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
+ const AbstractMetaType &type,
+ const QString &contextName);
+ void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
+ const AbstractMetaFunctionCPtr &func);
+ void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
+ const AbstractMetaClassCPtr &metaClass);
+ void collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context);
+ void collectInstantiatedOpqaqueContainers(InstantiationCollectContext &context);
+ void collectContainerTypesFromSnippets(InstantiationCollectContext &context);
+ void collectContainerTypesFromConverterMacros(InstantiationCollectContext &context,
+ const QString &code,
+ bool toPythonMacro);
+ void addInstantiatedSmartPointer(InstantiationCollectContext &context,
+ const AbstractMetaType &type);
+
+ AbstractMetaBuilder *m_builder = nullptr;
+};
+
+ApiExtractor::ApiExtractor() :
+ d(new ApiExtractorPrivate)
{
- m_cppFileNames = cppFileName;
}
-void ApiExtractor::setTypeSystem(const QString& typeSystemFileName)
+ApiExtractor::~ApiExtractor()
{
- m_typeSystemFileName = typeSystemFileName;
+ delete d->m_builder;
+ delete d;
}
-void ApiExtractor::setSkipDeprecated(bool value)
+HeaderPaths ApiExtractor::includePaths() const
{
- m_skipDeprecated = value;
- if (m_builder)
- m_builder->setSkipDeprecated(m_skipDeprecated);
+ return d->m_includePaths;
}
-void ApiExtractor::setSuppressWarnings ( bool value )
+void ApiExtractor::setLogDirectory(const QString& logDir)
{
- TypeDatabase::instance()->setSuppressWarnings(value);
+ d->m_logDirectory = logDir;
}
-void ApiExtractor::setSilent ( bool value )
+void ApiExtractor::setCppFileNames(const QFileInfoList &cppFileName)
{
- ReportHandler::setSilent(value);
+ d->m_cppFileNames = cppFileName;
}
-bool ApiExtractor::setApiVersion(const QString& package, const QString &version)
+QFileInfoList ApiExtractor::cppFileNames() const
{
- return TypeDatabase::setApiVersion(package, version);
+ return d->m_cppFileNames;
}
-void ApiExtractor::setDropTypeEntries(const QStringList &dropEntries)
+void ApiExtractor::setTypeSystem(const QString& typeSystemFileName)
{
- TypeDatabase::instance()->setDropTypeEntries(dropEntries);
+ d->m_typeSystemFileName = typeSystemFileName;
+}
+
+QString ApiExtractor::typeSystem() const
+{
+ return d->m_typeSystemFileName;
}
const AbstractMetaEnumList &ApiExtractor::globalEnums() const
{
- Q_ASSERT(m_builder);
- return m_builder->globalEnums();
+ Q_ASSERT(d->m_builder);
+ return d->m_builder->globalEnums();
}
const AbstractMetaFunctionCList &ApiExtractor::globalFunctions() const
{
- Q_ASSERT(m_builder);
- return m_builder->globalFunctions();
+ Q_ASSERT(d->m_builder);
+ return d->m_builder->globalFunctions();
}
const AbstractMetaClassList &ApiExtractor::classes() const
{
- Q_ASSERT(m_builder);
- return m_builder->classes();
+ Q_ASSERT(d->m_builder);
+ return d->m_builder->classes();
}
const AbstractMetaClassList &ApiExtractor::smartPointers() const
{
- Q_ASSERT(m_builder);
- return m_builder->smartPointers();
+ Q_ASSERT(d->m_builder);
+ return d->m_builder->smartPointers();
}
// Add defines required for parsing Qt code headers
@@ -171,7 +329,7 @@ static void addPySideExtensions(QByteArrayList *a)
a->append(QByteArrayLiteral("-DQSIMD_H"));
}
-bool ApiExtractor::runHelper(bool usePySideExtensions)
+bool ApiExtractorPrivate::runHelper(ApiExtractorFlags flags)
{
if (m_builder)
return false;
@@ -181,9 +339,8 @@ bool ApiExtractor::runHelper(bool usePySideExtensions)
return false;
}
- const QString pattern = QDir::tempPath() + QLatin1Char('/')
- + m_cppFileNames.constFirst().baseName()
- + QStringLiteral("_XXXXXX.hpp");
+ const QString pattern = QDir::tempPath() + u'/'
+ + m_cppFileNames.constFirst().baseName() + "_XXXXXX.hpp"_L1;
QTemporaryFile ppFile(pattern);
bool autoRemove = !qEnvironmentVariableIsSet("KEEP_TEMP_FILES");
// make sure that a tempfile can be written
@@ -192,7 +349,7 @@ bool ApiExtractor::runHelper(bool usePySideExtensions)
<< ": " << qPrintable(ppFile.errorString()) << '\n';
return false;
}
- for (const auto &cppFileName : qAsConst(m_cppFileNames)) {
+ for (const auto &cppFileName : std::as_const(m_cppFileNames)) {
ppFile.write("#include \"");
ppFile.write(cppFileName.absoluteFilePath().toLocal8Bit());
ppFile.write("\"\n");
@@ -204,6 +361,7 @@ bool ApiExtractor::runHelper(bool usePySideExtensions)
m_builder->setGlobalHeaders(m_cppFileNames);
m_builder->setSkipDeprecated(m_skipDeprecated);
m_builder->setHeaderPaths(m_includePaths);
+ m_builder->setApiExtractorFlags(flags);
QByteArrayList arguments;
const auto clangOptionsSize = m_clangOptions.size();
@@ -220,19 +378,20 @@ bool ApiExtractor::runHelper(bool usePySideExtensions)
arguments.append(m_clangOptions.at(i).toUtf8());
}
- for (const HeaderPath &headerPath : qAsConst(m_includePaths))
+ 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 (usePySideExtensions)
- addPySideExtensions(&arguments);
-
- const bool result = m_builder->build(arguments, addCompilerSupportArguments, m_languageLevel);
+ const bool result = m_builder->build(arguments, flags, addCompilerSupportArguments,
+ m_languageLevel);
if (!result)
autoRemove = false;
if (!autoRemove) {
@@ -248,42 +407,414 @@ static inline void classListToCList(const AbstractMetaClassList &list, AbstractM
std::copy(list.cbegin(), list.cend(), std::back_inserter(*target));
}
-std::optional<ApiExtractorResult> ApiExtractor::run(bool usePySideExtensions)
+std::optional<ApiExtractorResult> ApiExtractor::run(ApiExtractorFlags flags)
{
- if (!runHelper(usePySideExtensions))
+ if (!d->runHelper(flags))
return {};
+ InstantiationCollectContext collectContext;
+ d->collectInstantiatedContainersAndSmartPointers(collectContext);
+
ApiExtractorResult result;
- classListToCList(m_builder->classes(), &result.m_metaClasses);
- classListToCList(m_builder->smartPointers(), &result.m_smartPointers);
- result.m_globalFunctions = m_builder->globalFunctions();
- result.m_globalEnums = m_builder->globalEnums();
- result.m_enums = m_builder->typeEntryToEnumsHash();
+ 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
{
- return m_languageLevel;
+ return d->m_languageLevel;
}
-void ApiExtractor::setLanguageLevel(LanguageLevel languageLevel)
+QStringList ApiExtractor::clangOptions() const
{
- m_languageLevel = languageLevel;
+ return d->m_clangOptions;
}
-QStringList ApiExtractor::clangOptions() const
+AbstractMetaFunctionPtr
+ ApiExtractor::inheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes)
+{
+ return AbstractMetaBuilder::inheritTemplateFunction(function, templateTypes);
+}
+
+AbstractMetaFunctionPtr
+ ApiExtractor::inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass)
+{
+ return AbstractMetaBuilder::inheritTemplateMember(function, templateTypes,
+ templateClass, subclass);
+}
+
+AbstractMetaClassPtr ApiExtractor::inheritTemplateClass(const ComplexTypeEntryPtr &te,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes)
{
- return m_clangOptions;
+ return AbstractMetaBuilder::inheritTemplateClass(te, templateClass,
+ templateTypes);
}
-void ApiExtractor::setClangOptions(const QStringList &co)
+QString ApiExtractorPrivate::getSimplifiedContainerTypeName(const AbstractMetaType &type)
{
- m_clangOptions = co;
+ const QString signature = type.cppSignature();
+ if (!type.typeEntry()->isContainer() && !type.typeEntry()->isSmartPointer())
+ return signature;
+ QString typeName = signature;
+ if (type.isConstant())
+ typeName.remove(0, sizeof("const ") / sizeof(char) - 1);
+ switch (type.referenceType()) {
+ case NoReference:
+ break;
+ case LValueReference:
+ typeName.chop(1);
+ break;
+ case RValueReference:
+ typeName.chop(2);
+ break;
+ }
+ while (typeName.endsWith(u'*') || typeName.endsWith(u' '))
+ typeName.chop(1);
+ return typeName;
}
-void ApiExtractor::setUseGlobalHeader(bool h)
+// Strip a "const QSharedPtr<const Foo> &" or similar to "QSharedPtr<Foo>" (PYSIDE-1016/454)
+AbstractMetaType canonicalSmartPtrInstantiation(const AbstractMetaType &type)
{
- AbstractMetaBuilder::setUseGlobalHeader(h);
+ const AbstractMetaTypeList &instantiations = type.instantiations();
+ Q_ASSERT(instantiations.size() == 1);
+ const bool needsFix = type.isConstant() || type.referenceType() != NoReference;
+ const bool pointeeNeedsFix = instantiations.constFirst().isConstant();
+ if (!needsFix && !pointeeNeedsFix)
+ return type;
+ auto fixedType = type;
+ fixedType.setReferenceType(NoReference);
+ fixedType.setConstant(false);
+ if (pointeeNeedsFix) {
+ auto fixedPointeeType = instantiations.constFirst();
+ fixedPointeeType.setConstant(false);
+ fixedType.setInstantiations(AbstractMetaTypeList(1, fixedPointeeType));
+ }
+ return fixedType;
+}
+
+static inline TypeEntryCPtr pointeeTypeEntry(const AbstractMetaType &smartPtrType)
+{
+ return smartPtrType.instantiations().constFirst().typeEntry();
+}
+
+static AbstractMetaType simplifiedType(AbstractMetaType type)
+{
+ type.setIndirections(0);
+ type.setConstant(false);
+ type.setReferenceType(NoReference);
+ type.decideUsagePattern();
+ return type;
+}
+
+void
+ApiExtractorPrivate::addInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
+ const AbstractMetaType &type,
+ const QString &contextName)
+{
+ for (const auto &t : type.instantiations())
+ addInstantiatedContainersAndSmartPointers(context, t, contextName);
+ const auto typeEntry = type.typeEntry();
+ const bool isContainer = typeEntry->isContainer();
+ if (!isContainer
+ && !(typeEntry->isSmartPointer() && typeEntry->generateCode())) {
+ return;
+ }
+ if (type.hasTemplateChildren()) {
+ 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(" Calling context: "_L1 + contextName);
+
+ qCWarning(lcShiboken).noquote().nospace() << warning;
+ return;
+
+ }
+ if (isContainer) {
+ const QString typeName = getSimplifiedContainerTypeName(type);
+ if (!context.instantiatedContainersNames.contains(typeName)) {
+ context.instantiatedContainersNames.append(typeName);
+ context.instantiatedContainers.append(simplifiedType(type));
+ }
+ return;
+ }
+
+ // Is smart pointer. Check if the (const?) pointee is already known for the given
+ // smart pointer type entry.
+ auto pt = pointeeTypeEntry(type);
+ const bool present =
+ std::any_of(context.instantiatedSmartPointers.cbegin(),
+ context.instantiatedSmartPointers.cend(),
+ [typeEntry, pt] (const InstantiatedSmartPointer &smp) {
+ return smp.type.typeEntry() == typeEntry
+ && pointeeTypeEntry(smp.type) == pt;
+ });
+ if (!present)
+ addInstantiatedSmartPointer(context, type);
+}
+
+// Create a modification that invalidates the pointee argument of a smart
+// pointer constructor or reset().
+static FunctionModification invalidateArgMod(const AbstractMetaFunctionCPtr &f, int index = 1)
+{
+ ArgumentModification argMod;
+ argMod.setTargetOwnerShip(TypeSystem::CppOwnership);
+ argMod.setIndex(index);
+ FunctionModification funcMod;
+ funcMod.setSignature(f->minimalSignature());
+ funcMod.setArgument_mods({argMod});
+ return funcMod;
+}
+
+static void addOwnerModification(const AbstractMetaFunctionCList &functions,
+ const ComplexTypeEntryPtr &typeEntry)
+{
+ for (const auto &f : functions) {
+ if (!f->arguments().isEmpty()
+ && f->arguments().constFirst().type().indirections() > 0) {
+ std::const_pointer_cast<AbstractMetaFunction>(f)->clearModificationsCache();
+ typeEntry->addFunctionModification(invalidateArgMod(f));
+ }
+ }
+}
+
+void ApiExtractorPrivate::addInstantiatedSmartPointer(InstantiationCollectContext &context,
+ const AbstractMetaType &type)
+{
+ InstantiatedSmartPointer smp;
+ smp.type = canonicalSmartPtrInstantiation(type);
+ smp.smartPointer = AbstractMetaClass::findClass(m_builder->smartPointers(),
+ type.typeEntry());
+ Q_ASSERT(smp.smartPointer);
+
+ const auto &instantiatedType = type.instantiations().constFirst();
+ const auto ste = std::static_pointer_cast<const SmartPointerTypeEntry>(smp.smartPointer->typeEntry());
+ QString name = ste->getTargetName(smp.type);
+ auto parentTypeEntry = ste->parent();
+
+ // FIXME PYSIDE 7: Make global scope the default behavior?
+ // Note: Also requires changing SmartPointerTypeEntry::getTargetName()
+ // to not strip namespaces from unnamed instances.
+ const bool globalScope = name.startsWith("::"_L1);
+ if (globalScope) {
+ name.remove(0, 2);
+ parentTypeEntry = typeSystemTypeEntry(ste);
+ }
+
+ auto colonPos = name.lastIndexOf(u"::");
+ const bool withinNameSpace = colonPos != -1;
+ if (withinNameSpace) { // user defined
+ const QString nameSpace = name.left(colonPos);
+ name.remove(0, colonPos + 2);
+ const auto nameSpaces = TypeDatabase::instance()->findNamespaceTypes(nameSpace);
+ if (nameSpaces.isEmpty())
+ throw Exception(msgNamespaceNotFound(name));
+ parentTypeEntry = nameSpaces.constFirst();
+ }
+
+ 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});
+ Q_ASSERT(smp.specialized);
+ if (parentTypeEntry->type() != TypeEntry::TypeSystemType) { // move class to desired namespace
+ const auto enclClass = AbstractMetaClass::findClass(m_builder->classes(), parentTypeEntry);
+ Q_ASSERT(enclClass);
+ auto specialized = std::const_pointer_cast<AbstractMetaClass>(smp.specialized);
+ specialized->setEnclosingClass(enclClass);
+ enclClass->addInnerClass(specialized);
+ }
+
+ if (instantiationEntry->isComplex()) {
+ addOwnerModification(smp.specialized->queryFunctions(FunctionQueryOption::Constructors),
+ instantiationEntry);
+ if (!ste->resetMethod().isEmpty()) {
+ addOwnerModification(smp.specialized->findFunctions(ste->resetMethod()),
+ instantiationEntry);
+ }
+ }
+
+ context.instantiatedSmartPointers.append(smp);
+}
+
+void
+ApiExtractorPrivate::collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context,
+ const AbstractMetaFunctionCPtr &func)
+{
+ addInstantiatedContainersAndSmartPointers(context, func->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 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.
+ const auto &innerClasses = metaClass->innerClasses();
+ for (auto i = innerClasses.size() - 1; i >= 0; --i) {
+ const auto innerClass = innerClasses.at(i);
+ if (!innerClass->typeEntry()->isSmartPointer())
+ collectInstantiatedContainersAndSmartPointers(context, innerClass);
+ }
+}
+
+void
+ApiExtractorPrivate::collectInstantiatedContainersAndSmartPointers(InstantiationCollectContext &context)
+{
+ collectInstantiatedOpqaqueContainers(context);
+ for (const auto &func : m_builder->globalFunctions())
+ collectInstantiatedContainersAndSmartPointers(context, func);
+ for (const auto &metaClass : m_builder->classes())
+ collectInstantiatedContainersAndSmartPointers(context, metaClass);
+ collectContainerTypesFromSnippets(context);
+}
+
+// Whether to generate an opaque container: If the instantiation type is in
+// the current package or, for primitive types, if the container is in the
+// current package.
+static bool generateOpaqueContainer(const AbstractMetaType &type,
+ const TypeSystemTypeEntryCPtr &moduleEntry)
+{
+ auto te = type.instantiations().constFirst().typeEntry();
+ auto typeModuleEntry = typeSystemTypeEntry(te);
+ return typeModuleEntry == moduleEntry
+ || (te->isPrimitive() && typeSystemTypeEntry(type.typeEntry()) == moduleEntry);
+}
+
+void ApiExtractorPrivate::collectInstantiatedOpqaqueContainers(InstantiationCollectContext &context)
+{
+ // Add all instantiations of opaque containers for types from the current
+ // module.
+ auto *td = TypeDatabase::instance();
+ const auto moduleEntry = TypeDatabase::instance()->defaultTypeSystemType();
+ const auto &containers = td->containerTypes();
+ for (const auto &container : containers) {
+ for (const auto &oc : container->opaqueContainers()) {
+ QString errorMessage;
+ const QString typeName = container->qualifiedCppName() + oc.templateParameters();
+ auto typeOpt = AbstractMetaType::fromString(typeName, &errorMessage);
+ if (typeOpt.has_value()
+ && generateOpaqueContainer(typeOpt.value(), moduleEntry)) {
+ addInstantiatedContainersAndSmartPointers(context, typeOpt.value(),
+ u"opaque containers"_s);
+ }
+ }
+ }
+}
+
+static void getCode(QStringList &code, const CodeSnipList &codeSnips)
+{
+ for (const CodeSnip &snip : std::as_const(codeSnips))
+ code.append(snip.code());
+}
+
+static void getCode(QStringList &code, const TypeEntryCPtr &type)
+{
+ if (type->isComplex())
+ getCode(code, std::static_pointer_cast<const ComplexTypeEntry>(type)->codeSnips());
+ else if (type->isTypeSystem())
+ getCode(code, std::static_pointer_cast<const TypeSystemTypeEntry>(type)->codeSnips());
+
+ auto customConversion = CustomConversion::getCustomConversion(type);
+ if (!customConversion)
+ return;
+
+ if (!customConversion->nativeToTargetConversion().isEmpty())
+ code.append(customConversion->nativeToTargetConversion());
+
+ const auto &toCppConversions = customConversion->targetToNativeConversions();
+ if (toCppConversions.isEmpty())
+ return;
+
+ for (const auto &toNative : std::as_const(toCppConversions))
+ code.append(toNative.conversion());
+}
+
+void ApiExtractorPrivate::collectContainerTypesFromSnippets(InstantiationCollectContext &context)
+{
+ QStringList snips;
+ auto *td = TypeDatabase::instance();
+ const PrimitiveTypeEntryCList &primitiveTypeList = td->primitiveTypes();
+ for (const auto &type : primitiveTypeList)
+ getCode(snips, type);
+ const ContainerTypeEntryCList &containerTypeList = td->containerTypes();
+ for (const auto &type : containerTypeList)
+ getCode(snips, type);
+ for (const auto &metaClass : m_builder->classes())
+ getCode(snips, metaClass->typeEntry());
+
+ const auto moduleEntry = td->defaultTypeSystemType();
+ Q_ASSERT(moduleEntry);
+ getCode(snips, moduleEntry);
+
+ for (const auto &func : m_builder->globalFunctions())
+ getCode(snips, func->injectedCodeSnips());
+
+ for (const QString &code : std::as_const(snips)) {
+ collectContainerTypesFromConverterMacros(context, code, true);
+ collectContainerTypesFromConverterMacros(context, code, false);
+ }
+}
+
+void
+ApiExtractorPrivate::collectContainerTypesFromConverterMacros(InstantiationCollectContext &context,
+ const QString &code,
+ bool toPythonMacro)
+{
+ QString convMacro = toPythonMacro ? u"%CONVERTTOPYTHON["_s : u"%CONVERTTOCPP["_s;
+ 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);
+ start += offset;
+ if (code.at(start) != u'%') {
+ QString typeString = code.mid(start, end - start);
+ auto type = AbstractMetaType::fromString(typeString, &errorMessage);
+ if (type.has_value()) {
+ const QString &d = type->originalTypeDescription();
+ addInstantiatedContainersAndSmartPointers(context, type.value(), d);
+ } else {
+ QString m;
+ QTextStream(&m) << __FUNCTION__ << ": Cannot translate type \""
+ << typeString << "\": " << errorMessage;
+ throw Exception(m);
+ }
+ }
+ start = end;
+ }
}
#ifndef QT_NO_DEBUG_STREAM
@@ -311,7 +842,7 @@ QDebug operator<<(QDebug d, const ApiExtractor &ae)
d.setVerbosity(3); // Trigger verbose output of AbstractMetaClass
d << "ApiExtractor(typeSystem=\"" << ae.typeSystem() << "\", cppFileNames=\""
<< ae.cppFileNames() << ", ";
- ae.m_builder->formatDebug(d);
+ ae.d->m_builder->formatDebug(d);
d << ')';
return d;
}
diff --git a/sources/shiboken6/ApiExtractor/apiextractor.h b/sources/shiboken6/ApiExtractor/apiextractor.h
index f7e3685f5..7bff5c252 100644
--- a/sources/shiboken6/ApiExtractor/apiextractor.h
+++ b/sources/shiboken6/ApiExtractor/apiextractor.h
@@ -1,109 +1,82 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef APIEXTRACTOR_H
#define APIEXTRACTOR_H
#include "abstractmetalang_typedefs.h"
+#include "apiextractorflags.h"
#include "header_paths.h"
-#include "typedatabase_typedefs.h"
-#include "typesystem_typedefs.h"
#include "clangparser/compilersupport.h"
-#include <QFileInfoList>
-#include <QStringList>
+#include "typesystem_typedefs.h"
+
+#include <QtCore/QFileInfoList>
+#include <QtCore/QStringList>
#include <optional>
class ApiExtractorResult;
-class AbstractMetaBuilder;
class AbstractMetaClass;
class AbstractMetaEnum;
class AbstractMetaFunction;
-class AbstractMetaType;
-class ContainerTypeEntry;
-class EnumTypeEntry;
-class FlagsTypeEntry;
-class PrimitiveTypeEntry;
-class TypeEntry;
+class ComplexTypeEntry;
+struct OptionDescription;
+class OptionsParser;
QT_BEGIN_NAMESPACE
class QDebug;
class QIODevice;
QT_END_NAMESPACE
+struct ApiExtractorPrivate;
+
class ApiExtractor
{
public:
- Q_DISABLE_COPY(ApiExtractor)
+ Q_DISABLE_COPY_MOVE(ApiExtractor)
ApiExtractor();
~ApiExtractor();
+ static QList<OptionDescription> options();
+ std::shared_ptr<OptionsParser> createOptionsParser();
+
void setTypeSystem(const QString& typeSystemFileName);
- QString typeSystem() const { return m_typeSystemFileName; }
+ QString typeSystem() const;
void setCppFileNames(const QFileInfoList &cppFileNames);
- QFileInfoList cppFileNames() const { return m_cppFileNames; }
- 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 { return m_includePaths; }
+ QFileInfoList cppFileNames() const;
+ 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;
const AbstractMetaClassList &classes() const;
const AbstractMetaClassList &smartPointers() const;
- std::optional<ApiExtractorResult> run(bool usePySideExtensions);
+ std::optional<ApiExtractorResult> run(ApiExtractorFlags flags);
+
+ /// Forwards to AbstractMetaBuilder::inheritTemplateFunction()
+ static AbstractMetaFunctionPtr
+ inheritTemplateFunction(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes);
+
+ /// Forwards to AbstractMetaBuilder::inheritTemplateMember()
+ static AbstractMetaFunctionPtr
+ inheritTemplateMember(const AbstractMetaFunctionCPtr &function,
+ const AbstractMetaTypeList &templateTypes,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaClassPtr &subclass);
+
+ /// Forwards to AbstractMetaBuilder::inheritTemplateClass()
+ static AbstractMetaClassPtr
+ inheritTemplateClass(const ComplexTypeEntryPtr &te,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes);
private:
- bool runHelper(bool usePySideExtensions);
-
- 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;
+ ApiExtractorPrivate *d;
#ifndef QT_NO_DEBUG_STREAM
friend QDebug operator<<(QDebug d, const ApiExtractor &ae);
diff --git a/sources/shiboken6/ApiExtractor/apiextractorflags.h b/sources/shiboken6/ApiExtractor/apiextractorflags.h
new file mode 100644
index 000000000..6f69b8b77
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/apiextractorflags.h
@@ -0,0 +1,18 @@
+// 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 APIEXTRACTORFLAGS_H
+#define APIEXTRACTORFLAGS_H
+
+#include <QtCore/QFlags>
+
+enum class ApiExtractorFlag
+{
+ UsePySideExtensions = 0x1,
+ AvoidProtectedHack = 0x2
+};
+
+Q_DECLARE_FLAGS(ApiExtractorFlags, ApiExtractorFlag)
+Q_DECLARE_OPERATORS_FOR_FLAGS(ApiExtractorFlags)
+
+#endif // APIEXTRACTORFLAGS_H
diff --git a/sources/shiboken6/ApiExtractor/apiextractorresult.cpp b/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
index 04566ada2..5a433bbeb 100644
--- a/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
+++ b/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
@@ -1,48 +1,95 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "apiextractorresult.h"
#include "abstractmetalang.h"
#include "abstractmetaenum.h"
-#include "typesystem.h"
+#include "enumtypeentry.h"
+#include "flagstypeentry.h"
+#include "smartpointertypeentry.h"
-std::optional<AbstractMetaEnum> ApiExtractorResult::findAbstractMetaEnum(const TypeEntry *typeEntry) const
+ApiExtractorResult::ApiExtractorResult() = default;
+
+ApiExtractorResult::ApiExtractorResult(const ApiExtractorResult &) = default;
+
+ApiExtractorResult &ApiExtractorResult::operator=(const ApiExtractorResult &) = default;
+
+ApiExtractorResult::ApiExtractorResult(ApiExtractorResult &&) noexcept = default;
+
+ApiExtractorResult &ApiExtractorResult::operator=(ApiExtractorResult &&) noexcept = default;
+
+ApiExtractorResult::~ApiExtractorResult() = default;
+
+const AbstractMetaEnumList &ApiExtractorResult::globalEnums() const
+{
+ return m_globalEnums;
+}
+
+const AbstractMetaFunctionCList &ApiExtractorResult::globalFunctions() const
+{
+ return m_globalFunctions;
+}
+
+const AbstractMetaClassCList &ApiExtractorResult::classes() const
+{
+ return m_metaClasses;
+}
+
+const AbstractMetaClassCList &ApiExtractorResult::smartPointers() const
+{
+ return m_smartPointers;
+}
+
+const AbstractMetaTypeList &ApiExtractorResult::instantiatedContainers() const
+{
+ return m_instantiatedContainers;
+}
+
+const InstantiatedSmartPointers &ApiExtractorResult::instantiatedSmartPointers() const
+{
+ 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 m_flags;
+}
+
+void ApiExtractorResult::setFlags(ApiExtractorFlags f)
+{
+ m_flags = f;
+}
+
+std::optional<AbstractMetaEnum>
+ ApiExtractorResult::findAbstractMetaEnum(TypeEntryCPtr typeEntry) const
{
if (typeEntry && typeEntry->isFlags())
- typeEntry = static_cast<const FlagsTypeEntry *>(typeEntry)->originator();
+ 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();
}
-AbstractMetaFunctionCList ApiExtractorResult::implicitConversions(const TypeEntry *type) const
+AbstractMetaFunctionCList ApiExtractorResult::implicitConversions(const TypeEntryCPtr &type) const
{
if (type->isValue()) {
if (auto metaClass = AbstractMetaClass::findClass(m_metaClasses, type))
diff --git a/sources/shiboken6/ApiExtractor/apiextractorresult.h b/sources/shiboken6/ApiExtractor/apiextractorresult.h
index 18b07a1b7..b2aae88ed 100644
--- a/sources/shiboken6/ApiExtractor/apiextractorresult.h
+++ b/sources/shiboken6/ApiExtractor/apiextractorresult.h
@@ -1,75 +1,81 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef APIEXTRACTORRESULT_H
#define APIEXTRACTORRESULT_H
-#include "abstractmetalang.h"
-#include "abstractmetaenum.h"
+#include "apiextractorflags.h"
#include "abstractmetatype.h"
+#include "abstractmetalang_typedefs.h"
#include "typesystem_typedefs.h"
#include <QtCore/QHash>
+#include <QtCore/QMultiHash>
#include <optional>
+class ApiExtractorResultData;
+
+struct InstantiatedSmartPointer
+{
+ AbstractMetaClassCPtr smartPointer; // Template class
+ AbstractMetaClassCPtr specialized; // Specialized for type
+ AbstractMetaType type;
+};
+
+using InstantiatedSmartPointers = QList<InstantiatedSmartPointer>;
+
/// Result of an ApiExtractor run.
-/// Note: The class lists in here are flat, non-owning lists, currently
-/// (pending introduction of QSharedPointer for AbstractMetaClass); the
-/// ApiExtractor/AbstractMetaBuilder must be kept alive during the
-/// generator run since it owns the classes.
class ApiExtractorResult
{
- friend class ApiExtractor;
public:
- const AbstractMetaEnumList &globalEnums() const { return m_globalEnums; }
- const AbstractMetaFunctionCList &globalFunctions() const { return m_globalFunctions; }
- const AbstractMetaClassCList &classes() const { return m_metaClasses; }
- const AbstractMetaClassCList &smartPointers() const { return m_smartPointers; }
+ ApiExtractorResult();
+ ApiExtractorResult(const ApiExtractorResult &);
+ ApiExtractorResult &operator=(const ApiExtractorResult &);
+ ApiExtractorResult(ApiExtractorResult &&) noexcept;
+ ApiExtractorResult &operator=(ApiExtractorResult &&) noexcept;
+ ~ApiExtractorResult();
+
+ const AbstractMetaEnumList &globalEnums() const;
+ const AbstractMetaFunctionCList &globalFunctions() const;
+ const AbstractMetaClassCList &classes() const;
+ const AbstractMetaClassCList &smartPointers() const;
+
+ 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> findAbstractMetaEnum(const TypeEntry* typeEntry) const;
+ std::optional<AbstractMetaEnum>
+ findAbstractMetaEnum(TypeEntryCPtr typeEntry) const;
/// Retrieves a list of constructors used in implicit conversions
/// available on the given type. The TypeEntry must be a value-type
/// or else it will return an empty list.
/// \param type a TypeEntry that is expected to be a value-type
/// \return a list of constructors that could be used as implicit converters
- AbstractMetaFunctionCList implicitConversions(const TypeEntry *type) const;
+ AbstractMetaFunctionCList implicitConversions(const TypeEntryCPtr &type) const;
AbstractMetaFunctionCList implicitConversions(const AbstractMetaType &metaType) const;
+ ApiExtractorFlags flags() const;
+ void setFlags(ApiExtractorFlags f);
+
private:
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;
- QHash<const TypeEntry *, AbstractMetaEnum> m_enums;
+ friend class ApiExtractor;
};
#endif // APIEXTRACTORRESULT_H
diff --git a/sources/shiboken6/ApiExtractor/arraytypeentry.h b/sources/shiboken6/ApiExtractor/arraytypeentry.h
new file mode 100644
index 000000000..5b9bb191e
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/arraytypeentry.h
@@ -0,0 +1,28 @@
+// 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 ARRAYTYPEENTRY_H
+#define ARRAYTYPEENTRY_H
+
+#include "typesystem.h"
+
+class ArrayTypeEntryPrivate;
+
+class ArrayTypeEntry : public TypeEntry
+{
+public:
+ explicit ArrayTypeEntry(const TypeEntryCPtr &nested_type, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ void setNestedTypeEntry(const TypeEntryPtr &nested);
+ TypeEntryCPtr nestedTypeEntry() const;
+
+ TypeEntry *clone() const override;
+
+protected:
+ explicit ArrayTypeEntry(ArrayTypeEntryPrivate *d);
+
+ QString buildTargetLangName() const override;
+};
+
+#endif // ARRAYTYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
index b968cf0ad..31e7efb05 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp
@@ -1,38 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "clangbuilder.h"
#include "compilersupport.h"
#include "clangutils.h"
+#include "clangdebugutils.h"
#include <codemodel.h>
#include <reporthandler.h>
+#include "qtcompat.h"
+
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QHash>
@@ -44,10 +22,9 @@
#include <cstring>
#include <ctype.h>
-namespace clang {
+using namespace Qt::StringLiterals;
-static inline QString colonColon() { return QStringLiteral("::"); }
-static inline QString templateBrackets() { return QStringLiteral("<>"); }
+namespace clang {
static inline bool isClassCursor(const CXCursor &c)
{
@@ -69,9 +46,9 @@ static inline bool withinClassDeclaration(const CXCursor &cursor)
static QString fixTypeName(QString t)
{
// Fix "Foo &" -> "Foo&", similarly "Bar **" -> "Bar**"
- int pos = t.size() - 1;
- for (; pos >= 0 && (t.at(pos) == QLatin1Char('&') || t.at(pos) == QLatin1Char('*')); --pos) {}
- if (pos > 0 && t.at(pos) == QLatin1Char(' '))
+ auto pos = t.size() - 1;
+ for (; pos >= 0 && (t.at(pos) == u'&' || t.at(pos) == u'*'); --pos) {}
+ if (pos > 0 && t.at(pos) == u' ')
t.remove(pos, 1);
return t;
}
@@ -81,13 +58,13 @@ static QString fixTypeName(QString t)
// the class name "Foo<T1,T2>" is the scope for nested items.
static bool insertTemplateParameterIntoClassName(const QString &parmName, QString *name)
{
- if (Q_UNLIKELY(!name->endsWith(QLatin1Char('>'))))
+ if (Q_UNLIKELY(!name->endsWith(u'>')))
return false;
- const bool needsComma = name->at(name->size() - 2) != QLatin1Char('<');
- const int insertionPos = name->size() - 1;
+ const bool needsComma = name->at(name->size() - 2) != u'<';
+ const auto insertionPos = name->size() - 1;
name->insert(insertionPos, parmName);
if (needsComma)
- name->insert(insertionPos, QLatin1Char(','));
+ name->insert(insertionPos, u',');
return true;
}
@@ -136,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)
@@ -200,13 +186,12 @@ public:
void addField(const CXCursor &cursor);
static QString cursorValueExpression(BaseVisitor *bv, const CXCursor &cursor);
- QString getBaseClassName(CXType type) const;
+ 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);
@@ -219,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;
@@ -230,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:
@@ -287,10 +272,9 @@ 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 QLatin1String("Cannot determine exception specification: \"")
- + snippet + QLatin1Char('"');
+ return u"Cannot determine exception specification: \""_s + snippet + u'"';
}
// Return whether noexcept(<value>) throws. noexcept() takes a constexpr value.
@@ -347,11 +331,13 @@ FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor,
{
QString name = getCursorSpelling(cursor);
// Apply type fixes to "operator X &" -> "operator X&"
- if (name.startsWith(QLatin1String("operator ")))
+ 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);
@@ -360,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);
@@ -399,13 +385,13 @@ FunctionModelItem BuilderPrivate::createMemberFunction(const CXCursor &cursor,
m_currentFunctionType == CodeModel::Signal || m_currentFunctionType == CodeModel::Slot
? m_currentFunctionType // by annotation
: functionTypeFromCursor(cursor);
- isTemplateCode |= m_currentClass->name().endsWith(QLatin1Char('>'));
+ isTemplateCode |= m_currentClass->name().endsWith(u'>');
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;
}
@@ -421,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
@@ -440,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);
}
@@ -453,14 +441,14 @@ void BuilderPrivate::addField(const CXCursor &cursor)
static QStringList qualifiedName(const QString &t)
{
QStringList result;
- int end = t.indexOf(QLatin1Char('<'));
+ int end = t.indexOf(u'<');
if (end == -1)
- end = t.indexOf(QLatin1Char('('));
+ end = t.indexOf(u'(');
if (end == -1)
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));
@@ -524,7 +512,7 @@ void BuilderPrivate::addTemplateInstantiations(const CXType &type,
&& !t->instantiations().isEmpty();
if (!parsed)
t->setInstantiations({});
- const QPair<int, int> pos = parsed
+ const auto pos = parsed
? parseTemplateArgumentList(*typeName, dummyTemplateArgumentHandler)
: t->parseTemplateArgumentList(*typeName);
if (pos.first != -1 && pos.second != -1 && pos.second > pos.first)
@@ -578,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)) {
}
@@ -588,21 +576,21 @@ 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(QLatin1String("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();
}
}
// Obtain template instantiations if the name has '<' (thus excluding
// typedefs like "std::string".
- if (typeName.contains(QLatin1Char('<')))
+ if (typeName.contains(u'<'))
addTemplateInstantiations(nestedType, &typeName, &typeInfo);
typeInfo.setQualifiedName(qualifiedName(typeName));
@@ -626,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 (int i = m_scopeStack.size() - 1; i >= 0; --i) {
- auto klass = qSharedPointerDynamicCast<_ClassModelItem>(m_scopeStack.at(i));
- if (!klass.isNull() && klass->isTemplate())
+ for (auto i = m_scopeStack.size() - 1; i >= 0; --i) {
+ auto klass = std::dynamic_pointer_cast<_ClassModelItem>(m_scopeStack.at(i));
+ if (klass && klass->isTemplate())
return klass;
}
return {};
@@ -648,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);
}
@@ -673,11 +660,17 @@ QString BuilderPrivate::cursorValueExpression(BaseVisitor *bv, const CXCursor &c
if (equalSign == std::string::npos)
return QString();
++equalSign;
- return QString::fromLocal8Bit(snippet.data() + equalSign,
- qsizetype(snippet.size() - equalSign)).trimmed();
+ QString result = QString::fromLocal8Bit(snippet.data() + equalSign,
+ qsizetype(snippet.size() - equalSign));
+ // Fix a default expression as read from code. Simplify white space
+ result.remove(u'\r');
+ return result.contains(u'"') ? result.trimmed() : result.simplified();
}
// 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
{
@@ -685,47 +678,41 @@ 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};
}
// Note: Return the baseclass for cursors like CXCursor_CXXBaseSpecifier,
// where the cursor spelling has "struct baseClass".
-QString BuilderPrivate::getBaseClassName(CXType type) const
+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
// "class X : public std::list<...>", "template<class T> class Foo : public T"
// and standard types like true_type, false_type.
if (it == m_cursorClassHash.constEnd())
- return baseClassName;
+ return {baseClassName, {}};
// Completely qualify the class name by looking it up and taking its scope
// plus the actual baseClass stripped off any scopes. Consider:
@@ -739,13 +726,13 @@ QString BuilderPrivate::getBaseClassName(CXType type) const
// "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;
+ return {baseClassName, it.value()};
}
// Add a base class to the current class from CXCursor_CXXBaseSpecifier
@@ -753,39 +740,8 @@ void BuilderPrivate::addBaseClass(const CXCursor &cursor)
{
Q_ASSERT(clang_getCursorKind(cursor) == CXCursor_CXXBaseSpecifier);
const auto access = accessPolicy(clang_getCXXAccessSpecifier(cursor));
- QString baseClassName = getBaseClassName(clang_getCursorType(cursor));
- m_currentClass->addBaseClass(baseClassName, 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);
- }
- }
+ const auto baseClass = getBaseClass(clang_getCursorType(cursor));
+ m_currentClass->addBaseClass({baseClass.first, baseClass.second, access});
}
void BuilderPrivate::setFileName(const CXCursor &cursor, _CodeModelItem *item)
@@ -821,14 +777,48 @@ 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"
+ || baseName == u"gl2.h"
+ || baseName == u"gl3.h"
+ || 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()) {
@@ -837,32 +827,38 @@ 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:
// Parse the following system headers to get the correct typdefs for types like
// int32_t, which are used in the macOS implementation of OpenGL framework.
+ // They are installed under /Applications/Xcode.app/Contents/Developer/Platforms...
if (baseName == u"gltypes.h"
- || fileName.startsWith(u"/usr/include/_types")
- || fileName.startsWith(u"/usr/include/_types")
- || fileName.startsWith(u"/usr/include/sys/_types")) {
- return true;
+ || fileName.contains(u"/usr/include/_types")
+ || fileName.contains(u"/usr/include/sys/_types")) {
+ return SpecialSystemHeader::Types;
}
break;
default:
break;
}
- for (const auto &systemInclude : m_systemIncludes) {
- if (systemInclude == baseName)
- 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;
}
- for (const auto &systemIncludePath : m_systemIncludePaths) {
- if (fileName.startsWith(systemIncludePath))
- return true;
- }
- return false;
+
+ return SpecialSystemHeader::None;
}
bool Builder::visitLocation(const QString &fileName, LocationType locationType) const
@@ -870,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);
}
}
@@ -885,14 +882,14 @@ 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)
{
- return getCursorKindName(cursor.kind) + QLatin1Char(' ')
- + getCursorSpelling(cursor) + QLatin1String(" encountered outside ")
- + QLatin1String(expectedScope) + QLatin1Char('.');
+ return getCursorKindName(cursor.kind) + u' '
+ + getCursorSpelling(cursor) + u" encountered outside "_s
+ + QLatin1StringView(expectedScope) + u'.';
}
static CodeModel::ClassType codeModelClassTypeFromCursor(CXCursorKind kind)
@@ -919,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.
@@ -939,16 +938,16 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
break;
case CXCursor_AnnotateAttr: {
const QString annotation = getCursorSpelling(cursor);
- if (annotation == QLatin1String("qt_slot"))
+ if (annotation == u"qt_slot")
d->m_currentFunctionType = CodeModel::Slot;
- else if (annotation == QLatin1String("qt_signal"))
+ else if (annotation == u"qt_signal")
d->m_currentFunctionType = CodeModel::Signal;
else
d->m_currentFunctionType = CodeModel::Normal;
}
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);
@@ -970,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
@@ -987,17 +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);
- d->m_currentEnum->setSigned(isSigned(clang_getEnumDeclIntegerType(cursor).kind));
- if (!qSharedPointerDynamicCast<_ClassModelItem>(d->m_scopeStack.back()).isNull())
+ if (clang_getCursorAvailability(cursor) == CXAvailability_Deprecated)
+ d->m_currentEnum->setDeprecated(true);
+ 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);
@@ -1008,9 +1011,11 @@ 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)
+ enumConstant->setDeprecated(true);
d->m_currentEnum->addEnumerator(enumConstant);
}
break;
@@ -1054,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:
@@ -1061,13 +1067,14 @@ BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor)
// operators). Note: CXTranslationUnit_SkipFunctionBodies must be off for
// clang_isCursorDefinition() to work here.
if (!d->m_withinFriendDecl || clang_isCursorDefinition(cursor) != 0) {
- int scope = d->m_scopeStack.size() - 1; // enclosing class
+ auto scope = d->m_scopeStack.size() - 1; // enclosing class
if (d->m_withinFriendDecl) {
// Friend declaration: go back to namespace or file scope.
for (--scope; d->m_scopeStack.at(scope)->kind() == _CodeModelItem::Kind_Class; --scope) {
}
}
d->m_currentFunction = d->createFunction(cursor, CodeModel::Normal, false);
+ d->m_currentFunction->setHiddenFriend(d->m_withinFriendDecl);
d->m_scopeStack.at(scope)->addFunction(d->m_currentFunction);
}
break;
@@ -1076,10 +1083,10 @@ 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")
- + QLatin1String(" (current scope: ") + d->m_scopeStack.back()->name() + QLatin1Char(')');
+ + u" (current scope: "_s + d->m_scopeStack.back()->name() + u')';
const Diagnostic d(message, cursor, CXDiagnostic_Error);
qWarning() << d;
appendDiagnostic(d);
@@ -1089,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);
@@ -1099,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()) {
@@ -1118,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);
@@ -1141,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);
@@ -1169,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()) {
- d->m_usingTypeRef = d->getBaseClassName(clang_getCursorType(cursor));
- }
+ 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() == ')'
@@ -1205,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:
@@ -1233,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 c84ffa356..b2ec6d304 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CLANGBUILDER_H
#define CLANGBUILDER_H
@@ -39,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 7123c22d8..3c002da9c 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "clangdebugutils.h"
#include "clangutils.h"
@@ -32,8 +7,6 @@
#include <QtCore/QDebug>
#include <QtCore/QString>
-#include <string.h>
-
#ifndef QT_NO_DEBUG_STREAM
#ifdef Q_OS_WIN
@@ -44,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;
}
@@ -74,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 ae3840fb4..7aac8a575 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.h
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangdebugutils.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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 15be8f5a4..6c0cf3ae2 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangparser.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "clangparser.h"
#include "clangutils.h"
@@ -38,6 +13,8 @@
#include <QtCore/QScopedArrayPointer>
#include <QtCore/QString>
+using namespace Qt::StringLiterals;
+
namespace clang {
QString SourceFileCache::getFileName(CXFile file)
@@ -64,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);
}
@@ -73,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);
@@ -238,9 +215,9 @@ static QByteArray msgCreateTranslationUnit(const QByteArrayList &clangArgs, unsi
{
QByteArray result = "clang_parseTranslationUnit2(0x";
result += QByteArray::number(flags, 16);
- const int count = clangArgs.size();
+ const auto count = clangArgs.size();
result += ", cmd[" + QByteArray::number(count) + "]=";
- for (int i = 0; i < count; ++i) {
+ for (qsizetype i = 0; i < count; ++i) {
const QByteArray &arg = clangArgs.at(i);
if (i)
result += ' ';
@@ -258,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
@@ -271,14 +249,17 @@ static CXTranslationUnit createTranslationUnit(CXIndex index,
"-Wno-expansion-to-defined", // Workaround for warnings in Darwin stdlib, see
// https://github.com/darlinghq/darling/issues/204
#endif
- "-Wno-constant-logical-operand"
+ "-Wno-constant-logical-operand",
+ "-x",
+ "c++" // Treat .h as C++, not C
};
QByteArrayList clangArgs;
if (addCompilerSupportArguments) {
- clangArgs += emulatedCompilerOptions();
+ clangArgs += emulatedCompilerOptions(level);
clangArgs += defaultArgs;
}
+ clangArgs += detectVulkan();
clangArgs += args;
QScopedArrayPointer<const char *> argv(byteArrayListToFlatArgV(clangArgs));
qDebug().noquote().nospace() << msgCreateTranslationUnit(clangArgs, flags);
@@ -300,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 */);
@@ -311,7 +292,7 @@ bool parse(const QByteArrayList &clangArgs, bool addCompilerSupportArguments,
CXTranslationUnit translationUnit =
createTranslationUnit(index, clangArgs, addCompilerSupportArguments,
- clangFlags);
+ level, clangFlags);
if (!translationUnit)
return false;
@@ -330,7 +311,7 @@ bool parse(const QByteArrayList &clangArgs, bool addCompilerSupportArguments,
debug.nospace();
debug << "Errors in "
<< QDir::toNativeSeparators(QFile::decodeName(clangArgs.constLast())) << ":\n";
- for (const Diagnostic &diagnostic : qAsConst(diagnostics))
+ for (const Diagnostic &diagnostic : std::as_const(diagnostics))
debug << diagnostic << '\n';
}
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangparser.h b/sources/shiboken6/ApiExtractor/clangparser/clangparser.h
index 81b40ae6f..22e0a50cd 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangparser.h
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangparser.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CLANGPARSER_H
#define CLANGPARSER_H
@@ -33,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 {
@@ -65,7 +42,7 @@ enum class LocationType
};
class BaseVisitor {
- Q_DISABLE_COPY(BaseVisitor)
+ Q_DISABLE_COPY_MOVE(BaseVisitor)
public:
using Diagnostics = QList<Diagnostic>;
@@ -104,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 c7d471547..1651e09ec 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangutils.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangutils.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "clangutils.h"
@@ -33,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;
@@ -102,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)
@@ -130,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);
@@ -138,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)
{
@@ -191,16 +215,17 @@ QList<Diagnostic> getDiagnostics(CXTranslationUnit tu)
return result;
}
-QPair<int, int> parseTemplateArgumentList(const QString &l,
- const TemplateArgumentHandler &handler,
- int from)
+std::pair<qsizetype, qsizetype>
+ parseTemplateArgumentList(const QString &l,
+ const TemplateArgumentHandler &handler,
+ qsizetype from)
{
- const int ltPos = l.indexOf(QLatin1Char('<'), from);
+ const auto ltPos = l.indexOf(u'<', from);
if (ltPos == - 1)
- return qMakePair(-1, -1);
- int startPos = ltPos + 1;
+ return std::make_pair(-1, -1);
+ auto startPos = ltPos + 1;
int level = 1;
- for (int p = startPos, end = l.size(); p < end; ) {
+ for (qsizetype p = startPos, end = l.size(); p < end; ) {
const char c = l.at(p).toLatin1();
switch (c) {
case ',':
@@ -209,9 +234,9 @@ QPair<int, int> parseTemplateArgumentList(const QString &l,
++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) == QLatin1Char(',')); ++p) {}
+ for (; p < end && (l.at(p).isSpace() || l.at(p) == u','); ++p) {}
}
startPos = p;
break;
@@ -225,7 +250,7 @@ QPair<int, int> parseTemplateArgumentList(const QString &l,
break;
}
}
- return qMakePair(-1, -1);
+ return std::make_pair(-1, -1);
}
CXDiagnosticSeverity maxSeverity(const QList<Diagnostic> &ds)
@@ -281,9 +306,9 @@ QDebug operator<<(QDebug s, const Diagnostic &d)
if (d.source != Diagnostic::Clang)
s << " [other]";
- if (const int childMessagesCount = d.childMessages.size()) {
+ if (const auto childMessagesCount = d.childMessages.size()) {
s << '\n';
- for (int i = 0; i < childMessagesCount; ++i)
+ for (qsizetype i = 0; i < childMessagesCount; ++i)
s << " " << d.childMessages.at(i) << '\n';
}
diff --git a/sources/shiboken6/ApiExtractor/clangparser/clangutils.h b/sources/shiboken6/ApiExtractor/clangparser/clangutils.h
index 4fcc833b1..fbbf95f1b 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/clangutils.h
+++ b/sources/shiboken6/ApiExtractor/clangparser/clangutils.h
@@ -1,49 +1,25 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CLANGUTILS_H
#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 {
@@ -51,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)
@@ -71,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);
@@ -114,9 +94,10 @@ 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<int, int> parseTemplateArgumentList(const QString &l,
- const TemplateArgumentHandler &handler,
- int from = 0);
+std::pair<qsizetype, qsizetype>
+ parseTemplateArgumentList(const QString &l,
+ const TemplateArgumentHandler &handler,
+ qsizetype from = 0);
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug, const SourceLocation &);
diff --git a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp
index fb42b78f0..20224020b 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp
+++ b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.cpp
@@ -1,36 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "compilersupport.h"
#include "header_paths.h"
+#include "clangutils.h"
#include <reporthandler.h>
+#include "qtcompat.h"
+
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
@@ -42,10 +20,11 @@
#include <clang-c/Index.h>
-#include <string.h>
#include <algorithm>
#include <iterator>
+using namespace Qt::StringLiterals;
+
namespace clang {
QVersionNumber libClangVersion()
@@ -64,6 +43,32 @@ static Compiler _compiler =
Compiler compiler() { return _compiler; }
+bool setCompiler(const QString &name)
+{
+ bool result = true;
+ if (name == u"msvc")
+ _compiler = Compiler::Msvc;
+ else if (name == u"g++")
+ _compiler = Compiler::Gpp;
+ else if (name == u"clang")
+ _compiler = Compiler::Clang;
+ else
+ result = false;
+ return result;
+}
+
+QString _compilerPath; // Pre-defined compiler path (from command line)
+
+const QString &compilerPath()
+{
+ return _compilerPath;
+}
+
+void setCompilerPath(const QString &name)
+{
+ _compilerPath = name;
+}
+
static Platform _platform =
#if defined (Q_OS_DARWIN)
Platform::macOS;
@@ -75,13 +80,33 @@ static Platform _platform =
Platform platform() { return _platform; }
+bool setPlatform(const QString &name)
+{
+ bool result = true;
+ if (name == u"windows")
+ _platform = Platform::Windows;
+ else if (name == u"darwin")
+ _platform = Platform::macOS;
+ else if (name == u"unix")
+ _platform = Platform::Unix;
+ else
+ result = false;
+ 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;
}
@@ -94,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;
}
@@ -153,15 +178,20 @@ static void filterHomebrewHeaderPaths(HeaderPaths &headerPaths)
static HeaderPaths gppInternalIncludePaths(const QString &compiler)
{
HeaderPaths result;
- QStringList arguments;
- arguments << QStringLiteral("-E") << QStringLiteral("-x") << QStringLiteral("c++")
- << QStringLiteral("-") << QStringLiteral("-v");
+ QStringList arguments{u"-E"_s, u"-x"_s, u"c++"_s, u"-"_s, u"-v"_s};
QByteArray stdOut;
QByteArray stdErr;
if (!runProcess(compiler, arguments, &stdOut, &stdErr))
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"))) {
@@ -186,16 +216,18 @@ static HeaderPaths gppInternalIncludePaths(const QString &compiler)
}
// Detect Vulkan as supported from Qt 5.10 by checking the environment variables.
-static void detectVulkan(HeaderPaths *headerPaths)
+QByteArrayList detectVulkan()
{
static const char *vulkanVariables[] = {"VULKAN_SDK", "VK_SDK_PATH"};
for (const char *vulkanVariable : vulkanVariables) {
if (qEnvironmentVariableIsSet(vulkanVariable)) {
- const QByteArray path = qgetenv(vulkanVariable) + QByteArrayLiteral("/include");
- headerPaths->append(HeaderPath{path, HeaderType::System});
- break;
+ const auto option = QByteArrayLiteral("-isystem")
+ + qgetenv(vulkanVariable)
+ + QByteArrayLiteral("/include");
+ return {option};
}
}
+ return {};
}
// For MSVC, we set the MS compatibility version and let Clang figure out its own
@@ -221,28 +253,35 @@ 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"}) {
if (qEnvironmentVariableIsSet(envVar)) {
- const QString path = QFile::decodeName(qgetenv(envVar)) + QLatin1String("/lib");
+ 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);
+ qCWarning(lcShiboken, "%s: %s as pointed to by %s does not exist.",
+ __FUNCTION__, qPrintable(path), envVar);
}
}
- const QString llvmConfig =
- QStandardPaths::findExecutable(QLatin1String("llvm-config"));
- if (!llvmConfig.isEmpty()) {
- QByteArray stdOut;
- if (runProcess(llvmConfig, QStringList{QLatin1String("--libdir")}, &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));
- }
- }
- return QString();
+ return queryLlvmConfigDir(u"--libdir"_s);
}
static QString findClangBuiltInIncludesDir()
@@ -251,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 + QLatin1String("/clang");
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()) {
@@ -269,20 +318,44 @@ static QString findClangBuiltInIncludesDir()
}
}
if (!candidate.isEmpty())
- return candidate + QStringLiteral("/include");
+ return candidate + "/include"_L1;
}
- return QString();
+ return queryLlvmConfigDir(u"--includedir"_s);
}
-static QString compilerFromCMake(const QString &defaultCompiler)
+QString compilerFromCMake()
{
-// Added !defined(Q_OS_DARWIN) due to PYSIDE-1032
- QString result = defaultCompiler;
- if (platform() != Platform::macOS)
#ifdef CMAKE_CXX_COMPILER
- result = QString::fromLocal8Bit(CMAKE_CXX_COMPILER);
+ return QString::fromLocal8Bit(CMAKE_CXX_COMPILER);
+#else
+ return {};
#endif
- return result;
+}
+
+// Return a compiler suitable for determining the internal include paths
+static QString compilerFromCMake(const QString &defaultCompiler)
+{
+ if (!compilerPath().isEmpty())
+ return compilerPath();
+ // 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)
@@ -294,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});
@@ -302,31 +376,40 @@ 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())
appendClangBuiltinIncludes(&headerPaths);
break;
case Compiler::Clang:
- headerPaths.append(gppInternalIncludePaths(compilerFromCMake(u"clang++"_qs)));
+ headerPaths.append(gppInternalIncludePaths(compilerFromCMake(u"clang++"_s)));
result.append(noStandardIncludeOption());
break;
case Compiler::Gpp:
if (needsClangBuiltinIncludes())
appendClangBuiltinIncludes(&headerPaths);
+
+ // Append the c++ include paths since Clang is unable to find
+ // <type_traits> etc (g++ 11.3).
+ 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);
+ }
break;
}
- detectVulkan(&headerPaths);
std::transform(headerPaths.cbegin(), headerPaths.cend(),
std::back_inserter(result), HeaderPath::includeOption);
return result;
diff --git a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h
index 479e211ce..f1d63b7c3 100644
--- a/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h
+++ b/sources/shiboken6/ApiExtractor/clangparser/compilersupport.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef COMPILERSUPPORT_H
#define COMPILERSUPPORT_H
@@ -32,6 +7,7 @@
#include <QtCore/QByteArrayList>
QT_FORWARD_DECLARE_CLASS(QVersionNumber)
+QT_FORWARD_DECLARE_CLASS(QString)
enum class LanguageLevel {
Default,
@@ -57,14 +33,24 @@ enum class Platform {
namespace clang {
QVersionNumber libClangVersion();
-QByteArrayList emulatedCompilerOptions();
+QByteArrayList emulatedCompilerOptions(LanguageLevel level);
LanguageLevel emulatedCompilerLanguageLevel();
const char *languageLevelOption(LanguageLevel l);
LanguageLevel languageLevelFromOption(const char *);
+QByteArrayList detectVulkan();
+
Compiler compiler();
+bool setCompiler(const QString &name);
+
+QString compilerFromCMake();
+
+const QString &compilerPath();
+void setCompilerPath(const QString &name);
+
Platform platform();
+bool setPlatform(const QString &name);
} // namespace clang
#endif // COMPILERSUPPORT_H
diff --git a/sources/shiboken6/ApiExtractor/classdocumentation.cpp b/sources/shiboken6/ApiExtractor/classdocumentation.cpp
new file mode 100644
index 000000000..637e4a422
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/classdocumentation.cpp
@@ -0,0 +1,381 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "classdocumentation.h"
+#include "messages.h"
+#include "debughelpers_p.h"
+
+#include <QtCore/QDebug>
+#include <QtCore/QBuffer>
+#include <QtCore/QFile>
+#include <QtCore/QXmlStreamReader>
+#include <QtCore/QXmlStreamAttributes>
+#include <QtCore/QXmlStreamWriter>
+
+#include <algorithm>
+
+using namespace Qt::StringLiterals;
+
+// Sort functions by name and argument count
+static bool functionDocumentationLessThan(const FunctionDocumentation &f1,
+ const FunctionDocumentation &f2)
+{
+ const int nc = f1.name.compare(f2.name);
+ if (nc != 0)
+ return nc < 0;
+ return f1.parameters.size() < f2.parameters.size();
+}
+
+static void sortDocumentation(ClassDocumentation *cd)
+{
+ std::stable_sort(cd->enums.begin(), cd->enums.end(),
+ [] (const EnumDocumentation &e1, const EnumDocumentation &e2) {
+ return e1.name < e2.name; });
+ std::stable_sort(cd->properties.begin(), cd->properties.end(),
+ [] (const PropertyDocumentation &p1, const PropertyDocumentation &p2) {
+ return p1.name < p2.name; });
+ std::stable_sort(cd->functions.begin(), cd->functions.end(),
+ functionDocumentationLessThan);
+}
+
+qsizetype ClassDocumentation::indexOfEnum(const QString &name) const
+{
+ for (qsizetype i = 0, size = enums.size(); i < size; ++i) {
+ if (enums.at(i).name == name)
+ return i;
+ }
+ return -1;
+}
+
+FunctionDocumentationList ClassDocumentation::findFunctionCandidates(const QString &name,
+ bool constant) const
+{
+ FunctionDocumentationList result;
+ std::copy_if(functions.cbegin(), functions.cend(),
+ std::back_inserter(result),
+ [name, constant](const FunctionDocumentation &fd) {
+ return fd.constant == constant && fd.name == name;
+ });
+ return result;
+}
+
+static bool matches(const FunctionDocumentation &fd, const FunctionDocumentationQuery &q)
+{
+ return fd.name == q.name && fd.constant == q.constant && fd.parameters == q.parameters;
+}
+
+qsizetype ClassDocumentation::indexOfFunction(const FunctionDocumentationList &fl,
+ const FunctionDocumentationQuery &q)
+{
+ for (qsizetype i = 0, size = fl.size(); i < size; ++i) {
+ if (matches(fl.at(i), q))
+ return i;
+ }
+ return -1;
+}
+
+qsizetype ClassDocumentation::indexOfProperty(const QString &name) const
+{
+ for (qsizetype i = 0, size = properties.size(); i < size; ++i) {
+ if (properties.at(i).name == name)
+ return i;
+ }
+ return -1;
+}
+
+enum class WebXmlCodeTag
+{
+ Class, Description, Enum, Function, Header, Parameter, Property, Typedef, Other
+};
+
+static WebXmlCodeTag tag(QStringView name)
+{
+ if (name == u"class" || name == u"namespace")
+ return WebXmlCodeTag::Class;
+ if (name == u"enum")
+ return WebXmlCodeTag::Enum;
+ if (name == u"function")
+ return WebXmlCodeTag::Function;
+ if (name == u"description")
+ return WebXmlCodeTag::Description;
+ if (name == u"header")
+ return WebXmlCodeTag::Header;
+ if (name == u"parameter")
+ return WebXmlCodeTag::Parameter;
+ if (name == u"property")
+ return WebXmlCodeTag::Property;
+ if (name == u"typedef")
+ return WebXmlCodeTag::Typedef;
+ return WebXmlCodeTag::Other;
+}
+
+static void parseWebXmlElement(WebXmlCodeTag tag, const QXmlStreamAttributes &attributes,
+ ClassDocumentation *cd)
+{
+ switch (tag) {
+ case WebXmlCodeTag::Class:
+ cd->name = attributes.value(u"name"_s).toString();
+ cd->type = ClassDocumentation::Class;
+ break;
+ 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 WebXmlCodeTag::Function: {
+ FunctionDocumentation fd;
+ fd.name = attributes.value(u"name"_s).toString();
+ fd.signature = attributes.value(u"signature"_s).toString();
+ fd.returnType = attributes.value(u"type"_s).toString();
+ fd.constant = attributes.value(u"const"_s) == u"true";
+ cd->functions.append(fd);
+ }
+ break;
+ case WebXmlCodeTag::Parameter:
+ Q_ASSERT(!cd->functions.isEmpty());
+ cd->functions.last().parameters.append(attributes.value(u"type"_s).toString());
+ break;
+ case WebXmlCodeTag::Property: {
+ PropertyDocumentation pd;
+ pd.name = attributes.value(u"name"_s).toString();
+ pd.brief = attributes.value(u"brief"_s).toString();
+ cd->properties.append(pd);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+// Retrieve the contents of <description>
+static QString extractWebXmlDescription(QXmlStreamReader &reader)
+{
+ QBuffer buffer;
+ buffer.open(QIODeviceBase::WriteOnly);
+ QXmlStreamWriter writer(&buffer);
+
+ do {
+ switch (reader.tokenType()) {
+ case QXmlStreamReader::StartElement:
+ writer.writeStartElement(reader.name().toString());
+ writer.writeAttributes(reader.attributes());
+ break;
+ case QXmlStreamReader::Characters:
+ writer.writeCharacters(reader.text().toString());
+ break;
+ case QXmlStreamReader::EndElement:
+ writer.writeEndElement();
+ if (reader.name() == u"description") {
+ buffer.close();
+ return QString::fromUtf8(buffer.buffer()).trimmed();
+ }
+ break;
+ default:
+ break;
+ }
+ reader.readNext();
+ } while (!reader.atEnd());
+
+ return {};
+}
+
+static QString msgXmlError(const QString &fileName, const QXmlStreamReader &reader)
+{
+ QString result;
+ QTextStream(&result) << fileName << ':' << reader.lineNumber() << ':'
+ << reader.columnNumber() << ':' << reader.errorString();
+ return result;
+}
+
+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 std::nullopt;
+ }
+
+ WebXmlCodeTag lastTag = WebXmlCodeTag::Other;
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd()) {
+ switch (reader.readNext()) {
+ case QXmlStreamReader::StartElement: {
+ const auto currentTag = tag(reader.name());
+ parseWebXmlElement(currentTag, reader.attributes(), &result);
+ switch (currentTag) { // Store relevant tags in lastTag
+ case WebXmlCodeTag::Class:
+ case WebXmlCodeTag::Function:
+ case WebXmlCodeTag::Enum:
+ case WebXmlCodeTag::Header:
+ case WebXmlCodeTag::Property:
+ case WebXmlCodeTag::Typedef:
+ lastTag = currentTag;
+ break;
+ case WebXmlCodeTag::Description: { // Append the description to the element
+ QString *target = nullptr;
+ switch (lastTag) {
+ case WebXmlCodeTag::Class:
+ target = &result.description;
+ break;
+ case WebXmlCodeTag::Function:
+ target = &result.functions.last().description;
+ break;
+ case WebXmlCodeTag::Enum:
+ target = &result.enums.last().description;
+ break;
+ case WebXmlCodeTag::Property:
+ target = &result.properties.last().description;
+ default:
+ break;
+ }
+ if (target != nullptr && target->isEmpty())
+ *target = extractWebXmlDescription(reader);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ default:
+ break;
+ }
+ }
+
+ if (reader.error() != QXmlStreamReader::NoError) {
+ *errorMessage= msgXmlError(fileName, reader);
+ return std::nullopt;
+ }
+
+ sortDocumentation(&result);
+ return result;
+}
+
+QString webXmlModuleDescription(const QString &fileName, QString *errorMessage)
+{
+ QFile file(fileName);
+ if (!file.open(QIODevice::Text | QIODevice::ReadOnly)) {
+ *errorMessage = msgCannotOpenForReading(file);
+ return {};
+ }
+
+ QString result;
+ QXmlStreamReader reader(&file);
+ while (!reader.atEnd()) {
+ switch (reader.readNext()) {
+ case QXmlStreamReader::StartElement:
+ if (reader.name() == u"description")
+ result = extractWebXmlDescription(reader);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (reader.error() != QXmlStreamReader::NoError) {
+ *errorMessage= msgXmlError(fileName, reader);
+ return {};
+ }
+
+ return result;
+}
+
+static void formatDescription(QDebug &debug, const QString &desc)
+{
+ debug << "description=";
+ if (desc.isEmpty()) {
+ debug << "<empty>";
+ return;
+ }
+ if (debug.verbosity() < 3)
+ debug << desc.size() << " chars";
+ else
+ debug << '"' << desc << '"';
+}
+
+QDebug operator<<(QDebug debug, const EnumDocumentation &e)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "Enum(";
+ if (e.name.isEmpty()) {
+ debug << "invalid";
+ } else {
+ debug << e.name << ", ";
+ formatDescription(debug, e.description);
+ }
+ debug << ')';
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const PropertyDocumentation &p)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "Property(";
+ if (p.name.isEmpty()) {
+ debug << "invalid";
+ } else {
+ debug << p.name << ", ";
+ formatDescription(debug, p.description);
+ }
+ debug << ')';
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const FunctionDocumentation &f)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "Function(";
+ if (f.name.isEmpty()) {
+ debug << "invalid";
+ } else {
+ debug << f.name;
+ if (!f.returnType.isEmpty())
+ debug << ", returns " << f.returnType;
+ if (f.constant)
+ debug << ", const";
+ formatList(debug, ", parameters", f.parameters, ", ");
+ debug << ", signature=\"" << f.signature << "\", ";
+ formatDescription(debug, f.description);
+ }
+ debug << ')';
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const FunctionDocumentationQuery &q)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "FunctionQuery(" << q.name;
+ if (q.constant)
+ debug << ", const";
+ formatList(debug, ", parameters", q.parameters);
+ debug << ')';
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const ClassDocumentation &c)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ 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
new file mode 100644
index 000000000..d47101389
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/classdocumentation.h
@@ -0,0 +1,82 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef CLASSDOCUMENTATION_H
+#define CLASSDOCUMENTATION_H
+
+#include <QtCore/QStringList>
+
+#include <optional>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+
+/// An enumeration in a WebXML/doxygen document
+struct EnumDocumentation
+{
+ QString name;
+ QString description;
+};
+
+/// A QObject property in a WebXML/doxygen document
+struct PropertyDocumentation
+{
+ QString name;
+ QString brief;
+ QString description;
+};
+
+/// Helper struct for querying a function in a WebXML/doxygen document
+struct FunctionDocumentationQuery
+{
+ QString name;
+ QStringList parameters;
+ bool constant = false;
+};
+
+/// A function in a WebXML/doxygen document
+struct FunctionDocumentation : public FunctionDocumentationQuery
+{
+ QString signature;
+ QString returnType;
+ QString description;
+};
+
+using FunctionDocumentationList = QList<FunctionDocumentation>;
+
+/// 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;
+ static qsizetype indexOfFunction(const FunctionDocumentationList &fl,
+ 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;
+};
+
+/// Parse a WebXML class/namespace document
+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);
+
+QDebug operator<<(QDebug debug, const EnumDocumentation &e);
+QDebug operator<<(QDebug debug, const PropertyDocumentation &p);
+QDebug operator<<(QDebug debug, const FunctionDocumentationQuery &q);
+QDebug operator<<(QDebug debug, const FunctionDocumentation &f);
+QDebug operator<<(QDebug debug, const ClassDocumentation &c);
+
+#endif // CLASSDOCUMENTATION_H
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
new file mode 100644
index 000000000..e2cd5eb35
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/codesnip.cpp
@@ -0,0 +1,78 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "codesnip.h"
+
+#include "qtcompat.h"
+#include "exception.h"
+#include "typedatabase.h"
+
+#include <QtCore/QDebug>
+
+using namespace Qt::StringLiterals;
+
+QString TemplateInstance::expandCode() const
+{
+ const auto templateEntry = TypeDatabase::instance()->findTemplate(m_name);
+ if (!templateEntry) {
+ const QString m = u"<insert-template> referring to non-existing template '"_s
+ + m_name + u"'."_s;
+ throw Exception(m);
+ }
+
+ QString code = templateEntry->code();
+ for (auto it = replaceRules.cbegin(), end = replaceRules.cend(); it != end; ++it)
+ code.replace(it.key(), it.value());
+ while (!code.isEmpty() && code.at(code.size() - 1).isSpace())
+ code.chop(1);
+ QString result = u"// TEMPLATE - "_s + m_name + u" - START"_s;
+ if (!code.startsWith(u'\n'))
+ result += u'\n';
+ result += code;
+ result += u"\n// TEMPLATE - "_s + m_name + u" - END\n"_s;
+ return result;
+}
+
+// ---------------------- CodeSnipFragment
+QString CodeSnipFragment::code() const
+{
+ return m_instance ? m_instance->expandCode() : m_code;
+}
+
+// ---------------------- CodeSnipAbstract
+QString CodeSnipAbstract::code() const
+{
+ QString res;
+ for (const CodeSnipFragment &codeFrag : codeList)
+ res.append(codeFrag.code());
+
+ return res;
+}
+
+void CodeSnipAbstract::addCode(const QString &code)
+{
+ codeList.append(CodeSnipFragment(fixSpaces(code)));
+}
+
+void CodeSnipAbstract::purgeEmptyFragments()
+{
+ auto end = std::remove_if(codeList.begin(), codeList.end(),
+ [](const CodeSnipFragment &f) { return f.isEmpty(); });
+ codeList.erase(end, codeList.end());
+}
+
+QRegularExpression CodeSnipAbstract::placeHolderRegex(int index)
+{
+ return QRegularExpression(u'%' + QString::number(index) + "\\b"_L1);
+}
+
+void purgeEmptyCodeSnips(QList<CodeSnip> *list)
+{
+ for (auto it = list->begin(); it != list->end(); ) {
+ it->purgeEmptyFragments();
+ if (it->isEmpty())
+ it = list->erase(it);
+ else
+ ++it;
+ }
+}
diff --git a/sources/shiboken6/ApiExtractor/codesnip.h b/sources/shiboken6/ApiExtractor/codesnip.h
new file mode 100644
index 000000000..86834a1db
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/codesnip.h
@@ -0,0 +1,107 @@
+// 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 CODESNIP_H
+#define CODESNIP_H
+
+#include "codesniphelpers.h"
+#include "typesystem_enums.h"
+
+#include <QtCore/QList>
+#include <QtCore/QHash>
+#include <QtCore/QString>
+
+#include <memory>
+
+class TemplateInstance
+{
+public:
+ explicit TemplateInstance(const QString &name) : m_name(name) {}
+
+ void addReplaceRule(const QString &name, const QString &value)
+ {
+ replaceRules[name] = value;
+ }
+
+ QString expandCode() const;
+
+ QString name() const
+ {
+ return m_name;
+ }
+
+private:
+ const QString m_name;
+ QHash<QString, QString> replaceRules;
+};
+
+using TemplateInstancePtr = std::shared_ptr<TemplateInstance>;
+
+class CodeSnipFragment
+{
+public:
+ CodeSnipFragment() = default;
+ 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; }
+
+ QString code() const;
+
+ TemplateInstancePtr instance() const { return m_instance; }
+
+private:
+ QString m_code;
+ std::shared_ptr<TemplateInstance> m_instance;
+};
+
+class CodeSnipAbstract : public CodeSnipHelpers
+{
+public:
+ QString code() const;
+
+ void addCode(const QString &code);
+ void addCode(QStringView code) { addCode(code.toString()); }
+
+ void addTemplateInstance(const TemplateInstancePtr &ti)
+ {
+ codeList.append(CodeSnipFragment(ti));
+ }
+
+ bool isEmpty() const { return codeList.isEmpty(); }
+ void purgeEmptyFragments();
+
+ QList<CodeSnipFragment> codeList;
+
+ static QRegularExpression placeHolderRegex(int index);
+};
+
+class TemplateEntry : public CodeSnipAbstract
+{
+public:
+ explicit TemplateEntry(const QString &name) : m_name(name) {}
+
+ QString name() const
+ {
+ return m_name;
+ }
+
+private:
+ QString m_name;
+};
+
+class CodeSnip : public CodeSnipAbstract
+{
+public:
+ CodeSnip() = default;
+ explicit CodeSnip(TypeSystem::Language lang) : language(lang) {}
+
+ TypeSystem::Language language = TypeSystem::TargetLangCode;
+ TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny;
+};
+
+/// Purge empty fragments and snippets caused by new line characters in
+/// conjunction with <insert-template>.
+void purgeEmptyCodeSnips(QList<CodeSnip> *list);
+
+#endif // CODESNIP_H
diff --git a/sources/shiboken6/ApiExtractor/codesniphelpers.cpp b/sources/shiboken6/ApiExtractor/codesniphelpers.cpp
index f9bae0a65..775cf10af 100644
--- a/sources/shiboken6/ApiExtractor/codesniphelpers.cpp
+++ b/sources/shiboken6/ApiExtractor/codesniphelpers.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "codesniphelpers.h"
@@ -51,9 +26,9 @@ QString CodeSnipHelpers::dedent(const QString &code)
if (code.isEmpty())
return code;
// Right trim if indent=0, or trim if single line
- if (!code.at(0).isSpace() || !code.contains(QLatin1Char('\n')))
+ if (!code.at(0).isSpace() || !code.contains(u'\n'))
return code.trimmed();
- const auto lines = QStringView{code}.split(QLatin1Char('\n'));
+ const auto lines = QStringView{code}.split(u'\n');
int spacesToRemove = std::numeric_limits<int>::max();
for (const auto &line : lines) {
if (!isEmpty(line)) {
@@ -68,35 +43,35 @@ QString CodeSnipHelpers::dedent(const QString &code)
for (const auto &line : lines) {
if (!isEmpty(line) && spacesToRemove < line.size())
result += line.mid(spacesToRemove).toString();
- result += QLatin1Char('\n');
+ result += u'\n';
}
return result;
}
QString CodeSnipHelpers::fixSpaces(QString code)
{
- code.remove(QLatin1Char('\r'));
+ code.remove(u'\r');
// Check for XML <tag>\n<space>bla...
- if (code.startsWith(QLatin1String("\n ")))
+ if (code.startsWith(u"\n "))
code.remove(0, 1);
while (!code.isEmpty() && code.back().isSpace())
code.chop(1);
code = dedent(code);
- if (!code.isEmpty() && !code.endsWith(QLatin1Char('\n')))
- code.append(QLatin1Char('\n'));
+ if (!code.isEmpty() && !code.endsWith(u'\n'))
+ code.append(u'\n');
return code;
}
// Prepend a line to the code, observing indentation
void CodeSnipHelpers::prependCode(QString *code, QString firstLine)
{
- while (!code->isEmpty() && code->front() == QLatin1Char('\n'))
+ while (!code->isEmpty() && code->front() == u'\n')
code->remove(0, 1);
if (!code->isEmpty() && code->front().isSpace()) {
const int indent = firstNonBlank(*code);
- firstLine.prepend(QString(indent, QLatin1Char(' ')));
+ firstLine.prepend(QString(indent, u' '));
}
- if (!firstLine.endsWith(QLatin1Char('\n')))
- firstLine += QLatin1Char('\n');
+ if (!firstLine.endsWith(u'\n'))
+ firstLine += u'\n';
code->prepend(firstLine);
}
diff --git a/sources/shiboken6/ApiExtractor/codesniphelpers.h b/sources/shiboken6/ApiExtractor/codesniphelpers.h
index d7da05ea0..e7a7545da 100644
--- a/sources/shiboken6/ApiExtractor/codesniphelpers.h
+++ b/sources/shiboken6/ApiExtractor/codesniphelpers.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CODESNIPHELPERS_H
#define CODESNIPHELPERS_H
diff --git a/sources/shiboken6/ApiExtractor/complextypeentry.h b/sources/shiboken6/ApiExtractor/complextypeentry.h
new file mode 100644
index 000000000..5b884f2cc
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/complextypeentry.h
@@ -0,0 +1,179 @@
+// 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 COMPLEXTYPEENTRY_H
+#define COMPLEXTYPEENTRY_H
+
+#include "configurabletypeentry.h"
+#include "typesystem_enums.h"
+#include "modifications_typedefs.h"
+#include "pymethoddefentry.h"
+
+#include <QtCore/QSet>
+
+class ComplexTypeEntryPrivate;
+
+struct TypeSystemPyMethodDefEntry : public PyMethodDefEntry
+{
+ QStringList signatures;
+};
+
+struct TypeSystemProperty
+{
+ bool isValid() const { return !name.isEmpty() && !read.isEmpty() && !type.isEmpty(); }
+
+ QString type;
+ QString name;
+ QString read;
+ QString write;
+ QString reset;
+ QString designable;
+ QString notify; // Q_PROPERTY/C++ only
+ // Indicates whether actual code is generated instead of relying on libpyside.
+ bool generateGetSetDef = false;
+};
+
+class ComplexTypeEntry : public ConfigurableTypeEntry
+{
+public:
+ enum TypeFlag {
+ DisableWrapper = 0x1,
+ Deprecated = 0x4,
+ ForceAbstract = 0x8,
+ // Indicates that the instances are used to create hierarchies
+ // like widgets; parent ownership heuristics are enabled for them.
+ ParentManagement = 0x10,
+ DisableQtMetaObjectFunctions = 0x20,
+ Typedef = 0x40 // Result of a <typedef-type>
+ };
+ Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
+
+ enum CopyableFlag {
+ CopyableSet,
+ NonCopyableSet,
+ Unknown
+ };
+
+ explicit ComplexTypeEntry(const QString &entryName, Type t, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ bool isComplex() const override;
+
+ TypeFlags typeFlags() const;
+ void setTypeFlags(TypeFlags flags);
+
+ // Override command line options to generate nb_bool from
+ // operator bool or method isNull().
+ TypeSystem::BoolCast operatorBoolMode() const;
+ void setOperatorBoolMode(TypeSystem::BoolCast b);
+ TypeSystem::BoolCast isNullMode() const;
+ void setIsNullMode(TypeSystem::BoolCast b);
+
+ FunctionModificationList functionModifications() const;
+ void setFunctionModifications(const FunctionModificationList &functionModifications);
+ void addFunctionModification(const FunctionModification &functionModification);
+ FunctionModificationList functionModifications(const QStringList &signatures) const;
+
+ const CodeSnipList &codeSnips() const;
+ CodeSnipList &codeSnips();
+ void setCodeSnips(const CodeSnipList &codeSnips);
+ void addCodeSnip(const CodeSnip &codeSnip);
+
+ void setDocModification(const DocModificationList& docMods);
+ /// Class documentation modifications
+ DocModificationList docModifications() const;
+ /// Function documentation modifications (matching signature)
+ DocModificationList functionDocModifications() const;
+
+ /// Extra includes for function arguments determined by the meta builder.
+ const IncludeList &argumentIncludes() const;
+ void addArgumentInclude(const Include &newInclude);
+
+ AddedFunctionList addedFunctions() const;
+ void setAddedFunctions(const AddedFunctionList &addedFunctions);
+ void addNewFunction(const AddedFunctionPtr &addedFunction);
+
+ const QList<TypeSystemPyMethodDefEntry> &addedPyMethodDefEntrys() const;
+ void addPyMethodDef(const TypeSystemPyMethodDefEntry &p);
+
+ // Functions specified in the "generate-functions" attribute
+ const QSet<QString> &generateFunctions() const;
+ void setGenerateFunctions(const QSet<QString> &f);
+
+ void setFieldModifications(const FieldModificationList &mods);
+ FieldModificationList fieldModifications() const;
+
+ const QList<TypeSystemProperty> &properties() const;
+ void addProperty(const TypeSystemProperty &p);
+
+ QString defaultSuperclass() const;
+ void setDefaultSuperclass(const QString &sc);
+
+ QString qualifiedCppName() const override;
+
+ void setIsPolymorphicBase(bool on);
+ bool isPolymorphicBase() const;
+
+ void setPolymorphicIdValue(const QString &value);
+ QString polymorphicIdValue() const;
+
+ QString polymorphicNameFunction() const;
+ void setPolymorphicNameFunction(const QString &n);
+
+ QString targetType() const;
+ void setTargetType(const QString &code);
+
+ bool isGenericClass() const;
+ void setGenericClass(bool isGeneric);
+
+ bool deleteInMainThread() const;
+ void setDeleteInMainThread(bool d);
+
+ CopyableFlag copyable() const;
+ void setCopyable(CopyableFlag flag);
+
+ TypeSystem::QtMetaTypeRegistration qtMetaTypeRegistration() const;
+ void setQtMetaTypeRegistration(TypeSystem::QtMetaTypeRegistration r);
+
+ QString hashFunction() const;
+ void setHashFunction(const QString &hashFunction);
+
+ void setBaseContainerType(const ComplexTypeEntryCPtr &baseContainer);
+
+ ComplexTypeEntryCPtr baseContainerType() const;
+
+ TypeSystem::ExceptionHandling exceptionHandling() const;
+ void setExceptionHandling(TypeSystem::ExceptionHandling e);
+
+ TypeSystem::AllowThread allowThread() const;
+ void setAllowThread(TypeSystem::AllowThread allowThread);
+
+ QString defaultConstructor() const;
+ void setDefaultConstructor(const QString& defaultConstructor);
+ bool hasDefaultConstructor() const;
+
+ TypeEntry *clone() const override;
+
+ void useAsTypedef(const ComplexTypeEntryCPtr &source);
+
+ TypeSystem::SnakeCase snakeCase() const;
+ void setSnakeCase(TypeSystem::SnakeCase sc);
+
+ // Determined by AbstractMetaBuilder from the code model.
+ bool isValueTypeWithCopyConstructorOnly() const;
+ void setValueTypeWithCopyConstructorOnly(bool v);
+
+ // FIXME PYSIDE 7: Remove this
+ static bool isParentManagementEnabled();
+ static void setParentManagementEnabled(bool e);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &debug) const override;
+#endif
+protected:
+ explicit ComplexTypeEntry(ComplexTypeEntryPrivate *d);
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(ComplexTypeEntry::TypeFlags)
+
+#endif // COMPLEXTYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp b/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp
index 20209769a..b6eda651c 100644
--- a/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp
+++ b/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp
@@ -1,36 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "conditionalstreamreader.h"
#include <QtCore/QDebug>
#include <QtCore/QHash>
+using namespace Qt::StringLiterals;
+
// ProxyEntityResolver proxies a QXmlStreamEntityResolver set by the user
// on ConditionalStreamReader and stores entity definitions from the
// <?entity name value?> processing instruction in a cache
@@ -151,7 +128,7 @@ bool ConditionalStreamReader::readEntityDefinitonPi()
const auto data = m_reader.processingInstructionData();
const auto separator = data.indexOf(u' ');
if (separator <= 0 || separator == data.size() - 1) {
- m_reader.raiseError(u"Malformed entity definition: "_qs + data.toString());
+ m_reader.raiseError(u"Malformed entity definition: "_s + data.toString());
return false;
}
defineEntity(data.left(separator).toString(),
@@ -188,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 db86ac1e6..730697525 100644
--- a/sources/shiboken6/ApiExtractor/conditionalstreamreader.h
+++ b/sources/shiboken6/ApiExtractor/conditionalstreamreader.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CONDITIONALSTREAMREADER_H
#define CONDITIONALSTREAMREADER_H
@@ -51,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/constantvaluetypeentry.h b/sources/shiboken6/ApiExtractor/constantvaluetypeentry.h
new file mode 100644
index 000000000..a16a7ad12
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/constantvaluetypeentry.h
@@ -0,0 +1,23 @@
+// 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 CONSTANTVALUETYPEENTRY_H
+#define CONSTANTVALUETYPEENTRY_H
+
+#include "typesystem.h"
+
+// For primitive values, typically to provide a dummy type for
+// example the '2' in non-type template 'Array<2>'.
+class ConstantValueTypeEntry : public TypeEntry
+{
+public:
+ explicit ConstantValueTypeEntry(const QString& name,
+ const TypeEntryCPtr &parent);
+
+ TypeEntry *clone() const override;
+
+protected:
+ explicit ConstantValueTypeEntry(TypeEntryPrivate *d);
+};
+
+#endif // CONSTANTVALUETYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/containertypeentry.h b/sources/shiboken6/ApiExtractor/containertypeentry.h
new file mode 100644
index 000000000..b2003816b
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/containertypeentry.h
@@ -0,0 +1,63 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef CONTAINERTYPEENTRY_H
+#define CONTAINERTYPEENTRY_H
+
+#include "complextypeentry.h"
+#include "customconversion_typedefs.h"
+
+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:
+
+ enum ContainerKind {
+ ListContainer,
+ SetContainer,
+ MapContainer,
+ MultiMapContainer,
+ PairContainer,
+ SpanContainer, // Fixed size
+ };
+
+ explicit ContainerTypeEntry(const QString &entryName, ContainerKind containerKind,
+ const QVersionNumber &vr, const TypeEntryCPtr &parent);
+
+ ContainerKind containerKind() const;
+
+ /// Number of template parameters (except allocators)
+ qsizetype templateParameterCount() const;
+
+ const OpaqueContainers &opaqueContainers() 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);
+ CustomConversionPtr customConversion() const;
+
+ TypeEntry *clone() const override;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+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
new file mode 100644
index 000000000..4cfd1b974
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/customconversion.cpp
@@ -0,0 +1,197 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "customconversion.h"
+#include "containertypeentry.h"
+#include "customtypenentry.h"
+#include "primitivetypeentry.h"
+#include "valuetypeentry.h"
+
+#include <QtCore/qdebug.h>
+
+using namespace Qt::StringLiterals;
+
+CustomConversion::CustomConversion(const TypeEntryCPtr &ownerType) :
+ m_ownerType(ownerType)
+{
+}
+
+TypeEntryCPtr CustomConversion::ownerType() const
+{
+ return m_ownerType;
+}
+
+QString CustomConversion::nativeToTargetConversion() const
+{
+ return m_nativeToTargetConversion;
+}
+
+void CustomConversion::setNativeToTargetConversion(const QString &nativeToTargetConversion)
+{
+ m_nativeToTargetConversion = nativeToTargetConversion;
+}
+
+bool CustomConversion::replaceOriginalTargetToNativeConversions() const
+{
+ return m_replaceOriginalTargetToNativeConversions;
+}
+
+void CustomConversion::setReplaceOriginalTargetToNativeConversions(bool r)
+{
+ m_replaceOriginalTargetToNativeConversions = r;
+}
+
+bool CustomConversion::hasTargetToNativeConversions() const
+{
+ return !(m_targetToNativeConversions.isEmpty());
+}
+
+TargetToNativeConversions &CustomConversion::targetToNativeConversions()
+{
+ return m_targetToNativeConversions;
+}
+
+const TargetToNativeConversions &CustomConversion::targetToNativeConversions() const
+{
+ return m_targetToNativeConversions;
+}
+
+void CustomConversion::addTargetToNativeConversion(const QString &sourceTypeName,
+ const QString &sourceTypeCheck,
+ const QString &conversion)
+{
+ m_targetToNativeConversions.append(TargetToNativeConversion(sourceTypeName,
+ sourceTypeCheck,
+ conversion));
+}
+
+TargetToNativeConversion::TargetToNativeConversion(const QString &sourceTypeName,
+ const QString &sourceTypeCheck,
+ const QString &conversion) :
+ m_sourceTypeName(sourceTypeName), m_sourceTypeCheck(sourceTypeCheck),
+ m_conversion(conversion)
+{
+}
+
+TypeEntryCPtr TargetToNativeConversion::sourceType() const
+{
+ return m_sourceType;
+}
+
+void TargetToNativeConversion::setSourceType(const TypeEntryCPtr &sourceType)
+{
+ m_sourceType = sourceType;
+}
+
+bool TargetToNativeConversion::isCustomType() const
+{
+ return m_sourceType == nullptr;
+}
+
+QString TargetToNativeConversion::sourceTypeName() const
+{
+ return m_sourceTypeName;
+}
+
+QString TargetToNativeConversion::sourceTypeCheck() const
+{
+ if (!m_sourceTypeCheck.isEmpty())
+ return m_sourceTypeCheck;
+
+ if (m_sourceType != nullptr && m_sourceType->isCustom()) {
+ 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
+ result += u"(%in)"_s;
+ return result;
+ }
+ }
+
+ return {};
+}
+
+QString TargetToNativeConversion::conversion() const
+{
+ return m_conversion;
+}
+
+void TargetToNativeConversion::setConversion(const QString &conversion)
+{
+ m_conversion = conversion;
+}
+
+void TargetToNativeConversion::formatDebug(QDebug &debug) const
+{
+ debug << "(source=\"" << m_sourceTypeName << '"';
+ if (debug.verbosity() > 2)
+ debug << ", conversion=\"" << m_conversion << '"';
+ if (isCustomType())
+ debug << ", [custom]";
+ debug << ')';
+}
+
+CustomConversionPtr CustomConversion::getCustomConversion(const TypeEntryCPtr &type)
+{
+ if (type->isPrimitive())
+ return std::static_pointer_cast<const PrimitiveTypeEntry>(type)->customConversion();
+ if (type->isContainer())
+ return std::static_pointer_cast<const ContainerTypeEntry>(type)->customConversion();
+ if (type->isValue())
+ return std::static_pointer_cast<const ValueTypeEntry>(type)->customConversion();
+ return {};
+}
+
+void CustomConversion::formatDebug(QDebug &debug) const
+{
+ debug << "(owner=\"" << m_ownerType->qualifiedCppName() << '"';
+ if (!m_nativeToTargetConversion.isEmpty())
+ debug << ", nativeToTargetConversion=\"" << m_nativeToTargetConversion << '"';
+ if (!m_targetToNativeConversions.isEmpty()) {
+ debug << ", targetToNativeConversions=[";
+ for (qsizetype i = 0, size = m_targetToNativeConversions.size(); i < size; ++i) {
+ if (i)
+ debug << ", ";
+ debug << m_targetToNativeConversions.at(i);
+
+ }
+ debug << ']';
+ }
+ if (m_replaceOriginalTargetToNativeConversions)
+ debug << ", [replaceOriginalTargetToNativeConversions]";
+ debug << ')';
+}
+
+QDebug operator<<(QDebug debug, const TargetToNativeConversion &t)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "TargetToNativeConversion";
+ t.formatDebug(debug);
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const CustomConversion &c)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "CustomConversion";
+ c.formatDebug(debug);
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const CustomConversionPtr &cptr)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "CustomConversionPtr";
+ if (auto *c = cptr.get()) {
+ c->formatDebug(debug);
+ } else {
+ debug << "(0)";
+ }
+ return debug;
+}
diff --git a/sources/shiboken6/ApiExtractor/customconversion.h b/sources/shiboken6/ApiExtractor/customconversion.h
new file mode 100644
index 000000000..fd0a67759
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/customconversion.h
@@ -0,0 +1,81 @@
+// 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 CUSTOMCONVERSION_H
+#define CUSTOMCONVERSION_H
+
+#include "customconversion_typedefs.h"
+#include "typesystem_typedefs.h"
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+
+class TypeEntry;
+
+class TargetToNativeConversion
+{
+public:
+ explicit TargetToNativeConversion(const QString &sourceTypeName,
+ const QString &sourceTypeCheck,
+ const QString &conversion = {});
+
+ TypeEntryCPtr sourceType() const;
+ void setSourceType(const TypeEntryCPtr &sourceType);
+ bool isCustomType() const;
+ QString sourceTypeName() const;
+ QString sourceTypeCheck() const;
+ QString conversion() const;
+ void setConversion(const QString &conversion);
+
+ void formatDebug(QDebug &d) const;
+
+private:
+ TypeEntryCPtr m_sourceType;
+ QString m_sourceTypeName;
+ QString m_sourceTypeCheck;
+ QString m_conversion;
+};
+
+using TargetToNativeConversions = QList<TargetToNativeConversion>;
+
+class CustomConversion
+{
+public:
+ explicit CustomConversion(const TypeEntryCPtr &ownerType);
+
+ TypeEntryCPtr ownerType() const;
+ QString nativeToTargetConversion() const;
+ void setNativeToTargetConversion(const QString &nativeToTargetConversion);
+
+ /// Returns true if the target to C++ custom conversions should
+ /// replace the original existing ones, and false if the custom
+ /// conversions should be added to the original.
+ bool replaceOriginalTargetToNativeConversions() const;
+ void setReplaceOriginalTargetToNativeConversions(bool r);
+
+ bool hasTargetToNativeConversions() const;
+ TargetToNativeConversions &targetToNativeConversions();
+ const TargetToNativeConversions &targetToNativeConversions() const;
+ void addTargetToNativeConversion(const QString &sourceTypeName,
+ const QString &sourceTypeCheck,
+ const QString &conversion = QString());
+
+ /// Return the custom conversion of a type; helper for type system parser
+ static CustomConversionPtr getCustomConversion(const TypeEntryCPtr &type);
+
+ void formatDebug(QDebug &debug) const;
+
+private:
+ TypeEntryCPtr m_ownerType;
+ QString m_nativeToTargetConversion;
+ TargetToNativeConversions m_targetToNativeConversions;
+ bool m_replaceOriginalTargetToNativeConversions = false;
+};
+
+QDebug operator<<(QDebug debug, const TargetToNativeConversion &t);
+QDebug operator<<(QDebug debug, const CustomConversion &c);
+QDebug operator<<(QDebug debug, const CustomConversionPtr &cptr);
+
+#endif // CUSTOMCONVERSION_H
diff --git a/sources/shiboken6/ApiExtractor/customconversion_typedefs.h b/sources/shiboken6/ApiExtractor/customconversion_typedefs.h
new file mode 100644
index 000000000..6528f7d7b
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/customconversion_typedefs.h
@@ -0,0 +1,14 @@
+// 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 CUSTOMCONVERSION_TYPEDEFS_H
+#define CUSTOMCONVERSION_TYPEDEFS_H
+
+#include <QtCore/QList>
+
+#include <memory>
+
+class CustomConversion;
+using CustomConversionPtr = std::shared_ptr<CustomConversion>;
+
+#endif // CUSTOMCONVERSION_TYPEDEFS_H
diff --git a/sources/shiboken6/ApiExtractor/customtypenentry.h b/sources/shiboken6/ApiExtractor/customtypenentry.h
new file mode 100644
index 000000000..a57bb858f
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/customtypenentry.h
@@ -0,0 +1,30 @@
+// 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 CUSTOMTYPENENTRY_H
+#define CUSTOMTYPENENTRY_H
+
+#include "typesystem.h"
+
+class CustomTypeEntry : public TypeEntry
+{
+public:
+ explicit CustomTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ TypeEntry *clone() const override;
+
+ bool hasCheckFunction() const;
+ QString checkFunction() const;
+ void setCheckFunction(const QString &f);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+protected:
+ explicit CustomTypeEntry(TypeEntryPrivate *d);
+};
+
+
+#endif // CUSTOMTYPENENTRY_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 ee6301525..aa280de03 100644
--- a/sources/shiboken6/ApiExtractor/dependency.h
+++ b/sources/shiboken6/ApiExtractor/dependency.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef DEPENDENCY_H
#define DEPENDENCY_H
@@ -38,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 9445adf81..468fe1098 100644
--- a/sources/shiboken6/ApiExtractor/docparser.cpp
+++ b/sources/shiboken6/ApiExtractor/docparser.cpp
@@ -1,44 +1,25 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "docparser.h"
+#include "abstractmetaargument.h"
#include "abstractmetaenum.h"
-#include "abstractmetafield.h"
#include "abstractmetafunction.h"
#include "abstractmetalang.h"
+#include "abstractmetatype.h"
#include "messages.h"
#include "modifications.h"
#include "reporthandler.h"
-#include "typesystem.h"
+#include "enumtypeentry.h"
+#include "complextypeentry.h"
#include "xmlutils.h"
+
+#include <QtCore/QBuffer>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QTextStream>
-#include <QBuffer>
+
+#include "qtcompat.h"
#include <cstdlib>
#ifdef HAVE_LIBXSLT
@@ -48,15 +29,39 @@
#include <algorithm>
-DocParser::DocParser()
+using namespace Qt::StringLiterals;
+
+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)
{
@@ -73,9 +78,16 @@ QString DocParser::execXQuery(const XQueryPtr &xquery, const QString& query)
return result;
}
+static bool usesRValueReference(const AbstractMetaArgument &a)
+{
+ return a.type().referenceType() == RValueReference;
+}
+
bool DocParser::skipForQuery(const AbstractMetaFunctionCPtr &func)
{
// Skip private functions and copies created by AbstractMetaClass::fixFunctions()
+ // Note: Functions inherited from templates will cause warnings about missing
+ // documentation, but they should at least be listed.
if (!func || func->isPrivate()
|| func->attributes().testFlag(AbstractMetaFunction::AddedMethod)
|| func->isModifiedRemoved()
@@ -91,25 +103,95 @@ bool DocParser::skipForQuery(const AbstractMetaFunctionCPtr &func)
default:
break;
}
- return false;
+
+ return std::any_of(func->arguments().cbegin(), func->arguments().cend(),
+ usesRValueReference);
}
-AbstractMetaFunctionCList DocParser::documentableFunctions(const AbstractMetaClass *metaClass)
+DocModificationList DocParser::getDocModifications(const AbstractMetaClassCPtr &cppClass)
+
{
- auto result = metaClass->functionsInTargetLang();
- for (int i = result.size() - 1; i >= 0; --i) {
- if (DocParser::skipForQuery(result.at(i)) || result.at(i)->isUserAdded())
- result.removeAt(i);
+ auto result = cppClass->typeEntry()->docModifications();
+ removeXpathDocModifications(&result);
+ return result;
+}
+
+static void filterBySignature(const AbstractMetaFunctionCPtr &func, DocModificationList *l)
+{
+ 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());
+ }
+}
+
+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;
}
-static inline bool isXpathDocModification(const DocModification &mod)
+DocModificationList DocParser::getXpathDocModifications(const AbstractMetaClassCPtr &cppClass)
{
- return mod.mode() == TypeSystem::DocModificationXPathReplace;
+ 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;
}
-QString DocParser::applyDocModifications(const DocModificationList& mods, const QString& xml)
+QString DocParser::enumBaseClass(const AbstractMetaEnum &e)
+{
+ switch (e.typeEntry()->pythonEnumType()) {
+ case TypeSystem::PythonEnumType::IntEnum:
+ return u"IntEnum"_s;
+ case TypeSystem::PythonEnumType::Flag:
+ return u"Flag"_s;
+ case TypeSystem::PythonEnumType::IntFlag:
+ return u"IntFlag"_s;
+ default:
+ break;
+ }
+ return e.typeEntry()->flags() != nullptr ? u"Flag"_s : u"Enum"_s;
+}
+
+AbstractMetaFunctionCList DocParser::documentableFunctions(const AbstractMetaClassCPtr &metaClass)
+{
+ auto result = metaClass->functionsInTargetLang();
+ for (auto i = result.size() - 1; i >= 0; --i) {
+ if (DocParser::skipForQuery(result.at(i)) || result.at(i)->isUserAdded())
+ result.removeAt(i);
+ }
+ result.append(metaClass->cppSignalFunctions());
+ return result;
+}
+
+QString DocParser::applyDocModifications(const DocModificationList& xpathMods,
+ const QString& xml)
{
const char xslPrefix[] =
R"(<xsl:template match="/">
@@ -123,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 = QLatin1String(xslPrefix);
- for (const DocModification &mod : mods) {
- if (isXpathDocModification(mod)) {
- QString xpath = mod.xpath();
- xpath.replace(QLatin1Char('"'), QLatin1String("&quot;"));
- xsl += QLatin1String("<xsl:template match=\"")
- + xpath + QLatin1String("\">")
- + mod.code() + QLatin1String("</xsl:template>\n");
- }
+ QString xsl = QLatin1StringView(xslPrefix);
+ 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 = QLatin1String("Query did not result in any modifications to \"")
- + xml + QLatin1Char('"');
+ 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 206370bca..6d458b25a 100644
--- a/sources/shiboken6/ApiExtractor/docparser.h
+++ b/sources/shiboken6/ApiExtractor/docparser.h
@@ -1,38 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef DOCPARSER_H
#define DOCPARSER_H
-#include "typesystem_typedefs.h"
#include "abstractmetalang_typedefs.h"
+#include "modifications_typedefs.h"
#include <QtCore/QString>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
class AbstractMetaClass;
class DocModification;
@@ -40,16 +16,20 @@ class Documentation;
class XQuery;
+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
@@ -114,12 +94,25 @@ public:
static bool skipForQuery(const AbstractMetaFunctionCPtr &func);
+ /// Helper to return the documentation modifications for a class
+ /// or a member function.
+ 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);
+
protected:
static QString getDocumentation(const XQueryPtr &xquery,
const QString &query,
const DocModificationList &mods);
- static AbstractMetaFunctionCList documentableFunctions(const AbstractMetaClass *metaClass);
+ static AbstractMetaFunctionCList documentableFunctions(const AbstractMetaClassCPtr &metaClass);
+
+ static QString applyDocModifications(const DocModificationList &xpathMods, const QString &xml);
private:
QString m_packageName;
@@ -127,7 +120,6 @@ private:
QString m_libSourceDir;
static QString execXQuery(const XQueryPtr &xquery, const QString &query) ;
- static QString applyDocModifications(const DocModificationList &mods, const QString &xml) ;
};
#endif // DOCPARSER_H
diff --git a/sources/shiboken6/ApiExtractor/documentation.cpp b/sources/shiboken6/ApiExtractor/documentation.cpp
index f4c016d97..33cf0e9fb 100644
--- a/sources/shiboken6/ApiExtractor/documentation.cpp
+++ b/sources/shiboken6/ApiExtractor/documentation.cpp
@@ -1,33 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "documentation.h"
+#include <QtCore/QDebug>
+
Documentation::Documentation(const QString &detailed,
const QString &brief,
Format fmt) :
@@ -58,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();
@@ -73,3 +44,22 @@ void Documentation::setBrief(const QString &brief)
{
m_brief = brief.trimmed();
}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug debug, const Documentation &d)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "Documentation(";
+ if (!d.isEmpty()) {
+ debug << "format=" << d.format();
+ if (!d.brief().isEmpty())
+ debug << ", brief=\"" << d.brief() << '"';
+ if (!d.detailed().isEmpty())
+ debug << ", detailed=\"" << d.detailed() << '"';
+ }
+ debug << ')';
+ return debug;
+}
+#endif // QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken6/ApiExtractor/documentation.h b/sources/shiboken6/ApiExtractor/documentation.h
index df2a3fd6f..df9d5d614 100644
--- a/sources/shiboken6/ApiExtractor/documentation.h
+++ b/sources/shiboken6/ApiExtractor/documentation.h
@@ -1,35 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef DOCUMENTATION_H
#define DOCUMENTATION_H
#include <QtCore/QString>
+#include <QtCore/QtCompare>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
class Documentation
{
@@ -67,14 +45,21 @@ 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
#endif // DOCUMENTATION_H
diff --git a/sources/shiboken6/ApiExtractor/dotview.cpp b/sources/shiboken6/ApiExtractor/dotview.cpp
index 0ead28f68..0bd192257 100644
--- a/sources/shiboken6/ApiExtractor/dotview.cpp
+++ b/sources/shiboken6/ApiExtractor/dotview.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "dotview.h"
@@ -34,12 +9,14 @@
#include <QtCore/QProcess>
#include <QtCore/QTemporaryFile>
+using namespace Qt::StringLiterals;
+
bool showDotGraph(const QString &name, const QString &graph)
{
- const QString imageType = u"jpg"_qs;
+ constexpr auto imageType = "jpg"_L1;
// Write out the graph to a temporary file
- QTemporaryFile dotFile(QDir::tempPath() + u'/' + name + u"_XXXXXX.dot"_qs);
+ QTemporaryFile dotFile(QDir::tempPath() + u'/' + name + u"_XXXXXX.dot"_s);
if (!dotFile.open()) {
qWarning("Cannot open temporary file: %s", qPrintable(dotFile.errorString()));
return false;
@@ -51,7 +28,7 @@ bool showDotGraph(const QString &name, const QString &graph)
// Convert to image using "dot"
const QString imageFile = tempDotFile.left(tempDotFile.size() - 3) + imageType;
QProcess process;
- process.start(u"dot"_qs, {u"-T"_qs + imageType, u"-o"_qs + imageFile, tempDotFile});
+ process.start(u"dot"_s, {u"-T"_s + imageType, u"-o"_s + imageFile, tempDotFile});
if (!process.waitForStarted() || !process.waitForFinished()) {
qWarning("Image conversion failed: %s", qPrintable(process.errorString()));
return false;
@@ -66,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"_qs;
+ constexpr auto imageViewer = "gwenview"_L1;
#else
- const QString imageViewer = u"mspaint"_qs;
+ 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/dotview.h b/sources/shiboken6/ApiExtractor/dotview.h
index 462cc2b75..87fb7db65 100644
--- a/sources/shiboken6/ApiExtractor/dotview.h
+++ b/sources/shiboken6/ApiExtractor/dotview.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef DOTVIEW_H
#define DOTVIEW_H
diff --git a/sources/shiboken6/ApiExtractor/doxygenparser.cpp b/sources/shiboken6/ApiExtractor/doxygenparser.cpp
index ed589dd09..da790015f 100644
--- a/sources/shiboken6/ApiExtractor/doxygenparser.cpp
+++ b/sources/shiboken6/ApiExtractor/doxygenparser.cpp
@@ -1,57 +1,38 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "doxygenparser.h"
+#include "abstractmetaargument.h"
#include "abstractmetalang.h"
#include "abstractmetafield.h"
#include "abstractmetafunction.h"
#include "abstractmetaenum.h"
+#include "abstractmetatype.h"
#include "documentation.h"
#include "messages.h"
#include "modifications.h"
#include "propertyspec.h"
#include "reporthandler.h"
-#include "typesystem.h"
+#include "complextypeentry.h"
#include "xmlutils.h"
+#include "qtcompat.h"
+
#include <QtCore/QFile>
#include <QtCore/QDir>
+using namespace Qt::StringLiterals;
+
static QString getSectionKindAttr(const AbstractMetaFunctionCPtr &func)
{
if (func->isSignal())
- return QLatin1String("signal");
+ return u"signal"_s;
QString kind = func->isPublic()
- ? QLatin1String("public") : QLatin1String("protected");
+ ? u"public"_s : u"protected"_s;
if (func->isStatic())
- kind += QLatin1String("-static");
+ kind += u"-static"_s;
else if (func->isSlot())
- kind += QLatin1String("-slot");
+ kind += u"-slot"_s;
return kind;
}
@@ -60,7 +41,7 @@ Documentation DoxygenParser::retrieveModuleDocumentation()
return retrieveModuleDocumentation(packageName());
}
-void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
+void DoxygenParser::fillDocumentation(const AbstractMetaClassPtr &metaClass)
{
if (!metaClass)
return;
@@ -68,18 +49,17 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
QString doxyFileSuffix;
if (metaClass->enclosingClass()) {
doxyFileSuffix += metaClass->enclosingClass()->name();
- doxyFileSuffix += QLatin1String("_1_1"); // FIXME: Check why _1_1!!
+ doxyFileSuffix += u"_1_1"_s; // FIXME: Check why _1_1!!
}
doxyFileSuffix += metaClass->name();
- doxyFileSuffix += QLatin1String(".xml");
+ 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() + QLatin1Char('/')
- + QLatin1String(prefix) + doxyFileSuffix;
+ for (const auto &prefix : prefixes) {
+ doxyFilePath = documentationDataDirectory() + u'/' + prefix + doxyFileSuffix;
if (QFile::exists(doxyFilePath))
break;
doxyFilePath.clear();
@@ -95,20 +75,20 @@ 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 = {
- { Documentation::Brief, QLatin1String("briefdescription") },
- { Documentation::Detailed, QLatin1String("detaileddescription") }
+ static const QList<std::pair<Documentation::Type, QString>> docTags = {
+ { Documentation::Brief, u"briefdescription"_s },
+ { Documentation::Detailed, u"detaileddescription"_s }
};
// Get class documentation
Documentation classDoc;
for (const auto &tag : docTags) {
- const QString classQuery = QLatin1String("/doxygen/compounddef/") + tag.second;
+ const QString classQuery = u"/doxygen/compounddef/"_s + tag.second;
QString doc = getDocumentation(xquery, classQuery,
metaClass->typeEntry()->docModifications());
if (doc.isEmpty())
@@ -123,37 +103,37 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
//Functions Documentation
const auto &funcs = DocParser::documentableFunctions(metaClass);
for (const auto &func : funcs) {
- QString query = QLatin1String("/doxygen/compounddef/sectiondef");
+ QString query = u"/doxygen/compounddef/sectiondef"_s;
// properties
if (func->isPropertyReader() || func->isPropertyWriter()
|| func->isPropertyResetter()) {
const auto prop = metaClass->propertySpecs().at(func->propertySpecIndex());
- query += QLatin1String("[@kind=\"property\"]/memberdef/name[text()=\"")
- + prop.name() + QLatin1String("\"]");
+ query += u"[@kind=\"property\"]/memberdef/name[text()=\""_s
+ + prop.name() + u"\"]"_s;
isProperty = true;
} else { // normal methods
QString kind = getSectionKindAttr(func);
- query += QLatin1String("[@kind=\"") + kind
- + QLatin1String("-func\"]/memberdef/name[text()=\"")
- + func->originalName() + QLatin1String("\"]");
+ query += u"[@kind=\""_s + kind
+ + u"-func\"]/memberdef/name[text()=\""_s
+ + func->originalName() + u"\"]"_s;
if (func->arguments().isEmpty()) {
- QString args = func->isConstant() ? QLatin1String("() const ") : QLatin1String("()");
- query += QLatin1String("/../argsstring[text()=\"") + args + QLatin1String("\"]");
+ QString args = func->isConstant() ? u"() const"_s : u"()"_s;
+ query += u"/../argsstring[text()=\""_s + args + u"\"]"_s;
} else {
int i = 1;
const AbstractMetaArgumentList &arguments = func->arguments();
for (const AbstractMetaArgument &arg : arguments) {
if (!arg.type().isPrimitive()) {
- query += QLatin1String("/../param[") + QString::number(i)
- + QLatin1String("]/type/ref[text()=\"")
+ query += u"/../param["_s + QString::number(i)
+ + u"]/type/ref[text()=\""_s
+ arg.type().cppSignature().toHtmlEscaped()
- + QLatin1String("\"]/../..");
+ + u"\"]/../.."_s;
} else {
- query += QLatin1String("/../param[") + QString::number(i)
- + QLatin1String("]/type[text(), \"")
+ query += u"/../param["_s + QString::number(i)
+ + u"]/type[text(), \""_s
+ arg.type().cppSignature().toHtmlEscaped()
- + QLatin1String("\"]/..");
+ + u"\"]/.."_s;
}
++i;
}
@@ -163,22 +143,23 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
for (const auto &tag : docTags) {
QString funcQuery(query);
if (!isProperty) {
- funcQuery += QLatin1String("/../") + tag.second;
+ funcQuery += u"/../"_s + tag.second;
} else {
- funcQuery = QLatin1Char('(') + funcQuery;
- funcQuery += u"/../"_qs + tag.second + u")[1]"_qs;
+ funcQuery = u'(' + funcQuery;
+ funcQuery += u"/../"_s + tag.second + u")[1]"_s;
}
- QString doc = getDocumentation(xquery, funcQuery, DocModificationList());
+ QString doc = getDocumentation(xquery, funcQuery,
+ DocParser::getXpathDocModifications(func, metaClass));
if (doc.isEmpty()) {
qCWarning(lcShibokenDoc, "%s",
- qPrintable(msgCannotFindDocumentation(doxyFilePath, metaClass, 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;
}
@@ -189,8 +170,8 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
Documentation fieldDoc;
for (const auto &tag : docTags) {
- QString query = QLatin1String("/doxygen/compounddef/sectiondef/memberdef/name[text()=\"")
- + field.name() + QLatin1String("\"]/../") + tag.second;
+ QString query = u"/doxygen/compounddef/sectiondef/memberdef/name[text()=\""_s
+ + field.name() + u"\"]/../"_s + tag.second;
QString doc = getDocumentation(xquery, query, DocModificationList());
if (doc.isEmpty()) {
qCWarning(lcShibokenDoc, "%s",
@@ -205,8 +186,8 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
//Enums
for (AbstractMetaEnum &meta_enum : metaClass->enums()) {
- QString query = QLatin1String("/doxygen/compounddef/sectiondef/memberdef[@kind=\"enum\"]/name[text()=\"")
- + meta_enum.name() + QLatin1String("\"]/..");
+ QString query = u"/doxygen/compounddef/sectiondef/memberdef[@kind=\"enum\"]/name[text()=\""_s
+ + meta_enum.name() + u"\"]/.."_s;
QString doc = getDocumentation(xquery, query, DocModificationList());
if (doc.isEmpty()) {
qCWarning(lcShibokenDoc, "%s",
@@ -219,24 +200,24 @@ void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass)
Documentation DoxygenParser::retrieveModuleDocumentation(const QString& name){
- QString sourceFile = documentationDataDirectory() + QLatin1String("/indexpage.xml");
+ QString sourceFile = documentationDataDirectory() + u"/indexpage.xml"_s;
if (!QFile::exists(sourceFile)) {
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 {};
}
// Module documentation
- QString query = QLatin1String("/doxygen/compounddef/detaileddescription");
+ QString query = u"/doxygen/compounddef/detaileddescription"_s;
const QString doc = getDocumentation(xquery, query, DocModificationList());
return Documentation(doc, {});
}
diff --git a/sources/shiboken6/ApiExtractor/doxygenparser.h b/sources/shiboken6/ApiExtractor/doxygenparser.h
index ada64ac18..4f6a9e53c 100644
--- a/sources/shiboken6/ApiExtractor/doxygenparser.h
+++ b/sources/shiboken6/ApiExtractor/doxygenparser.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef DOXYGENPARSER_H
#define DOXYGENPARSER_H
@@ -35,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 5d6394f11..2421ae527 100644
--- a/sources/shiboken6/ApiExtractor/enclosingclassmixin.cpp
+++ b/sources/shiboken6/ApiExtractor/enclosingclassmixin.cpp
@@ -1,38 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "enclosingclassmixin.h"
#include "abstractmetalang.h"
-#include "typesystem.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 61fbc816f..8d735d5ec 100644
--- a/sources/shiboken6/ApiExtractor/enclosingclassmixin.h
+++ b/sources/shiboken6/ApiExtractor/enclosingclassmixin.h
@@ -1,44 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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
new file mode 100644
index 000000000..3360d7db5
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/enumtypeentry.h
@@ -0,0 +1,51 @@
+// 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 ENUMTYPEENTRY_H
+#define ENUMTYPEENTRY_H
+
+#include "configurabletypeentry.h"
+#include "typesystem_enums.h"
+
+class EnumTypeEntryPrivate;
+
+// EnumTypeEntry is configurable for global enums only
+class EnumTypeEntry : public ConfigurableTypeEntry
+{
+public:
+ explicit EnumTypeEntry(const QString &entryName,
+ const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ TypeSystem::PythonEnumType pythonEnumType() const;
+ void setPythonEnumType(TypeSystem::PythonEnumType t);
+
+ QString targetLangQualifier() const;
+
+ QString qualifier() const;
+
+ EnumValueTypeEntryCPtr nullValue() const;
+ void setNullValue(const EnumValueTypeEntryCPtr &n);
+
+ void setFlags(const FlagsTypeEntryPtr &flags);
+ FlagsTypeEntryPtr flags() const;
+
+ QString cppType() const;
+ void setCppType(const QString &t);
+
+ bool isEnumValueRejected(const QString &name) const;
+ 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;
+#endif
+protected:
+ explicit EnumTypeEntry(EnumTypeEntryPrivate *d);
+};
+
+#endif // ENUMTYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/enumvaluetypeentry.h b/sources/shiboken6/ApiExtractor/enumvaluetypeentry.h
new file mode 100644
index 000000000..006b84e0a
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/enumvaluetypeentry.h
@@ -0,0 +1,31 @@
+// 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 ENUMVALUETYPEENTRY_H
+#define ENUMVALUETYPEENTRY_H
+
+#include "typesystem.h"
+
+class EnumTypeEntry;
+class EnumValueTypeEntryPrivate;
+
+// EnumValueTypeEntry is used for resolving integer type templates
+// like array<EnumValue>. Note: Dummy entries for integer values will
+// be created for non-type template parameters, where m_enclosingEnum==nullptr.
+class EnumValueTypeEntry : public TypeEntry
+{
+public:
+ explicit EnumValueTypeEntry(const QString& name, const QString& value,
+ const EnumTypeEntryCPtr &enclosingEnum,
+ bool isScopedEnum, const QVersionNumber &vr);
+
+ QString value() const;
+ EnumTypeEntryCPtr enclosingEnum() const;
+
+ TypeEntry *clone() const override;
+
+protected:
+ explicit EnumValueTypeEntry(EnumValueTypeEntryPrivate *d);
+};
+
+#endif // ENUMVALUETYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/exception.h b/sources/shiboken6/ApiExtractor/exception.h
index 36e94638a..396b56f5d 100644
--- a/sources/shiboken6/ApiExtractor/exception.h
+++ b/sources/shiboken6/ApiExtractor/exception.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef EXCEPTION_H
#define EXCEPTION_H
-#include <QString>
+#include <QtCore/QString>
#include <string>
#include <exception>
diff --git a/sources/shiboken6/ApiExtractor/fileout.cpp b/sources/shiboken6/ApiExtractor/fileout.cpp
index 84455dd9e..6f9ec4d8a 100644
--- a/sources/shiboken6/ApiExtractor/fileout.cpp
+++ b/sources/shiboken6/ApiExtractor/fileout.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "fileout.h"
#include "messages.h"
@@ -67,20 +42,20 @@ FileOut::~FileOut()
}
}
-static QList<int> lcsLength(const QByteArrayList &a, const QByteArrayList &b)
+static QList<qsizetype> lcsLength(const QByteArrayList &a, const QByteArrayList &b)
{
- const int height = a.size() + 1;
- const int width = b.size() + 1;
+ const auto height = a.size() + 1;
+ const auto width = b.size() + 1;
- QList<int> res(width * height, 0);
+ QList<qsizetype> res(width * height, 0);
- for (int row = 1; row < height; row++) {
- for (int col = 1; col < width; col++) {
- if (a[row-1] == b[col-1])
- res[width * row + col] = res[width * (row-1) + col-1] + 1;
+ for (qsizetype row = 1; row < height; row++) {
+ for (qsizetype col = 1; col < width; col++) {
+ if (a.at(row - 1) == b.at(col - 1))
+ res[width * row + col] = res[width * (row - 1) + col - 1] + 1;
else
- res[width * row + col] = qMax(res[width * row + col-1],
- res[width * (row-1) + col]);
+ res[width * row + col] = qMax(res[width * row + col - 1],
+ res[width * (row - 1) + col]);
}
}
return res;
@@ -95,8 +70,8 @@ enum Type {
struct Unit
{
Type type;
- int start;
- int end;
+ qsizetype start;
+ qsizetype end;
void print(const QByteArrayList &a, const QByteArrayList &b) const;
};
@@ -106,33 +81,33 @@ void Unit::print(const QByteArrayList &a, const QByteArrayList &b) const
switch (type) {
case Unchanged:
if ((end - start) > 9) {
- for (int i = start; i <= start + 2; i++)
+ for (auto i = start; i <= start + 2; ++i)
std::printf(" %s\n", a.at(i).constData());
std::printf("%s=\n= %d more lines\n=%s\n",
- colorInfo, end - start - 6, colorReset);
- for (int i = end - 2; i <= end; i++)
+ colorInfo, int(end - start - 6), colorReset);
+ for (auto i = end - 2; i <= end; ++i)
std::printf(" %s\n", a.at(i).constData());
} else {
- for (int i = start; i <= end; i++)
+ for (auto i = start; i <= end; ++i)
std::printf(" %s\n", a.at(i).constData());
}
break;
case Add:
std::fputs(colorAdd, stdout);
- for (int i = start; i <= end; i++)
+ for (auto i = start; i <= end; ++i)
std::printf("+ %s\n", b.at(i).constData());
std::fputs(colorReset, stdout);
break;
case Delete:
std::fputs(colorDelete, stdout);
- for (int i = start; i <= end; i++)
+ for (auto i = start; i <= end; ++i)
std::printf("- %s\n", a.at(i).constData());
std::fputs(colorReset, stdout);
break;
}
}
-static void unitAppend(Type type, int pos, QList<Unit> *units)
+static void unitAppend(Type type, qsizetype pos, QList<Unit> *units)
{
if (!units->isEmpty() && units->last().type == type)
units->last().end = pos;
@@ -140,9 +115,9 @@ static void unitAppend(Type type, int pos, QList<Unit> *units)
units->append(Unit{type, pos, pos});
}
-static QList<Unit> diffHelper(const QList<int> &lcs,
- const QByteArrayList &a, const QByteArrayList &b,
- int row, int col)
+static QList<Unit> diffHelper(const QList<qsizetype> &lcs,
+ const QByteArrayList &a, const QByteArrayList &b,
+ qsizetype row, qsizetype col)
{
if (row > 0 && col > 0 && a.at(row - 1) == b.at(col - 1)) {
QList<Unit> result = diffHelper(lcs, a, b, row - 1, col - 1);
@@ -150,7 +125,7 @@ static QList<Unit> diffHelper(const QList<int> &lcs,
return result;
}
- const int width = b.size() + 1;
+ const auto width = b.size() + 1;
if (col > 0
&& (row == 0 || lcs.at(width * row + col -1 ) >= lcs.at(width * (row - 1) + col))) {
QList<Unit> result = diffHelper(lcs, a, b, row, col - 1);
@@ -200,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 5b5f33578..b11ad1e20 100644
--- a/sources/shiboken6/ApiExtractor/fileout.h
+++ b/sources/shiboken6/ApiExtractor/fileout.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef FILEOUT_H
#define FILEOUT_H
@@ -39,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
new file mode 100644
index 000000000..6eddcd12b
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/flagstypeentry.h
@@ -0,0 +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
+
+#ifndef FLAGSTYPEENTRY_H
+#define FLAGSTYPEENTRY_H
+
+#include "typesystem.h"
+
+class EnumTypeEntry;
+class FlagsTypeEntryPrivate;
+
+// FlagsTypeEntry is configurable for global flags only
+class FlagsTypeEntry : public TypeEntry
+{
+public:
+ explicit FlagsTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ QString originalName() const;
+ void setOriginalName(const QString &s);
+
+ QString flagsName() const;
+ void setFlagsName(const QString &name);
+
+ EnumTypeEntryPtr originator() const;
+ void setOriginator(const EnumTypeEntryPtr &e);
+
+ TypeEntry *clone() const override;
+
+protected:
+ explicit FlagsTypeEntry(FlagsTypeEntryPrivate *d);
+
+ QString buildTargetLangName() const override;
+};
+
+#endif // FLAGSTYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/functiontypeentry.h b/sources/shiboken6/ApiExtractor/functiontypeentry.h
new file mode 100644
index 000000000..53aa1fad6
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/functiontypeentry.h
@@ -0,0 +1,35 @@
+// 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 FUNCTIONTYPEENTRY_H
+#define FUNCTIONTYPEENTRY_H
+
+#include "typesystem.h"
+
+class FunctionTypeEntryPrivate;
+
+class FunctionTypeEntry : public TypeEntry
+{
+public:
+ explicit FunctionTypeEntry(const QString& name, const QString& signature,
+ const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ const QStringList &signatures() const;
+ bool hasSignature(const QString& signature) const;
+ void addSignature(const QString& signature);
+
+ QString docFile() const;
+ void setDocFile(const QString &df);
+
+ TypeEntry *clone() const override;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+protected:
+ explicit FunctionTypeEntry(FunctionTypeEntryPrivate *d);
+};
+
+#endif // FUNCTIONTYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/graph.h b/sources/shiboken6/ApiExtractor/graph.h
index 26aed4328..447a26da0 100644
--- a/sources/shiboken6/ApiExtractor/graph.h
+++ b/sources/shiboken6/ApiExtractor/graph.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef GRAPH_H
#define GRAPH_H
diff --git a/sources/shiboken6/ApiExtractor/header_paths.h b/sources/shiboken6/ApiExtractor/header_paths.h
index 0c25702ef..af4a768e8 100644
--- a/sources/shiboken6/ApiExtractor/header_paths.h
+++ b/sources/shiboken6/ApiExtractor/header_paths.h
@@ -1,37 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef HEADER_PATHS_H
#define HEADER_PATHS_H
-#include <QByteArray>
-#include <QList>
-#include <QString>
+#include <QtCore/QByteArray>
+#include <QtCore/QList>
enum class HeaderType
{
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 ea31d000a..aee6b7337 100644
--- a/sources/shiboken6/ApiExtractor/include.cpp
+++ b/sources/shiboken6/ApiExtractor/include.cpp
@@ -1,56 +1,44 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "include.h"
#include "textstream.h"
-#include <QDebug>
-#include <QDir>
-#include <QTextStream>
-#include <QHash>
+
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QHash>
+#include <QtCore/QTextStream>
+
+#include "qtcompat.h"
+
+#include <algorithm>
+
+using namespace Qt::StringLiterals;
QString Include::toString() const
{
if (m_type == IncludePath)
- return QLatin1String("#include <") + m_name + QLatin1Char('>');
+ return u"#include <"_s + m_name + u'>';
if (m_type == LocalPath)
- return QLatin1String("#include \"") + m_name + QLatin1Char('"');
- return QLatin1String("import ") + m_name + QLatin1Char(';');
+ return u"#include \""_s + m_name + u'"';
+ return u"import "_s + m_name + u';';
}
-size_t qHash(const Include& inc)
+Qt::strong_ordering compareThreeWay(const Include &lhs, const Include &rhs) noexcept
{
- 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& include)
+QTextStream& operator<<(QTextStream& out, const Include& g)
{
- if (include.isValid())
- out << include.toString() << Qt::endl;
+ if (g.isValid())
+ out << g.toString() << Qt::endl;
return out;
}
@@ -61,6 +49,19 @@ TextStream& operator<<(TextStream& out, const Include& include)
return out;
}
+TextStream& operator<<(TextStream &out, const IncludeGroup& g)
+{
+ if (!g.includes.isEmpty()) {
+ if (!g.title.isEmpty())
+ out << "\n// " << g.title << "\n";
+ auto includes = g.includes;
+ std::sort(includes.begin(), includes.end());
+ for (const Include &inc : std::as_const(includes))
+ out << inc.toString() << '\n';
+ }
+ return out;
+}
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const Include &i)
{
diff --git a/sources/shiboken6/ApiExtractor/include.h b/sources/shiboken6/ApiExtractor/include.h
index 405a8e3fb..875a941f9 100644
--- a/sources/shiboken6/ApiExtractor/include.h
+++ b/sources/shiboken6/ApiExtractor/include.h
@@ -1,36 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef INCLUDE_H
#define INCLUDE_H
-#include <QString>
-#include <QList>
+#include <QtCore/QtCompare>
+#include <QtCore/QHashFunctions>
+#include <QtCore/QString>
+#include <QtCore/QList>
QT_BEGIN_NAMESPACE
class QTextStream;
@@ -67,23 +44,25 @@ public:
QString toString() const;
- bool operator<(const Include& other) const
+ int compare(const Include &rhs) const;
+
+private:
+ friend size_t qHash(Include &inc, size_t seed = 0) noexcept
{
- return m_name < other.m_name;
+ return qHashMulti(seed, inc.m_type, inc.m_name);
}
-
- bool operator==(const Include& other) const
+ friend bool comparesEqual(const Include &lhs, const Include &rhs) noexcept
{
- return m_type == other.m_type && m_name == other.m_name;
+ 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)
- friend size_t qHash(const Include&);
- private:
- IncludeType m_type = IncludePath;
- QString m_name;
+ IncludeType m_type = IncludePath;
+ QString m_name;
};
-size_t qHash(const Include& inc);
QTextStream& operator<<(QTextStream& out, const Include& include);
TextStream& operator<<(TextStream& out, const Include& include);
#ifndef QT_NO_DEBUG_STREAM
@@ -92,4 +71,25 @@ QDebug operator<<(QDebug d, const Include &i);
using IncludeList = QList<Include>;
+struct IncludeGroup
+{
+ QString title;
+ IncludeList includes;
+
+ void append(const Include &include)
+ {
+ IncludeGroup::appendInclude(include, &includes);
+ }
+
+ static void appendInclude(const Include &include, IncludeList *list)
+ {
+ if (include.isValid() && !list->contains(include))
+ list->append(include);
+ }
+};
+
+TextStream& operator<<(TextStream &out, const IncludeGroup& include);
+
+using IncludeGroupList = QList<IncludeGroup>;
+
#endif
diff --git a/sources/shiboken6/ApiExtractor/messages.cpp b/sources/shiboken6/ApiExtractor/messages.cpp
index 8079e5851..170595660 100644
--- a/sources/shiboken6/ApiExtractor/messages.cpp
+++ b/sources/shiboken6/ApiExtractor/messages.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "messages.h"
#include "abstractmetaenum.h"
@@ -34,21 +9,40 @@
#include "modifications.h"
#include "sourcelocation.h"
#include "typedatabase.h"
-#include "typesystem.h"
+#include "functiontypeentry.h"
+#include "enumtypeentry.h"
+#include "smartpointertypeentry.h"
#include <codemodel.h>
-#include <QtCore/QCoreApplication>
+#include "qtcompat.h"
+
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QStringList>
#include <QtCore/QXmlStreamReader>
-static inline QString colonColon() { return QStringLiteral("::"); }
+using namespace Qt::StringLiterals;
// 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,
@@ -68,8 +62,8 @@ QString msgNoFunctionForModification(const AbstractMetaClass *klass,
str << " " << s << '\n';
} else if (!allFunctions.isEmpty()) {
str << "\n No candidates were found. Member functions:\n";
- const int maxCount = qMin(10, allFunctions.size());
- for (int f = 0; f < maxCount; ++f)
+ const auto maxCount = qMin(qsizetype(10), allFunctions.size());
+ for (qsizetype f = 0; f < maxCount; ++f)
str << " " << allFunctions.at(f)->minimalSignature() << '\n';
if (maxCount < allFunctions.size())
str << " ...\n";
@@ -77,6 +71,14 @@ QString msgNoFunctionForModification(const AbstractMetaClass *klass,
return result;
}
+QString msgArgumentIndexOutOfRange(const AbstractMetaFunction *func, int index)
+{
+ QString result;
+ QTextStream str(&result);
+ str <<"Index " << index << " out of range for " << func->classQualifiedSignature() << '.';
+ return result;
+}
+
QString msgTypeModificationFailed(const QString &type, int n,
const AbstractMetaFunction *func,
const QString &why)
@@ -90,12 +92,26 @@ 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;
}
+QString msgInvalidArgumentModification(const AbstractMetaFunctionCPtr &func,
+ int argIndex)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Invalid ";
+ if (argIndex == 0)
+ str << "return type modification";
+ else
+ str << "modification of argument " << argIndex;
+ str << " for " << func->classQualifiedSignature();
+ return result;
+}
+
QString msgArgumentOutOfRange(int number, int minValue, int maxValue)
{
QString result;
@@ -110,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;
@@ -123,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();
@@ -146,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())
@@ -154,7 +170,7 @@ static void msgFormatEnumType(Stream &str,
}
static void formatAddedFuncError(const QString &addedFuncName,
- const AbstractMetaClass *context,
+ const AbstractMetaClassCPtr &context,
QTextStream &str)
{
if (context) {
@@ -170,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;
@@ -183,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)
{
@@ -207,7 +223,7 @@ QString msgUnnamedArgumentDefaultExpression(const AbstractMetaClass *context,
return result;
}
-QString msgClassOfEnumNotFound(const EnumTypeEntry *entry)
+QString msgClassOfEnumNotFound(const EnumTypeEntryCPtr &entry)
{
QString result;
QTextStream str(&result);
@@ -224,13 +240,14 @@ 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;
}
QString msgNoEnumTypeConflict(const EnumModelItem &enumItem,
const QString &className,
- const TypeEntry *t)
+ const TypeEntryCPtr &t)
{
QString result;
QDebug debug(&result); // Use the debug operator for TypeEntry::Type
@@ -248,22 +265,28 @@ 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;
}
-QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntries &te)
+QString msgNamespaceNotFound(const QString &name)
+{
+ return u"namespace '"_s + name + u"' not found."_s;
+}
+
+QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntryCList &te)
{
- QString result = QLatin1String("Ambiguous types of varying types found for \"") + qualifiedName
- + QLatin1String("\": ");
+ QString result = u"Ambiguous types of varying types found for \""_s + qualifiedName
+ + u"\": "_s;
QDebug(&result) << te;
return result;
}
-QString msgAmbiguousTypesFound(const QString &qualifiedName, const TypeEntries &te)
+QString msgAmbiguousTypesFound(const QString &qualifiedName, const TypeEntryCList &te)
{
- QString result = QLatin1String("Ambiguous types found for \"") + qualifiedName
- + QLatin1String("\": ");
+ QString result = u"Ambiguous types found for \""_s + qualifiedName
+ + u"\": "_s;
QDebug(&result) << te;
return result;
}
@@ -284,9 +307,9 @@ QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n,
QString msgUnmatchedReturnType(const FunctionModelItem &functionItem,
const QString &why)
{
- return QLatin1String("unmatched return type '")
+ return u"unmatched return type '"_s
+ functionItem->type().toString()
- + QLatin1String("': ") + why;
+ + u"': "_s + why;
}
QString msgSkippingFunction(const FunctionModelItem &functionItem,
@@ -294,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.";
}
@@ -311,13 +336,12 @@ QString msgShadowingFunction(const AbstractMetaFunction *f1,
auto f2Class = f2->implementingClass();
QString result;
QTextStream str(&result);
- str << f2Class->sourceLocation() << "Shadowing: " << f1->implementingClass()->name()
- << "::" << f1->signature() << " and " << f2Class->name() << "::"
- << f2->signature();
+ str << f2Class->sourceLocation() << "Shadowing: " << f1->classQualifiedSignature()
+ << " and " << f2->classQualifiedSignature();
return result;
}
-QString msgSignalOverloaded(const AbstractMetaClass *c,
+QString msgSignalOverloaded(const AbstractMetaClassCPtr &c,
const AbstractMetaFunction *f)
{
QString result;
@@ -332,24 +356,31 @@ 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;
}
static const char msgCompilationError[] =
"This could potentially lead to compilation errors.";
-QString msgTypeNotDefined(const TypeEntry *entry)
+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;
}
-QString msgGlobalFunctionNotDefined(const FunctionTypeEntry *fte,
+QString msgGlobalFunctionNotDefined(const FunctionTypeEntryCPtr &fte,
const QString &signature,
const QStringList &candidates)
{
@@ -358,25 +389,26 @@ QString msgGlobalFunctionNotDefined(const FunctionTypeEntry *fte,
str << fte->sourceLocation() << "Global function '" << signature
<< "' is specified in typesystem, but not defined.";
if (!candidates.isEmpty())
- str << " Candidates are: " << candidates.join(u", "_qs);
+ str << " Candidates are: " << candidates.join(u", "_s);
str << ' ' << msgCompilationError;
return result;
}
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;
}
-QString msgEnumNotDefined(const EnumTypeEntry *t)
+QString msgEnumNotDefined(const EnumTypeEntryCPtr &t)
{
QString result;
QTextStream str(&result);
@@ -385,7 +417,7 @@ QString msgEnumNotDefined(const EnumTypeEntry *t)
return result;
}
-QString msgUnknownBase(const AbstractMetaClass *metaClass,
+QString msgUnknownBase(const AbstractMetaClassCPtr &metaClass,
const QString &baseClassName)
{
QString result;
@@ -395,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;
@@ -418,20 +450,18 @@ QString msgArrayModificationFailed(const FunctionModelItem &functionItem,
QString msgCannotResolveEntity(const QString &name, const QString &reason)
{
- return QLatin1String("Cannot resolve entity \"") + name
- + QLatin1String("\": ") + reason;
+ return u"Cannot resolve entity \""_s + name + u"\": "_s + reason;
}
QString msgCannotSetArrayUsage(const QString &function, int i, const QString &reason)
{
- return function + QLatin1String(": Cannot use parameter ")
- + QString::number(i + 1) + QLatin1String(" as an array: ") + reason;
+ return function + u": Cannot use parameter "_s
+ + QString::number(i + 1) + u" as an array: "_s + reason;
}
QString msgUnableToTranslateType(const QString &t, const QString &why)
{
- return QLatin1String("Unable to translate type \"")
- + t + QLatin1String("\": ") + why;
+ return u"Unable to translate type \""_s + t + u"\": "_s + why;
}
QString msgUnableToTranslateType(const TypeInfo &typeInfo,
@@ -442,24 +472,39 @@ QString msgUnableToTranslateType(const TypeInfo &typeInfo,
QString msgCannotFindTypeEntry(const QString &t)
{
- return QLatin1String("Cannot find type entry for \"") + t + QLatin1String("\".");
+ return u"Cannot find type entry for \""_s + t + u"\"."_s;
}
QString msgCannotFindTypeEntryForSmartPointer(const QString &t, const QString &smartPointerType)
{
- return QLatin1String("Cannot find type entry \"") + t
- + QLatin1String("\" for instantiation of \"") + smartPointerType + QLatin1String("\".");
+ return u"Cannot find type entry \""_s + t
+ + 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 QLatin1String("Invalid smart pointer type \"") + i.toString() + QLatin1String("\".");
+ return u"Invalid smart pointer type \""_s +i.toString() + u"\"."_s;
}
QString msgCannotFindSmartPointerInstantion(const TypeInfo &i)
{
- return QLatin1String("Cannot find instantiation of smart pointer type for \"")
- + i.toString() + QLatin1String("\".");
+ return u"Cannot find instantiation of smart pointer type for \""_s
+ + i.toString() + u"\"."_s;
}
QString msgCannotTranslateTemplateArgument(int i,
@@ -485,9 +530,9 @@ QString msgDisallowThread(const AbstractMetaFunction *f)
QString msgNamespaceToBeExtendedNotFound(const QString &namespaceName, const QString &packageName)
{
- return QLatin1String("The namespace '") + namespaceName
- + QLatin1String("' to be extended cannot be found in package ")
- + packageName + QLatin1Char('.');
+ return u"The namespace '"_s + namespaceName
+ + u"' to be extended cannot be found in package "_s
+ + packageName + u'.';
}
QString msgPropertyTypeParsingFailed(const QString &name, const QString &typeName,
@@ -502,12 +547,11 @@ QString msgPropertyTypeParsingFailed(const QString &name, const QString &typeNam
QString msgPropertyExists(const QString &className, const QString &name)
{
- return QLatin1String("class ") + className
- + QLatin1String(" already has a property \"") + name
- + QLatin1String("\" (defined by Q_PROPERTY).");
+ return u"class "_s + className + u" already has a property \""_s
+ + name + u"\" (defined by Q_PROPERTY)."_s;
}
-QString msgFunctionVisibilityModified(const AbstractMetaClass *c,
+QString msgFunctionVisibilityModified(const AbstractMetaClassCPtr &c,
const AbstractMetaFunction *f)
{
QString result;
@@ -517,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)
{
@@ -535,40 +579,73 @@ QString msgCannotFindDocumentation(const QString &fileName,
const QString &query)
{
QString result;
- QTextStream(&result) << "Cannot find documentation for " << what
- << ' ' << name << " in:\n " << QDir::toNativeSeparators(fileName)
- << "\n using query:\n " << query;
+ QTextStream str(&result);
+ str << "Cannot find documentation for " << what
+ << ' ' << name << " in:\n " << QDir::toNativeSeparators(fileName);
+ if (!query.isEmpty())
+ str << "\n using query:\n " << query;
+ return result;
+}
+
+QString msgFallbackForDocumentation(const QString &fileName,
+ const char *what, const QString &name,
+ const QString &query)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Fallback used while trying to find documentation for " << what
+ << ' ' << name << " in:\n " << QDir::toNativeSeparators(fileName);
+ if (!query.isEmpty())
+ str << "\n using query:\n " << query;
+ return result;
+}
+
+static QString functionDescription(const AbstractMetaFunction *function)
+{
+ QString result = u'"' + function->classQualifiedSignature() + u'"';
+ if (function->flags().testFlag(AbstractMetaFunction::Flag::HiddenFriend))
+ result += u" (hidden friend)"_s;
+ if (function->flags().testFlag(AbstractMetaFunction::Flag::InheritedFromTemplate))
+ result += u" (inherited from template)"_s;
return result;
}
QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
const AbstractMetaFunction *function,
const QString &query)
{
- const QString name = metaClass->name() + QLatin1String("::")
- + function->minimalSignature();
- return msgCannotFindDocumentation(fileName, "function", name, query);
+ return msgCannotFindDocumentation(fileName, "function",
+ functionDescription(function), query);
+}
+
+QString msgFallbackForDocumentation(const QString &fileName,
+ const AbstractMetaFunction *function,
+ const QString &query)
+{
+ return msgFallbackForDocumentation(fileName, "function",
+ functionDescription(function), query);
}
QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaEnum &e,
const QString &query)
{
- return msgCannotFindDocumentation(fileName, "enum",
- metaClass->name() + QLatin1String("::") + 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() + QLatin1String("::") + 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,
@@ -596,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());
}
@@ -619,80 +696,64 @@ QString msgWriteFailed(const QFile &f, qsizetype size)
QString msgCannotUseEnumAsInt(const QString &name)
{
- return QLatin1String("Cannot convert the protected scoped enum \"") + name
- + QLatin1String("\" to type int when generating wrappers for the protected hack. "
- "Compilation errors may occur when used as a function argument.");
+ return u"Cannot convert the protected scoped enum \""_s + name
+ + u"\" to type int when generating wrappers for the protected hack. "
+ "Compilation errors may occur when used as a function argument."_s;
}
-QString msgConversionTypesDiffer(const QString &varType, const QString &conversionType)
+QString msgCannotFindSmartPointerGetter(const SmartPointerTypeEntryCPtr &te)
{
- 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;
+ return u"Getter \""_s + te->getter() + u"()\" of smart pointer \""_s
+ + te->name() + u"\" not found."_s;
}
-QString msgCannotFindSmartPointer(const QString &instantiationType,
- const AbstractMetaClassCList &pointers)
+QString msgCannotFindSmartPointerMethod(const SmartPointerTypeEntryCPtr &te, const QString &m)
{
- QString result;
- QTextStream str(&result);
- str << "Unable to find smart pointer type for " << instantiationType << " (known types:";
- for (auto t : pointers) {
- auto typeEntry = t->typeEntry();
- str << ' ' << typeEntry->targetLangName() << '/' << typeEntry->qualifiedCppName();
- }
- str << ").";
- return result;
+ return u"Method \""_s + m + u"()\" of smart pointer \""_s
+ + te->name() + u"\" not found."_s;
+}
+
+QString msgMethodNotFound(const AbstractMetaClassCPtr &klass, const QString &name)
+{
+ return u"Method \""_s + name + u"\" not found in class "_s
+ + klass->name() + u'.';
}
// 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(QLatin1Char(' '));
+ str << "shiboken: Unprocessed arguments: " << remainingArgs
+ << "\nCommand line: " << argV.join(u' ');
return message;
}
QString msgInvalidVersion(const QString &package, const QString &version)
{
- return QLatin1String("Invalid version \"") + version
- + QLatin1String("\" specified for package ") + package + QLatin1Char('.');
+ return u"Invalid version \""_s + version
+ + u"\" specified for package "_s + package + u'.';
}
QString msgCyclicDependency(const QString &funcName, const QString &graphName,
- const QList<const AbstractMetaFunction *> &involvedConversions)
+ const AbstractMetaFunctionCList &cyclic,
+ const AbstractMetaFunctionCList &involvedConversions)
{
QString result;
QTextStream str(&result);
str << "Cyclic dependency found on overloaddata for \"" << funcName
- << "\" method! The graph boy saved the graph at \""
- << QDir::toNativeSeparators(graphName) << "\".";
- if (const int count = involvedConversions.size()) {
+ << "\" method! The graph boy saved the graph at \"" << QDir::toNativeSeparators(graphName)
+ << "\". Cyclic functions:";
+ for (const auto &c : cyclic)
+ str << ' ' << c->signature();
+ if (const auto count = involvedConversions.size()) {
str << " Implicit conversions (" << count << "): ";
- for (int i = 0; i < count; ++i) {
+ for (qsizetype i = 0; i < count; ++i) {
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() << ')';
}
}
@@ -701,19 +762,28 @@ QString msgCyclicDependency(const QString &funcName, const QString &graphName,
// shibokengenerator.cpp
-QString msgClassNotFound(const TypeEntry *t)
+QString msgClassNotFound(const TypeEntryCPtr &t)
{
- return QLatin1String("Could not find class \"")
+ return u"Could not find class \""_s
+ t->qualifiedCppName()
- + QLatin1String("\" in the code model. Maybe it is forward declared?");
+ + u"\" in the code model. Maybe it is forward declared?"_s;
}
-QString msgUnknownOperator(const AbstractMetaFunction* func)
+QString msgEnclosingClassNotFound(const TypeEntryCPtr &t)
{
- QString result = QLatin1String("Unknown operator: \"") + func->originalName()
- + QLatin1Char('"');
- if (const AbstractMetaClass *c = func->implementingClass())
- result += QLatin1String(" in class: ") + c->name();
+ QString result;
+ QTextStream str(&result);
+ str << "Warning: Enclosing class \"" << t->parent()->name()
+ << "\" of class \"" << t->name() << "\" not found.";
+ return result;
+}
+
+QString msgUnknownOperator(const AbstractMetaFunction *func)
+{
+ QString result = u"Unknown operator: \""_s + func->originalName()
+ + u'"';
+ if (const auto c = func->implementingClass())
+ result += u" in class: "_s + c->name();
return result;
}
@@ -723,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;
@@ -741,8 +811,7 @@ QString msgCannotFindType(const QString &type, const QString &variable,
QString msgCannotBuildMetaType(const QString &s)
{
- return QLatin1String("Unable to build meta type for \"")
- + s + QLatin1String("\": ");
+ return u"Unable to build meta type for \""_s + s + u"\": "_s;
}
QString msgCouldNotFindMinimalConstructor(const QString &where, const QString &type, const QString &why)
@@ -766,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;
}
@@ -788,36 +857,36 @@ QString msgRejectReason(const TypeRejection &r, const QString &needle)
QString msgCannotFindNamespaceToExtend(const QString &name,
const QString &extendsPackage)
{
- return QLatin1String("Cannot find namespace ") + name
- + QLatin1String(" in package ") + extendsPackage;
+ return u"Cannot find namespace "_s + name
+ + u" in package "_s + extendsPackage;
}
QString msgExtendingNamespaceRequiresPattern(const QString &name)
{
- return QLatin1String("Namespace ") + name
- + QLatin1String(" requires a file pattern since it extends another namespace.");
+ return u"Namespace "_s + name
+ + u" requires a file pattern since it extends another namespace."_s;
}
QString msgInvalidRegularExpression(const QString &pattern, const QString &why)
{
- return QLatin1String("Invalid pattern \"") + pattern + QLatin1String("\": ") + why;
+ return u"Invalid pattern \""_s + pattern + u"\": "_s + why;
}
QString msgNoRootTypeSystemEntry()
{
- return QLatin1String("Type system entry appears out of order, there does not seem to be a root type system element.");
+ return u"Type system entry appears out of order, there does not seem to be a root type system element."_s;
}
QString msgIncorrectlyNestedName(const QString &name)
{
- return QLatin1String("Nesting types by specifying '::' is no longer supported (")
- + name + QLatin1String(").");
+ return u"Nesting types by specifying '::' is no longer supported ("_s
+ + name + u")."_s;
}
QString msgCannotFindView(const QString &viewedName, const QString &name)
{
- return QLatin1String("Unable to find viewed type ") + viewedName
- + QLatin1String(" for ") + name;
+ return u"Unable to find viewed type "_s + viewedName
+ + u" for "_s + name;
}
QString msgCannotFindSnippet(const QString &file, const QString &snippetLabel)
@@ -829,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)
@@ -857,23 +941,64 @@ QString msgUnknownTypeInArgumentTypeReplacement(const QString &typeReplaced,
QString msgDuplicateBuiltInTypeEntry(const QString &name)
{
- return u"A type entry duplicating the built-in type \""_qs
- + name + u"\" was found. It is ignored."_qs;
+ return u"A type entry duplicating the built-in type \""_s
+ + name + u"\" was found. It is ignored."_s;
}
QString msgDuplicateTypeEntry(const QString &name)
{
- return u"Duplicate type entry: '"_qs + name + u"'."_qs;
+ return u"Duplicate type entry: '"_s + name + u"'."_s;
}
QString msgInvalidTargetLanguageApiName(const QString &name)
{
- return u"Invalid target language API name \""_qs
- + name + u"\"."_qs;
+ return u"Invalid target language API name \""_s
+ + name + u"\"."_s;
+}
+
+QString msgUnknownCheckFunction(const TypeEntryCPtr &t)
+{
+ return u"Unknown check function for type: '"_s
+ + t->qualifiedCppName() + u"'."_s;
+}
+
+QString msgArgumentClassNotFound(const AbstractMetaFunctionCPtr &func,
+ const TypeEntryCPtr &t)
+{
+ QString result;
+ QTextStream(&result) << "Internal Error: Class \"" << t->qualifiedCppName()
+ << "\" for \"" << func->classQualifiedSignature() << "\" not found!";
+ return result;
+}
+
+QString msgMissingCustomConversion(const TypeEntryCPtr &t)
+{
+ QString result;
+ QTextStream(&result) << "Entry \"" << t->qualifiedCppName()
+ << "\" is missing a custom conversion.";
+ return result;
+}
+
+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;
}
-QString msgUnknownCheckFunction(const TypeEntry *t)
+QString msgCannotFindImage(const QString &href, const QString &context,
+ const QString &candidate)
{
- return u"Unknown check function for type: '"_qs
- + t->qualifiedCppName() + u"'."_qs;
+ return "Cannot resolve image "_L1 + href + " for "_L1 + context
+ + " (tried "_L1 + QDir::toNativeSeparators(candidate) + ")."_L1;
}
diff --git a/sources/shiboken6/ApiExtractor/messages.h b/sources/shiboken6/ApiExtractor/messages.h
index 813818304..5216b26a7 100644
--- a/sources/shiboken6/ApiExtractor/messages.h
+++ b/sources/shiboken6/ApiExtractor/messages.h
@@ -1,44 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef MESSAGES_H
#define MESSAGES_H
#include "abstractmetalang_typedefs.h"
#include "parser/codemodel_fwd.h"
+#include "modifications_typedefs.h"
#include "typesystem_typedefs.h"
-#include <QtCore/QMap>
#include <QtCore/QString>
-#include <QtCore/QList>
class EnumTypeEntry;
class FunctionTypeEntry;
+class SmartPointerTypeEntry;
class TypeEntry;
class TypeInfo;
struct TypeRejection;
@@ -50,17 +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 msgNoFunctionForModification(const AbstractMetaClass *klass,
+QString msgArgumentIndexOutOfRange(const AbstractMetaFunction *func, int index);
+
+QString msgNoFunctionForModification(const AbstractMetaClassCPtr &klass,
const QString &signature,
const QString &originalSignature,
const QStringList &possibleSignatures,
@@ -70,12 +47,15 @@ QString msgTypeModificationFailed(const QString &type, int n,
const AbstractMetaFunction *func,
const QString &why);
+QString msgInvalidArgumentModification(const AbstractMetaFunctionCPtr &func,
+ int argIndex);
+
QString msgArgumentOutOfRange(int number, int minValue, int maxValue);
QString msgArgumentRemovalFailed(const AbstractMetaFunction *func, int n,
const QString &why);
-QString msgClassOfEnumNotFound(const EnumTypeEntry *entry);
+QString msgClassOfEnumNotFound(const EnumTypeEntryCPtr &entry);
QString msgNoEnumTypeEntry(const EnumModelItem &enumItem,
const QString &className);
@@ -83,13 +63,15 @@ QString msgNoEnumTypeEntry(const EnumModelItem &enumItem,
QString msgNoEnumTypeConflict(const EnumModelItem &enumItem,
const QString &className,
- const TypeEntry *t);
+ const TypeEntryCPtr &t);
QString msgNamespaceNoTypeEntry(const NamespaceModelItem &item,
const QString &fullName);
-QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntries &te);
-QString msgAmbiguousTypesFound(const QString &qualifiedName, const TypeEntries &te);
+QString msgNamespaceNotFound(const QString &name);
+
+QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntryCList &te);
+QString msgAmbiguousTypesFound(const QString &qualifiedName, const TypeEntryCList &te);
QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n,
const QString &why);
@@ -100,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,
@@ -109,22 +91,23 @@ QString msgSkippingFunction(const FunctionModelItem &functionItem,
QString msgSkippingField(const VariableModelItem &field, const QString &className,
const QString &type);
-QString msgTypeNotDefined(const TypeEntry *entry);
+QString msgTypeNotDefined(const TypeEntryCPtr &entry);
-QString msgGlobalFunctionNotDefined(const FunctionTypeEntry *fte,
+QString msgGlobalFunctionNotDefined(const FunctionTypeEntryCPtr &fte,
const QString &signature,
const QStringList &candidates);
QString msgStrippingArgument(const FunctionModelItem &f, int i,
const QString &originalSignature,
- const ArgumentModelItem &arg);
+ const ArgumentModelItem &arg,
+ const QString &reason);
-QString msgEnumNotDefined(const EnumTypeEntry *t);
+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,
@@ -143,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);
@@ -158,29 +145,36 @@ 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);
QString msgCannotFindDocumentation(const QString &fileName,
const char *what, const QString &name,
- const QString &query);
+ const QString &query = {});
+
+QString msgFallbackForDocumentation(const QString &fileName,
+ const char *what, const QString &name,
+ const QString &query = {});
QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
const AbstractMetaFunction *function,
- const QString &query);
+ const QString &query = {});
+
+QString msgFallbackForDocumentation(const QString &fileName,
+ const AbstractMetaFunction *function,
+ const QString &query = {});
QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaEnum &e,
- const QString &query);
+ const QString &query = {});
QString msgCannotFindDocumentation(const QString &fileName,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaField &f,
const QString &query);
@@ -195,12 +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 msgCannotFindSmartPointer(const QString &instantiationType,
- const AbstractMetaClassCList &pointers);
+QString msgCannotFindSmartPointerMethod(const SmartPointerTypeEntryCPtr &te, const QString &m);
-QString msgLeftOverArguments(const QVariantMap &remainingArgs);
+QString msgMethodNotFound(const AbstractMetaClassCPtr &klass, const QString &name);
+
+QString msgLeftOverArguments(const QString &remainingArgs, const QStringList &argV);
QString msgInvalidVersion(const QString &package, const QString &version);
@@ -218,13 +213,18 @@ 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 QList<const AbstractMetaFunction *> &involvedConversions);
+ const AbstractMetaFunctionCList &cyclic,
+ const AbstractMetaFunctionCList &involvedConversions);
+
+QString msgClassNotFound(const TypeEntryCPtr &t);
-QString msgClassNotFound(const TypeEntry *t);
+QString msgEnclosingClassNotFound(const TypeEntryCPtr &t);
-QString msgUnknownOperator(const AbstractMetaFunction* func);
+QString msgUnknownOperator(const AbstractMetaFunction *func);
QString msgWrongIndex(const char *varName, const QString &capture,
const AbstractMetaFunction *func);
@@ -248,6 +248,20 @@ QString msgDuplicateBuiltInTypeEntry(const QString &name);
QString msgDuplicateTypeEntry(const QString &name);
QString msgInvalidTargetLanguageApiName(const QString &name);
-QString msgUnknownCheckFunction(const TypeEntry *t);
+QString msgUnknownCheckFunction(const TypeEntryCPtr &t);
+
+QString msgArgumentClassNotFound(const AbstractMetaFunctionCPtr &func,
+ const TypeEntryCPtr &t);
+
+QString msgMissingCustomConversion(const TypeEntryCPtr &t);
+
+QString msgUnknownArrayPointerConversion(const QString &s);
+
+QString msgMissingProjectFileMarker(const QString &name, const QByteArray &startMarker);
+
+QString msgInvalidLanguageLevel(const QString &l);
+
+QString msgCannotFindImage(const QString &href, const QString &context,
+ const QString &candidate);
#endif // MESSAGES_H
diff --git a/sources/shiboken6/ApiExtractor/modifications.cpp b/sources/shiboken6/ApiExtractor/modifications.cpp
index 92b445791..d876e8035 100644
--- a/sources/shiboken6/ApiExtractor/modifications.cpp
+++ b/sources/shiboken6/ApiExtractor/modifications.cpp
@@ -1,102 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "modifications.h"
-#include "modifications_p.h"
-#include "exception.h"
-#include "typedatabase.h"
-#include "typeparser.h"
-#include "typesystem.h"
+#include "codesnip.h"
+
+#include "qtcompat.h"
#include <QtCore/QDebug>
+#include <QtCore/QRegularExpression>
#include <algorithm>
#include <limits>
-static inline QString callOperator() { return QStringLiteral("operator()"); }
-
-QString TemplateInstance::expandCode() const
-{
- TemplateEntry *templateEntry = TypeDatabase::instance()->findTemplate(m_name);
- if (!templateEntry) {
- const QString m = QLatin1String("<insert-template> referring to non-existing template '")
- + m_name + QLatin1String("'.");
- throw Exception(m);
- }
-
- QString code = templateEntry->code();
- for (auto it = replaceRules.cbegin(), end = replaceRules.cend(); it != end; ++it)
- code.replace(it.key(), it.value());
- while (!code.isEmpty() && code.at(code.size() - 1).isSpace())
- code.chop(1);
- QString result = QLatin1String("// TEMPLATE - ") + m_name + QLatin1String(" - START");
- if (!code.startsWith(QLatin1Char('\n')))
- result += QLatin1Char('\n');
- result += code;
- result += QLatin1String("\n// TEMPLATE - ") + m_name + QLatin1String(" - END\n");
- return result;
-}
-
-// ---------------------- CodeSnipFragment
-QString CodeSnipFragment::code() const
-{
- return m_instance ? m_instance->expandCode() : m_code;
-}
-
-// ---------------------- CodeSnipAbstract
-QString CodeSnipAbstract::code() const
-{
- QString res;
- for (const CodeSnipFragment &codeFrag : codeList)
- res.append(codeFrag.code());
-
- return res;
-}
-
-void CodeSnipAbstract::addCode(const QString &code)
-{
- codeList.append(CodeSnipFragment(fixSpaces(code)));
-}
-
-QRegularExpression CodeSnipAbstract::placeHolderRegex(int index)
-{
- return QRegularExpression(QLatin1Char('%') + QString::number(index) + QStringLiteral("\\b"));
-}
-
-// ---------------------- Modification
-QString FunctionModification::accessModifierString() const
-{
- if (isPrivate()) return QLatin1String("private");
- if (isProtected()) return QLatin1String("protected");
- if (isPublic()) return QLatin1String("public");
- if (isFriendly()) return QLatin1String("friendly");
- return QString();
-}
+using namespace Qt::StringLiterals;
// ---------------------- FieldModification
@@ -118,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
@@ -204,184 +120,6 @@ void FieldModification::setSnakeCase(TypeSystem::SnakeCase s)
d->snakeCase = s;
}
-// 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;
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug d, const Argument &a)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "Argument(type=\"" << a.type << '"';
- if (!a.name.isEmpty())
- d << ", name=\"" << a.name << '"';
- if (!a.defaultValue.isEmpty())
- d << ", defaultValue=\"" << a.defaultValue << '"';
- d << ')';
- return d;
-}
-#endif // QT_NO_DEBUG_STREAM
-
-// Helper for finding the end of a function parameter, observing
-// nested template parameters or lists.
-static int parameterTokenEnd(int startPos, QStringView paramString)
-{
- const int end = paramString.size();
- int nestingLevel = 0;
- for (int p = startPos; p < end; ++p) {
- switch (paramString.at(p).toLatin1()) {
- case ',':
- if (nestingLevel == 0)
- return p;
- break;
- case '<': // templates
- case '{': // initializer lists of default values
- case '(': // initialization, function pointers
- case '[': // array dimensions
- ++nestingLevel;
- break;
- case '>':
- case '}':
- case ')':
- case ']':
- --nestingLevel;
- break;
- }
- }
- return end;
-}
-
-// Split a function parameter list into string tokens containing one
-// parameters (including default value, etc).
-static QList<QStringView> splitParameterTokens(QStringView paramString)
-{
- QList<QStringView> result;
- int startPos = 0;
- for ( ; startPos < paramString.size(); ) {
- int end = parameterTokenEnd(startPos, paramString);
- result.append(paramString.mid(startPos, end - startPos).trimmed());
- startPos = end + 1;
- }
- return result;
-}
-
-// Split a function parameter list
-Arguments splitParameters(QStringView paramString, QString *errorMessage)
-{
- Arguments result;
- const QList<QStringView> tokens = splitParameterTokens(paramString);
-
- for (const auto &t : tokens) {
- Argument argument;
- // Check defaultValue, "int @b@=5"
- const int equalPos = t.lastIndexOf(QLatin1Char('='));
- if (equalPos != -1) {
- const int defaultValuePos = equalPos + 1;
- argument.defaultValue =
- t.mid(defaultValuePos, t.size() - defaultValuePos).trimmed().toString();
- }
- QString typeString = (equalPos != -1 ? t.left(equalPos) : t).trimmed().toString();
- // Check @name@
- const int atPos = typeString.indexOf(QLatin1Char('@'));
- if (atPos != -1) {
- const int namePos = atPos + 1;
- const int nameEndPos = typeString.indexOf(QLatin1Char('@'), namePos);
- if (nameEndPos == -1) {
- if (errorMessage != nullptr) {
- *errorMessage = QLatin1String("Mismatched @ in \"")
- + paramString.toString() + QLatin1Char('"');
- }
- return {};
- }
- argument.name = typeString.mid(namePos, nameEndPos - namePos).trimmed();
- typeString.remove(atPos, nameEndPos - atPos + 1);
- }
- argument.type = typeString.trimmed();
- result.append(argument);
- }
-
- return result;
-}
-
-} // namespace AddedFunctionParser
-
-AddedFunction::AddedFunction(const QString &name, const QList<Argument> &arguments,
- const TypeInfo &returnType) :
- m_name(name),
- m_arguments(arguments),
- m_returnType(returnType)
-{
-}
-
-AddedFunction::AddedFunctionPtr
- AddedFunction::createAddedFunction(const QString &signatureIn, const QString &returnTypeIn,
- QString *errorMessage)
-
-{
- errorMessage->clear();
-
- QList<Argument> arguments;
- const TypeInfo returnType = returnTypeIn.isEmpty()
- ? TypeInfo::voidType()
- : TypeParser::parse(returnTypeIn, errorMessage);
- if (!errorMessage->isEmpty())
- return {};
-
- QStringView signature = QStringView{signatureIn}.trimmed();
-
- // Skip past "operator()(...)"
- const int parenSearchStartPos = signature.startsWith(callOperator())
- ? callOperator().size() : 0;
- const int openParenPos = signature.indexOf(QLatin1Char('('), 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(QLatin1Char(')'));
- if (closingParenPos < 0) {
- *errorMessage = QLatin1String("Missing closing parenthesis");
- return {};
- }
-
- // Check for "foo() const"
- bool isConst = false;
- const int signatureLength = signature.length();
- const int qualifierLength = signatureLength - closingParenPos - 1;
- if (qualifierLength >= 5
- && signature.right(qualifierLength).contains(QLatin1String("const"))) {
- isConst = true;
- }
-
- const auto paramString = signature.mid(openParenPos + 1, closingParenPos - openParenPos - 1);
- const auto params = AddedFunctionParser::splitParameters(paramString, errorMessage);
- if (params.isEmpty() && !errorMessage->isEmpty())
- return {};
- for (const auto &p : params) {
- TypeInfo type = p.type == QLatin1String("...")
- ? TypeInfo::varArgsType() : TypeParser::parse(p.type, errorMessage);
- if (!errorMessage->isEmpty()) {
- errorMessage->prepend(u"Unable to parse added function "_qs + signatureIn
- + u": "_qs);
- return {};
- }
- arguments.append({type, p.name, p.defaultValue});
- }
-
- AddedFunctionPtr result(new AddedFunction(name, arguments, returnType));
- result->setConstant(isConst);
- return result;
-}
-
// Remove the parameter names enclosed in '@' from an added function signature
// so that it matches the C++ type signature.
static QString removeParameterNames(QString signature)
@@ -428,17 +166,29 @@ QDebug operator<<(QDebug d, const CodeSnip &s)
QDebugStateSaver saver(d);
d.noquote();
d.nospace();
- d << "CodeSnip(language=" << s.language << ", position=" << s.position << ", \"";
- for (const auto &f : s.codeList) {
- const QString &code = f.code();
- const auto lines = QStringView{code}.split(QLatin1Char('\n'));
- for (int i = 0, size = lines.size(); i < size; ++i) {
- if (i)
- d << "\\n";
- d << lines.at(i).trimmed();
+ const auto size = s.codeList.size();
+ d << "CodeSnip(language=" << s.language << ", position=" << s.position
+ << ", fragments[" << size << "]=";
+ for (qsizetype i = 0; i < size; ++i) {
+ const auto &f = s.codeList.at(i);
+ if (i)
+ d << ", ";
+ d << '#' << i << ' ';
+ if (!f.instance()) {
+ d << '"';
+ const QString &code = f.code();
+ const auto lines = QStringView{code}.split(u'\n');
+ for (qsizetype i = 0, size = lines.size(); i < size; ++i) {
+ if (i)
+ d << "\\n";
+ d << lines.at(i).trimmed();
+ }
+ d << '"';
+ } else {
+ d << "template=\"" << f.instance()->name() << '"';
}
}
- d << "\")";
+ d << ')';
return d;
}
@@ -477,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
@@ -659,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;
@@ -672,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
@@ -689,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())
@@ -793,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;
@@ -815,21 +551,26 @@ void FunctionModification::setAllowThread(FunctionModification::AllowThread allo
d->m_allowThread = allow;
}
-bool FunctionModification::matches(const QString &functionSignature) const
+bool FunctionModification::matches(const QStringList &functionSignatures) const
{
- return d->m_signature.isEmpty()
- ? d->m_signaturePattern.match(functionSignature).hasMatch()
- : d->m_signature == functionSignature;
+ if (!d->m_signature.isEmpty())
+ return functionSignatures.contains(d->m_signature);
+
+ for (const auto &s : functionSignatures) {
+ if (d->m_signaturePattern.match(s).hasMatch())
+ return true;
+ }
+ return false;
}
bool FunctionModification::setSignature(const QString &s, QString *errorMessage)
{
- if (s.startsWith(QLatin1Char('^'))) {
+ if (s.startsWith(u'^')) {
d->m_signaturePattern.setPattern(s);
if (!d->m_signaturePattern.isValid()) {
if (errorMessage) {
- *errorMessage = QLatin1String("Invalid signature pattern: \"")
- + s + QLatin1String("\": ") + d->m_signaturePattern.errorString();
+ *errorMessage = u"Invalid signature pattern: \""_s
+ + s + u"\": "_s + d->m_signaturePattern.errorString();
}
return false;
}
@@ -911,6 +652,9 @@ QDebug operator<<(QDebug d, const ArgumentModification &a)
d << ", native ownership=" << a.nativeOwnership();
if (!a.renamedToName().isEmpty())
d << ", renamed_to=\"" << a.renamedToName() << '"';
+ const auto &rules = a.conversionRules();
+ if (!rules.isEmpty())
+ d << ", conversionRules[" << rules.size() << "]=" << rules;
d << ", owner=" << a.owner() << ')';
return d;
}
@@ -925,37 +669,4 @@ QDebug operator<<(QDebug d, const FunctionModification &fm)
d << ')';
return d;
}
-
-QDebug operator<<(QDebug d, const AddedFunction::Argument &a)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "Argument(";
- d << a.typeInfo;
- if (!a.name.isEmpty())
- d << ' ' << a.name;
- if (!a.defaultValue.isEmpty())
- d << " = " << a.defaultValue;
- d << ')';
- return d;
-}
-
-QDebug operator<<(QDebug d, const AddedFunction &af)
-{
- QDebugStateSaver saver(d);
- d.noquote();
- d.nospace();
- d << "AddedFunction(";
- if (af.access() == AddedFunction::Protected)
- d << "protected";
- if (af.isStatic())
- d << " static";
- d << af.returnType() << ' ' << af.name() << '(' << af.arguments() << ')';
- if (af.isConstant())
- d << " const";
- if (af.isDeclaration())
- d << " [declaration]";
- return d;
-}
#endif // !QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken6/ApiExtractor/modifications.h b/sources/shiboken6/ApiExtractor/modifications.h
index 917dd7459..27a38f1aa 100644
--- a/sources/shiboken6/ApiExtractor/modifications.h
+++ b/sources/shiboken6/ApiExtractor/modifications.h
@@ -1,46 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef MODIFICATIONS_H
#define MODIFICATIONS_H
#include "typesystem_enums.h"
-#include "typesystem_typedefs.h"
-#include "codesniphelpers.h"
-#include "parser/typeinfo.h"
+#include "modifications_typedefs.h"
#include <QtCore/QList>
-#include <QtCore/QRegularExpression>
#include <QtCore/QSharedDataPointer>
-#include <QtCore/QSharedPointer>
#include <QtCore/QString>
class ArgumentModificationData;
+class CodeSnip;
class FunctionModificationData;
class ModificationData;
class FieldModificationData;
@@ -49,28 +21,6 @@ QT_BEGIN_NAMESPACE
class QDebug;
QT_END_NAMESPACE
-class TemplateInstance
-{
-public:
- explicit TemplateInstance(const QString &name) : m_name(name) {}
-
- void addReplaceRule(const QString &name, const QString &value)
- {
- replaceRules[name] = value;
- }
-
- QString expandCode() const;
-
- QString name() const
- {
- return m_name;
- }
-
-private:
- const QString m_name;
- QHash<QString, QString> replaceRules;
-};
-
struct ReferenceCount
{
enum Action { // 0x01 - 0xff
@@ -107,73 +57,6 @@ struct ArgumentOwner
int index = InvalidIndex;
};
-using TemplateInstancePtr = QSharedPointer<TemplateInstance>;
-
-class CodeSnipFragment
-{
-public:
- CodeSnipFragment() = default;
- explicit CodeSnipFragment(const QString &code) : m_code(code) {}
- explicit CodeSnipFragment(const TemplateInstancePtr &instance) : m_instance(instance) {}
-
- QString code() const;
-
-private:
- QString m_code;
- QSharedPointer<TemplateInstance> m_instance;
-};
-
-class CodeSnipAbstract : public CodeSnipHelpers
-{
-public:
- QString code() const;
-
- void addCode(const QString &code);
- void addCode(QStringView code) { addCode(code.toString()); }
-
- void addTemplateInstance(const TemplateInstancePtr &ti)
- {
- codeList.append(CodeSnipFragment(ti));
- }
-
- QList<CodeSnipFragment> codeList;
-
- static QRegularExpression placeHolderRegex(int index);
-};
-
-class CustomFunction : public CodeSnipAbstract
-{
-public:
- explicit CustomFunction(const QString &n = QString()) : name(n) {}
-
- QString name;
- QString paramName;
-};
-
-class TemplateEntry : public CodeSnipAbstract
-{
-public:
- explicit TemplateEntry(const QString &name) : m_name(name) {}
-
- QString name() const
- {
- return m_name;
- }
-
-private:
- QString m_name;
-};
-
-class CodeSnip : public CodeSnipAbstract
-{
-public:
- CodeSnip() = default;
- explicit CodeSnip(TypeSystem::Language lang) : language(lang) {}
-
- TypeSystem::Language language = TypeSystem::TargetLangCode;
- TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny;
-};
-
class ArgumentModification
{
public:
@@ -181,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
@@ -209,8 +92,8 @@ public:
void setNativeOwnership(TypeSystem::Ownership o);
// Different conversion rules
- const CodeSnipList &conversionRules() const;
- CodeSnipList &conversionRules();
+ const QList<CodeSnip> &conversionRules() const;
+ QList<CodeSnip> &conversionRules();
// QObject parent(owner) of this argument
ArgumentOwner owner() const;
@@ -251,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,
@@ -272,7 +154,8 @@ public:
CodeInjection = 0x1000,
Rename = 0x2000,
Deprecated = 0x4000,
- ReplaceExpression = 0x8000
+ Undeprecated = 0x8000,
+ ReplaceExpression = 0x10000
};
Q_DECLARE_FLAGS(Modifiers, ModifierFlag);
@@ -307,10 +190,6 @@ public:
{
return accessModifier() == Public;
}
- bool isFriendly() const
- {
- return accessModifier() == Friendly;
- }
bool isFinal() const
{
return modifiers().testFlag(Final);
@@ -319,7 +198,6 @@ public:
{
return modifiers().testFlag(NonFinal);
}
- QString accessModifierString() const;
bool isDeprecated() const
{
@@ -339,13 +217,11 @@ public:
{
return modifiers().testFlag(CodeInjection);
}
- void setIsThread(bool flag);
- bool isThread() const;
AllowThread allowThread() const;
void setAllowThread(AllowThread allow);
- bool matches(const QString &functionSignature) const;
+ bool matches(const QStringList &functionSignatures) const;
bool setSignature(const QString &s, QString *errorMessage = nullptr);
QString signature() const;
@@ -359,10 +235,10 @@ public:
int overloadNumber() const;
void setOverloadNumber(int overloadNumber);
- const CodeSnipList &snips() const;
- CodeSnipList &snips();
+ const QList<CodeSnip> &snips() const;
+ QList<CodeSnip> &snips();
void appendSnip(const CodeSnip &snip);
- void setSnips(const CodeSnipList &snips);
+ void setSnips(const QList<CodeSnip> &snips);
const QList<ArgumentModification> &argument_mods() const;
QList<ArgumentModification> &argument_mods();
@@ -383,6 +259,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(FunctionModification::Modifiers)
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const ReferenceCount &);
+QDebug operator<<(QDebug d, const CodeSnip &s);
QDebug operator<<(QDebug d, const ArgumentOwner &a);
QDebug operator<<(QDebug d, const ArgumentModification &a);
QDebug operator<<(QDebug d, const FunctionModification &fm);
@@ -394,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;
@@ -424,121 +301,6 @@ private:
QSharedDataPointer<FieldModificationData> d;
};
-/**
-* \internal
-* Struct used to store information about functions added by the typesystem.
-* This info will be used later to create a fake AbstractMetaFunction which
-* will be inserted into the right AbstractMetaClass.
-*/
-struct AddedFunction
-{
- using AddedFunctionPtr = QSharedPointer<AddedFunction>;
-
- /// Function access types.
- enum Access {
- Protected = 0x1,
- Public = 0x2
- };
-
- struct Argument
- {
- TypeInfo typeInfo;
- QString name;
- QString defaultValue;
- };
-
- /// Creates a new AddedFunction with a signature and a return type.
- explicit AddedFunction(const QString &name, const QList<Argument> &arguments,
- const TypeInfo &returnType);
-
- static AddedFunctionPtr createAddedFunction(const QString &signatureIn,
- const QString &returnTypeIn,
- QString *errorMessage);
-
- AddedFunction() = default;
-
- /// Returns the function name.
- QString name() const
- {
- return m_name;
- }
-
- /// Set the function access type.
- void setAccess(Access access)
- {
- m_access = access;
- }
-
- /// Returns the function access type.
- Access access() const
- {
- return m_access;
- }
-
- /// Returns the function return type.
- TypeInfo returnType() const
- {
- return m_returnType;
- }
-
- /// Returns a list of argument type infos.
- const QList<Argument> &arguments() const
- {
- return m_arguments;
- }
-
- /// Returns true if this is a constant method.
- bool isConstant() const
- {
- return m_isConst;
- }
- void setConstant(bool c) { m_isConst = c; };
-
- /// Set this method static.
- void setStatic(bool value)
- {
- m_isStatic = value;
- }
-
- /// Set this method as a classmethod.
- void setClassMethod(bool value)
- {
- m_isClassMethod = value;
- }
-
- /// Returns true if this is a static method.
- bool isStatic() const
- {
- return m_isStatic;
- }
-
- /// Returns true if this is a class method.
- bool isClassMethod() const
- {
- return m_isClassMethod;
- }
-
- bool isDeclaration() const { return m_isDeclaration; } // <declare-function>
- void setDeclaration(bool value) { m_isDeclaration = value; }
-
- FunctionModificationList modifications;
-
-private:
- QString m_name;
- QList<Argument> m_arguments;
- TypeInfo m_returnType;
- Access m_access = Public;
- bool m_isConst = false;
- bool m_isClassMethod = false;
- bool m_isStatic = false;
- bool m_isDeclaration = false;
-};
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug d, const AddedFunction::Argument &a);
-QDebug operator<<(QDebug d, const AddedFunction &af);
-#endif
-
class DocModification
{
public:
diff --git a/sources/shiboken6/ApiExtractor/modifications_p.h b/sources/shiboken6/ApiExtractor/modifications_p.h
deleted file mode 100644
index c8f18308e..000000000
--- a/sources/shiboken6/ApiExtractor/modifications_p.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef MODIFICATIONS_P_H
-#define MODIFICATIONS_P_H
-
-#include <QtCore/QList>
-#include <QtCore/QString>
-#include <QtCore/QStringView>
-
-QT_BEGIN_NAMESPACE
-class QDebug;
-QT_END_NAMESPACE
-
-// Helpers to split a parameter list of <add-function>, <declare-function>
-// in a separate header for testing purposes
-
-namespace AddedFunctionParser {
-
-struct Argument
-{
- bool equals(const Argument &rhs) const;
-
- QString type;
- QString name;
- QString defaultValue;
-};
-
-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
-
-Arguments splitParameters(QStringView paramString, QString *errorMessage = nullptr);
-
-} // namespace AddedFunctionParser
-
-#endif // MODIFICATIONS_P_H
diff --git a/sources/shiboken6/ApiExtractor/modifications_typedefs.h b/sources/shiboken6/ApiExtractor/modifications_typedefs.h
new file mode 100644
index 000000000..3b86c55d3
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/modifications_typedefs.h
@@ -0,0 +1,25 @@
+// 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 MODIFICATIONS_TYPEDEFS_H
+#define MODIFICATIONS_TYPEDEFS_H
+
+#include <QtCore/QList>
+
+#include <memory>
+
+class CodeSnip;
+class DocModification;
+
+struct AddedFunction;
+class FieldModification;
+class FunctionModification;
+
+using AddedFunctionPtr = std::shared_ptr<AddedFunction>;
+using AddedFunctionList = QList<AddedFunctionPtr>;
+using CodeSnipList = QList<CodeSnip>;
+using DocModificationList = QList<DocModification>;
+using FieldModificationList = QList<FieldModification>;
+using FunctionModificationList = QList<FunctionModification>;
+
+#endif // MODIFICATIONS_TYPEDEFS_H
diff --git a/sources/shiboken6/ApiExtractor/namespacetypeentry.h b/sources/shiboken6/ApiExtractor/namespacetypeentry.h
new file mode 100644
index 000000000..6ffd38430
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/namespacetypeentry.h
@@ -0,0 +1,51 @@
+// 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 NAMESPACETYPEENTRY_H
+#define NAMESPACETYPEENTRY_H
+
+#include "complextypeentry.h"
+
+class NamespaceTypeEntryPrivate;
+
+class NamespaceTypeEntry : public ComplexTypeEntry
+{
+public:
+ explicit NamespaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ TypeEntry *clone() const override;
+
+ NamespaceTypeEntryCPtr extends() const;
+ void setExtends(const NamespaceTypeEntryCPtr &e);
+
+ const QRegularExpression &filePattern() const; // restrict files
+ void setFilePattern(const QRegularExpression &r);
+
+ bool hasPattern() const;
+
+ bool matchesFile(const QString &needle) const;
+
+ bool isVisible() const;
+ void setVisibility(TypeSystem::Visibility v);
+
+ // C++ 11 inline namespace, from code model
+ bool isInlineNamespace() const;
+ void setInlineNamespace(bool i);
+
+ static bool isVisibleScope(const TypeEntryCPtr &e);
+ static bool isVisibleScope(const TypeEntry *e);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+ // Whether to generate "using namespace" into wrapper
+ bool generateUsing() const;
+ void setGenerateUsing(bool generateUsing);
+
+protected:
+ explicit NamespaceTypeEntry(NamespaceTypeEntryPrivate *d);
+};
+
+#endif // NAMESPACETYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/objecttypeentry.h b/sources/shiboken6/ApiExtractor/objecttypeentry.h
new file mode 100644
index 000000000..da91e8ff4
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/objecttypeentry.h
@@ -0,0 +1,21 @@
+// 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 OBJECTTYPEENTRY_H
+#define OBJECTTYPEENTRY_H
+
+#include "complextypeentry.h"
+
+class ObjectTypeEntry : public ComplexTypeEntry
+{
+public:
+ explicit ObjectTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ TypeEntry *clone() const override;
+
+protected:
+ explicit ObjectTypeEntry(ComplexTypeEntryPrivate *d);
+};
+
+#endif // OBJECTTYPEENTRY_H
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 1ea9f45f6..259a706dc 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel.cpp
@@ -1,61 +1,29 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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>
-// 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;
-};
+using namespace Qt::StringLiterals;
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{};
}
// ---------------------------------------------------------------------------
@@ -76,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);
}
@@ -94,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))
@@ -106,7 +74,7 @@ static CodeModelItem findRecursion(const ScopeModelItem &scope,
}
}
}
- return CodeModelItem();
+ return {};
}
CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, const ScopeModelItem &scope)
@@ -143,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';
@@ -256,27 +224,27 @@ SourceLocation _CodeModelItem::sourceLocation() const
return SourceLocation(m_fileName, m_startLine);
}
-#ifndef QT_NO_DEBUG_STREAM
-template <class It>
-void formatSequence(QDebug &d, It i1, It i2, const char *separator=", ")
+const _ScopeModelItem *_CodeModelItem::enclosingScope() const
{
- for (It i = i1; i != i2; ++i) {
- if (i != i1)
- d << separator;
- d << *i;
- }
+ return m_enclosingScope;
}
-template <class It>
-static void formatPtrSequence(QDebug &d, It i1, It i2, const char *separator=", ")
+void _CodeModelItem::setEnclosingScope(const _ScopeModelItem *s)
+{
+ m_enclosingScope = s;
+}
+
+_ScopeModelItem::_ScopeModelItem(CodeModel *model, int kind)
+ : _CodeModelItem(model, kind)
{
- for (It i = i1; i != i2; ++i) {
- if (i != i1)
- d << separator;
- d << i->data();
- }
}
+_ScopeModelItem::_ScopeModelItem(CodeModel *model, const QString &name, int kind)
+ : _CodeModelItem(model, name, kind)
+{
+}
+
+#ifndef QT_NO_DEBUG_STREAM
void _CodeModelItem::formatKind(QDebug &d, int k)
{
switch (k) {
@@ -377,14 +345,6 @@ void _ClassModelItem::setTemplateParameters(const TemplateParameterList &templat
m_templateParameters = templateParameters;
}
-void _ClassModelItem::addBaseClass(const QString &name, Access accessPolicy)
-{
- _ClassModelItem::BaseClass baseClass;
- baseClass.name = name;
- baseClass.accessPolicy = accessPolicy;
- m_baseClasses.append(baseClass);
-}
-
bool _ClassModelItem::extendsClass(const QString &name) const
{
for (const BaseClass &bc : m_baseClasses) {
@@ -394,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;
@@ -436,9 +406,9 @@ template <class List>
static void formatModelItemList(QDebug &d, const char *prefix, const List &l,
const char *separator = ", ")
{
- if (const int size = l.size()) {
+ if (const auto size = l.size()) {
d << prefix << '[' << size << "](";
- for (int i = 0; i < size; ++i) {
+ for (qsizetype i = 0; i < size; ++i) {
if (i)
d << separator;
l.at(i)->formatDebug(d);
@@ -455,7 +425,7 @@ void _ClassModelItem::formatDebug(QDebug &d) const
d << " [final]";
d << ", inherits=";
d << ", inherits=";
- for (int i = 0, size = m_baseClasses.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = m_baseClasses.size(); i < size; ++i) {
if (i)
d << ", ";
d << m_baseClasses.at(i).name << " (" << m_baseClasses.at(i).accessPolicy << ')';
@@ -474,12 +444,12 @@ void _ClassModelItem::formatDebug(QDebug &d) const
// ---------------------------------------------------------------------------
FunctionModelItem _ScopeModelItem::declaredFunction(const FunctionModelItem &item)
{
- for (const FunctionModelItem &fun : qAsConst(m_functions)) {
+ for (const FunctionModelItem &fun : std::as_const(m_functions)) {
if (fun->name() == item->name() && fun->isSimilar(item))
return fun;
}
- return FunctionModelItem();
+ return {};
}
_ScopeModelItem::~_ScopeModelItem() = default;
@@ -492,26 +462,31 @@ void _ScopeModelItem::addEnumsDeclaration(const QString &enumsDeclaration)
void _ScopeModelItem::addClass(const ClassModelItem &item)
{
m_classes.append(item);
+ item->setEnclosingScope(this);
}
void _ScopeModelItem::addFunction(const FunctionModelItem &item)
{
m_functions.append(item);
+ item->setEnclosingScope(this);
}
void _ScopeModelItem::addVariable(const VariableModelItem &item)
{
m_variables.append(item);
+ item->setEnclosingScope(this);
}
void _ScopeModelItem::addTypeDef(const TypeDefModelItem &item)
{
m_typeDefs.append(item);
+ item->setEnclosingScope(this);
}
void _ScopeModelItem::addTemplateTypeAlias(const TemplateTypeAliasModelItem &item)
{
m_templateTypeAliases.append(item);
+ item->setEnclosingScope(this);
}
qsizetype _ScopeModelItem::indexOfEnum(const QString &name) const
@@ -525,6 +500,7 @@ qsizetype _ScopeModelItem::indexOfEnum(const QString &name) const
void _ScopeModelItem::addEnum(const EnumModelItem &item)
{
+ item->setEnclosingScope(this);
// A forward declaration of an enum ("enum class Foo;") is undistinguishable
// from an enum without values ("enum class QCborTag {}"), so, add all
// enums and replace existing ones without values by ones with values.
@@ -573,12 +549,12 @@ template class LIBSAMPLE_EXPORT Tpl<54>;
*/
void _ScopeModelItem::purgeClassDeclarations()
{
- for (int i = m_classes.size() - 1; i >= 0; --i) {
+ for (auto i = m_classes.size() - 1; i >= 0; --i) {
auto klass = m_classes.at(i);
// For an empty class, check if there is a matching template
// definition, and remove it if this is the case.
if (!klass->isTemplate() && klass->isEmpty()) {
- const QString definitionPrefix = klass->name() + QLatin1Char('<');
+ const QString definitionPrefix = klass->name() + u'<';
const bool definitionFound =
std::any_of(m_classes.cbegin(), m_classes.cend(),
[definitionPrefix] (const ClassModelItem &c) {
@@ -642,57 +618,135 @@ 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()) == QLatin1Char('<');
- }
-
-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(QLatin1Char('<'))
- ? std::find_if(m_classes.begin(), m_classes.end(), ModelItemNamePredicate<_ClassModelItem>(name))
- : std::find_if(m_classes.begin(), m_classes.end(), ClassNamePredicate(name));
+ const ClassList::const_iterator it = name.contains(u'<')
+ ? 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);
}
-FunctionList _ScopeModelItem::findFunctions(const QString &name) const
+_ScopeModelItem::FindEnumByValueReturn
+ _ScopeModelItem::findEnumByValueHelper(QStringView fullValue,
+ QStringView enumValue) const
+{
+ const bool unqualified = fullValue.size() == enumValue.size();
+ QString scopePrefix = scope().join(u"::");
+ if (!scopePrefix.isEmpty())
+ scopePrefix += u"::"_s;
+ scopePrefix += name() + u"::"_s;
+
+ for (const auto &e : m_enums) {
+ const auto index = e->indexOfValue(enumValue);
+ if (index != -1) {
+ QString fullyQualifiedName = scopePrefix;
+ if (e->enumKind() != AnonymousEnum)
+ fullyQualifiedName += e->name() + u"::"_s;
+ fullyQualifiedName += e->enumerators().at(index)->name();
+ if (unqualified || fullyQualifiedName.endsWith(fullValue))
+ return {e, fullyQualifiedName};
+ // For standard enums, check the name without enum name
+ if (e->enumKind() == CEnum) {
+ const QString qualifiedName =
+ scopePrefix + e->enumerators().at(index)->name();
+ if (qualifiedName.endsWith(fullValue))
+ return {e, fullyQualifiedName};
+ }
+ }
+ }
+
+ return {};
+}
+
+// Helper to recursively find the scope of an enum value
+_ScopeModelItem::FindEnumByValueReturn
+ _ScopeModelItem::findEnumByValueRecursion(const _ScopeModelItem *scope,
+ QStringView fullValue,
+ QStringView enumValue,
+ bool searchSiblingNamespaces)
+{
+ if (const auto e = scope->findEnumByValueHelper(fullValue, enumValue))
+ return e;
+
+ if (auto *enclosingScope = scope->enclosingScope()) {
+ // The enclosing scope may have several sibling namespaces of that name.
+ if (searchSiblingNamespaces && scope->kind() == Kind_Namespace) {
+ if (auto *enclosingNamespace = dynamic_cast<const _NamespaceModelItem *>(enclosingScope)) {
+ for (const auto &sibling : enclosingNamespace->namespaces()) {
+ if (sibling.get() != scope && sibling->name() == scope->name()) {
+ if (const auto e = findEnumByValueRecursion(sibling.get(),
+ fullValue, enumValue, false)) {
+ return e;
+ }
+ }
+ }
+ }
+ }
+
+ if (const auto e = findEnumByValueRecursion(enclosingScope, fullValue, enumValue))
+ return e;
+ }
+
+ // 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) {
+ auto *c = base.klass.get();
+ if (const auto e = findEnumByValueRecursion(c, fullValue, enumValue))
+ return e;
+ }
+ }
+ }
+
+ return {};
+}
+
+_ScopeModelItem::FindEnumByValueReturn
+ _ScopeModelItem::findEnumByValue(QStringView value) const
+{
+ const auto lastQualifier = value.lastIndexOf(u"::");
+ const auto enumValue = lastQualifier == -1
+ ? value : value.mid(lastQualifier + 2);
+ return findEnumByValueRecursion(this, value, enumValue);
+}
+
+FunctionList _ScopeModelItem::findFunctions(QAnyStringView name) const
{
FunctionList result;
for (const FunctionModelItem &func : m_functions) {
@@ -703,16 +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);
}
@@ -744,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;
@@ -768,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 << '"';
}
@@ -791,12 +874,12 @@ bool _FunctionModelItem::isSimilar(const FunctionModelItem &other) const
if (isVariadics() != other->isVariadics())
return false;
- if (arguments().count() != other->arguments().count())
+ if (arguments().size() != other->arguments().size())
return false;
// ### check the template parameters
- for (int i = 0; i < arguments().count(); ++i) {
+ for (qsizetype i = 0; i < arguments().size(); ++i) {
ArgumentModelItem arg1 = arguments().at(i);
ArgumentModelItem arg2 = other->arguments().at(i);
@@ -807,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;
@@ -837,55 +930,76 @@ void _FunctionModelItem::setVariadics(bool isVariadics)
m_isVariadics = isVariadics;
}
-bool _FunctionModelItem::isDefaultConstructor() const
+bool _FunctionModelItem::scopeResolution() const
{
- return m_functionType == CodeModel::Constructor
- && (m_arguments.isEmpty() || m_arguments.constFirst()->defaultValue());
+ return m_scopeResolution;
}
-bool _FunctionModelItem::isNoExcept() const
+void _FunctionModelItem::setScopeResolution(bool v)
{
- return m_exceptionSpecification == ExceptionSpecification::NoExcept;
+ m_scopeResolution = v;
}
-ExceptionSpecification _FunctionModelItem::exceptionSpecification() const
+bool _FunctionModelItem::isDefaultConstructor() const
{
- return m_exceptionSpecification;
+ return m_functionType == CodeModel::Constructor
+ && (m_arguments.isEmpty() || m_arguments.constFirst()->defaultValue());
}
-void _FunctionModelItem::setExceptionSpecification(ExceptionSpecification e)
+bool _FunctionModelItem::isSpaceshipOperator() const
{
- m_exceptionSpecification = e;
+ return m_functionType == CodeModel::ComparisonOperator
+ && name() == u"operator<=>";
}
-bool _FunctionModelItem::isDeleted() const
+bool _FunctionModelItem::isNoExcept() const
{
- return m_isDeleted;
+ return m_exceptionSpecification == ExceptionSpecification::NoExcept;
}
-void _FunctionModelItem::setDeleted(bool d)
+bool _FunctionModelItem::isOperator() const
{
- m_isDeleted = d;
+ bool result = false;
+ switch (m_functionType) {
+ case CodeModel::CallOperator:
+ case CodeModel::ConversionOperator:
+ case CodeModel::DereferenceOperator:
+ case CodeModel::ReferenceOperator:
+ case CodeModel::ArrowOperator:
+ case CodeModel::ArithmeticOperator:
+ case CodeModel::IncrementOperator:
+ case CodeModel::DecrementOperator:
+ case CodeModel::BitwiseOperator:
+ case CodeModel::LogicalOperator:
+ case CodeModel::ShiftOperator:
+ case CodeModel::SubscriptOperator:
+ case CodeModel::ComparisonOperator:
+ result = true;
+ break;
+ default:
+ break;
+ }
+ return result;
}
-bool _FunctionModelItem::isDeprecated() const
+ExceptionSpecification _FunctionModelItem::exceptionSpecification() const
{
- return m_isDeprecated;
+ return m_exceptionSpecification;
}
-void _FunctionModelItem::setDeprecated(bool d)
+void _FunctionModelItem::setExceptionSpecification(ExceptionSpecification e)
{
- m_isDeprecated = d;
+ m_exceptionSpecification = e;
}
-bool _FunctionModelItem::isVirtual() const
+bool _FunctionModelItem::isDeleted() const
{
- return m_isVirtual;
+ return m_isDeleted;
}
-void _FunctionModelItem::setVirtual(bool isVirtual)
+void _FunctionModelItem::setDeleted(bool d)
{
- m_isVirtual = isVirtual;
+ m_isDeleted = d;
}
bool _FunctionModelItem::isInline() const
@@ -893,60 +1007,19 @@ 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::isAbstract() const
-{
- return m_isAbstract;
-}
-
-void _FunctionModelItem::setAbstract(bool isAbstract)
+bool _FunctionModelItem::isHiddenFriend() const
{
- m_isAbstract = isAbstract;
+ return m_isHiddenFriend;
}
-// Qt
-bool _FunctionModelItem::isInvokable() const
+void _FunctionModelItem::setHiddenFriend(bool f)
{
- return m_isInvokable;
-}
-
-void _FunctionModelItem::setInvokable(bool isInvokable)
-{
- m_isInvokable = isInvokable;
+ m_isHiddenFriend = f;
}
QString _FunctionModelItem::typeSystemSignature() const // For dumping out type system files
@@ -954,7 +1027,7 @@ QString _FunctionModelItem::typeSystemSignature() const // For dumping out type
QString result;
QTextStream str(&result);
str << name() << '(';
- for (int a = 0, size = m_arguments.size(); a < size; ++a) {
+ for (qsizetype a = 0, size = m_arguments.size(); a < size; ++a) {
if (a)
str << ',';
m_arguments.at(a)->type().formatTypeSystemSignature(str);
@@ -998,6 +1071,7 @@ static const NameFunctionTypeHash &nameToOperatorFunction()
{u"operator>=", CodeModel::ComparisonOperator},
{u"operator==", CodeModel::ComparisonOperator},
{u"operator!=", CodeModel::ComparisonOperator},
+ {u"operator<=>", CodeModel::ComparisonOperator},
{u"operator!", CodeModel::LogicalOperator},
{u"operator&&", CodeModel::LogicalOperator},
{u"operator||", CodeModel::LogicalOperator},
@@ -1072,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 << ",...";
@@ -1093,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;
@@ -1144,7 +1230,7 @@ void _TemplateTypeAliasModelItem::formatDebug(QDebug &d) const
{
_CodeModelItem::formatDebug(d);
d << ", <";
- for (int i = 0, count = m_templateParameters.size(); i < count; ++i) {
+ for (qsizetype i = 0, count = m_templateParameters.size(); i < count; ++i) {
if (i)
d << ", ";
d << m_templateParameters.at(i)->name();
@@ -1154,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;
@@ -1176,6 +1272,15 @@ void _EnumModelItem::addEnumerator(const EnumeratorModelItem &item)
m_enumerators.append(item);
}
+qsizetype _EnumModelItem::indexOfValue(QStringView value) const
+{
+ for (qsizetype i = 0, size = m_enumerators.size(); i < size; ++i) {
+ if (m_enumerators.at(i)->name() == value)
+ return i;
+ }
+ return -1;
+}
+
bool _EnumModelItem::isSigned() const
{
return m_signed;
@@ -1186,6 +1291,26 @@ 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;
+}
+
+void _EnumModelItem::setDeprecated(bool d)
+{
+ m_deprecated = d;
+}
+
#ifndef QT_NO_DEBUG_STREAM
void _EnumModelItem::formatDebug(QDebug &d) const
{
@@ -1200,6 +1325,8 @@ void _EnumModelItem::formatDebug(QDebug &d) const
d << " (class)";
break;
}
+ if (m_deprecated)
+ d << " (deprecated)";
if (!m_signed)
d << " (unsigned)";
formatModelItemList(d, ", enumerators=", m_enumerators);
@@ -1209,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;
@@ -1219,17 +1356,40 @@ void _EnumeratorModelItem::setStringValue(const QString &value)
m_stringValue = value;
}
+bool _EnumeratorModelItem::isDeprecated() const
+{
+ return m_deprecated;
+}
+
+void _EnumeratorModelItem::setDeprecated(bool d)
+{
+ m_deprecated = d;
+}
+
#ifndef QT_NO_DEBUG_STREAM
void _EnumeratorModelItem::formatDebug(QDebug &d) const
{
_CodeModelItem::formatDebug(d);
d << ", value=" << m_value << ", stringValue=\"" << m_stringValue << '"';
+ if (m_deprecated)
+ d << " (deprecated)";
}
#endif // !QT_NO_DEBUG_STREAM
// ---------------------------------------------------------------------------
_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;
@@ -1293,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 76abd47cf..b31c09163 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel.h
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel.h
@@ -1,31 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CODEMODEL_H
@@ -37,13 +12,14 @@
#include "typeinfo.h"
#include <QtCore/QHash>
-#include <QtCore/QPair>
#include <QtCore/QSet>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QList>
+#include <QtCore/QWeakPointer>
#include <optional>
+#include <utility>
QT_FORWARD_DECLARE_CLASS(QDebug)
@@ -56,7 +32,7 @@ class CodeModel
{
Q_GADGET
public:
- Q_DISABLE_COPY(CodeModel)
+ Q_DISABLE_COPY_MOVE(CodeModel)
enum FunctionType {
Normal,
@@ -98,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);
@@ -115,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,
@@ -167,6 +144,9 @@ public:
inline CodeModel *model() const { return m_model; }
+ const _ScopeModelItem *enclosingScope() const;
+ void setEnclosingScope(const _ScopeModelItem *s);
+
#ifndef QT_NO_DEBUG_STREAM
static void formatKind(QDebug &d, int k);
virtual void formatDebug(QDebug &d) const;
@@ -178,6 +158,7 @@ protected:
private:
CodeModel *m_model;
+ const _ScopeModelItem *m_enclosingScope = nullptr;
int m_kind;
int m_startLine;
int m_startColumn;
@@ -195,12 +176,13 @@ QDebug operator<<(QDebug d, const _CodeModelItem *t);
class _ScopeModelItem: public _CodeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_ScopeModelItem)
DECLARE_MODEL_NODE(Scope)
~_ScopeModelItem();
ClassList classes() const { return m_classes; }
- EnumList enums() const { return m_enums; }
+ const EnumList &enums() const { return m_enums; }
inline const FunctionList &functions() const { return m_functions; }
TypeDefList typeDefs() const { return m_typeDefs; }
TemplateTypeAliasList templateTypeAliases() const { return m_templateTypeAliases; }
@@ -214,11 +196,21 @@ public:
void addVariable(const VariableModelItem &item);
ClassModelItem findClass(const QString &name) const;
- EnumModelItem findEnum(const QString &name) 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;
+ EnumModelItem findEnum(QAnyStringView name) const;
+
+ struct FindEnumByValueReturn
+ {
+ operator bool() const { return bool(item); }
+
+ EnumModelItem item;
+ QString qualifiedName;
+ };
+ FindEnumByValueReturn findEnumByValue(QStringView value) 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; }
@@ -233,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);
@@ -247,6 +238,13 @@ protected:
private:
qsizetype indexOfEnum(const QString &name) const;
+ FindEnumByValueReturn findEnumByValueHelper(QStringView fullValue,
+ QStringView value) const;
+ static FindEnumByValueReturn
+ findEnumByValueRecursion(const _ScopeModelItem *scope,
+ QStringView fullValue, QStringView value,
+ bool searchSiblingNamespaces = true);
+
ClassList m_classes;
EnumList m_enums;
TypeDefList m_typeDefs;
@@ -261,11 +259,13 @@ private:
class _ClassModelItem: public _ScopeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_ClassModelItem)
DECLARE_MODEL_NODE(Class)
struct BaseClass
{
QString name;
+ ClassModelItem klass; // Might be null in case of templates
Access accessPolicy = Access::Public;
};
@@ -276,19 +276,18 @@ 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();
- QList<BaseClass> baseClasses() const { return m_baseClasses; }
+ const QList<BaseClass> &baseClasses() const { return m_baseClasses; }
const QList<UsingMember> &usingMembers() const;
void addUsingMember(const QString &className, const QString &memberName,
Access accessPolicy);
- void addBaseClass(const QString &name, Access accessPolicy);
+ void addBaseClass(const BaseClass &b) { m_baseClasses.append(b); }
TemplateParameterList templateParameters() const;
void setTemplateParameters(const TemplateParameterList &templateParameters);
@@ -315,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;
@@ -324,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; }
@@ -339,7 +338,7 @@ public:
void addNamespace(NamespaceModelItem item);
- NamespaceModelItem findNamespace(const QString &name) const;
+ NamespaceModelItem findNamespace(QAnyStringView name) const;
void appendNamespace(const _NamespaceModelItem &other);
@@ -355,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;
@@ -384,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
@@ -391,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;
@@ -445,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;
@@ -465,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;
@@ -482,42 +485,34 @@ 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 isInvokable() const; // Qt
- void setInvokable(bool isInvokable); // Qt
-
- bool isAbstract() const;
- void setAbstract(bool isAbstract);
+ bool isHiddenFriend() const;
+ void setHiddenFriend(bool f);
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;
bool isSimilar(const FunctionModelItem &other) const;
bool isNoExcept() const;
+ bool isOperator() const;
+
ExceptionSpecification exceptionSpecification() const;
void setExceptionSpecification(ExceptionSpecification e);
@@ -534,19 +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;
};
@@ -558,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
@@ -569,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);
@@ -612,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;
@@ -630,29 +617,39 @@ public:
EnumKind enumKind() const { return m_enumKind; }
void setEnumKind(EnumKind kind) { m_enumKind = kind; }
+ qsizetype indexOfValue(QStringView value) const;
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
#endif
+ bool isDeprecated() const;
+ void setDeprecated(bool d);
+
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;
+ bool m_deprecated = false;
bool m_signed = true;
};
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;
@@ -661,6 +658,9 @@ public:
EnumValue value() const { return m_value; }
void setValue(EnumValue v) { m_value = v; }
+ bool isDeprecated() const;
+ void setDeprecated(bool d);
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
#endif
@@ -668,17 +668,18 @@ public:
private:
QString m_stringValue;
EnumValue m_value;
+ bool m_deprecated = false;
};
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;
@@ -693,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 4f5121a08..e5c429bd0 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel_enums.h
@@ -1,34 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CODEMODEL_ENUMS_H
#define CODEMODEL_ENUMS_H
+#include <QtCore/qflags.h>
+
enum ReferenceType {
NoReference,
LValueReference,
@@ -68,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 b138f2a2f..f0a25c9db 100644
--- a/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h
+++ b/sources/shiboken6/ApiExtractor/parser/codemodel_fwd.h
@@ -1,38 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CODEMODEL_FWD_H
#define CODEMODEL_FWD_H
#include <QtCore/QList>
-#include <QtCore/QSharedPointer>
+
+#include <memory>
// forward declarations
class CodeModel;
@@ -52,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 2ee7398ea..3749e16a8 100644
--- a/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp
+++ b/sources/shiboken6/ApiExtractor/parser/enumvalue.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "enumvalue.h"
@@ -32,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;
@@ -50,11 +47,37 @@ 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
+ d << m_unsignedValue << 'u';
}
#ifndef QT_NO_DEBUG_STREAM
@@ -64,10 +87,7 @@ QDebug operator<<(QDebug d,const EnumValue &v)
d.nospace();
d.noquote();
d << "EnumValue(";
- if (v.m_type == EnumValue::Signed)
- d << v.m_value;
- else
- d << v.m_unsignedValue << 'u';
+ v.formatDebug(d);
d << ')';
return d;
}
diff --git a/sources/shiboken6/ApiExtractor/parser/enumvalue.h b/sources/shiboken6/ApiExtractor/parser/enumvalue.h
index 3cd7d01a4..bbd5a712d 100644
--- a/sources/shiboken6/ApiExtractor/parser/enumvalue.h
+++ b/sources/shiboken6/ApiExtractor/parser/enumvalue.h
@@ -1,35 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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)
@@ -45,18 +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
@@ -70,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 e3fdeac84..f8c5c31d8 100644
--- a/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp
+++ b/sources/shiboken6/ApiExtractor/parser/typeinfo.cpp
@@ -1,37 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "typeinfo.h"
#include "codemodel.h"
#include <clangparser/clangutils.h>
+#include <debughelpers_p.h>
+
+#include "qtcompat.h"
#include <QtCore/QDebug>
#include <QtCore/QStack>
@@ -39,6 +17,8 @@
#include <iostream>
+using namespace Qt::StringLiterals;
+
class TypeInfoData : public QSharedData
{
@@ -67,10 +47,10 @@ public:
};
};
- ReferenceType m_referenceType;
+ ReferenceType m_referenceType = NoReference;
};
-TypeInfoData::TypeInfoData() : flags(0), m_referenceType(NoReference)
+TypeInfoData::TypeInfoData() : flags(0)
{
}
@@ -81,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)
{
@@ -94,13 +73,13 @@ static inline TypeInfo createType(const QString &name)
TypeInfo TypeInfo::voidType()
{
- static const TypeInfo result = createType(QLatin1String("void"));
+ static const TypeInfo result = createType(u"void"_s);
return result;
}
TypeInfo TypeInfo::varArgsType()
{
- static const TypeInfo result = createType(QLatin1String("..."));
+ static const TypeInfo result = createType(u"..."_s);
return result;
}
@@ -119,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);
@@ -148,7 +127,7 @@ bool TypeInfoData::isVoid() const
&& m_arguments.isEmpty() && m_arrayElements.isEmpty()
&& m_instantiations.isEmpty()
&& m_qualifiedName.size() == 1
- && m_qualifiedName.constFirst() == QLatin1String("void");
+ && m_qualifiedName.constFirst() == u"void";
}
bool TypeInfo::isVoid() const
@@ -287,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();
@@ -307,34 +292,34 @@ 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(QLatin1String("::")))
+ << "() on " << qPrintable(__type.qualifiedName().join(u"::"_s))
<< std::endl;
return otherType;
}
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
// other="QList<int>", replace the instantiations to obtain "QVector<int>".
auto aliasInstantiations = templateTypeAlias->type().instantiations();
const auto &concreteInstantiations = otherType.instantiations();
- const int count = qMin(aliasInstantiations.size(), concreteInstantiations.size());
- for (int i = 0; i < count; ++i)
- aliasInstantiations[i] = concreteInstantiations[i];
+ const auto count = qMin(aliasInstantiations.size(), concreteInstantiations.size());
+ 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);
@@ -362,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);
}
@@ -382,7 +371,8 @@ private:
QStack<TypeInfo *> m_parseStack;
};
-QPair<int, int> TypeInfo::parseTemplateArgumentList(const QString &l, int from)
+std::pair<qsizetype, qsizetype>
+ TypeInfo::parseTemplateArgumentList(const QString &l, qsizetype from)
{
return clang::parseTemplateArgumentList(l, clang::TemplateArgumentHandler(TypeInfoTemplateArgumentHandler(this)), from);
}
@@ -391,23 +381,23 @@ QString TypeInfo::toString() const
{
QString tmp;
if (isConstant())
- tmp += QLatin1String("const ");
+ tmp += u"const "_s;
if (isVolatile())
- tmp += QLatin1String("volatile ");
+ tmp += u"volatile "_s;
- tmp += d->m_qualifiedName.join(QLatin1String("::"));
+ tmp += d->m_qualifiedName.join(u"::"_s);
- if (const int instantiationCount = d->m_instantiations.size()) {
- tmp += QLatin1Char('<');
- for (int i = 0; i < instantiationCount; ++i) {
+ if (const auto instantiationCount = d->m_instantiations.size()) {
+ tmp += u'<';
+ for (qsizetype i = 0; i < instantiationCount; ++i) {
if (i)
- tmp += QLatin1String(", ");
+ tmp += u", "_s;
tmp += d->m_instantiations.at(i).toString();
}
- if (tmp.endsWith(QLatin1Char('>')))
- tmp += QLatin1Char(' ');
- tmp += QLatin1Char('>');
+ if (tmp.endsWith(u'>'))
+ tmp += u' ';
+ tmp += u'>';
}
for (Indirection i : d->m_indirections)
@@ -417,40 +407,37 @@ QString TypeInfo::toString() const
case NoReference:
break;
case LValueReference:
- tmp += QLatin1Char('&');
+ tmp += u'&';
break;
case RValueReference:
- tmp += QLatin1String("&&");
+ tmp += u"&&"_s;
break;
}
if (isFunctionPointer()) {
- tmp += QLatin1String(" (*)(");
- for (int i = 0; i < d->m_arguments.count(); ++i) {
+ tmp += u" (*)("_s;
+ for (qsizetype i = 0; i < d->m_arguments.size(); ++i) {
if (i != 0)
- tmp += QLatin1String(", ");
+ tmp += u", "_s;
tmp += d->m_arguments.at(i).toString();
}
- tmp += QLatin1Char(')');
+ tmp += u')';
}
- for (const QString &elt : d->m_arrayElements) {
- tmp += QLatin1Char('[');
- tmp += elt;
- tmp += QLatin1Char(']');
- }
+ for (const QString &elt : d->m_arrayElements)
+ tmp += u'[' + elt + u']';
return tmp;
}
bool TypeInfoData::equals(const TypeInfoData &other) const
{
- if (m_arrayElements.count() != other.m_arrayElements.count())
+ if (m_arrayElements.size() != other.m_arrayElements.size())
return false;
#if defined (RXX_CHECK_ARRAY_ELEMENTS) // ### it'll break
- for (int i = 0; i < arrayElements().count(); ++i) {
+ for (qsizetype i = 0; i < arrayElements().size(); ++i) {
QString elt1 = arrayElements().at(i).trimmed();
QString elt2 = other.arrayElements().at(i).trimmed();
@@ -465,34 +452,31 @@ 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 int qualifierSize = qualifier.size();
+ const auto qualifierSize = qualifier.size();
if (s->size() < qualifierSize + 1 || !s->startsWith(qualifier)
|| !s->at(qualifierSize).isSpace()) {
return false;
@@ -508,10 +492,8 @@ void TypeInfo::stripQualifiers(QString *s)
{
stripLeadingConst(s);
stripLeadingVolatile(s);
- while (s->endsWith(QLatin1Char('&')) || s->endsWith(QLatin1Char('*'))
- || s->endsWith(QLatin1Char(' '))) {
+ while (s->endsWith(u'&') || s->endsWith(u'*') || s->endsWith(u' '))
s->chop(1);
- }
}
// Helper functionality to simplify a raw standard type as returned by
@@ -522,7 +504,7 @@ void TypeInfo::stripQualifiers(QString *s)
bool TypeInfoData::isStdType() const
{
return m_qualifiedName.size() > 1
- && m_qualifiedName.constFirst() == QLatin1String("std");
+ && m_qualifiedName.constFirst() == u"std";
}
bool TypeInfo::isStdType() const
@@ -532,15 +514,15 @@ bool TypeInfo::isStdType() const
static inline bool discardStdType(const QString &name)
{
- return name == QLatin1String("allocator") || name == QLatin1String("less");
+ return name == u"allocator" || name == u"less";
}
void TypeInfoData::simplifyStdType()
{
Q_ASSERT(isStdType());
- if (m_qualifiedName.at(1).startsWith(QLatin1String("__")))
+ if (m_qualifiedName.at(1).startsWith(u"__"))
m_qualifiedName.removeAt(1);
- for (int t = m_instantiations.size() - 1; t >= 0; --t) {
+ for (auto t = m_instantiations.size() - 1; t >= 0; --t) {
if (m_instantiations.at(t).isStdType()) {
if (discardStdType(m_instantiations.at(t).qualifiedName().constLast()))
m_instantiations.removeAt(t);
@@ -560,7 +542,7 @@ void TypeInfo::formatTypeSystemSignature(QTextStream &str) const
{
if (d->m_constant)
str << "const ";
- str << d->m_qualifiedName.join(QLatin1String("::"));
+ str << d->m_qualifiedName.join(u"::"_s);
switch (d->m_referenceType) {
case NoReference:
break;
@@ -584,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 38e585726..e4f363b67 100644
--- a/sources/shiboken6/ApiExtractor/parser/typeinfo.h
+++ b/sources/shiboken6/ApiExtractor/parser/typeinfo.h
@@ -1,31 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TYPEINFO_H
#define TYPEINFO_H
@@ -35,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)
@@ -53,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();
@@ -102,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<int, int> parseTemplateArgumentList(const QString &l, int 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??
@@ -125,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;
@@ -138,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
new file mode 100644
index 000000000..992f735ac
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/predefined_templates.cpp
@@ -0,0 +1,276 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "predefined_templates.h"
+
+#include "qtcompat.h"
+
+using namespace Qt::StringLiterals;
+
+static QString pySequenceToCppContainer(const QString &insertFunc,
+ bool reserve)
+{
+ QString result = u"(%out).clear();\n"_s;
+ if (reserve) {
+ result += uR"(if (PyList_Check(%in)) {
+ const Py_ssize_t size = PySequence_Size(%in);
+ if (size > 10)
+ (%out).reserve(size);
+}
+
+)"_s;
+ }
+
+ result += uR"(Shiboken::AutoDecRef it(PyObject_GetIter(%in));
+while (true) {
+ 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);
+ (%out).)"_s;
+
+ result += insertFunc;
+ result += uR"((cppItem);
+}
+)"_s;
+ return result;
+}
+
+// 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 = std::cbegin(%in), end = std::cend(%in); it != end; ++it) {
+ const auto &key = it)"_s
+ + (isQMap ? qtMapKeyAccessor : stlMapKeyAccessor)
+ + uR"(;
+ const auto &value = it)"_s
+ + (isQMap ? qtMapValueAccessor : stlMapValueAccessor)
+ + uR"(;
+ PyObject *pyKey = %CONVERTTOPYTHON[%INTYPE_0](key);
+ PyObject *pyValue = %CONVERTTOPYTHON[%INTYPE_1](value);
+ PyDict_SetItem(%out, pyKey, pyValue);
+ Py_DECREF(pyKey);
+ Py_DECREF(pyValue);
+}
+return %out;
+)"_s;
+}
+
+static QString pyDictToCppMap(bool isQMap)
+{
+ return uR"(PyObject *key;
+PyObject *value;
+%out.clear();
+Py_ssize_t pos = 0;
+while (PyDict_Next(%in, &pos, &key, &value)) {
+ %OUTTYPE_0 cppKey = %CONVERTTOCPP[%OUTTYPE_0](key);
+ %OUTTYPE_1 cppValue = %CONVERTTOCPP[%OUTTYPE_1](value);
+ %out.insert()"_s
+ // STL needs a pair
+ + (isQMap ? u"cppKey, cppValue"_s : u"{cppKey, cppValue}"_s) + uR"();
+}
+)"_s;
+}
+
+// Convert a STL or Qt multi map to Dict of Lists using upperBound()
+static QString cppMultiMapToPyDict(bool isQMultiMap)
+{
+ return uR"(PyObject *%out = PyDict_New();
+ for (auto it = std::cbegin(%in), end = std::cend(%in); it != end; ) {
+ const auto &key = it)"_s
+ + (isQMultiMap ? qtMapKeyAccessor : stlMapKeyAccessor)
+ + uR"(;
+ PyObject *pyKey = %CONVERTTOPYTHON[%INTYPE_0](key);
+ auto upper = %in.)"_s
+ + (isQMultiMap ? u"upperBound"_s : u"upper_bound"_s)
+ + uR"((key);
+ const auto count = Py_ssize_t(std::distance(it, upper));
+ PyObject *pyValues = PyList_New(count);
+ Py_ssize_t idx = 0;
+ for (; it != upper; ++it, ++idx) {
+ const auto &cppItem = it.value();
+ PyList_SET_ITEM(pyValues, idx, %CONVERTTOPYTHON[%INTYPE_1](cppItem));
+ }
+ PyDict_SetItem(%out, pyKey, pyValues);
+ Py_DECREF(pyKey);
+ }
+ return %out;
+)"_s;
+}
+
+// Convert a STL or Qt multi hash to Dict of Lists using equalRange()
+static QString cppMultiHashToPyDict(bool isQMultiHash)
+{
+ return uR"(PyObject *%out = PyDict_New();
+ for (auto it = std::cbegin(%in), end = std::cend(%in); it != end; ) {
+ const auto &key = it)"_s
+ + (isQMultiHash ? qtMapKeyAccessor : stlMapKeyAccessor)
+ + uR"(;
+ PyObject *pyKey = %CONVERTTOPYTHON[%INTYPE_0](key);
+ auto range = %in.equal_range(key);
+ const auto count = Py_ssize_t(std::distance(range.first, range.second));
+ PyObject *pyValues = PyList_New(count);
+ Py_ssize_t idx = 0;
+ for (; it != range.second; ++it, ++idx) {
+ const auto &cppItem = it.value();
+ PyList_SET_ITEM(pyValues, idx, %CONVERTTOPYTHON[%INTYPE_1](cppItem));
+ }
+ PyDict_SetItem(%out, pyKey, pyValues);
+ Py_DECREF(pyKey);
+ }
+ return %out;
+)"_s;
+}
+
+// Convert Dict of Lists to a STL or Qt multi hash/map
+static QString pyDictToCppMultiHash(bool isQMultiHash)
+{
+ return uR"(PyObject *key;
+ PyObject *values;
+ %out.clear();
+ Py_ssize_t pos = 0;
+ while (PyDict_Next(%in, &pos, &key, &values)) {
+ %OUTTYPE_0 cppKey = %CONVERTTOCPP[%OUTTYPE_0](key);
+ const Py_ssize_t size = PySequence_Size(values);
+ for (Py_ssize_t i = 0; i < size; ++i) {
+ Shiboken::AutoDecRef value(PySequence_GetItem(values, i));
+ %OUTTYPE_1 cppValue = %CONVERTTOCPP[%OUTTYPE_1](value);
+ %out.insert()"_s
+ + (isQMultiHash ? u"cppKey, cppValue"_s : u"{cppKey, cppValue}"_s)
+ + uR"();
+ }
+ }
+)"_s;
+}
+
+const PredefinedTemplates &predefinedTemplates()
+{
+ static const PredefinedTemplates result{
+ {u"shiboken_conversion_pylong_to_cpp"_s,
+ u"%out = %OUTTYPE(PyLong_AsLong(%in));\n"_s},
+
+ // QPair/std::pair
+ {u"shiboken_conversion_pysequence_to_cpppair"_s,
+ uR"(%out.first = %CONVERTTOCPP[%OUTTYPE_0](PySequence_Fast_GET_ITEM(%in, 0));
+%out.second = %CONVERTTOCPP[%OUTTYPE_1](PySequence_Fast_GET_ITEM(%in, 1));
+)"_s},
+
+ {u"shiboken_conversion_cpppair_to_pytuple"_s,
+ uR"(PyObject *%out = PyTuple_New(2);
+PyTuple_SET_ITEM(%out, 0, %CONVERTTOPYTHON[%INTYPE_0](%in.first));
+PyTuple_SET_ITEM(%out, 1, %CONVERTTOPYTHON[%INTYPE_1](%in.second));
+return %out;
+)"_s},
+
+ // Sequential containers
+ {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 = std::cbegin(%in), end = std::cend(%in); it != end; ++it, ++idx) {
+ const auto &cppItem = *it;
+ PyList_SET_ITEM(%out, idx, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
+}
+return %out;)"_s},
+
+ // PySet
+ {u"shiboken_conversion_cppsequence_to_pyset"_s,
+ uR"(PyObject *%out = PySet_New(nullptr);
+for (const auto &cppItem : %in) {
+ PySet_Add(%out, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
+}
+return %out;)"_s},
+
+ {u"shiboken_conversion_pyiterable_to_cppsequentialcontainer"_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)},
+
+ // Maps
+ {u"shiboken_conversion_stdmap_to_pydict"_s,
+ cppMapToPyDict(false)},
+ {u"shiboken_conversion_qmap_to_pydict"_s,
+ cppMapToPyDict(true)},
+ {u"shiboken_conversion_pydict_to_stdmap"_s,
+ pyDictToCppMap(false)},
+ {u"shiboken_conversion_pydict_to_qmap"_s,
+ pyDictToCppMap(true)},
+
+ // Multi maps
+ {u"shiboken_conversion_stdmultimap_to_pydict"_s,
+ cppMultiMapToPyDict(false)},
+ {u"shiboken_conversion_qmultimap_to_pydict"_s,
+ cppMultiMapToPyDict(true)},
+
+ // Multi hashes
+ {u"shiboken_conversion_stdunorderedmultimap_to_pydict"_s,
+ cppMultiHashToPyDict(false)},
+ {u"shiboken_conversion_qmultihash_to_pydict"_s,
+ cppMultiHashToPyDict(true)},
+
+ // STL multi hash/map
+ {u"shiboken_conversion_pydict_to_stdmultimap"_s,
+ pyDictToCppMultiHash(false)},
+ {u"shiboken_conversion_pydict_to_qmultihash"_s,
+ pyDictToCppMultiHash(true)}
+ };
+
+ return result;
+}
+
+QByteArray containerTypeSystemSnippet(const char *name, const char *type,
+ const char *include,
+ const char *nativeToTarget,
+ const char *targetToNativeType,
+ const char *targetToNative)
+{
+ 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>
+)";
+ 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>
+)");
+ }
+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
new file mode 100644
index 000000000..0cc2c7f32
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/predefined_templates.h
@@ -0,0 +1,27 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef PREDEFINED_TEMPLATES_H
+#define PREDEFINED_TEMPLATES_H
+
+#include <QtCore/QList>
+#include <QtCore/QString>
+
+struct PredefinedTemplate
+{
+ QString name;
+ QString content;
+};
+
+using PredefinedTemplates = QList<PredefinedTemplate>;
+
+const PredefinedTemplates &predefinedTemplates();
+
+// Create an XML snippet for a container type.
+QByteArray containerTypeSystemSnippet(const char *name, const char *type,
+ const char *include,
+ const char *nativeToTarget,
+ const char *targetToNativeType = nullptr,
+ const char *targetToNative = nullptr);
+
+#endif // PREDEFINED_TEMPLATES_H
diff --git a/sources/shiboken6/ApiExtractor/primitivetypeentry.h b/sources/shiboken6/ApiExtractor/primitivetypeentry.h
new file mode 100644
index 000000000..6faaf7a61
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/primitivetypeentry.h
@@ -0,0 +1,72 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef PRIMITIVETYPEENTRY_H
+#define PRIMITIVETYPEENTRY_H
+
+#include "typesystem.h"
+#include "customconversion_typedefs.h"
+
+class PrimitiveTypeEntryPrivate;
+
+/// A PrimitiveTypeEntry is user-defined type with conversion rules, a C++
+/// primitive type for which a PrimitiveTypeConverter exists in libshiboken
+/// or a typedef to a C++ primitive type as determined by AbstractMetaBuilder.
+class PrimitiveTypeEntry : public TypeEntry
+{
+public:
+ explicit PrimitiveTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ QString defaultConstructor() const;
+ void setDefaultConstructor(const QString& defaultConstructor);
+ bool hasDefaultConstructor() const;
+
+ /**
+ * The PrimitiveTypeEntry pointed by this type entry if it
+ * represents a typedef).
+ * \return the type referenced by the typedef, or a null pointer
+ * if the current object is not an typedef
+ */
+ PrimitiveTypeEntryPtr referencedTypeEntry() const;
+
+ /**
+ * Defines type referenced by this entry.
+ * \param referencedTypeEntry type referenced by this entry
+ */
+ void setReferencedTypeEntry(PrimitiveTypeEntryPtr referencedTypeEntry);
+
+ /// Returns whether this entry references another entry.
+ bool referencesType() const;
+
+ bool preferredTargetLangType() const;
+ void setPreferredTargetLangType(bool b);
+
+ bool hasCustomConversion() const;
+ void setCustomConversion(const CustomConversionPtr &customConversion);
+ CustomConversionPtr customConversion() const;
+
+ TypeEntry *clone() const override;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+protected:
+ explicit PrimitiveTypeEntry(PrimitiveTypeEntryPrivate *d);
+};
+
+/// Finds the most basic primitive type that the typedef represents,
+/// i.e. a type that is not an typedef'ed.
+/// \return the most basic non-typedef'ed primitive type represented
+/// by this typedef or self in case it is not a reference.
+PrimitiveTypeEntryCPtr basicReferencedTypeEntry(const PrimitiveTypeEntryCPtr &e);
+PrimitiveTypeEntryCPtr basicReferencedTypeEntry(const TypeEntryCPtr &e);
+
+/// Finds the basic primitive type that the typedef represents
+/// and was explicitly specified in the type system.
+/// \return the basic primitive type that was explicitly specified in
+/// the type system.
+PrimitiveTypeEntryCPtr basicReferencedNonBuiltinTypeEntry(const PrimitiveTypeEntryCPtr &e);
+
+#endif // PRIMITIVETYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/propertyspec.cpp b/sources/shiboken6/ApiExtractor/propertyspec.cpp
index f66eeeaf6..32b756fad 100644
--- a/sources/shiboken6/ApiExtractor/propertyspec.cpp
+++ b/sources/shiboken6/ApiExtractor/propertyspec.cpp
@@ -1,38 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "propertyspec.h"
#include "abstractmetalang.h"
#include "abstractmetabuilder_p.h"
#include "abstractmetatype.h"
-#include "codemodel.h"
+#include "documentation.h"
#include "messages.h"
-#include "typesystem.h"
+#include "complextypeentry.h"
+#include "typeinfo.h"
+
+#include "qtcompat.h"
#include <QtCore/QHash>
@@ -42,6 +20,8 @@
#include <algorithm>
+using namespace Qt::StringLiterals;
+
class QPropertySpecData : public QSharedData
{
public:
@@ -52,6 +32,7 @@ public:
m_write(ts.write),
m_designable(ts.designable),
m_reset(ts.reset),
+ m_notify(ts.notify),
m_type(type),
m_generateGetSetDef(ts.generateGetSetDef)
{
@@ -62,6 +43,8 @@ public:
QString m_write;
QString m_designable;
QString m_reset;
+ QString m_notify;
+ Documentation m_documentation;
AbstractMetaType m_type;
int m_index = -1;
// Indicates whether actual code is generated instead of relying on libpyside.
@@ -76,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
@@ -91,7 +74,7 @@ void QPropertySpec::setType(const AbstractMetaType &t)
d->m_type = t;
}
-const TypeEntry *QPropertySpec::typeEntry() const
+TypeEntryCPtr QPropertySpec::typeEntry() const
{
return d->m_type.typeEntry();
}
@@ -107,6 +90,17 @@ void QPropertySpec::setName(const QString &name)
d->m_name = name;
}
+Documentation QPropertySpec::documentation() const
+{
+ return d->m_documentation;
+}
+
+void QPropertySpec::setDocumentation(const Documentation &doc)
+{
+ if (d->m_documentation != doc)
+ d->m_documentation = doc;
+}
+
QString QPropertySpec::read() const
{
return d->m_read;
@@ -156,6 +150,17 @@ void QPropertySpec::setReset(const QString &reset)
d->m_reset = reset;
}
+QString QPropertySpec::notify() const
+{
+ return d->m_notify;
+}
+
+void QPropertySpec::setNotify(const QString &notify)
+{
+ if (d->m_notify != notify)
+ d->m_notify = notify;
+}
+
int QPropertySpec::index() const
{
return d->m_index;
@@ -184,13 +189,15 @@ void QPropertySpec::setGenerateGetSetDef(bool generateGetSetDef)
TypeSystemProperty QPropertySpec::typeSystemPropertyFromQ_Property(const QString &declarationIn,
QString *errorMessage)
{
- enum class PropertyToken { None, Read, Write, Designable, Reset };
+ 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}
+ {"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();
@@ -200,7 +207,7 @@ TypeSystemProperty QPropertySpec::typeSystemPropertyFromQ_Property(const QString
// Q_PROPERTY(QString objectName READ objectName WRITE setObjectName NOTIFY objectNameChanged)
const QString declaration = declarationIn.simplified();
- auto propertyTokens = declaration.split(QLatin1Char(' '), Qt::SkipEmptyParts);
+ auto propertyTokens = declaration.split(u' ', Qt::SkipEmptyParts);
// To properly parse complicated type declarations like
// "Q_PROPERTY(const QList<QString > *objectName READ objectName ..."
@@ -209,17 +216,17 @@ TypeSystemProperty QPropertySpec::typeSystemPropertyFromQ_Property(const QString
const auto it = std::find_if(propertyTokens.cbegin(), propertyTokens.cend(),
[](const QString &t) { return tokenLookup.contains(t); });
if (it == propertyTokens.cend()) {
- *errorMessage = QLatin1String("Invalid property specification, READ missing");
+ *errorMessage = u"Invalid property specification, READ missing"_s;
return result;
}
- const int firstToken = int(it - propertyTokens.cbegin());
+ const auto firstToken = qsizetype(it - propertyTokens.cbegin());
if (firstToken < 2) {
- *errorMessage = QLatin1String("Insufficient number of tokens in property specification");
+ *errorMessage = u"Insufficient number of tokens in property specification"_s;
return result;
}
- for (int pos = firstToken; pos + 1 < propertyTokens.size(); pos += 2) {
+ for (qsizetype pos = firstToken; pos + 1 < propertyTokens.size(); pos += 2) {
switch (tokenLookup.value(propertyTokens.at(pos))) {
case PropertyToken::Read:
result.read = propertyTokens.at(pos + 1);
@@ -233,17 +240,25 @@ TypeSystemProperty QPropertySpec::typeSystemPropertyFromQ_Property(const QString
case PropertyToken::Designable:
result.designable = propertyTokens.at(pos + 1);
break;
+ 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)
- result.type += QLatin1Char(' ') + propertyTokens.at(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*"
while (!result.name.isEmpty() && !result.name.at(0).isLetter()) {
@@ -251,7 +266,7 @@ TypeSystemProperty QPropertySpec::typeSystemPropertyFromQ_Property(const QString
result.name.remove(0, 1);
}
if (!result.isValid())
- *errorMessage = QLatin1String("Incomplete property specification");
+ *errorMessage = u"Incomplete property specification"_s;
return result;
}
@@ -259,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)
@@ -275,7 +290,7 @@ std::optional<QPropertySpec>
auto type = b->translateType(info, metaClass, {}, &typeError);
if (!type.has_value()) {
const QStringList qualifiedName = info.qualifiedName();
- for (int j = scopes.size(); j >= 0 && !type; --j) {
+ for (auto j = scopes.size(); j >= 0 && !type; --j) {
info.setQualifiedName(scopes.mid(0, j) + qualifiedName);
type = b->translateType(info, metaClass, {}, &typeError);
}
@@ -292,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)
@@ -315,6 +330,8 @@ void QPropertySpec::formatDebug(QDebug &debug) const
debug << ", reset=" << d->m_reset;
if (!d->m_designable.isEmpty())
debug << ", designable=" << d->m_designable;
+ if (!d->m_documentation.isEmpty())
+ debug << ", doc=\"" << d->m_documentation << '"';
}
QDebug operator<<(QDebug d, const QPropertySpec &p)
diff --git a/sources/shiboken6/ApiExtractor/propertyspec.h b/sources/shiboken6/ApiExtractor/propertyspec.h
index 4121f72d2..9e2e0f3d4 100644
--- a/sources/shiboken6/ApiExtractor/propertyspec.h
+++ b/sources/shiboken6/ApiExtractor/propertyspec.h
@@ -1,36 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef PROPERTYSPEC_H
#define PROPERTYSPEC_H
class AbstractMetaType;
+#include "abstractmetalang_typedefs.h"
+#include "typesystem_typedefs.h"
+
#include <QtCore/QStringList>
#include <QtCore/QSharedDataPointer>
@@ -39,6 +17,7 @@ class AbstractMetaType;
class AbstractMetaClass;
class AbstractMetaBuilderPrivate;
class AbstractMetaType;
+class Documentation;
class TypeEntry;
struct TypeSystemProperty;
@@ -54,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,
@@ -64,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);
@@ -79,11 +58,14 @@ public:
const AbstractMetaType &type() const;
void setType(const AbstractMetaType &t);
- const TypeEntry *typeEntry() const;
+ TypeEntryCPtr typeEntry() const;
QString name() const;
void setName(const QString &name);
+ Documentation documentation() const;
+ void setDocumentation(const Documentation &doc);
+
QString read() const;
void setRead(const QString &read);
@@ -97,6 +79,9 @@ public:
QString reset() const;
void setReset(const QString &reset);
+ QString notify() const; // Q_PROPERTY/C++ only
+ void setNotify(const QString &notify);
+
int index() const;
void setIndex(int index);
diff --git a/sources/shiboken6/ApiExtractor/pymethoddefentry.cpp b/sources/shiboken6/ApiExtractor/pymethoddefentry.cpp
new file mode 100644
index 000000000..64d44378b
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/pymethoddefentry.cpp
@@ -0,0 +1,53 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "pymethoddefentry.h"
+#include "textstream.h"
+
+#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 << "\", " << castToPyCFunction(e.function) <<", ";
+ if (e.methFlags.isEmpty()) {
+ s << '0';
+ } else {
+ for (qsizetype i = 0, size = e.methFlags.size(); i < size; ++i) {
+ if (i)
+ s << '|';
+ s << e.methFlags.at(i);
+ }
+ }
+ if (e.doc.isEmpty())
+ s << ", nullptr";
+ else
+ s << ", R\"(" << e.doc << ")\"";
+ s << '}';
+ return s;
+}
+
+TextStream &operator<<(TextStream &s, const PyMethodDefEntries &entries)
+{
+ for (const auto &e : entries)
+ s << e << ",\n";
+ return s;
+}
+
+QDebug operator<<(QDebug debug, const PyMethodDefEntry &e)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "PyMethodDefEntry(\"" << e.name << "\", " << e.function
+ << ", " << e.methFlags;
+ if (!e.doc.isEmpty())
+ debug << ", \"" << e.doc << '"';
+ debug << ')';
+ return debug;
+}
diff --git a/sources/shiboken6/ApiExtractor/pymethoddefentry.h b/sources/shiboken6/ApiExtractor/pymethoddefentry.h
new file mode 100644
index 000000000..a8694eb30
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/pymethoddefentry.h
@@ -0,0 +1,38 @@
+// 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 PYMETHODDEFENTRY_H
+#define PYMETHODDEFENTRY_H
+
+#include <QtCore/QByteArrayList>
+#include <QtCore/QString>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+
+class TextStream;
+
+struct castToPyCFunction
+{
+ explicit castToPyCFunction(QAnyStringView function) noexcept :
+ m_function(function) {}
+
+ QAnyStringView m_function;
+};
+
+struct PyMethodDefEntry
+{
+ QString name;
+ QString function;
+ QByteArrayList methFlags; // "METH_O" etc.
+ QString doc;
+};
+
+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);
+
+QDebug operator<<(QDebug debug, const PyMethodDefEntry &e);
+
+#endif // PYMETHODDEFENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/pythontypeentry.h b/sources/shiboken6/ApiExtractor/pythontypeentry.h
new file mode 100644
index 000000000..2e0fbda97
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/pythontypeentry.h
@@ -0,0 +1,29 @@
+// 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 PYTHONTYPEENTRY_H
+#define PYTHONTYPEENTRY_H
+
+#include "customtypenentry.h"
+#include "typesystem_enums.h"
+
+class PythonTypeEntry : public CustomTypeEntry
+{
+public:
+ explicit PythonTypeEntry(const QString &entryName,
+ const QString &checkFunction,
+ TypeSystem::CPythonType type);
+
+ TypeEntry *clone() const override;
+
+ TypeSystem::CPythonType cPythonType() const;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+
+protected:
+ explicit PythonTypeEntry(TypeEntryPrivate *d);
+};
+
+#endif // PYTHONTYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/qtcompat.h b/sources/shiboken6/ApiExtractor/qtcompat.h
new file mode 100644
index 000000000..3837dcfd2
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/qtcompat.h
@@ -0,0 +1,37 @@
+// 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 QTCOMPAT_H
+#define QTCOMPAT_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#if QT_VERSION < 0x060400
+
+// QTBUG-98434, provide literals of Qt 6.4 for compatibility.
+
+# include <QtCore/QString>
+
+# define QLatin1StringView QLatin1String
+
+namespace Qt {
+inline namespace Literals {
+inline namespace StringLiterals {
+
+constexpr inline QLatin1String operator"" _L1(const char *str, size_t size) noexcept
+{
+ return QLatin1String(str, qsizetype(size));
+}
+
+inline QString operator"" _s(const char16_t *str, size_t size) noexcept
+{
+ return QString(QStringPrivate(nullptr, const_cast<char16_t *>(str), qsizetype(size)));
+}
+
+} // StringLiterals
+} // Literals
+} // Qt
+
+#endif // < 6.4
+
+#endif // QTCOMPAT_H
diff --git a/sources/shiboken6/ApiExtractor/qtdocparser.cpp b/sources/shiboken6/ApiExtractor/qtdocparser.cpp
index 9214dc6f4..5bd99bbd8 100644
--- a/sources/shiboken6/ApiExtractor/qtdocparser.cpp
+++ b/sources/shiboken6/ApiExtractor/qtdocparser.cpp
@@ -1,72 +1,69 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "qtdocparser.h"
+#include "classdocumentation.h"
+#include "abstractmetaargument.h"
#include "abstractmetaenum.h"
-#include "abstractmetafield.h"
#include "abstractmetafunction.h"
#include "abstractmetalang.h"
+#include "abstractmetatype.h"
#include "documentation.h"
#include "modifications.h"
#include "messages.h"
#include "propertyspec.h"
#include "reporthandler.h"
-#include "typesystem.h"
-#include "xmlutils.h"
+#include "flagstypeentry.h"
+#include "complextypeentry.h"
+#include "functiontypeentry.h"
+#include "enumtypeentry.h"
+
+#include "qtcompat.h"
#include <QtCore/QDir>
#include <QtCore/QFile>
-#include <QtCore/QTextStream>
-#include <QtCore/QXmlStreamAttributes>
-#include <QtCore/QXmlStreamReader>
-#include <QUrl>
+#include <QtCore/QUrl>
+
+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()
{
return retrieveModuleDocumentation(packageName());
}
-static void formatFunctionArgTypeQuery(QTextStream &str, const AbstractMetaArgument &arg)
+static void formatPreQualifications(QTextStream &str, const AbstractMetaType &type)
{
- const AbstractMetaType &metaType = arg.type();
- if (metaType.isConstant())
+ if (type.isConstant())
str << "const " ;
+}
+
+static void formatPostQualifications(QTextStream &str, const AbstractMetaType &type)
+{
+ if (type.referenceType() == LValueReference)
+ str << " &";
+ else if (type.referenceType() == RValueReference)
+ str << " &&";
+ else if (type.indirections())
+ str << ' ' << QByteArray(type.indirections(), '*');
+}
+
+static void formatFunctionUnqualifiedArgTypeQuery(QTextStream &str,
+ const AbstractMetaType &metaType)
+{
switch (metaType.typeUsagePattern()) {
case AbstractMetaType::FlagsPattern: {
// Modify qualified name "QFlags<Qt::AlignmentFlag>" with name "Alignment"
// to "Qt::Alignment" as seen by qdoc.
- const auto *flagsEntry = static_cast<const FlagsTypeEntry *>(metaType.typeEntry());
+ const auto flagsEntry = std::static_pointer_cast<const FlagsTypeEntry>(metaType.typeEntry());
QString name = flagsEntry->qualifiedCppName();
- if (name.endsWith(QLatin1Char('>')) && name.startsWith(QLatin1String("QFlags<"))) {
- const int lastColon = name.lastIndexOf(QLatin1Char(':'));
+ if (name.endsWith(u'>') && name.startsWith(u"QFlags<")) {
+ const int lastColon = name.lastIndexOf(u':');
if (lastColon != -1) {
name.replace(lastColon + 1, name.size() - lastColon - 1, metaType.name());
name.remove(0, 7);
@@ -80,10 +77,13 @@ static void formatFunctionArgTypeQuery(QTextStream &str, const AbstractMetaArgum
case AbstractMetaType::ContainerPattern: { // QVector<int>
str << metaType.typeEntry()->qualifiedCppName() << '<';
const auto instantiations = metaType.instantiations();
- for (int i = 0, size = instantiations.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = instantiations.size(); i < size; ++i) {
if (i)
str << ", ";
- str << instantiations.at(i).typeEntry()->qualifiedCppName();
+ const auto &instantiation = instantiations.at(i);
+ formatPreQualifications(str, instantiation);
+ str << instantiation.typeEntry()->qualifiedCppName();
+ formatPostQualifications(str, instantiation);
}
str << '>';
}
@@ -92,170 +92,209 @@ static void formatFunctionArgTypeQuery(QTextStream &str, const AbstractMetaArgum
str << metaType.typeEntry()->qualifiedCppName();
break;
}
-
- if (metaType.referenceType() == LValueReference)
- str << " &";
- else if (metaType.referenceType() == RValueReference)
- str << " &&";
- else if (metaType.indirections())
- str << ' ' << QByteArray(metaType.indirections(), '*');
}
-enum FunctionMatchFlags
-{
- MatchArgumentCount = 0x1,
- MatchArgumentType = 0x2,
- DescriptionOnly = 0x4
-};
-
-static QString functionXQuery(const QString &classQuery,
- const AbstractMetaFunctionCPtr &func,
- unsigned matchFlags = MatchArgumentCount | MatchArgumentType
- | DescriptionOnly)
+static QString formatFunctionArgTypeQuery(const AbstractMetaType &metaType)
{
QString result;
- QTextStream str(&result);
- const AbstractMetaArgumentList &arguments = func->arguments();
- str << classQuery << "/function[@name=\"" << func->originalName()
- << "\" and @const=\"" << (func->isConstant() ? "true" : "false") << '"';
- if (matchFlags & MatchArgumentCount)
- str << " and count(parameter)=" << arguments.size();
- str << ']';
- if (!arguments.isEmpty() && (matchFlags & MatchArgumentType)) {
- for (int i = 0, size = arguments.size(); i < size; ++i) {
- str << "/parameter[" << (i + 1) << "][@type=\"";
- // Fixme: Use arguments.at(i)->type()->originalTypeDescription()
- // instead to get unresolved typedefs?
- formatFunctionArgTypeQuery(str, arguments.at(i));
- str << "\"]/..";
- }
- }
- if (matchFlags & DescriptionOnly)
- str << "/description";
+ QTextStream str(&result);formatPreQualifications(str, metaType);
+ formatFunctionUnqualifiedArgTypeQuery(str, metaType);
+ formatPostQualifications(str, metaType);
return result;
}
-static QStringList signaturesFromWebXml(QString w)
+QString QtDocParser::functionDocumentation(const QString &sourceFileName,
+ const ClassDocumentation &classDocumentation,
+ const AbstractMetaClassCPtr &metaClass,
+ const AbstractMetaFunctionCPtr &func,
+ QString *errorMessage)
{
- QStringList result;
- if (w.isEmpty())
- return result;
- w.prepend(QLatin1String("<root>")); // Fake root element
- w.append(QLatin1String("</root>"));
- QXmlStreamReader reader(w);
- while (!reader.atEnd()) {
- if (reader.readNext() == QXmlStreamReader::StartElement
- && reader.name() == QLatin1String("function")) {
- result.append(reader.attributes().value(QStringLiteral("signature")).toString());
- }
- }
- return result;
-}
+ errorMessage->clear();
-static QString msgArgumentCountMatch(const AbstractMetaFunction *func,
- const QStringList &matches)
-{
- QString result;
- QTextStream str(&result);
- str << "\n Note: Querying for the argument count=="
- << func->arguments().size() << " only yields " << matches.size()
- << " matches";
- if (!matches.isEmpty())
- str << ": \"" << matches.join(QLatin1String("\", \"")) << '"';
- return result;
+ const QString docString =
+ queryFunctionDocumentation(sourceFileName, classDocumentation, metaClass,
+ func, errorMessage);
+
+ const auto funcModifs = DocParser::getXpathDocModifications(func, metaClass);
+ return docString.isEmpty() || funcModifs.isEmpty()
+ ? docString : applyDocModifications(funcModifs, docString);
}
QString QtDocParser::queryFunctionDocumentation(const QString &sourceFileName,
- const AbstractMetaClass* metaClass,
- const QString &classQuery,
+ const ClassDocumentation &classDocumentation,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaFunctionCPtr &func,
- const DocModificationList &signedModifs,
- const XQueryPtr &xquery,
QString *errorMessage)
{
- DocModificationList funcModifs;
- for (const DocModification &funcModif : signedModifs) {
- if (funcModif.signature() == func->minimalSignature())
- funcModifs.append(funcModif);
+ // Search candidates by name and const-ness
+ FunctionDocumentationList candidates =
+ classDocumentation.findFunctionCandidates(func->name(), func->isConstant());
+ if (candidates.isEmpty()) {
+ *errorMessage = msgCannotFindDocumentation(sourceFileName, func.get())
+ + u" (no matches)"_s;
+ return {};
}
- // Properties
- if (func->isPropertyReader() || func->isPropertyWriter() || func->isPropertyResetter()) {
- const auto prop = metaClass->propertySpecs().at(func->propertySpecIndex());
- const QString propertyQuery = classQuery + QLatin1String("/property[@name=\"")
- + prop.name() + QLatin1String("\"]/description");
- const QString properyDocumentation = getDocumentation(xquery, propertyQuery, funcModifs);
- if (properyDocumentation.isEmpty()) {
- *errorMessage =
- msgCannotFindDocumentation(sourceFileName, metaClass, func.data(),
- propertyQuery);
+ // Try an exact query
+ FunctionDocumentationQuery fq;
+ fq.name = func->name();
+ fq.constant = func->isConstant();
+ for (const auto &arg : func->arguments())
+ fq.parameters.append(formatFunctionArgTypeQuery(arg.type()));
+
+ const auto funcFlags = func->flags();
+ // Re-add arguments removed by the metabuilder to binary operator functions
+ if (funcFlags.testFlag(AbstractMetaFunction::Flag::OperatorLeadingClassArgumentRemoved)
+ || funcFlags.testFlag(AbstractMetaFunction::Flag::OperatorTrailingClassArgumentRemoved)) {
+ QString classType = metaClass->qualifiedCppName();
+ if (!funcFlags.testFlag(AbstractMetaFunction::Flag::OperatorClassArgumentByValue)) {
+ classType.prepend(u"const "_s);
+ classType.append(u" &"_s);
}
- return properyDocumentation;
+ if (funcFlags.testFlag(AbstractMetaFunction::Flag::OperatorLeadingClassArgumentRemoved))
+ fq.parameters.prepend(classType);
+ else
+ fq.parameters.append(classType);
}
- // Query with full match of argument types
- const QString fullQuery = functionXQuery(classQuery, func);
- const QString result = getDocumentation(xquery, fullQuery, funcModifs);
- if (!result.isEmpty())
- return result;
- *errorMessage = msgCannotFindDocumentation(sourceFileName, metaClass, func.data(), fullQuery);
- if (func->arguments().isEmpty()) // No arguments, can't be helped
- return result;
- // Test whether some mismatch in argument types occurred by checking for
- // the argument count only. Include the outer <function> element.
- QString countOnlyQuery = functionXQuery(classQuery, func, MatchArgumentCount);
- QStringList signatures =
- signaturesFromWebXml(getDocumentation(xquery, countOnlyQuery, funcModifs));
- if (signatures.size() == 1) {
- // One match was found. Repeat the query restricted to the <description>
- // element and use the result with a warning.
- countOnlyQuery = functionXQuery(classQuery, func, MatchArgumentCount | DescriptionOnly);
- errorMessage->append(QLatin1String("\n Falling back to \"") + signatures.constFirst()
- + QLatin1String("\" obtained by matching the argument count only."));
- return getDocumentation(xquery, countOnlyQuery, funcModifs);
+ const qsizetype index = ClassDocumentation::indexOfFunction(candidates, fq);
+
+ if (debugFunctionSearch) {
+ qDebug() << __FUNCTION__ << metaClass->name() << fq << funcFlags << "returns"
+ << index << "\n " << candidates.value(index) << "\n " << candidates;
}
- *errorMessage += msgArgumentCountMatch(func.data(), signatures);
- return result;
+
+ if (index != -1)
+ return candidates.at(index).description;
+
+ // Fallback: Try matching by argument count
+ const auto parameterCount = func->arguments().size();
+ auto pend = std::remove_if(candidates.begin(), candidates.end(),
+ [parameterCount](const FunctionDocumentation &fd) {
+ return fd.parameters.size() != parameterCount; });
+ candidates.erase(pend, candidates.end());
+ if (candidates.size() == 1) {
+ const auto &match = candidates.constFirst();
+ 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.get())
+ << " (" << candidates.size() << " candidates matching the argument count)";
+ return {};
}
// Extract the <brief> section from a WebXML (class) documentation and remove it
// 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(),
- QLatin1String("<rst> More_...</rst>"));
+ 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;
- const AbstractMetaClass* context = metaClass->enclosingClass();
- while(context) {
- if (context->enclosingClass() == nullptr)
+ auto context = metaClass->enclosingClass();
+ while (context) {
+ if (!context->enclosingClass())
break;
context = context->enclosingClass();
}
- QString sourceFileRoot = documentationDataDirectory() + QLatin1Char('/')
+ QString sourceFileRoot = documentationDataDirectory() + u'/'
+ metaClass->qualifiedCppName().toLower();
- sourceFileRoot.replace(QLatin1String("::"), QLatin1String("-"));
+ 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: "
@@ -265,33 +304,26 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
const QString sourceFileName = sourceFile.absoluteFilePath();
QString errorMessage;
- XQueryPtr xquery = XQuery::create(sourceFileName, &errorMessage);
- if (xquery.isNull()) {
+
+ const auto classDocumentationO = parseWebXml(sourceFileName, &errorMessage);
+ if (!classDocumentationO.has_value()) {
qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
return;
}
- QString className = metaClass->name();
-
- // Class/Namespace documentation
- const QString classQuery = QLatin1String("/WebXML/document/")
- + (metaClass->isNamespace() ? QLatin1String("namespace") : QLatin1String("class"))
- + QLatin1String("[@name=\"") + className + QLatin1String("\"]");
- QString query = classQuery + QLatin1String("/description");
-
- DocModificationList signedModifs, classModifs;
- const DocModificationList &mods = metaClass->typeEntry()->docModifications();
- for (const DocModification &docModif : mods) {
- if (docModif.signature().isEmpty())
- classModifs.append(docModif);
- else
- signedModifs.append(docModif);
+ const auto &classDocumentation = classDocumentationO.value();
+ for (const auto &p : classDocumentation.properties) {
+ Documentation doc(p.description, p.brief);
+ metaClass->setPropertyDocumentation(p.name, doc);
}
- QString docString = getDocumentation(xquery, query, classModifs);
+ QString docString = applyDocModifications(DocParser::getXpathDocModifications(metaClass),
+ classDocumentation.description);
+
if (docString.isEmpty()) {
+ QString className = metaClass->name();
qCWarning(lcShibokenDoc, "%s",
- qPrintable(msgCannotFindDocumentation(sourceFileName, "class", className, query)));
+ qPrintable(msgCannotFindDocumentation(sourceFileName, "class", className, {})));
}
const QString brief = extractBrief(&docString);
@@ -305,12 +337,12 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
const auto &funcs = DocParser::documentableFunctions(metaClass);
for (const auto &func : funcs) {
const QString detailed =
- queryFunctionDocumentation(sourceFileName, metaClass, classQuery,
- func, signedModifs, xquery, &errorMessage);
+ functionDocumentation(sourceFileName, classDocumentation,
+ metaClass, func, &errorMessage);
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
@@ -326,24 +358,41 @@ void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass)
#endif
// Enums
for (AbstractMetaEnum &meta_enum : metaClass->enums()) {
- query.clear();
- QTextStream(&query) << classQuery << "/enum[@name=\""
- << meta_enum.name() << "\"]/description";
- doc.setValue(getDocumentation(xquery, query, DocModificationList()));
- if (doc.isEmpty()) {
+ if (!extractEnumDocumentation(classDocumentation, meta_enum)) {
qCWarning(lcShibokenDoc, "%s",
- qPrintable(msgCannotFindDocumentation(sourceFileName, metaClass, meta_enum, query)));
+ qPrintable(msgCannotFindDocumentation(sourceFileName, metaClass, meta_enum, {})));
}
- meta_enum.setDocumentation(doc);
}
}
+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;
QTextStream(&result) << "<para>The module also provides <link"
- << " type=\"page\""
- << " page=\"http://doc.qt.io/qt-5/" << qmlModuleFi.baseName() << ".html\""
+ << R"( type="page" page="https://doc.qt.io/qt-)" << QT_VERSION_MAJOR
+ << '/' << qmlModuleFi.baseName() << R"(.html")"
<< ">QML types</link>.</para>";
return result;
}
@@ -353,13 +402,13 @@ Documentation QtDocParser::retrieveModuleDocumentation(const QString& name)
// TODO: This method of acquiring the module name supposes that the target language uses
// dots as module separators in package names. Improve this.
QString moduleName = name;
- moduleName.remove(0, name.lastIndexOf(QLatin1Char('.')) + 1);
- const QString prefix = documentationDataDirectory() + QLatin1Char('/')
+ moduleName.remove(0, name.lastIndexOf(u'.') + 1);
+ if (moduleName == u"QtQuickControls2")
+ moduleName.chop(1);
+ const QString prefix = documentationDataDirectory() + u'/'
+ moduleName.toLower();
- QString sourceFile = prefix + QLatin1String(".xml");
- if (!QFile::exists(sourceFile))
- sourceFile = prefix + QLatin1String("-module.webxml");
+ const QString sourceFile = prefix + u"-index.webxml"_s;
if (!QFile::exists(sourceFile)) {
qCWarning(lcShibokenDoc).noquote().nospace()
<< "Can't find qdoc file for module " << name << ", tried: "
@@ -368,27 +417,24 @@ Documentation QtDocParser::retrieveModuleDocumentation(const QString& name)
}
QString errorMessage;
- XQueryPtr xquery = XQuery::create(sourceFile, &errorMessage);
- if (xquery.isNull()) {
+ QString docString = webXmlModuleDescription(sourceFile, &errorMessage);
+ if (!errorMessage.isEmpty()) {
qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage));
return {};
}
- // Module documentation
- QString query = QLatin1String("/WebXML/document/module[@name=\"")
- + moduleName + QLatin1String("\"]/description");
- const QString detailed = getDocumentation(xquery, query, DocModificationList());
- Documentation doc(detailed, {});
+ Documentation doc(docString, {});
if (doc.isEmpty()) {
- qCWarning(lcShibokenDoc, "%s", qPrintable(msgCannotFindDocumentation(sourceFile, "module", name, query)));
+ qCWarning(lcShibokenDoc, "%s",
+ qPrintable(msgCannotFindDocumentation(sourceFile, "module", name)));
return doc;
}
// If a QML module info file exists, insert a link to the Qt docs.
- const QFileInfo qmlModuleFi(prefix + QLatin1String("-qmlmodule.webxml"));
+ const QFileInfo qmlModuleFi(prefix + u"-qmlmodule.webxml"_s);
if (qmlModuleFi.isFile()) {
QString docString = doc.detailed();
- const int pos = docString.lastIndexOf(QLatin1String("</description>"));
+ const int pos = docString.lastIndexOf(u"</description>");
if (pos != -1) {
docString.insert(pos, qmlReferenceLink(qmlModuleFi));
doc.setDetailed(docString);
diff --git a/sources/shiboken6/ApiExtractor/qtdocparser.h b/sources/shiboken6/ApiExtractor/qtdocparser.h
index 4cc335282..f6ba5e47a 100644
--- a/sources/shiboken6/ApiExtractor/qtdocparser.h
+++ b/sources/shiboken6/ApiExtractor/qtdocparser.h
@@ -1,52 +1,39 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef QTDOCPARSER_H
#define QTDOCPARSER_H
#include "docparser.h"
+struct ClassDocumentation;
+
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 AbstractMetaClassCPtr &metaClass,
+ const AbstractMetaFunctionCPtr &func,
+ QString *errorMessage);
+
static QString queryFunctionDocumentation(const QString &sourceFileName,
- const AbstractMetaClass* metaClass,
- const QString &classQuery,
+ const ClassDocumentation &classDocumentation,
+ const AbstractMetaClassCPtr &metaClass,
const AbstractMetaFunctionCPtr &func,
- const DocModificationList &signedModifs,
- const XQueryPtr &xquery,
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 f0c5bf31e..23066ba21 100644
--- a/sources/shiboken6/ApiExtractor/reporthandler.cpp
+++ b/sources/shiboken6/ApiExtractor/reporthandler.cpp
@@ -1,40 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "reporthandler.h"
-#include "typesystem.h"
#include "typedatabase.h"
+
+#include "qtcompat.h"
+
#include <QtCore/QElapsedTimer>
#include <QtCore/QSet>
#include <cstring>
#include <cstdarg>
#include <cstdio>
+using namespace Qt::StringLiterals;
+
#if defined(_WINDOWS) || defined(NOCOLOR)
#define COLOR_END ""
#define COLOR_WHITE ""
@@ -54,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;
@@ -84,11 +64,11 @@ void ReportHandler::setDebugLevel(ReportHandler::DebugLevel level)
bool ReportHandler::setDebugLevelFromArg(const QString &level)
{
bool result = true;
- if (level == QLatin1String("sparse"))
+ if (level == u"sparse")
ReportHandler::setDebugLevel(ReportHandler::SparseDebug);
- else if (level == QLatin1String("medium"))
+ else if (level == u"medium")
ReportHandler::setDebugLevel(ReportHandler::MediumDebug);
- else if (level == QLatin1String("full"))
+ else if (level == u"full")
ReportHandler::setDebugLevel(ReportHandler::FullDebug);
else
result = false;
@@ -123,7 +103,7 @@ void ReportHandler::setPrefix(const QString &p)
void ReportHandler::messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &text)
{
// Check for file location separator added by SourceLocation
- int fileLocationPos = text.indexOf(QLatin1String(":\t"));
+ int fileLocationPos = text.indexOf(u":\t");
if (type == QtWarningMsg) {
if (m_silent || m_reportedWarnings.contains(text))
return;
@@ -142,12 +122,12 @@ void ReportHandler::messageOutput(QtMsgType type, const QMessageLogContext &cont
}
QString message = m_prefix;
if (!message.isEmpty())
- message.append(QLatin1Char(' '));
- const int prefixLength = message.size();
+ message.append(u' ');
+ const auto prefixLength = message.size();
message.append(text);
// Replace file location tab by space
if (fileLocationPos >= 0)
- message[prefixLength + fileLocationPos + 1] = QLatin1Char(' ');
+ message[prefixLength + fileLocationPos + 1] = u' ';
fprintf(stderr, "%s\n", qPrintable(qFormatLogMessage(type, context, message)));
}
@@ -168,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()
@@ -179,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/reporthandler.h b/sources/shiboken6/ApiExtractor/reporthandler.h
index 21f0e8933..b79adfa73 100644
--- a/sources/shiboken6/ApiExtractor/reporthandler.h
+++ b/sources/shiboken6/ApiExtractor/reporthandler.h
@@ -1,36 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef REPORTHANDLER_H
#define REPORTHANDLER_H
-#include <QLoggingCategory>
-#include <QString>
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QString>
Q_DECLARE_LOGGING_CATEGORY(lcShiboken)
Q_DECLARE_LOGGING_CATEGORY(lcShibokenDoc)
diff --git a/sources/shiboken6/ApiExtractor/smartpointertypeentry.h b/sources/shiboken6/ApiExtractor/smartpointertypeentry.h
new file mode 100644
index 000000000..7b712fe35
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/smartpointertypeentry.h
@@ -0,0 +1,57 @@
+// 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 SMARTPOINTERTYPEENTRY_H
+#define SMARTPOINTERTYPEENTRY_H
+
+#include "complextypeentry.h"
+
+class SmartPointerTypeEntryPrivate;
+
+struct SmartPointerInstantiation
+{
+ QString name; // user defined name
+ TypeEntryCPtr typeEntry;
+};
+
+class SmartPointerTypeEntry : public ComplexTypeEntry
+{
+public:
+ using Instantiations = QList<SmartPointerInstantiation>;
+
+ explicit SmartPointerTypeEntry(const QString &entryName,
+ const QString &getterName,
+ TypeSystem::SmartPointerType type,
+ const QString &refCountMethodName,
+ const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ TypeSystem::SmartPointerType smartPointerType() const;
+
+ QString getter() const;
+
+ QString refCountMethodName() const;
+
+ QString valueCheckMethod() const;
+ void setValueCheckMethod(const QString &);
+ QString nullCheckMethod() const;
+ void setNullCheckMethod(const QString &);
+ QString resetMethod() const;
+ void setResetMethod(const QString &);
+
+ TypeEntry *clone() const override;
+
+ const Instantiations &instantiations() const;
+ void setInstantiations(const Instantiations &i);
+ bool matchesInstantiation(const TypeEntryCPtr &e) const;
+
+ QString getTargetName(const AbstractMetaType &metaType) const;
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+protected:
+ SmartPointerTypeEntry(SmartPointerTypeEntryPrivate *d);
+};
+
+#endif // SMARTPOINTERTYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/sourcelocation.cpp b/sources/shiboken6/ApiExtractor/sourcelocation.cpp
index 1ba66e05b..003f201ac 100644
--- a/sources/shiboken6/ApiExtractor/sourcelocation.cpp
+++ b/sources/shiboken6/ApiExtractor/sourcelocation.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "sourcelocation.h"
#include <QtCore/QDir>
diff --git a/sources/shiboken6/ApiExtractor/sourcelocation.h b/sources/shiboken6/ApiExtractor/sourcelocation.h
index 630a841d8..0b188dca3 100644
--- a/sources/shiboken6/ApiExtractor/sourcelocation.h
+++ b/sources/shiboken6/ApiExtractor/sourcelocation.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SOURCE_LOCATION_H
#define SOURCE_LOCATION_H
-#include <QString>
+#include <QtCore/QString>
QT_FORWARD_DECLARE_CLASS(QDebug)
QT_FORWARD_DECLARE_CLASS(QTextStream)
diff --git a/sources/shiboken6/ApiExtractor/templateargumententry.h b/sources/shiboken6/ApiExtractor/templateargumententry.h
new file mode 100644
index 000000000..9f2338022
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/templateargumententry.h
@@ -0,0 +1,26 @@
+// 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 TEMPLATEARGUMENTENTRY_H
+#define TEMPLATEARGUMENTENTRY_H
+
+#include "typesystem.h"
+
+class TemplateArgumentEntryPrivate;
+
+class TemplateArgumentEntry : public TypeEntry
+{
+public:
+ explicit TemplateArgumentEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ int ordinal() const;
+ void setOrdinal(int o);
+
+ TypeEntry *clone() const override;
+
+protected:
+ explicit TemplateArgumentEntry(TemplateArgumentEntryPrivate *d);
+};
+
+#endif // TEMPLATEARGUMENTENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/tests/CMakeLists.txt b/sources/shiboken6/ApiExtractor/tests/CMakeLists.txt
index 97ae0f850..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)
@@ -15,7 +18,7 @@ macro(declare_test testname)
${CMAKE_CURRENT_BINARY_DIR}
${apiextractor_SOURCE_DIR}
)
- target_link_libraries(${testname} PRIVATE apiextractor Qt${QT_MAJOR_VERSION}::Test)
+ target_link_libraries(${testname} PRIVATE apiextractor Qt::Test)
add_test(${testname} ${testname})
if (INSTALL_TESTS)
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${testname}
diff --git a/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp
index 850df753f..4b5da0c3a 100644
--- a/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.cpp
@@ -1,95 +1,77 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testabstractmetaclass.h"
#include "abstractmetabuilder.h"
-#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
#include <usingmember.h>
#include <typesystem.h>
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
void TestAbstractMetaClass::testClassName()
{
- const char* cppCode ="class ClassName {};";
- const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"ClassName\"/></typesystem>";
+ const char cppCode[] = "class ClassName {};";
+ const char xmlCode[] = R"(<typesystem package="Foo">
+ <value-type name="ClassName"/>
+</typesystem>)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 1);
- QCOMPARE(classes[0]->name(), QLatin1String("ClassName"));
+ QCOMPARE(classes.size(), 1);
+ QCOMPARE(classes[0]->name(), u"ClassName");
}
void TestAbstractMetaClass::testClassNameUnderNamespace()
{
- const char* cppCode ="namespace Namespace { class ClassName {}; }\n";
- const char* xmlCode = R"XML(
+ const char cppCode[] = "namespace Namespace { class ClassName {}; }\n";
+ const char xmlCode[] = R"XML(
<typesystem package="Foo">
<namespace-type name="Namespace">
<value-type name="ClassName"/>
</namespace-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2); // 1 namespace + 1 class
- if (classes.constFirst()->name() != QLatin1String("ClassName"))
+ QCOMPARE(classes.size(), 2); // 1 namespace + 1 class
+ if (classes.constFirst()->name() != u"ClassName")
qSwap(classes[0], classes[1]);
- QCOMPARE(classes[0]->name(), QLatin1String("ClassName"));
- QCOMPARE(classes[0]->qualifiedCppName(), QLatin1String("Namespace::ClassName"));
- QCOMPARE(classes[1]->name(), QLatin1String("Namespace"));
+ QCOMPARE(classes[0]->name(), u"ClassName");
+ QCOMPARE(classes[0]->qualifiedCppName(), u"Namespace::ClassName");
+ QCOMPARE(classes[1]->name(), u"Namespace");
QVERIFY(classes[1]->isNamespace());
// Check ctors info
QVERIFY(classes[0]->hasConstructors());
QCOMPARE(classes[0]->functions().size(), 2); // default ctor + copy ctor
- auto ctors = classes[0]->queryFunctions(FunctionQueryOption::Constructors);
+ auto ctors = classes[0]->queryFunctions(FunctionQueryOption::AnyConstructor);
QCOMPARE(ctors.size(), 2);
- if (ctors.constFirst()->minimalSignature() != QLatin1String("ClassName()"))
+ if (ctors.constFirst()->minimalSignature() != u"ClassName()")
qSwap(ctors[0], ctors[1]);
QCOMPARE(ctors[0]->arguments().size(), 0);
- QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("ClassName()"));
+ QCOMPARE(ctors[0]->minimalSignature(), u"ClassName()");
QCOMPARE(ctors[1]->arguments().size(), 1);
- QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("ClassName(Namespace::ClassName)"));
+ QCOMPARE(ctors[1]->minimalSignature(), u"ClassName(Namespace::ClassName)");
QVERIFY(!classes[0]->hasPrivateDestructor());
- QVERIFY(classes[0]->hasCloneOperator()); // implicit default copy ctor
- QVERIFY(!classes[0]->hasHashFunction());
+ QVERIFY(classes[0]->isCopyConstructible()); // implicit default copy ctor
// This method is buggy and nobody wants to fix it or needs it fixed :-/
// QVERIFY(classes[0]->hasNonPrivateConstructor());
}
-static AbstractMetaFunctionCList virtualFunctions(const AbstractMetaClass *c)
+static AbstractMetaFunctionCList virtualFunctions(const AbstractMetaClassCPtr &c)
{
AbstractMetaFunctionCList result;
const auto &functions = c->functions();
@@ -128,18 +110,16 @@ public:
</typesystem>
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 4);
- AbstractMetaClass* a = AbstractMetaClass::findClass(classes, QLatin1String("A"));
- AbstractMetaClass* b = AbstractMetaClass::findClass(classes, QLatin1String("B"));
- AbstractMetaClass* c = AbstractMetaClass::findClass(classes, QLatin1String("C"));
- const AbstractMetaClass *f = AbstractMetaClass::findClass(classes, QLatin1String("F"));
+ QCOMPARE(classes.size(), 4);
+ 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);
- AbstractMetaClass* no_class = nullptr;
-
- QCOMPARE(a->baseClass(), no_class);
+ QCOMPARE(a->baseClass(), nullptr);
QCOMPARE(b->baseClass(), a);
QCOMPARE(c->baseClass(), b);
QCOMPARE(f->baseClass(), c);
@@ -179,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);
@@ -214,48 +194,49 @@ 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, QLatin1String("Base"));
+ const auto base = AbstractMetaClass::findClass(classes, "Base");
QVERIFY(base);
QVERIFY(base->isPolymorphic());
- auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived"));
+ const auto derived = AbstractMetaClass::findClass(classes, "Derived");
QVERIFY(derived);
QVERIFY(derived->isPolymorphic());
}
void TestAbstractMetaClass::testDefaultValues()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
class B {};\n\
void method(B b = B());\n\
};\n";
- const char* xmlCode = R"XML(
+ const char xmlCode[] = R"XML(
<typesystem package="Foo">
<value-type name='A'>
<value-type name='B'/>
</value-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
- AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
- QCOMPARE(classA->queryFunctionsByName(QLatin1String("method")).count(), 1);
- const auto method = classA->queryFunctionsByName(QLatin1String("method")).constFirst();
+ QCOMPARE(classes.size(), 2);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto candidates = classA->queryFunctionsByName(u"method"_s);
+ QCOMPARE(candidates.size(), 1);
+ const auto &method = candidates.constFirst();
const AbstractMetaArgument &arg = method->arguments().constFirst();
QCOMPARE(arg.defaultValueExpression(), arg.originalDefaultValueExpression());
}
void TestAbstractMetaClass::testModifiedDefaultValues()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
class B {};\n\
void method(B b = B());\n\
};\n";
- const char* xmlCode = R"XML(
+ const char xmlCode[] = R"XML(
<typesystem package="Foo">
<value-type name='A'>
<modify-function signature='method(A::B)'>
@@ -267,39 +248,39 @@ 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.count(), 2);
- AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
- const auto methodMatches = classA->queryFunctionsByName(QLatin1String("method"));
- QCOMPARE(methodMatches.count(), 1);
+ QCOMPARE(classes.size(), 2);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto methodMatches = classA->queryFunctionsByName(u"method"_s);
+ QCOMPARE(methodMatches.size(), 1);
const auto method = methodMatches.constFirst();
const AbstractMetaArgument &arg = method->arguments().constFirst();
- QCOMPARE(arg.defaultValueExpression(), QLatin1String("Hello"));
- QCOMPARE(arg.originalDefaultValueExpression(), QLatin1String("A::B()"));
+ QCOMPARE(arg.defaultValueExpression(), u"Hello");
+ QCOMPARE(arg.originalDefaultValueExpression(), u"A::B()");
}
void TestAbstractMetaClass::testInnerClassOfAPolymorphicOne()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
class B {};\n\
virtual void method();\n\
};\n";
- const char* xmlCode = R"XML(
+ const char xmlCode[] = R"XML(
<typesystem package="Foo">
<object-type name='A'>
<value-type name='B'/>
</object-type>
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classes.size(), 2);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QVERIFY(classA->isPolymorphic());
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("A::B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "A::B");
QVERIFY(classB);
QVERIFY(!classB->isPolymorphic());
}
@@ -321,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.count(), 2);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classes.size(), 2);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("A::B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "A::B");
QVERIFY(classB);
- const auto fooF = classB->findFunction(QLatin1String("foo"));
- QVERIFY(!fooF.isNull());
+ const auto fooF = classB->findFunction("foo");
+ QVERIFY(fooF);
}
void TestAbstractMetaClass::testSpecialFunctions()
@@ -352,35 +333,35 @@ void TestAbstractMetaClass::testSpecialFunctions()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
+ QCOMPARE(classes.size(), 2);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- auto ctors = classA->queryFunctions(FunctionQueryOption::Constructors);
+ auto ctors = classA->queryFunctions(FunctionQueryOption::AnyConstructor);
QCOMPARE(ctors.size(), 2);
QCOMPARE(ctors.constFirst()->functionType(), AbstractMetaFunction::ConstructorFunction);
QCOMPARE(ctors.at(1)->functionType(), AbstractMetaFunction::CopyConstructorFunction);
- auto assigmentOps = classA->queryFunctionsByName(QLatin1String("operator="));
+ auto assigmentOps = classA->queryFunctionsByName(u"operator="_s);
QCOMPARE(assigmentOps.size(), 1);
QCOMPARE(assigmentOps.constFirst()->functionType(),
AbstractMetaFunction::AssignmentOperatorFunction);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
- ctors = classB->queryFunctions(FunctionQueryOption::Constructors);
+ ctors = classB->queryFunctions(FunctionQueryOption::AnyConstructor);
QCOMPARE(ctors.size(), 2);
QCOMPARE(ctors.constFirst()->functionType(), AbstractMetaFunction::ConstructorFunction);
QCOMPARE(ctors.at(1)->functionType(), AbstractMetaFunction::CopyConstructorFunction);
- assigmentOps = classA->queryFunctionsByName(QLatin1String("operator="));
+ assigmentOps = classA->queryFunctionsByName(u"operator="_s);
QCOMPARE(assigmentOps.size(), 1);
QCOMPARE(assigmentOps.constFirst()->functionType(), AbstractMetaFunction::AssignmentOperatorFunction);
}
void TestAbstractMetaClass::testClassDefaultConstructors()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {};\n\
\n\
struct B {\n\
@@ -406,7 +387,7 @@ void TestAbstractMetaClass::testClassDefaultConstructors()
struct F {\n\
F(int, int);\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='int'/>\n\
<value-type name='A'/>\n\
@@ -418,163 +399,163 @@ void TestAbstractMetaClass::testClassDefaultConstructors()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 6);
+ QCOMPARE(classes.size(), 6);
- AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->functions().size(), 2);
- auto ctors = classA->queryFunctions(FunctionQueryOption::Constructors);
+ auto ctors = classA->queryFunctions(FunctionQueryOption::AnyConstructor);
QCOMPARE(ctors.size(), 2);
- if (ctors.constFirst()->minimalSignature() != QLatin1String("A()"))
+ if (ctors.constFirst()->minimalSignature() != u"A()")
qSwap(ctors[0], ctors[1]);
QCOMPARE(ctors[0]->arguments().size(), 0);
- QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("A()"));
+ QCOMPARE(ctors[0]->minimalSignature(), u"A()");
QCOMPARE(ctors[1]->arguments().size(), 1);
- QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("A(A)"));
+ QCOMPARE(ctors[1]->minimalSignature(), u"A(A)");
- AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
QCOMPARE(classB->functions().size(), 2);
- QCOMPARE(classB->functions().constFirst()->minimalSignature(), QLatin1String("B()"));
+ QCOMPARE(classB->functions().constFirst()->minimalSignature(), u"B()");
- AbstractMetaClass* classC = AbstractMetaClass::findClass(classes, QLatin1String("C"));
+ const auto classC = AbstractMetaClass::findClass(classes, "C");
QVERIFY(classC);
QCOMPARE(classC->functions().size(), 1);
- QCOMPARE(classC->functions().constFirst()->minimalSignature(), QLatin1String("C(C)"));
+ QCOMPARE(classC->functions().constFirst()->minimalSignature(), u"C(C)");
- AbstractMetaClass* classD = AbstractMetaClass::findClass(classes, QLatin1String("D"));
+ const auto classD = AbstractMetaClass::findClass(classes, "D");
QVERIFY(classD);
QCOMPARE(classD->functions().size(), 1);
- QCOMPARE(classD->functions().constFirst()->minimalSignature(), QLatin1String("D(D)"));
+ QCOMPARE(classD->functions().constFirst()->minimalSignature(), u"D(D)");
QVERIFY(classD->functions().constFirst()->isPrivate());
- AbstractMetaClass* classE = AbstractMetaClass::findClass(classes, QLatin1String("E"));
+ const auto classE = AbstractMetaClass::findClass(classes, "E");
QVERIFY(classE);
QVERIFY(classE->hasPrivateDestructor());
QCOMPARE(classE->functions().size(), 0);
- AbstractMetaClass* classF = AbstractMetaClass::findClass(classes, QLatin1String("F"));
+ const auto classF = AbstractMetaClass::findClass(classes, "F");
QVERIFY(classF);
- ctors = classF->queryFunctions(FunctionQueryOption::Constructors);
+ ctors = classF->queryFunctions(FunctionQueryOption::AnyConstructor);
QCOMPARE(ctors.size(), 2);
- if (ctors.constFirst()->minimalSignature() != QLatin1String("F(int,int)"))
+ if (ctors.constFirst()->minimalSignature() != u"F(int,int)")
qSwap(ctors[0], ctors[1]);
QCOMPARE(ctors[0]->arguments().size(), 2);
- QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("F(int,int)"));
+ QCOMPARE(ctors[0]->minimalSignature(), u"F(int,int)");
QCOMPARE(ctors[1]->arguments().size(), 1);
- QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("F(F)"));
+ QCOMPARE(ctors[1]->minimalSignature(), u"F(F)");
}
void TestAbstractMetaClass::testClassInheritedDefaultConstructors()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
A();\n\
private: \n\
A(const A&);\n\
};\n\
struct B : public A {};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<object-type name='A'/>\n\
<object-type name='B'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
- AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classes.size(), 2);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- auto ctors = classA->queryFunctions(FunctionQueryOption::Constructors);
+ auto ctors = classA->queryFunctions(FunctionQueryOption::AnyConstructor);
QCOMPARE(ctors.size(), 2);
- if (ctors.constFirst()->minimalSignature() != QLatin1String("A()"))
+ if (ctors.constFirst()->minimalSignature() != u"A()")
qSwap(ctors[0], ctors[1]);
QCOMPARE(ctors[0]->arguments().size(), 0);
- QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("A()"));
+ QCOMPARE(ctors[0]->minimalSignature(), u"A()");
QCOMPARE(ctors[1]->arguments().size(), 1);
- QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("A(A)"));
+ QCOMPARE(ctors[1]->minimalSignature(), u"A(A)");
QVERIFY(ctors[1]->isPrivate());
- AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
ctors = classB->queryFunctions(FunctionQueryOption::Constructors);
QCOMPARE(ctors.size(), 1);
QCOMPARE(ctors.constFirst()->arguments().size(), 0);
- QCOMPARE(ctors.constFirst()->minimalSignature(), QLatin1String("B()"));
+ QCOMPARE(ctors.constFirst()->minimalSignature(), u"B()");
}
void TestAbstractMetaClass::testAbstractClassDefaultConstructors()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
virtual void method() = 0;\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<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.count(), 1);
- AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classes.size(), 1);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
const auto ctors = classA->queryFunctions(FunctionQueryOption::Constructors);
QCOMPARE(ctors.size(), 1);
QCOMPARE(ctors.constFirst()->arguments().size(), 0);
- QCOMPARE(ctors.constFirst()->minimalSignature(), QLatin1String("A()"));
+ QCOMPARE(ctors.constFirst()->minimalSignature(), u"A()");
}
void TestAbstractMetaClass::testObjectTypesMustNotHaveCopyConstructors()
{
- const char* cppCode ="struct A {};\n";
- const char* xmlCode = "\
+ const char cppCode[] = "struct A {};\n";
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<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.count(), 1);
- AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classes.size(), 1);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
const auto ctors = classA->queryFunctions(FunctionQueryOption::Constructors);
QCOMPARE(ctors.size(), 1);
QCOMPARE(ctors.constFirst()->arguments().size(), 0);
- QCOMPARE(ctors.constFirst()->minimalSignature(), QLatin1String("A()"));
+ QCOMPARE(ctors.constFirst()->minimalSignature(), u"A()");
}
void TestAbstractMetaClass::testIsPolymorphic()
{
- const char* cppCode = "\
+ const char cppCode[] = "\
class A\n\
{\n\
public:\n\
A();\n\
- inline bool abc() const {}\n\
+ inline bool abc() const { return false; }\n\
};\n\
\n\
class B : public A\n\
{\n\
public:\n\
B();\n\
- inline bool abc() const {}\n\
+ inline bool abc() const { return false; }\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='bool'/>\n\
<value-type name='A'/>\n\
@@ -582,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.count(), 2);
- AbstractMetaClass* b = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classes.size(), 2);
+ const auto b = AbstractMetaClass::findClass(classes, "A");
QVERIFY(!b->isPolymorphic());
- AbstractMetaClass* a = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto a = AbstractMetaClass::findClass(classes, "B");
QVERIFY(!a->isPolymorphic());
}
@@ -612,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.count(), 2);
- auto base = AbstractMetaClass::findClass(classes, QLatin1String("Base"));
+ QCOMPARE(classes.size(), 2);
+ const auto base = AbstractMetaClass::findClass(classes, "Base");
QVERIFY(base);
- auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived"));
+ const auto derived = AbstractMetaClass::findClass(classes, "Derived");
QVERIFY(derived);
QCOMPARE(derived->baseClasses().value(0), base);
}
@@ -663,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());
@@ -697,15 +678,15 @@ public:
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
- auto base = AbstractMetaClass::findClass(classes, QLatin1String("Base"));
+ QCOMPARE(classes.size(), 2);
+ const auto base = AbstractMetaClass::findClass(classes, "Base");
QVERIFY(base);
- auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived"));
+ const auto derived = AbstractMetaClass::findClass(classes, "Derived");
QVERIFY(derived);
const auto usingMembers = derived->usingMembers();
- QCOMPARE(usingMembers.count(), 2);
+ QCOMPARE(usingMembers.size(), 2);
for (const auto &um : usingMembers) {
QCOMPARE(um.access, Access::Public);
QCOMPARE(um.baseClass, base);
@@ -752,13 +733,46 @@ 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, QLatin1String("ValueList"));
+ const auto valueList = AbstractMetaClass::findClass(classes, "ValueList");
QVERIFY(valueList);
auto list = valueList->templateBaseClass();
- QVERIFY(valueList->isUsingMember(list, QLatin1String("append"), Access::Public));
- QCOMPARE(valueList->queryFunctionsByName(QLatin1String("append")).size(), 2);
+ QVERIFY(valueList->isUsingMember(list, u"append"_s, Access::Public));
+ QCOMPARE(valueList->queryFunctionsByName(u"append"_s).size(), 2);
+}
+
+void TestAbstractMetaClass::testGenerateFunctions()
+{
+ const char cppCode[] = R"CPP(
+class TestClass {
+public:
+ TestClass();
+
+ void alpha(int);
+ void beta(int);
+ void beta(double);
+ void gamma(int);
+};
+)CPP";
+
+ const char xmlCode[] = R"XML(
+<typesystem package='Foo'>
+ <object-type name='TestClass' generate-functions='beta(double);gamma'/>
+</typesystem>
+)XML";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(builder);
+ AbstractMetaClassList classes = builder->classes();
+ 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);
+ const auto generateCount =
+ std::count_if(functions.cbegin(), functions.cend(),
+ [](const auto &af) { return af->generateBinding(); });
+ QCOMPARE(generateCount, 3);
}
QTEST_APPLESS_MAIN(TestAbstractMetaClass)
diff --git a/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.h b/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.h
index ab171d6b7..a6bd2bf06 100644
--- a/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.h
+++ b/sources/shiboken6/ApiExtractor/tests/testabstractmetaclass.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTABSTRACTMETACLASS_H
#define TESTABSTRACTMETACLASS_H
-#include <QObject>
+#include <QtCore/QObject>
class AbstractMetaBuilder;
@@ -57,6 +32,7 @@ private slots:
void testUsingMembers();
void testUsingTemplateMembers_data();
void testUsingTemplateMembers();
+ void testGenerateFunctions();
};
#endif // TESTABSTRACTMETACLASS_H
diff --git a/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
index 897940cd5..2c320c874 100644
--- a/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.cpp
@@ -1,40 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testabstractmetatype.h"
-#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
+#include <abstractmetatype.h>
#include <typesystem.h>
#include <parser/codemodel.h>
#include <typeparser.h>
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
void TestAbstractMetaType::parsing_data()
{
QTest::addColumn<QString>("input");
@@ -66,20 +48,20 @@ void TestAbstractMetaType::parsing()
void TestAbstractMetaType::testConstCharPtrType()
{
- const char* cppCode ="const char* justAtest();\n";
- const char* xmlCode = "<typesystem package=\"Foo\">\n\
+ const char cppCode[] = "const char* justAtest();\n";
+ const char xmlCode[] = "<typesystem package=\"Foo\">\n\
<primitive-type name='char'/>\n\
<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();
// Test properties of const char*
QVERIFY(!rtype.isVoid());
- QCOMPARE(rtype.package(), QLatin1String("Foo"));
- QCOMPARE(rtype.name(), QLatin1String("char"));
+ QCOMPARE(rtype.package(), u"Foo");
+ QCOMPARE(rtype.name(), u"char");
QVERIFY(rtype.isConstant());
QVERIFY(!rtype.isArray());
QVERIFY(!rtype.isContainer());
@@ -93,9 +75,9 @@ void TestAbstractMetaType::testConstCharPtrType()
void TestAbstractMetaType::testApiVersionSupported()
{
- const char* cppCode ="class foo {}; class foo2 {};\n\
+ const char cppCode[] = "class foo {}; class foo2 {};\n\
void justAtest(); void justAtest3();\n";
- const char* xmlCode = "<typesystem package='Foo'>\n\
+ const char xmlCode[] = "<typesystem package='Foo'>\n\
<value-type name='foo' since='0.1'/>\n\
<value-type name='foo2' since='1.0'/>\n\
<value-type name='foo3' since='1.1'/>\n\
@@ -104,8 +86,8 @@ void TestAbstractMetaType::testApiVersionSupported()
<function signature='justAtest3()'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
- false, QLatin1String("1.0")));
- QVERIFY(!builder.isNull());
+ false, u"1.0"_s));
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 2);
@@ -117,13 +99,13 @@ void TestAbstractMetaType::testApiVersionSupported()
void TestAbstractMetaType::testApiVersionNotSupported()
{
- const char* cppCode ="class object {};\n";
- const char* xmlCode = "<typesystem package='Foo'>\n\
+ const char cppCode[] = "class object {};\n";
+ const char xmlCode[] = "<typesystem package='Foo'>\n\
<value-type name='object' since='0.1'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
- true, QLatin1String("0.1")));
- QVERIFY(!builder.isNull());
+ true, u"0.1"_s));
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
QCOMPARE(classes.size(), 1);
@@ -131,18 +113,18 @@ void TestAbstractMetaType::testApiVersionNotSupported()
void TestAbstractMetaType::testCharType()
{
- const char* cppCode ="char justAtest(); class A {};\n";
- const char* xmlCode = "<typesystem package=\"Foo\">\n\
+ const char cppCode[] = "char justAtest(); class A {};\n";
+ const char xmlCode[] = "<typesystem package=\"Foo\">\n\
<primitive-type name='char'/>\n\
<value-type name='A'/>\n\
<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);
- QCOMPARE(classes.constFirst()->package(), QLatin1String("Foo"));
+ QCOMPARE(classes.constFirst()->package(), u"Foo");
const auto functions = builder->globalFunctions();
QCOMPARE(functions.size(), 1);
@@ -150,8 +132,8 @@ void TestAbstractMetaType::testCharType()
AbstractMetaType rtype = func->type();
// Test properties of const char*
QVERIFY(!rtype.isVoid());
- QCOMPARE(rtype.package(), QLatin1String("Foo"));
- QCOMPARE(rtype.name(), QLatin1String("char"));
+ QCOMPARE(rtype.package(), u"Foo");
+ QCOMPARE(rtype.name(), u"char");
QVERIFY(!rtype.isConstant());
QVERIFY(!rtype.isArray());
QVERIFY(!rtype.isContainer());
@@ -165,28 +147,28 @@ void TestAbstractMetaType::testCharType()
void TestAbstractMetaType::testTypedef()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
void someMethod();\n\
};\n\
typedef A B;\n\
typedef B C;\n";
- const char* xmlCode = "<typesystem package=\"Foo\">\n\
+ const char xmlCode[] = "<typesystem package=\"Foo\">\n\
<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, QLatin1String("C"));
+ const auto c = AbstractMetaClass::findClass(classes, "C");
QVERIFY(c);
QVERIFY(c->isTypeDef());
}
void TestAbstractMetaType::testTypedefWithTemplates()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
template<typename T>\n\
class A {};\n\
\n\
@@ -194,52 +176,52 @@ void TestAbstractMetaType::testTypedefWithTemplates()
typedef A<B> C;\n\
\n\
void func(C c);\n";
- const char* xmlCode = "<typesystem package=\"Foo\">\n\
+ const char xmlCode[] = "<typesystem package=\"Foo\">\n\
<container-type name='A' type='list'/>\n\
<value-type name='B' />\n\
<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);
const auto functions = builder->globalFunctions();
- QCOMPARE(functions.count(), 1);
+ QCOMPARE(functions.size(), 1);
const auto function = functions.constFirst();
AbstractMetaArgumentList args = function->arguments();
- QCOMPARE(args.count(), 1);
+ QCOMPARE(args.size(), 1);
const AbstractMetaArgument &arg = args.constFirst();
AbstractMetaType metaType = arg.type();
- QCOMPARE(metaType.cppSignature(), QLatin1String("A<B >"));
+ QCOMPARE(metaType.cppSignature(), u"A<B>");
}
void TestAbstractMetaType::testObjectTypeUsedAsValue()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
class A {\n\
void method(A);\n\
};\n";
- const char* xmlCode = "<typesystem package='Foo'>\n\
+ const char xmlCode[] = "<typesystem package='Foo'>\n\
<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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto overloads = classA->queryFunctionsByName(QLatin1String("method"));
- QCOMPARE(overloads.count(), 1);
+ const auto overloads = classA->queryFunctionsByName(u"method"_s);
+ QCOMPARE(overloads.size(), 1);
const auto method = overloads.constFirst();
QVERIFY(method);
AbstractMetaArgumentList args = method->arguments();
- QCOMPARE(args.count(), 1);
+ QCOMPARE(args.size(), 1);
const AbstractMetaArgument &arg = args.constFirst();
AbstractMetaType metaType = arg.type();
- QCOMPARE(metaType.cppSignature(), QLatin1String("A"));
+ QCOMPARE(metaType.cppSignature(), u"A");
QVERIFY(metaType.isValue());
QVERIFY(metaType.typeEntry()->isObject());
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.h b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.h
index b39a27a54..fdcf0c787 100644
--- a/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.h
+++ b/sources/shiboken6/ApiExtractor/tests/testabstractmetatype.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTABSTRACTMETATYPE_H
#define TESTABSTRACTMETATYPE_H
-#include <QObject>
+#include <QtCore/QObject>
class TestAbstractMetaType : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp
index 1c5e31f35..a891e1e28 100644
--- a/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testaddfunction.cpp
@@ -1,80 +1,67 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testaddfunction.h"
-#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
-#include <modifications.h>
-#include <modifications_p.h>
-#include <typesystem.h>
+#include <abstractmetatype.h>
+#include <codesnip.h>
+#include <addedfunction.h>
+#include <addedfunction_p.h>
+#include <complextypeentry.h>
+#include <primitivetypeentry.h>
+
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+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(QLatin1String(sig1), QLatin1String("void"),
- &errorMessage);
- QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
- QCOMPARE(f1->name(), QLatin1String("func"));
- QCOMPARE(f1->arguments().count(), 3);
+ 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{QLatin1String("void")});
+ 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(QLatin1String(sig2),
- QLatin1String("const Abc<int& , C<char*> * > * *"),
+ 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));
- QCOMPARE(f2->name(), QLatin1String("_fu__nc_"));
+ QVERIFY2(f2, qPrintable(errorMessage));
+ QCOMPARE(f2->name(), u"_fu__nc_");
const auto &args = f2->arguments();
- QCOMPARE(args.count(), 4);
+ QCOMPARE(args.size(), 4);
retval = f2->returnType();
- QCOMPARE(retval.qualifiedName(), QStringList{QLatin1String("Abc")});
+ QCOMPARE(retval.qualifiedName(), QStringList{u"Abc"_s});
QCOMPARE(retval.instantiations().size(), 2);
- QCOMPARE(retval.toString(), QLatin1String("const Abc<int&, C<char*>*>**"));
+ QCOMPARE(retval.toString(), u"const Abc<int&, C<char*>*>**");
QCOMPARE(retval.indirections(), 2);
QCOMPARE(retval.isConstant(), true);
QCOMPARE(retval.referenceType(), NoReference);
QVERIFY(args.at(0).name.isEmpty());
QVERIFY(args.at(1).name.isEmpty());
- QCOMPARE(args.at(2).name, QLatin1String("my_name"));
+ QCOMPARE(args.at(2).name, u"my_name");
auto arg2Type = args.at(2).typeInfo;
- QCOMPARE(arg2Type.qualifiedName(), QStringList{QLatin1String("Abc")});
+ QCOMPARE(arg2Type.qualifiedName(), QStringList{u"Abc"_s});
QCOMPARE(arg2Type.instantiations().size(), 2);
- QCOMPARE(arg2Type.toString(), QLatin1String("const Abc<int&, C<char*>*>**"));
+ QCOMPARE(arg2Type.toString(), u"const Abc<int&, C<char*>*>**");
QCOMPARE(arg2Type.indirections(), 2);
QCOMPARE(arg2Type.isConstant(), true);
QCOMPARE(arg2Type.referenceType(), NoReference);
@@ -82,20 +69,17 @@ void TestAddFunction::testParsingFuncNameAndConstness()
QVERIFY(args.at(3).name.isEmpty());
// function with no args.
- const char sig3[] = "func()";
- auto f3 = AddedFunction::createAddedFunction(QLatin1String(sig3), QLatin1String("void"),
- &errorMessage);
- QVERIFY2(!f3.isNull(), qPrintable(errorMessage));
- QCOMPARE(f3->name(), QLatin1String("func"));
- QCOMPARE(f3->arguments().count(), 0);
+ 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(QLatin1String(sig4), QLatin1String("int"),
- &errorMessage);
- QVERIFY2(!f4.isNull(), qPrintable(errorMessage));
- QCOMPARE(f4->name(), QLatin1String("operator()"));
- QCOMPARE(f4->arguments().count(), 1);
+ 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());
}
@@ -118,14 +102,15 @@ struct A {
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
- TypeDatabase* typeDb = TypeDatabase::instance();
+ QVERIFY(builder);
+ auto *typeDb = TypeDatabase::instance();
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- QCOMPARE(classA->functions().count(), 5); // default ctor, default copy ctor, func a() and the added functions
+ // default ctor, default copy ctor, func a() and the added functions
+ QCOMPARE(classA->functions().size(), 5);
- auto addedFunc = classA->findFunction(QLatin1String("b"));
+ auto addedFunc = classA->findFunction("b");
QVERIFY(addedFunc);
QCOMPARE(addedFunc->access(), Access::Protected);
QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction);
@@ -139,14 +124,14 @@ struct A {
QVERIFY(!addedFunc->isStatic());
AbstractMetaType returnType = addedFunc->type();
- QCOMPARE(returnType.typeEntry(), typeDb->findPrimitiveType(QLatin1String("int")));
+ QCOMPARE(returnType.typeEntry(), typeDb->findPrimitiveType(u"int"_s));
const AbstractMetaArgumentList &args = addedFunc->arguments();
- QCOMPARE(args.count(), 3);
+ QCOMPARE(args.size(), 3);
QCOMPARE(args.at(0).type().typeEntry(), returnType.typeEntry());
- QCOMPARE(args.at(1).defaultValueExpression(), QLatin1String("4.6"));
- QCOMPARE(args.at(2).type().typeEntry(), typeDb->findType(QLatin1String("B")));
+ QCOMPARE(args.at(1).defaultValueExpression(), u"4.6");
+ QCOMPARE(args.at(2).type().typeEntry(), typeDb->findType(u"B"_s));
- auto addedCallOperator = classA->findFunction(QLatin1String("operator()"));
+ auto addedCallOperator = classA->findFunction("operator()");
QVERIFY(addedCallOperator);
}
@@ -161,11 +146,11 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- QCOMPARE(classA->functions().count(), 3); // default and added ctors
+ QCOMPARE(classA->functions().size(), 3); // default and added ctors
const auto addedFunc = classA->functions().constLast();
QCOMPARE(addedFunc->access(), Access::Public);
QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::ConstructorFunction);
@@ -184,11 +169,12 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- QCOMPARE(classA->functions().count(), 3); // default ctor, default copy ctor and the added function
+ // default ctor, default copy ctor and the added function
+ QCOMPARE(classA->functions().size(), 3);
const auto addedFunc = classA->functions().constLast();
QCOMPARE(addedFunc->access(), Access::Public);
QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction);
@@ -209,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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
const auto addedFunc = classA->functions().constLast();
QVERIFY(addedFunc->hasInjectedCode());
@@ -219,13 +205,12 @@ void TestAddFunction::testAddFunctionCodeSnippets()
void TestAddFunction::testAddFunctionWithoutParenteses()
{
- const char sig1[] = "func";
+ static constexpr auto sig1 = "func"_L1;
QString errorMessage;
- auto f1 = AddedFunction::createAddedFunction(QLatin1String(sig1), QLatin1String("void"),
- &errorMessage);
- QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
- QCOMPARE(f1->name(), QLatin1String("func"));
- QCOMPARE(f1->arguments().count(), 0);
+ 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);
const char cppCode[] = "struct A {};\n";
@@ -239,25 +224,26 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(QLatin1String("func"));
- QVERIFY(!addedFunc.isNull());
+ const auto addedFunc = classA->findFunction(sig1);
+ QVERIFY(addedFunc);
QVERIFY(addedFunc->hasInjectedCode());
- QCOMPARE(addedFunc->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode).count(), 1);
+ const auto snips = addedFunc->injectedCodeSnips(TypeSystem::CodeSnipPositionAny,
+ TypeSystem::TargetLangCode);
+ QCOMPARE(snips.size(), 1);
}
void TestAddFunction::testAddFunctionWithDefaultArgs()
{
- const char sig1[] = "func";
+ static constexpr auto sig1 = "func"_L1;
QString errorMessage;
- auto f1 = AddedFunction::createAddedFunction(QLatin1String(sig1), QLatin1String("void"),
- &errorMessage);
- QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
- QCOMPARE(f1->name(), QLatin1String("func"));
- QCOMPARE(f1->arguments().count(), 0);
+ 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);
const char cppCode[] = "struct A { };\n";
@@ -274,14 +260,14 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(QLatin1String("func"));
- QVERIFY(!addedFunc.isNull());
+ const auto addedFunc = classA->findFunction(sig1);
+ QVERIFY(addedFunc);
const AbstractMetaArgument &arg = addedFunc->arguments().at(1);
- QCOMPARE(arg.defaultValueExpression(), QLatin1String("2"));
+ QCOMPARE(arg.defaultValueExpression(), u"2");
}
void TestAddFunction::testAddFunctionAtModuleLevel()
@@ -297,34 +283,33 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- TypeDatabase* typeDb = TypeDatabase::instance();
+ auto *typeDb = TypeDatabase::instance();
- AddedFunctionList addedFuncs = typeDb->findGlobalUserFunctions(QLatin1String("func"));
+ AddedFunctionList addedFuncs = typeDb->findGlobalUserFunctions(u"func"_s);
QCOMPARE(addedFuncs.size(), 1);
- const FunctionModificationList mods = addedFuncs.constFirst()->modifications;
+ auto &mods = addedFuncs.constFirst()->modifications();
QCOMPARE(mods.size(), 1);
QVERIFY(mods.constFirst().isCodeInjection());
CodeSnip snip = mods.constFirst().snips().constFirst();
- QCOMPARE(snip.code().trimmed(), QLatin1String("custom_code();"));
+ QCOMPARE(snip.code().trimmed(), u"custom_code();");
}
void TestAddFunction::testAddFunctionWithVarargs()
{
- const char sig1[] = "func(int,char,...)";
QString errorMessage;
- auto f1 = AddedFunction::createAddedFunction(QLatin1String(sig1), QLatin1String("void"),
+ auto f1 = AddedFunction::createAddedFunction("func(int,char,...)"_L1, voidT,
&errorMessage);
- QVERIFY2(!f1.isNull(), qPrintable(errorMessage));
- QCOMPARE(f1->name(), QLatin1String("func"));
- QCOMPARE(f1->arguments().count(), 3);
+ QVERIFY2(f1, qPrintable(errorMessage));
+ QCOMPARE(f1->name(), u"func");
+ QCOMPARE(f1->arguments().size(), 3);
QVERIFY(!f1->isConstant());
const char cppCode[] = "struct A {};\n";
@@ -338,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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(QLatin1String("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());
@@ -362,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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(QLatin1String("func"));
- QVERIFY(!addedFunc.isNull());
+ const auto addedFunc = classA->findFunction("func");
+ QVERIFY(addedFunc);
QVERIFY(addedFunc->isStatic());
}
@@ -387,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.count(), 2);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(builder->classes(), QLatin1String("B"));
+ QCOMPARE(globalFuncs.size(), 2);
+ const auto classB = AbstractMetaClass::findClass(builder->classes(), "B");
QVERIFY(classB);
- QVERIFY(!classB->findFunction(QLatin1String("globalFunc")));
- QVERIFY(!classB->findFunction(QLatin1String("globalFunc2")));
+ QVERIFY(!classB->findFunction("globalFunc"));
+ QVERIFY(!classB->findFunction("globalFunc2"));
QVERIFY(!globalFuncs[0]->injectedCodeSnips().isEmpty());
QVERIFY(!globalFuncs[1]->injectedCodeSnips().isEmpty());
}
@@ -412,10 +397,10 @@ void TestAddFunction::testAddFunctionWithApiVersion()
</add-function>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
- true, QLatin1String("0.1")));
- QVERIFY(!builder.isNull());
+ true, u"0.1"_s));
+ QVERIFY(builder);
const auto globalFuncs = builder->globalFunctions();
- QCOMPARE(globalFuncs.count(), 1);
+ QCOMPARE(globalFuncs.size(), 1);
}
void TestAddFunction::testModifyAddedFunction()
@@ -436,16 +421,16 @@ void TestAddFunction::testModifyAddedFunction()
</typesystem>
)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- AbstractMetaClass* foo = AbstractMetaClass::findClass(classes, QLatin1String("Foo"));
- const auto method = foo->findFunction(QLatin1String("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(), QLatin1String("0"));
- QCOMPARE(arg.name(), QLatin1String("varName"));
- QCOMPARE(method->argumentName(2), QLatin1String("varName"));
+ QCOMPARE(arg.defaultValueExpression(), u"0");
+ QCOMPARE(arg.name(), u"varName");
+ QCOMPARE(method->argumentName(2), u"varName");
}
void TestAddFunction::testAddFunctionOnTypedef()
@@ -453,8 +438,6 @@ void TestAddFunction::testAddFunctionOnTypedef()
const char cppCode[] = "template<class T> class Foo { }; typedef Foo<int> FooInt;\n";
const char xmlCode[] = "\
<typesystem package='Package'>\n\
- <custom-type name='PySequence'/>\n\
- <primitive-type name='int'/>\n\
<value-type name='FooInt'>\n\
<add-function signature='FooInt(PySequence)'>\n\
<inject-code class='target' position='beginning'>custom_code();</inject-code>\n\
@@ -465,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();
- AbstractMetaClass* foo = AbstractMetaClass::findClass(classes, QLatin1String("FooInt"));
+ const auto foo = AbstractMetaClass::findClass(classes, "FooInt");
QVERIFY(foo);
QVERIFY(foo->hasNonPrivateConstructor());
- const auto &lst = foo->queryFunctions(FunctionQueryOption::Constructors);
+ 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(QLatin1String("method"));
- QVERIFY(!method.isNull());
+ const auto method = foo->findFunction("method");
+ QVERIFY(method);
}
void TestAddFunction::testAddFunctionWithTemplateArg()
@@ -489,11 +472,11 @@ 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();
- QCOMPARE(arg.type().instantiations().count(), 1);
+ QCOMPARE(arg.type().instantiations().size(), 1);
}
// Test splitting of <add-function> parameter lists.
@@ -512,18 +495,18 @@ void TestAddFunction::testAddFunctionTypeParser_data()
QTest::newRow("1-arg")
<< QString::fromLatin1("int @a@=42")
- << Arguments{{QLatin1String("int"), QLatin1String("a"), QLatin1String("42")}};
+ << Arguments{{u"int"_s, u"a"_s, u"42"_s}};
QTest::newRow("2-args")
<< QString::fromLatin1("double @d@, int @a@=42")
- << Arguments{{QLatin1String("double"), QLatin1String("d"), {}},
- {QLatin1String("int"), QLatin1String("a"), QLatin1String("42")}};
+ << Arguments{{u"double"_s, u"d"_s, {}},
+ {u"int"_s, u"a"_s, u"42"_s}};
QTest::newRow("template-var_args")
<< QString::fromLatin1("const QList<X,Y> &@list@ = QList<X,Y>{1,2}, int @b@=5, ...")
- << Arguments{{QLatin1String("const QList<X,Y> &"), QLatin1String("list"), QLatin1String("QList<X,Y>{1,2}")},
- {QLatin1String("int"), QLatin1String("b"), QLatin1String("5")},
- {QLatin1String("..."), {}, {}}};
+ << Arguments{{u"const QList<X,Y> &"_s, u"list"_s, u"QList<X,Y>{1,2}"_s},
+ {u"int"_s, u"b"_s, u"5"_s},
+ {u"..."_s, {}, {}}};
}
void TestAddFunction::testAddFunctionTypeParser()
diff --git a/sources/shiboken6/ApiExtractor/tests/testaddfunction.h b/sources/shiboken6/ApiExtractor/tests/testaddfunction.h
index 195633030..77339609f 100644
--- a/sources/shiboken6/ApiExtractor/tests/testaddfunction.h
+++ b/sources/shiboken6/ApiExtractor/tests/testaddfunction.h
@@ -1,34 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTADDFUNCTION_H
#define TESTADDFUNCTION_H
-#include <QObject>
+#include <QtCore/QObject>
class TestAddFunction : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp b/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp
index 22cf7ab40..6e1820bed 100644
--- a/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testarrayargument.cpp
@@ -1,48 +1,30 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testarrayargument.h"
-#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetaenum.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
-#include <typesystem.h>
+#include <abstractmetatype.h>
+#include <primitivetypeentry.h>
#include <parser/enumvalue.h>
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
void TestArrayArgument::testArrayArgumentWithSizeDefinedByInteger()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
enum SomeEnum { Value0, Value1, NValues };\n\
void method(double[3]);\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='double'/>\n\
<object-type name='A'>\n\
@@ -52,19 +34,19 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByInteger()
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
QVERIFY(!builder.isNull());
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
const AbstractMetaArgument &arg = classA->functions().constLast()->arguments().constFirst();
QVERIFY(arg.type().isArray());
QCOMPARE(arg.type().arrayElementCount(), 3);
- QCOMPARE(arg.type().arrayElementType()->name(), QLatin1String("double"));
+ 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()
@@ -90,33 +72,33 @@ void TestArrayArgument::testArraySignature()
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
QVERIFY(!builder.isNull());
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
- QCOMPARE(functionMinimalSignature(classA, QLatin1String("mi1")),
- QLatin1String("mi1(int[5])"));
- QCOMPARE(functionMinimalSignature(classA, QLatin1String("mi1c")),
- QLatin1String("mi1c(const int[5])"));
- QCOMPARE(functionMinimalSignature(classA, QLatin1String("mi1cu")),
- QLatin1String("mi1cu(const int[])"));
- QCOMPARE(functionMinimalSignature(classA, QLatin1String("mc1cu")),
- QLatin1String("mc1cu(const char*)"));
- QCOMPARE(functionMinimalSignature(classA, QLatin1String("mc1cup")),
- QLatin1String("mc1cup(const char*[])"));
- QCOMPARE(functionMinimalSignature(classA, QLatin1String("muc2")),
- QLatin1String("muc2(unsigned char*[2][3])"));
- QCOMPARE(functionMinimalSignature(classA, QLatin1String("mc2c")),
- QLatin1String("mc2c(const char*[5][6])"));
- QCOMPARE(functionMinimalSignature(classA, QLatin1String("mc2cu")),
- QLatin1String("mc2cu(const char[][2])"));
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
+ QCOMPARE(functionMinimalSignature(classA, u"mi1"_s),
+ u"mi1(int[5])");
+ QCOMPARE(functionMinimalSignature(classA, u"mi1c"_s),
+ u"mi1c(const int[5])");
+ QCOMPARE(functionMinimalSignature(classA, u"mi1cu"_s),
+ u"mi1cu(const int[])");
+ QCOMPARE(functionMinimalSignature(classA, u"mc1cu"_s),
+ u"mc1cu(const char*)");
+ QCOMPARE(functionMinimalSignature(classA, u"mc1cup"_s),
+ u"mc1cup(const char*[])");
+ QCOMPARE(functionMinimalSignature(classA, u"muc2"_s),
+ u"muc2(unsigned char*[2][3])");
+ QCOMPARE(functionMinimalSignature(classA, u"mc2c"_s),
+ u"mc2c(const char*[5][6])");
+ QCOMPARE(functionMinimalSignature(classA, u"mc2cu"_s),
+ u"mc2cu(const char[][2])");
}
void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValue()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
enum SomeEnum { Value0, Value1, NValues };\n\
void method(double[NValues]);\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='double'/>\n\
<object-type name='A'>\n\
@@ -126,28 +108,28 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValue()
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
QVERIFY(!builder.isNull());
- AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ AbstractMetaClassPtr classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
- auto someEnum = classA->findEnum(QLatin1String("SomeEnum"));
+ auto someEnum = classA->findEnum(u"SomeEnum"_s);
QVERIFY(someEnum.has_value());
- auto nvalues = classA->findEnumValue(QLatin1String("NValues"));
+ auto nvalues = classA->findEnumValue(u"NValues"_s);
QVERIFY(nvalues.has_value());
const AbstractMetaArgument &arg = classA->functions().constLast()->arguments().constFirst();
QVERIFY(arg.type().isArray());
QCOMPARE(arg.type().arrayElementCount(), nvalues->value().value());
- QCOMPARE(arg.type().arrayElementType()->name(), QLatin1String("double"));
+ QCOMPARE(arg.type().arrayElementType()->name(), u"double");
};
void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnum()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
enum SomeEnum { Value0, Value1, NValues };\n\
struct A {\n\
void method(double[NValues]);\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='double'/>\n\
<enum-type name='SomeEnum'/>\n\
@@ -156,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(), QLatin1String("A"));
+ QVERIFY(builder);
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
AbstractMetaEnum someEnum = builder->globalEnums().constFirst();
@@ -167,7 +149,7 @@ void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnu
const AbstractMetaArgument &arg = classA->functions().constLast()->arguments().constFirst();
QVERIFY(arg.type().isArray());
QCOMPARE(arg.type().arrayElementCount(), nvalues->value().value());
- QCOMPARE(arg.type().arrayElementType()->name(), QLatin1String("double"));
+ QCOMPARE(arg.type().arrayElementType()->name(), u"double");
};
QTEST_APPLESS_MAIN(TestArrayArgument)
diff --git a/sources/shiboken6/ApiExtractor/tests/testarrayargument.h b/sources/shiboken6/ApiExtractor/tests/testarrayargument.h
index 2e58ae6ee..75ef0f792 100644
--- a/sources/shiboken6/ApiExtractor/tests/testarrayargument.h
+++ b/sources/shiboken6/ApiExtractor/tests/testarrayargument.h
@@ -1,34 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTARRAYARGUMENT_H
#define TESTARRAYARGUMENT_H
-#include <QObject>
+#include <QtCore/QObject>
class TestArrayArgument : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp
index 1d7ba9666..4829e6c33 100644
--- a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.cpp
@@ -1,40 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testcodeinjection.h"
-#include <QFileInfo>
-#include <QDir>
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetalang.h>
+#include <codesnip.h>
#include <modifications.h>
#include <textstream.h>
-#include <typesystem.h>
+#include <complextypeentry.h>
+#include <valuetypeentry.h>
+
+#include <qtcompat.h>
+
+#include <QtCore/QDir>
+#include <QtCore/QFileInfo>
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
void TestCodeInjections::testReadFile_data()
{
@@ -59,38 +41,40 @@ void TestCodeInjections::testReadFile()
QFETCH(QString, snippet);
QFETCH(QString, expected);
- const char* cppCode ="struct A {};\n";
+ const char cppCode[] = "struct A {};\n";
int argc = 0;
char *argv[] = {nullptr};
QCoreApplication app(argc, argv);
- QString attribute = QLatin1String("file='") + filePath + QLatin1Char('\'');
+ QString attribute = u"file='"_s + filePath + u'\'';
if (!snippet.isEmpty())
- attribute += QLatin1String(" snippet='") + snippet + QLatin1Char('\'');
+ attribute += u" snippet='"_s + snippet + u'\'';
- QString xmlCode = QLatin1String("\
+ QString xmlCode = u"\
<typesystem package=\"Foo\">\n\
<value-type name='A'>\n\
- <conversion-rule class='target' ") + attribute + QLatin1String("/>\n\
- <inject-code class='target' ") + attribute + QLatin1String("/>\n\
+ <conversion-rule class='target' "_s + attribute + u"/>\n\
+ <inject-code class='target' "_s + attribute + u"/>\n\
<value-type name='B'/>\n\
</value-type>\n\
- </typesystem>\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, QLatin1String("A"));
- QCOMPARE(classA->typeEntry()->codeSnips().count(), 1);
+ 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);
- code = classA->typeEntry()->targetConversionRule();
+ QVERIFY(classA->typeEntry()->isValue());
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(classA->typeEntry());
+ code = vte->targetConversionRule();
QVERIFY(code.indexOf(expected) != -1);
}
void TestCodeInjections::testInjectWithValidApiVersion()
{
- const char* cppCode ="struct A {};\n";
- const char* xmlCode = "\
+ const char cppCode[] = "struct A {};\n";
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<value-type name='A'>\n\
<inject-code class='target' since='1.0'>\n\
@@ -100,17 +84,17 @@ void TestCodeInjections::testInjectWithValidApiVersion()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
- true, QLatin1String("1.0")));
- QVERIFY(!builder.isNull());
+ true, u"1.0"_s));
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
- QCOMPARE(classA->typeEntry()->codeSnips().count(), 1);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ QCOMPARE(classA->typeEntry()->codeSnips().size(), 1);
}
void TestCodeInjections::testInjectWithInvalidApiVersion()
{
- const char* cppCode ="struct A {};\n";
- const char* xmlCode = "\
+ const char cppCode[] = "struct A {};\n";
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<value-type name='A'>\n\
<inject-code class='target' since='1.0'>\n\
@@ -120,31 +104,28 @@ void TestCodeInjections::testInjectWithInvalidApiVersion()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
- true, QLatin1String("0.1")));
- QVERIFY(!builder.isNull());
+ true, u"0.1"_s));
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
- QCOMPARE(classA->typeEntry()->codeSnips().count(), 0);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ QCOMPARE(classA->typeEntry()->codeSnips().size(), 0);
}
void TestCodeInjections::testTextStream()
{
StringStream str(TextStream::Language::Cpp);
- str << "void foo(int a, int b) {\n";
- {
- Indentation i(str);
- str << "if (a == b)\n" << indent << "return a;\n" << outdent
- << "#if Q_OS_WIN\nprint()\n#endif\nreturn a + b;\n";
- }
- str << "}\n\n// A table\n|"
+ str << "void foo(int a, int b) {\n" << indent
+ << "if (a == b)\n" << indent << "return a;\n" << outdent
+ << "#if Q_OS_WIN\nprint()\n#endif\nreturn a + b;\n" << outdent
+ << "}\n\n// A table\n|"
<< AlignedField("bla", 40, QTextStream::AlignRight) << "|\n|"
<< AlignedField("bla", 40, QTextStream::AlignLeft) << "|\n|"
<< AlignedField(QString(), 40, QTextStream::AlignLeft) << "|\n";
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
@@ -160,9 +141,24 @@ static const char expected[] = R"(void foo(int a, int b) {
2nd table
|bla||
-)";
+)"_L1;
+
+ QCOMPARE(str.toString(), expected);
+}
+
+void TestCodeInjections::testTextStreamRst()
+{
+ // Test that sphinx error: "Inline strong start-string without end-string."
+ // is avoided, that is, characters following a formatting end are escaped.
+
+ StringStream str;
+ str << rstBold << "QObject" << rstBoldOff << "'s properties..."
+ << rstItalic << "some italic" << rstItalicOff << " followed by space.";
+
+ static const char16_t expected[] =
+ uR"(**QObject**\'s properties...*some italic* followed by space.)";
- QCOMPARE(str.toString(), QLatin1String(expected));
+ QCOMPARE(str.toString(), expected);
}
QTEST_APPLESS_MAIN(TestCodeInjections)
diff --git a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.h b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.h
index 05b95a11e..a164ea36e 100644
--- a/sources/shiboken6/ApiExtractor/tests/testcodeinjection.h
+++ b/sources/shiboken6/ApiExtractor/tests/testcodeinjection.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTCODEINJECTIONS_H
#define TESTCODEINJECTIONS_H
-#include <QObject>
+#include <QtCore/QObject>
class AbstractMetaBuilder;
@@ -42,6 +17,7 @@ private slots:
void testInjectWithValidApiVersion();
void testInjectWithInvalidApiVersion();
void testTextStream();
+ void testTextStreamRst();
};
#endif
diff --git a/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp b/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp
index 3ee39e4ec..0bb72b3c1 100644
--- a/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testcontainer.cpp
@@ -1,41 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testcontainer.h"
#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetalang.h>
#include <abstractmetatype.h>
-#include <typesystem.h>
+#include <complextypeentry.h>
+#include <containertypeentry.h>
void TestContainer::testContainerType()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
namespace std {\n\
template<class T>\n\
class list {\n\
@@ -44,7 +20,7 @@ void TestContainer::testContainerType()
}\n\
class A : public std::list<int> {\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<namespace-type name='std' generate='no' />\n\
<container-type name='std::list' type='list' />\n\
@@ -52,21 +28,21 @@ void TestContainer::testContainerType()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
+ QCOMPARE(classes.size(), 2);
//search for class A
- AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
auto baseContainer = classA->typeEntry()->baseContainerType();
QVERIFY(baseContainer);
- QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer)->containerKind(),
+ QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer.get())->containerKind(),
ContainerTypeEntry::ListContainer);
}
void TestContainer::testListOfValueType()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
namespace std {\n\
template<class T>\n\
class list {\n\
@@ -76,7 +52,7 @@ void TestContainer::testListOfValueType()
class ValueType {};\n\
class A : public std::list<ValueType> {\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<namespace-type name='std' generate='no'/>\n\
<container-type name='std::list' type='list'/>\n\
@@ -85,13 +61,13 @@ void TestContainer::testListOfValueType()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 3);
+ QCOMPARE(classes.size(), 3);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- QCOMPARE(classA->templateBaseClassInstantiations().count(), 1);
+ QCOMPARE(classA->templateBaseClassInstantiations().size(), 1);
const AbstractMetaType templateInstanceType =
classA->templateBaseClassInstantiations().constFirst();
diff --git a/sources/shiboken6/ApiExtractor/tests/testcontainer.h b/sources/shiboken6/ApiExtractor/tests/testcontainer.h
index 44e6636aa..3fd23c3f0 100644
--- a/sources/shiboken6/ApiExtractor/tests/testcontainer.h
+++ b/sources/shiboken6/ApiExtractor/tests/testcontainer.h
@@ -1,34 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTCONTAINER_H
#define TESTCONTAINER_H
-#include <QObject>
+#include <QtCore/QObject>
class TestContainer : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp b/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp
index 32071f533..8f2b277af 100644
--- a/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testconversionoperator.cpp
@@ -1,38 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testconversionoperator.h"
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
+#include <abstractmetatype.h>
#include <typesystem.h>
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
void TestConversionOperator::testConversionOperator()
{
const char cppCode[] = "\
@@ -52,18 +33,18 @@ 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, QLatin1String("A"));
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
- const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, QLatin1String("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);
- QCOMPARE(classA->functions().count(), 2);
- QCOMPARE(classB->functions().count(), 3);
- QCOMPARE(classC->functions().count(), 3);
- QCOMPARE(classA->externalConversionOperators().count(), 2);
+ QCOMPARE(classA->functions().size(), 2);
+ QCOMPARE(classB->functions().size(), 3);
+ QCOMPARE(classC->functions().size(), 3);
+ QCOMPARE(classA->externalConversionOperators().size(), 2);
AbstractMetaFunctionCPtr convOp;
for (const auto &func : classB->functions()) {
@@ -72,7 +53,7 @@ void TestConversionOperator::testConversionOperator()
break;
}
}
- QVERIFY(!convOp.isNull());
+ QVERIFY(convOp);
QVERIFY(classA->externalConversionOperators().contains(convOp));
}
@@ -90,11 +71,11 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- QCOMPARE(classA->externalConversionOperators().count(), 0);
+ QCOMPARE(classA->externalConversionOperators().size(), 0);
}
void TestConversionOperator::testRemovedConversionOperator()
@@ -114,16 +95,16 @@ 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, QLatin1String("A"));
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classA);
QVERIFY(classB);
- QCOMPARE(classA->functions().count(), 2);
- QCOMPARE(classB->functions().count(), 3);
- QCOMPARE(classA->externalConversionOperators().count(), 0);
- QCOMPARE(classA->implicitConversions().count(), 0);
+ QCOMPARE(classA->functions().size(), 2);
+ QCOMPARE(classB->functions().size(), 3);
+ QCOMPARE(classA->externalConversionOperators().size(), 0);
+ QCOMPARE(classA->implicitConversions().size(), 0);
}
void TestConversionOperator::testConversionOperatorReturningReference()
@@ -140,24 +121,24 @@ 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, QLatin1String("A"));
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classA);
QVERIFY(classB);
- QCOMPARE(classA->functions().count(), 2);
- QCOMPARE(classB->functions().count(), 3);
- QCOMPARE(classA->externalConversionOperators().count(), 1);
+ QCOMPARE(classA->functions().size(), 2);
+ QCOMPARE(classB->functions().size(), 3);
+ QCOMPARE(classA->externalConversionOperators().size(), 1);
QCOMPARE(classA->externalConversionOperators().constFirst()->type().cppSignature(),
- QLatin1String("A"));
+ u"A");
QCOMPARE(classA->externalConversionOperators().constFirst()->ownerClass()->name(),
- QLatin1String("B"));
- QCOMPARE(classA->implicitConversions().count(), 1);
+ u"B");
+ QCOMPARE(classA->implicitConversions().size(), 1);
QCOMPARE(classA->implicitConversions().constFirst()->type().cppSignature(),
- QLatin1String("A"));
+ u"A");
QCOMPARE(classA->implicitConversions().constFirst()->ownerClass()->name(),
- QLatin1String("B"));
+ u"B");
}
void TestConversionOperator::testConversionOperatorReturningConstReference()
@@ -174,24 +155,24 @@ 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, QLatin1String("A"));
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classA);
QVERIFY(classB);
- QCOMPARE(classA->functions().count(), 2);
- QCOMPARE(classB->functions().count(), 3);
- QCOMPARE(classA->externalConversionOperators().count(), 1);
+ QCOMPARE(classA->functions().size(), 2);
+ QCOMPARE(classB->functions().size(), 3);
+ QCOMPARE(classA->externalConversionOperators().size(), 1);
QCOMPARE(classA->externalConversionOperators().constFirst()->type().cppSignature(),
- QLatin1String("A"));
+ u"A"_s);
QCOMPARE(classA->externalConversionOperators().constFirst()->ownerClass()->name(),
- QLatin1String("B"));
- QCOMPARE(classA->implicitConversions().count(), 1);
+ u"B"_s);
+ QCOMPARE(classA->implicitConversions().size(), 1);
QCOMPARE(classA->implicitConversions().constFirst()->type().cppSignature(),
- QLatin1String("A"));
+ u"A"_s);
QCOMPARE(classA->implicitConversions().constFirst()->ownerClass()->name(),
- QLatin1String("B"));
+ u"B"_s);
}
QTEST_APPLESS_MAIN(TestConversionOperator)
diff --git a/sources/shiboken6/ApiExtractor/tests/testconversionoperator.h b/sources/shiboken6/ApiExtractor/tests/testconversionoperator.h
index b571a57a0..68288d240 100644
--- a/sources/shiboken6/ApiExtractor/tests/testconversionoperator.h
+++ b/sources/shiboken6/ApiExtractor/tests/testconversionoperator.h
@@ -1,34 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTCONVERSIONOPERATOR_H
#define TESTCONVERSIONOPERATOR_H
-#include <QObject>
+#include <QtCore/QObject>
class TestConversionOperator : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp b/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp
index 1f244bd83..b5efd92a6 100644
--- a/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testconversionruletag.cpp
@@ -1,64 +1,49 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testconversionruletag.h"
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetalang.h>
-#include <typesystem.h>
-#include <QFile>
-#include <QTemporaryFile>
+#include <complextypeentry.h>
+#include <customconversion.h>
+#include <primitivetypeentry.h>
+#include <valuetypeentry.h>
+
+#include <qtcompat.h>
+
+#include <QtCore/QFile>
+#include <QtCore/QTemporaryFile>
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
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";
- QString xmlCode = QLatin1String("\
+ QString xmlCode = u"\
<typesystem package='Foo'>\n\
<value-type name='A'>\n\
- <conversion-rule class='target' file='") + file.fileName() + QLatin1String("'/>\n\
+ <conversion-rule class='target' file='"_s + file.fileName() + u"'/>\n\
</value-type>\n\
- </typesystem>\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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const ComplexTypeEntry* typeEntry = classA->typeEntry();
- QVERIFY(typeEntry->hasTargetConversionRule());
- QCOMPARE(typeEntry->targetConversionRule(), QLatin1String(conversionData));
+ const auto typeEntry = classA->typeEntry();
+ QVERIFY(typeEntry->isValue());
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(typeEntry);
+ QVERIFY(vte->hasTargetConversionRule());
+ QCOMPARE(vte->targetConversionRule(), conversionData);
}
void TestConversionRuleTag::testConversionRuleTagReplace()
@@ -71,7 +56,7 @@ void TestConversionRuleTag::testConversionRuleTagReplace()
struct B {\n\
A createA();\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='int'/>\n\
<primitive-type name='char'/>\n\
@@ -100,48 +85,49 @@ void TestConversionRuleTag::testConversionRuleTagReplace()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
- TypeDatabase* typeDb = TypeDatabase::instance();
- PrimitiveTypeEntry* typeA = typeDb->findPrimitiveType(QLatin1String("A"));
+ QVERIFY(builder);
+ auto *typeDb = TypeDatabase::instance();
+ auto typeA = typeDb->findPrimitiveType(u"A"_s);
QVERIFY(typeA);
- CustomConversion* conversion = typeA->customConversion();
- QVERIFY(conversion);
+ QVERIFY(typeA->hasCustomConversion());
+ auto conversion = typeA->customConversion();
QCOMPARE(typeA, conversion->ownerType());
QCOMPARE(conversion->nativeToTargetConversion().simplified(),
- QLatin1String("DoThis(); return ConvertFromCppToPython(%IN);"));
+ u"DoThis(); return ConvertFromCppToPython(%IN);");
QVERIFY(conversion->replaceOriginalTargetToNativeConversions());
QVERIFY(conversion->hasTargetToNativeConversions());
QCOMPARE(conversion->targetToNativeConversions().size(), 3);
- CustomConversion::TargetToNativeConversion* toNative = conversion->targetToNativeConversions().at(0);
- QVERIFY(toNative);
- QCOMPARE(toNative->sourceTypeName(), QLatin1String("TargetNone"));
- QVERIFY(toNative->isCustomType());
- QCOMPARE(toNative->sourceType(), nullptr);
- QCOMPARE(toNative->sourceTypeCheck(), QLatin1String("%IN == Target_None"));
- QCOMPARE(toNative->conversion().simplified(),
- QLatin1String("DoThat(); DoSomething(); %OUT = A();"));
+ QVERIFY(!conversion->targetToNativeConversions().isEmpty());
+ auto toNative = conversion->targetToNativeConversions().at(0);
+ QCOMPARE(toNative.sourceTypeName(), u"TargetNone");
+ QVERIFY(toNative.isCustomType());
+ QCOMPARE(toNative.sourceType(), nullptr);
+ QCOMPARE(toNative.sourceTypeCheck(), u"%IN == Target_None");
+ QCOMPARE(toNative.conversion().simplified(),
+ u"DoThat(); DoSomething(); %OUT = A();");
+ QVERIFY(conversion->targetToNativeConversions().size() > 1);
toNative = conversion->targetToNativeConversions().at(1);
- QVERIFY(toNative);
- QCOMPARE(toNative->sourceTypeName(), QLatin1String("B"));
- QVERIFY(!toNative->isCustomType());
- TypeEntry* typeB = typeDb->findType(QLatin1String("B"));
+ QCOMPARE(toNative.sourceTypeName(), u"B");
+ QVERIFY(!toNative.isCustomType());
+ auto typeB = typeDb->findType(u"B"_s);
QVERIFY(typeB);
- QCOMPARE(toNative->sourceType(), typeB);
- QCOMPARE(toNative->sourceTypeCheck(), QLatin1String("CheckIfInputObjectIsB(%IN)"));
- QCOMPARE(toNative->conversion().trimmed(), QLatin1String("%OUT = %IN.createA();"));
+ QCOMPARE(toNative.sourceType(), typeB);
+ QCOMPARE(toNative.sourceTypeCheck(), u"CheckIfInputObjectIsB(%IN)");
+ QCOMPARE(toNative.conversion().trimmed(), u"%OUT = %IN.createA();");
+ QVERIFY(conversion->targetToNativeConversions().size() > 2);
toNative = conversion->targetToNativeConversions().at(2);
- QVERIFY(toNative);
- QCOMPARE(toNative->sourceTypeName(), QLatin1String("String"));
- QVERIFY(toNative->isCustomType());
- QCOMPARE(toNative->sourceType(), nullptr);
- QCOMPARE(toNative->sourceTypeCheck(), QLatin1String("String_Check(%IN)"));
- QCOMPARE(toNative->conversion().trimmed(), QLatin1String("%OUT = new A(String_AsString(%IN), String_GetSize(%IN));"));
+ QCOMPARE(toNative.sourceTypeName(), u"String");
+ QVERIFY(toNative.isCustomType());
+ QCOMPARE(toNative.sourceType(), nullptr);
+ QCOMPARE(toNative.sourceTypeCheck(), u"String_Check(%IN)");
+ QCOMPARE(toNative.conversion().trimmed(),
+ u"%OUT = new A(String_AsString(%IN), String_GetSize(%IN));");
}
void TestConversionRuleTag::testConversionRuleTagAdd()
@@ -151,7 +137,7 @@ void TestConversionRuleTag::testConversionRuleTagAdd()
Date();\n\
Date(int, int, int);\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='int'/>\n\
<value-type name='Date'>\n\
@@ -167,12 +153,14 @@ if (!TargetDateTimeAPI) TargetDateTime_IMPORT;\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("Date"));
+ QVERIFY(builder);
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "Date");
QVERIFY(classA);
- CustomConversion* conversion = classA->typeEntry()->customConversion();
- QVERIFY(conversion);
+ QVERIFY(classA->typeEntry()->isValue());
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(classA->typeEntry());
+ QVERIFY(vte->hasCustomConversion());
+ auto conversion = vte->customConversion();
QCOMPARE(conversion->nativeToTargetConversion(), QString());
@@ -180,21 +168,21 @@ if (!TargetDateTimeAPI) TargetDateTime_IMPORT;\n\
QVERIFY(conversion->hasTargetToNativeConversions());
QCOMPARE(conversion->targetToNativeConversions().size(), 1);
- CustomConversion::TargetToNativeConversion *toNative =
- conversion->targetToNativeConversions().constFirst();
- QVERIFY(toNative);
- QCOMPARE(toNative->sourceTypeName(), QLatin1String("TargetDate"));
- QVERIFY(toNative->isCustomType());
- QCOMPARE(toNative->sourceType(), nullptr);
- QCOMPARE(toNative->sourceTypeCheck(), QLatin1String("TargetDate_Check(%IN)"));
- QCOMPARE(toNative->conversion().trimmed(),
- QLatin1String("if (!TargetDateTimeAPI) TargetDateTime_IMPORT;\n%OUT = new Date(TargetDate_Day(%IN), TargetDate_Month(%IN), TargetDate_Year(%IN));"));
+ QVERIFY(!conversion->targetToNativeConversions().isEmpty());
+ const auto &toNative = conversion->targetToNativeConversions().constFirst();
+ QCOMPARE(toNative.sourceTypeName(), u"TargetDate");
+ QVERIFY(toNative.isCustomType());
+ QCOMPARE(toNative.sourceType(), nullptr);
+ QCOMPARE(toNative.sourceTypeCheck(), u"TargetDate_Check(%IN)");
+ QCOMPARE(toNative.conversion().trimmed(),
+ uR"(if (!TargetDateTimeAPI) TargetDateTime_IMPORT;
+%OUT = new Date(TargetDate_Day(%IN), TargetDate_Month(%IN), TargetDate_Year(%IN));)");
}
void TestConversionRuleTag::testConversionRuleTagWithInsertTemplate()
{
const char cppCode[] = "struct A {};";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='int'/>\n\
<!-- single line -->\n\
@@ -228,25 +216,25 @@ void TestConversionRuleTag::testConversionRuleTagWithInsertTemplate()
"// TEMPLATE - target_to_native - END";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
- TypeDatabase* typeDb = TypeDatabase::instance();
- PrimitiveTypeEntry* typeA = typeDb->findPrimitiveType(QLatin1String("A"));
+ QVERIFY(builder);
+ auto *typeDb = TypeDatabase::instance();
+ auto typeA = typeDb->findPrimitiveType(u"A"_s);
QVERIFY(typeA);
- CustomConversion* conversion = typeA->customConversion();
- QVERIFY(conversion);
+ QVERIFY(typeA->hasCustomConversion());
+ auto conversion = typeA->customConversion();
QCOMPARE(typeA, conversion->ownerType());
QCOMPARE(conversion->nativeToTargetConversion().trimmed(),
- QLatin1String(nativeToTargetExpected));
+ QLatin1StringView(nativeToTargetExpected));
QVERIFY(conversion->hasTargetToNativeConversions());
QCOMPARE(conversion->targetToNativeConversions().size(), 1);
- CustomConversion::TargetToNativeConversion* toNative = conversion->targetToNativeConversions().constFirst();
- QVERIFY(toNative);
- QCOMPARE(toNative->conversion().trimmed(),
- QLatin1String(targetToNativeExpected));
+ QVERIFY(!conversion->targetToNativeConversions().isEmpty());
+ const auto &toNative = conversion->targetToNativeConversions().constFirst();
+ QCOMPARE(toNative.conversion().trimmed(),
+ QLatin1StringView(targetToNativeExpected));
}
QTEST_APPLESS_MAIN(TestConversionRuleTag)
diff --git a/sources/shiboken6/ApiExtractor/tests/testconversionruletag.h b/sources/shiboken6/ApiExtractor/tests/testconversionruletag.h
index 894bd3d71..64d496cc3 100644
--- a/sources/shiboken6/ApiExtractor/tests/testconversionruletag.h
+++ b/sources/shiboken6/ApiExtractor/tests/testconversionruletag.h
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTCONVERSIONRULE_H
#define TESTCONVERSIONRULE_H
-#include <QObject>
+
+#include <QtCore/QObject>
class TestConversionRuleTag : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testctorinformation.cpp b/sources/shiboken6/ApiExtractor/tests/testctorinformation.cpp
index 7718d3df6..c3a3ebef0 100644
--- a/sources/shiboken6/ApiExtractor/tests/testctorinformation.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testctorinformation.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testctorinformation.h"
#include "abstractmetabuilder.h"
@@ -35,41 +10,47 @@
void TestCtorInformation::testCtorIsPrivate()
{
- const char* cppCode = "class Control { public: Control() {} };\n\
+ const char cppCode[] = "class Control { public: Control() {} };\n\
class Subject { private: Subject() {} };\n\
class CtorLess { };\n";
- const char* xmlCode = "<typesystem package='Foo'>\n\
+ const char xmlCode[] = "<typesystem package='Foo'>\n\
<value-type name='Control'/>\n\
<object-type name='Subject'/>\n\
<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.count(), 3);
- QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->hasNonPrivateConstructor(), true);
- QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasNonPrivateConstructor(), false);
- QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("CtorLess"))->hasNonPrivateConstructor(), true);
+ QCOMPARE(classes.size(), 3);
+ auto klass = AbstractMetaClass::findClass(classes, "Control");
+ QVERIFY(klass);
+ QVERIFY(klass->hasNonPrivateConstructor());
+ klass = AbstractMetaClass::findClass(classes, "Subject");
+ QVERIFY(klass);
+ QVERIFY(!klass->hasNonPrivateConstructor());
+ klass = AbstractMetaClass::findClass(classes, "CtorLess");
+ QVERIFY(klass);
+ QVERIFY(klass->hasNonPrivateConstructor());
}
void TestCtorInformation::testHasNonPrivateCtor()
{
- const char* cppCode = "template<typename T>\n\
+ const char cppCode[] = "template<typename T>\n\
struct Base { Base(double) {} };\n\
typedef Base<int> Derived;\n";
- const char* xmlCode = "<typesystem package='Foo'>\n\
+ const char xmlCode[] = "<typesystem package='Foo'>\n\
<primitive-type name='int'/>\n\
<primitive-type name='double'/>\n\
<object-type name='Base' generate='no'/>\n\
<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.count(), 2);
- const AbstractMetaClass *base = AbstractMetaClass::findClass(classes, QLatin1String("Base"));
+ QCOMPARE(classes.size(), 2);
+ const auto base = AbstractMetaClass::findClass(classes, "Base");
QCOMPARE(base->hasNonPrivateConstructor(), true);
- const AbstractMetaClass *derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived"));
+ const auto derived = AbstractMetaClass::findClass(classes, "Derived");
QCOMPARE(derived->hasNonPrivateConstructor(), true);
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testctorinformation.h b/sources/shiboken6/ApiExtractor/tests/testctorinformation.h
index ee655d450..58f1648e4 100644
--- a/sources/shiboken6/ApiExtractor/tests/testctorinformation.h
+++ b/sources/shiboken6/ApiExtractor/tests/testctorinformation.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTCTORINFORMATION_H
#define TESTCTORINFORMATION_H
-#include <QObject>
+#include <QtCore/QObject>
class AbstractMetaBuilder;
diff --git a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp
index 303532b65..16f50e69d 100644
--- a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.cpp
@@ -1,40 +1,20 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testdroptypeentries.h"
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetaenum.h>
#include <abstractmetalang.h>
#include <typesystem.h>
#include <conditionalstreamreader.h>
-static const char* cppCode ="\
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
+static const char cppCode[] = "\
struct ValueA {};\n\
struct ValueB {};\n\
struct ObjectA {};\n\
@@ -49,7 +29,7 @@ static const char* cppCode ="\
void funcA();\n\
void funcB();\n";
-static const char* xmlCode = "\
+static const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<value-type name='ValueA'/>\n\
<value-type name='ValueB'/>\n\
@@ -68,61 +48,61 @@ static const char* xmlCode = "\
void TestDropTypeEntries::testDropEntries()
{
- const QStringList droppedEntries{QLatin1String("Foo.ValueB"),
- QLatin1String("ObjectB"), // Check whether module can be omitted
- QLatin1String("Foo.NamespaceA.InnerClassA"),
- QLatin1String("Foo.NamespaceB"), QLatin1String("Foo.EnumB"),
- QLatin1String("Foo.funcB()"),
- QLatin1String("Foo.NamespaceA.InnerNamespaceA")};
+ const QStringList droppedEntries{u"Foo.ValueB"_s,
+ u"ObjectB"_s, // Check whether module can be omitted
+ u"Foo.NamespaceA.InnerClassA"_s,
+ u"Foo.NamespaceB"_s, u"Foo.EnumB"_s,
+ u"Foo.funcB()"_s,
+ 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, QLatin1String("ValueA")));
- QVERIFY(!AbstractMetaClass::findClass(classes, QLatin1String("ValueB")));
- QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("ObjectA")));
- QVERIFY(!AbstractMetaClass::findClass(classes, QLatin1String("ObjectB")));
- QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("NamespaceA")));
- QVERIFY(!AbstractMetaClass::findClass(classes, QLatin1String("NamespaceA::InnerClassA")));
- QVERIFY(!AbstractMetaClass::findClass(classes, QLatin1String("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.count(), 1);
- QCOMPARE(globalEnums.constFirst().name(), QLatin1String("EnumA"));
+ QCOMPARE(globalEnums.size(), 1);
+ QCOMPARE(globalEnums.constFirst().name(), u"EnumA");
- TypeDatabase* td = TypeDatabase::instance();
- QVERIFY(td->findType(QLatin1String("funcA")));
- QVERIFY(!td->findType(QLatin1String("funcB")));
+ auto *td = TypeDatabase::instance();
+ QVERIFY(td->findType(u"funcA"_s));
+ QVERIFY(!td->findType(u"funcB"_s));
}
void TestDropTypeEntries::testDontDropEntries()
{
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("ValueA")));
- QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("ValueB")));
- QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("ObjectA")));
- QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("ObjectB")));
- QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("NamespaceA")));
- QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("NamespaceA::InnerClassA")));
- QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("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);
- TypeDatabase* td = TypeDatabase::instance();
- QVERIFY(td->findType(QLatin1String("funcA")));
- QVERIFY(td->findType(QLatin1String("funcB")));
+ auto *td = TypeDatabase::instance();
+ QVERIFY(td->findType(u"funcA"_s));
+ QVERIFY(td->findType(u"funcB"_s));
}
-static const char* cppCode2 ="\
+static const char cppCode2[] = "\
struct ValueA {\n\
void func();\n\
};\n";
-static const char* xmlCode2 = R"(
+static const char xmlCode2[] = R"(
<typesystem package='Foo'>
<value-type name='ValueA'>
<modify-function signature='func()' remove='all'/>
@@ -132,24 +112,24 @@ static const char* xmlCode2 = R"(
void TestDropTypeEntries::testDropEntryWithChildTags()
{
- QStringList droppedEntries(QLatin1String("Foo.ValueA"));
+ QStringList droppedEntries(u"Foo.ValueA"_s);
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false,
QString(), droppedEntries));
- QVERIFY(!builder.isNull());
- QVERIFY(!AbstractMetaClass::findClass(builder->classes(), QLatin1String("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(), QLatin1String("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?>
@@ -165,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");
@@ -224,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/testdroptypeentries.h b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h
index d163b594d..98717bd21 100644
--- a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h
+++ b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTDROPTYPEENTRIES_H
#define TESTDROPTYPEENTRIES_H
-#include <QObject>
+#include <QtCore/QObject>
class TestDropTypeEntries : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testdtorinformation.cpp b/sources/shiboken6/ApiExtractor/tests/testdtorinformation.cpp
index 0eee8af24..2152d39de 100644
--- a/sources/shiboken6/ApiExtractor/tests/testdtorinformation.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testdtorinformation.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testdtorinformation.h"
#include "abstractmetabuilder.h"
@@ -35,83 +10,147 @@
void TestDtorInformation::testDtorIsPrivate()
{
- const char* cppCode ="class Control { public: ~Control() {} }; class Subject { private: ~Subject() {} };";
- const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"Control\"/><value-type name=\"Subject\"/></typesystem>";
+ const char cppCode[] = R"(class Control {
+public:
+ ~Control() {}
+};
+class Subject {
+private:
+ ~Subject() {}
+};
+)";
+ const char xmlCode[] = R"(<typesystem package="Foo">
+ <value-type name="Control"/>
+ <value-type name="Subject"/>
+</typesystem>)";
+
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
- QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->hasPrivateDestructor(), false);
- QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasPrivateDestructor(), true);
+ QCOMPARE(classes.size(), 2);
+ auto klass = AbstractMetaClass::findClass(classes, "Control");
+ QVERIFY(klass);
+ QVERIFY(!klass->hasPrivateDestructor());
+ klass = AbstractMetaClass::findClass(classes, "Subject");
+ QVERIFY(klass);
+ QVERIFY(klass->hasPrivateDestructor());
}
void TestDtorInformation::testDtorIsProtected()
{
- const char* cppCode ="class Control { public: ~Control() {} }; class Subject { protected: ~Subject() {} };";
- const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"Control\"/><value-type name=\"Subject\"/></typesystem>";
+ const char cppCode[] = R"(class Control {
+public:
+ ~Control() {}
+};
+class Subject {
+protected:
+ ~Subject() {}
+};
+)";
+ const char xmlCode[] = R"(<typesystem package="Foo">
+ <value-type name="Control"/>
+ <value-type name="Subject"/>
+</typesystem>)";
+
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
- QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->hasProtectedDestructor(), false);
- QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasProtectedDestructor(), true);
+ QCOMPARE(classes.size(), 2);
+ auto klass = AbstractMetaClass::findClass(classes, "Control");
+ QVERIFY(klass);
+ QVERIFY(!klass->hasProtectedDestructor());
+ klass = AbstractMetaClass::findClass(classes, "Subject");
+ QVERIFY(klass);
+ QVERIFY(klass->hasProtectedDestructor());
}
void TestDtorInformation::testDtorIsVirtual()
{
- const char* cppCode ="class Control { public: ~Control() {} }; class Subject { protected: virtual ~Subject() {} };";
- const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"Control\"/><value-type name=\"Subject\"/></typesystem>";
+ const char cppCode[] = R"(class Control {
+public:
+ ~Control() {}
+};
+class Subject {
+protected:
+ virtual ~Subject() {}
+};
+)";
+ const char xmlCode[] = R"(<typesystem package="Foo">
+ <value-type name="Control"/>
+ <value-type name="Subject"/>
+</typesystem>)";
+
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
- QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->hasVirtualDestructor(), false);
- QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasVirtualDestructor(), true);
+ QCOMPARE(classes.size(), 2);
+ auto klass = AbstractMetaClass::findClass(classes, "Control");
+ QVERIFY(klass);
+ QVERIFY(!klass->hasVirtualDestructor());
+ klass = AbstractMetaClass::findClass(classes, "Subject");
+ QVERIFY(klass);
+ QVERIFY(klass->hasVirtualDestructor());
}
void TestDtorInformation::testDtorFromBaseIsVirtual()
{
- const char* cppCode = R"CPP(class ControlBase { public: ~ControlBase() {} };
+ const char cppCode[] = R"CPP(class ControlBase { public: ~ControlBase() {} };
class Control : public ControlBase {};
class SubjectBase { public: virtual ~SubjectBase() {} };
class Subject : public SubjectBase {};
)CPP";
- const char* xmlCode = R"XML(<typesystem package="Foo"><value-type name="ControlBase"/>
+ const char xmlCode[] = R"XML(<typesystem package="Foo"><value-type name="ControlBase"/>
<value-type name="Control"/>"
<value-type name="SubjectBase"/>"
<value-type name="Subject"/>
</typesystem>
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 4);
+ QCOMPARE(classes.size(), 4);
- auto klass = AbstractMetaClass::findClass(classes, QLatin1String("ControlBase"));
+ auto klass = AbstractMetaClass::findClass(classes, "ControlBase");
QVERIFY(klass);
QVERIFY(!klass->hasVirtualDestructor());
- klass = AbstractMetaClass::findClass(classes, QLatin1String("Control"));
+ klass = AbstractMetaClass::findClass(classes, "Control");
QVERIFY(klass);
QVERIFY(!klass->hasVirtualDestructor());
- klass = AbstractMetaClass::findClass(classes, QLatin1String("SubjectBase"));
+ klass = AbstractMetaClass::findClass(classes, "SubjectBase");
QVERIFY(klass);
QVERIFY(klass->hasVirtualDestructor());
- klass = AbstractMetaClass::findClass(classes, QLatin1String("Subject"));
+ klass = AbstractMetaClass::findClass(classes, "Subject");
QVERIFY(klass);
QVERIFY(klass->hasVirtualDestructor());
}
void TestDtorInformation::testClassWithVirtualDtorIsPolymorphic()
{
- const char* cppCode ="class Control { public: virtual ~Control() {} }; class Subject { protected: virtual ~Subject() {} };";
- const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"Control\"/><value-type name=\"Subject\"/></typesystem>";
+ const char cppCode[] = R"(class Control {
+public:
+ virtual ~Control() {}
+};
+class Subject {
+protected:
+ virtual ~Subject() {}
+};
+)";
+ const char xmlCode[] = R"(<typesystem package="Foo">
+ <value-type name="Control"/>
+ <value-type name="Subject"/>
+</typesystem>)";
+
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
- QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->isPolymorphic(), true);
- QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->isPolymorphic(), true);
+ QCOMPARE(classes.size(), 2);
+ auto klass = AbstractMetaClass::findClass(classes, "Control");
+ QVERIFY(klass);
+ QVERIFY(klass->isPolymorphic());
+ klass = AbstractMetaClass::findClass(classes, "Subject");
+ QVERIFY(klass);
+ QVERIFY(klass->isPolymorphic());
}
QTEST_APPLESS_MAIN(TestDtorInformation)
diff --git a/sources/shiboken6/ApiExtractor/tests/testdtorinformation.h b/sources/shiboken6/ApiExtractor/tests/testdtorinformation.h
index 0a57dd8d1..0f8cb59b3 100644
--- a/sources/shiboken6/ApiExtractor/tests/testdtorinformation.h
+++ b/sources/shiboken6/ApiExtractor/tests/testdtorinformation.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTDTORINFORMATION_H
#define TESTDTORINFORMATION_H
-#include <QObject>
+#include <QtCore/QObject>
class AbstractMetaBuilder;
diff --git a/sources/shiboken6/ApiExtractor/tests/testenum.cpp b/sources/shiboken6/ApiExtractor/tests/testenum.cpp
index c1d552786..c7c2b8b3b 100644
--- a/sources/shiboken6/ApiExtractor/tests/testenum.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testenum.cpp
@@ -1,44 +1,26 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testenum.h"
-#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetaenum.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
#include <abstractmetabuilder_p.h>
-#include <typesystem.h>
+#include <enumtypeentry.h>
+#include <flagstypeentry.h>
#include <parser/enumvalue.h>
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
void TestEnum::testEnumCppSignature()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
enum GlobalEnum { A, B };\n\
\n\
struct A {\n\
@@ -46,7 +28,7 @@ void TestEnum::testEnumCppSignature()
void method(ClassEnum);\n\
};\n\
void func(A::ClassEnum);\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<enum-type name='GlobalEnum'/>\n\
<value-type name='A'>\n\
@@ -56,52 +38,52 @@ void TestEnum::testEnumCppSignature()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 1);
+ QCOMPARE(classes.size(), 1);
AbstractMetaEnumList globalEnums = builder->globalEnums();
- QCOMPARE(globalEnums.count(), 1);
- QCOMPARE(globalEnums.constFirst().name(), QLatin1String("GlobalEnum"));
+ QCOMPARE(globalEnums.size(), 1);
+ QCOMPARE(globalEnums.constFirst().name(), u"GlobalEnum");
// enum as parameter of a function
const auto functions = builder->globalFunctions();
- QCOMPARE(functions.count(), 1);
- QCOMPARE(functions.constFirst()->arguments().count(), 1);
+ QCOMPARE(functions.size(), 1);
+ QCOMPARE(functions.constFirst()->arguments().size(), 1);
QCOMPARE(functions.constFirst()->arguments().constFirst().type().cppSignature(),
- QLatin1String("A::ClassEnum"));
+ u"A::ClassEnum");
// enum as parameter of a method
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
- QCOMPARE(classA->enums().count(), 1);
- const auto funcs = classA->queryFunctionsByName(QLatin1String("method"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ QCOMPARE(classA->enums().size(), 1);
+ const auto funcs = classA->queryFunctionsByName(u"method"_s);
QVERIFY(!funcs.isEmpty());
const auto method = funcs.constFirst();
AbstractMetaArgument arg = method->arguments().constFirst();
- QCOMPARE(arg.type().name(), QLatin1String("ClassEnum"));
- QCOMPARE(arg.type().cppSignature(), QLatin1String("A::ClassEnum"));
- QCOMPARE(functions.constFirst()->arguments().count(), 1);
+ QCOMPARE(arg.type().name(), u"ClassEnum");
+ QCOMPARE(arg.type().cppSignature(), u"A::ClassEnum");
+ QCOMPARE(functions.constFirst()->arguments().size(), 1);
arg = functions.constFirst()->arguments().constFirst();
- QCOMPARE(arg.type().name(), QLatin1String("ClassEnum"));
- QCOMPARE(arg.type().cppSignature(), QLatin1String("A::ClassEnum"));
+ QCOMPARE(arg.type().name(), u"ClassEnum");
+ QCOMPARE(arg.type().cppSignature(), u"A::ClassEnum");
AbstractMetaEnumList classEnums = classA->enums();
QVERIFY(!classEnums.isEmpty());
- QCOMPARE(classEnums.constFirst().name(), QLatin1String("ClassEnum"));
- auto e = AbstractMetaClass::findEnumValue(classes, QLatin1String("CA"));
+ QCOMPARE(classEnums.constFirst().name(), u"ClassEnum");
+ auto e = AbstractMetaClass::findEnumValue(classes, u"CA"_s);
QVERIFY(e.has_value());
- e = AbstractMetaClass::findEnumValue(classes, QLatin1String("ClassEnum::CA"));
+ e = AbstractMetaClass::findEnumValue(classes, u"ClassEnum::CA"_s);
QVERIFY(e.has_value());
}
void TestEnum::testEnumWithApiVersion()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
enum ClassEnum { EnumA, EnumB };\n\
enum ClassEnum2 { EnumC, EnumD };\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<value-type name='A'>\n\
<enum-type name='ClassEnum' since='0.1'/>\n\
@@ -110,22 +92,22 @@ void TestEnum::testEnumWithApiVersion()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
- true, QLatin1String("0.1")));
- QVERIFY(!builder.isNull());
+ true, u"0.1"_s));
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 1);
- QCOMPARE(classes[0]->enums().count(), 1);
+ QCOMPARE(classes.size(), 1);
+ QCOMPARE(classes[0]->enums().size(), 1);
}
void TestEnum::testAnonymousEnum()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
enum { Global0, Global1 };\n\
struct A {\n\
enum { A0, A1 };\n\
enum { isThis = true, isThat = false };\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<!-- Uses the first value of the enum to identify it. -->\n\
<enum-type identified-by-value='Global0'/>\n\
@@ -137,101 +119,101 @@ void TestEnum::testAnonymousEnum()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaEnumList globalEnums = builder->globalEnums();
- QCOMPARE(globalEnums.count(), 1);
+ QCOMPARE(globalEnums.size(), 1);
QCOMPARE(globalEnums.constFirst().typeEntry()->qualifiedCppName(),
- QLatin1String("Global0"));
+ u"Global0");
QVERIFY(globalEnums.constFirst().isAnonymous());
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 1);
- QCOMPARE(classes[0]->enums().count(), 2);
+ QCOMPARE(classes.size(), 1);
+ QCOMPARE(classes[0]->enums().size(), 2);
- auto anonEnumA1 = classes[0]->findEnum(QLatin1String("A1"));
+ auto anonEnumA1 = classes[0]->findEnum(u"A1"_s);
QVERIFY(anonEnumA1.has_value());
QVERIFY(anonEnumA1->isAnonymous());
- QCOMPARE(anonEnumA1->typeEntry()->qualifiedCppName(), QLatin1String("A::A1"));
+ QCOMPARE(anonEnumA1->typeEntry()->qualifiedCppName(), u"A::A1");
AbstractMetaEnumValue enumValueA0 = anonEnumA1->values().constFirst();
- QCOMPARE(enumValueA0.name(), QLatin1String("A0"));
+ QCOMPARE(enumValueA0.name(), u"A0");
QCOMPARE(enumValueA0.value().value(), 0);
QCOMPARE(enumValueA0.stringValue(), QString());
AbstractMetaEnumValue enumValueA1 = anonEnumA1->values().constLast();
- QCOMPARE(enumValueA1.name(), QLatin1String("A1"));
+ QCOMPARE(enumValueA1.name(), u"A1");
QCOMPARE(enumValueA1.value().value(), 1);
QCOMPARE(enumValueA1.stringValue(), QString());
- auto anonEnumIsThis = classes[0]->findEnum(QLatin1String("isThis"));
+ auto anonEnumIsThis = classes[0]->findEnum(u"isThis"_s);
QVERIFY(anonEnumIsThis.has_value());
QVERIFY(anonEnumIsThis->isAnonymous());
- QCOMPARE(anonEnumIsThis->typeEntry()->qualifiedCppName(), QLatin1String("A::isThis"));
+ QCOMPARE(anonEnumIsThis->typeEntry()->qualifiedCppName(), u"A::isThis");
AbstractMetaEnumValue enumValueIsThis = anonEnumIsThis->values().constFirst();
- QCOMPARE(enumValueIsThis.name(), QLatin1String("isThis"));
+ QCOMPARE(enumValueIsThis.name(), u"isThis");
QCOMPARE(enumValueIsThis.value().value(), static_cast<int>(true));
- QCOMPARE(enumValueIsThis.stringValue(), QLatin1String("true"));
+ QCOMPARE(enumValueIsThis.stringValue(), u"true");
AbstractMetaEnumValue enumValueIsThat = anonEnumIsThis->values().constLast();
- QCOMPARE(enumValueIsThat.name(), QLatin1String("isThat"));
+ QCOMPARE(enumValueIsThat.name(), u"isThat");
QCOMPARE(enumValueIsThat.value().value(), static_cast<int>(false));
- QCOMPARE(enumValueIsThat.stringValue(), QLatin1String("false"));
+ QCOMPARE(enumValueIsThat.stringValue(), u"false");
}
void TestEnum::testGlobalEnums()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
enum EnumA { A0, A1 };\n\
enum EnumB { B0 = 2, B1 = 0x4 };\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<enum-type name='EnumA'/>\n\
<enum-type name='EnumB'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaEnumList globalEnums = builder->globalEnums();
- QCOMPARE(globalEnums.count(), 2);
+ QCOMPARE(globalEnums.size(), 2);
AbstractMetaEnum enumA = globalEnums.constFirst();
- QCOMPARE(enumA.typeEntry()->qualifiedCppName(), QLatin1String("EnumA"));
+ QCOMPARE(enumA.typeEntry()->qualifiedCppName(), u"EnumA");
AbstractMetaEnumValue enumValueA0 = enumA.values().constFirst();
- QCOMPARE(enumValueA0.name(), QLatin1String("A0"));
+ QCOMPARE(enumValueA0.name(), u"A0");
QCOMPARE(enumValueA0.value().value(), 0);
QCOMPARE(enumValueA0.stringValue(), QString());
AbstractMetaEnumValue enumValueA1 = enumA.values().constLast();
- QCOMPARE(enumValueA1.name(), QLatin1String("A1"));
+ QCOMPARE(enumValueA1.name(), u"A1");
QCOMPARE(enumValueA1.value().value(), 1);
QCOMPARE(enumValueA1.stringValue(), QString());
AbstractMetaEnum enumB = globalEnums.constLast();
- QCOMPARE(enumB.typeEntry()->qualifiedCppName(), QLatin1String("EnumB"));
+ QCOMPARE(enumB.typeEntry()->qualifiedCppName(), u"EnumB");
AbstractMetaEnumValue enumValueB0 = enumB.values().constFirst();
- QCOMPARE(enumValueB0.name(), QLatin1String("B0"));
+ QCOMPARE(enumValueB0.name(), u"B0");
QCOMPARE(enumValueB0.value().value(), 2);
- QCOMPARE(enumValueB0.stringValue(), QLatin1String("2"));
+ QCOMPARE(enumValueB0.stringValue(), u"2");
AbstractMetaEnumValue enumValueB1 = enumB.values().constLast();
- QCOMPARE(enumValueB1.name(), QLatin1String("B1"));
+ QCOMPARE(enumValueB1.name(), u"B1");
QCOMPARE(enumValueB1.value().value(), 4);
- QCOMPARE(enumValueB1.stringValue(), QLatin1String("0x4"));
+ QCOMPARE(enumValueB1.stringValue(), u"0x4");
}
void TestEnum::testEnumValueFromNeighbourEnum()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
namespace A {\n\
enum EnumA { ValueA0, ValueA1 };\n\
enum EnumB { ValueB0 = A::ValueA1, ValueB1 = ValueA0 };\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<namespace-type name='A'>\n\
<enum-type name='EnumA'/>\n\
@@ -240,44 +222,44 @@ void TestEnum::testEnumValueFromNeighbourEnum()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 1);
- QCOMPARE(classes[0]->enums().count(), 2);
+ QCOMPARE(classes.size(), 1);
+ QCOMPARE(classes[0]->enums().size(), 2);
- auto enumA = classes[0]->findEnum(QLatin1String("EnumA"));
+ auto enumA = classes[0]->findEnum(u"EnumA"_s);
QVERIFY(enumA.has_value());
- QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumA"));
+ QCOMPARE(enumA->typeEntry()->qualifiedCppName(), u"A::EnumA");
AbstractMetaEnumValue enumValueA0 = enumA->values().constFirst();
- QCOMPARE(enumValueA0.name(), QLatin1String("ValueA0"));
+ QCOMPARE(enumValueA0.name(), u"ValueA0");
QCOMPARE(enumValueA0.value().value(), 0);
QCOMPARE(enumValueA0.stringValue(), QString());
AbstractMetaEnumValue enumValueA1 = enumA->values().constLast();
- QCOMPARE(enumValueA1.name(), QLatin1String("ValueA1"));
+ QCOMPARE(enumValueA1.name(), u"ValueA1");
QCOMPARE(enumValueA1.value().value(), 1);
QCOMPARE(enumValueA1.stringValue(), QString());
- auto enumB = classes[0]->findEnum(QLatin1String("EnumB"));
+ auto enumB = classes[0]->findEnum(u"EnumB"_s);
QVERIFY(enumB.has_value());
- QCOMPARE(enumB->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumB"));
+ QCOMPARE(enumB->typeEntry()->qualifiedCppName(), u"A::EnumB");
AbstractMetaEnumValue enumValueB0 = enumB->values().constFirst();
- QCOMPARE(enumValueB0.name(), QLatin1String("ValueB0"));
+ QCOMPARE(enumValueB0.name(), u"ValueB0");
QCOMPARE(enumValueB0.value().value(), 1);
- QCOMPARE(enumValueB0.stringValue(), QLatin1String("A::ValueA1"));
+ QCOMPARE(enumValueB0.stringValue(), u"A::ValueA1");
AbstractMetaEnumValue enumValueB1 = enumB->values().constLast();
- QCOMPARE(enumValueB1.name(), QLatin1String("ValueB1"));
+ QCOMPARE(enumValueB1.name(), u"ValueB1");
QCOMPARE(enumValueB1.value().value(), 0);
- QCOMPARE(enumValueB1.stringValue(), QLatin1String("ValueA0"));
+ QCOMPARE(enumValueB1.stringValue(), u"ValueA0");
}
void TestEnum::testEnumValueFromExpression()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
enum EnumA : unsigned {\n\
ValueA0 = 3u,\n\
@@ -293,7 +275,7 @@ void TestEnum::testEnumValueFromExpression()
ValueB0 = ~3,\n\
};\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<value-type name='A'>\n\
<enum-type name='EnumA'/>\n\
@@ -302,77 +284,77 @@ void TestEnum::testEnumValueFromExpression()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
- AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ AbstractMetaClassPtr classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
- auto enumA = classA->findEnum(QLatin1String("EnumA"));
+ auto enumA = classA->findEnum(u"EnumA"_s);
QVERIFY(enumA.has_value());
QVERIFY(!enumA->isSigned());
- QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumA"));
+ QCOMPARE(enumA->typeEntry()->qualifiedCppName(), u"A::EnumA");
AbstractMetaEnumValue valueA0 = enumA->values().at(0);
- QCOMPARE(valueA0.name(), QLatin1String("ValueA0"));
- QCOMPARE(valueA0.stringValue(), QLatin1String("3u"));
+ QCOMPARE(valueA0.name(), u"ValueA0");
+ QCOMPARE(valueA0.stringValue(), u"3u");
QCOMPARE(valueA0.value().unsignedValue(), 3u);
AbstractMetaEnumValue valueA1 = enumA->values().at(1);
- QCOMPARE(valueA1.name(), QLatin1String("ValueA1"));
- QCOMPARE(valueA1.stringValue(), QLatin1String("~3u"));
+ QCOMPARE(valueA1.name(), u"ValueA1");
+ QCOMPARE(valueA1.stringValue(), u"~3u");
QCOMPARE(valueA1.value().unsignedValue(), ~3u);
AbstractMetaEnumValue valueA2 = enumA->values().at(2);
- QCOMPARE(valueA2.name(), QLatin1String("ValueA2"));
- QCOMPARE(valueA2.stringValue(), QLatin1String("0xffffffff"));
+ QCOMPARE(valueA2.name(), u"ValueA2");
+ QCOMPARE(valueA2.stringValue(), u"0xffffffff");
QCOMPARE(valueA2.value().unsignedValue(), 0xffffffffu);
AbstractMetaEnumValue valueA3 = enumA->values().at(3);
- QCOMPARE(valueA3.name(), QLatin1String("ValueA3"));
- QCOMPARE(valueA3.stringValue(), QLatin1String("0xf0"));
+ QCOMPARE(valueA3.name(), u"ValueA3");
+ QCOMPARE(valueA3.stringValue(), u"0xf0");
QCOMPARE(valueA3.value().unsignedValue(), 0xf0u);
AbstractMetaEnumValue valueA4 = enumA->values().at(4);
- QCOMPARE(valueA4.name(), QLatin1String("ValueA4"));
- QCOMPARE(valueA4.stringValue(), QLatin1String("8 |ValueA3"));
+ QCOMPARE(valueA4.name(), u"ValueA4");
+ QCOMPARE(valueA4.stringValue(), u"8 |ValueA3");
QCOMPARE(valueA4.value().unsignedValue(), 8|0xf0u);
AbstractMetaEnumValue valueA5 = enumA->values().at(5);
- QCOMPARE(valueA5.name(), QLatin1String("ValueA5"));
- QCOMPARE(valueA5.stringValue(), QLatin1String("ValueA3|32"));
+ QCOMPARE(valueA5.name(), u"ValueA5");
+ QCOMPARE(valueA5.stringValue(), u"ValueA3|32");
QCOMPARE(valueA5.value().unsignedValue(), 0xf0u|32);
AbstractMetaEnumValue valueA6 = enumA->values().at(6);
- QCOMPARE(valueA6.name(), QLatin1String("ValueA6"));
- QCOMPARE(valueA6.stringValue(), QLatin1String("ValueA3 >> 1"));
+ QCOMPARE(valueA6.name(), u"ValueA6");
+ QCOMPARE(valueA6.stringValue(), u"ValueA3 >> 1");
QCOMPARE(valueA6.value().unsignedValue(), 0xf0u >> 1);
AbstractMetaEnumValue valueA7 = enumA->values().at(7);
- QCOMPARE(valueA7.name(), QLatin1String("ValueA7"));
- QCOMPARE(valueA7.stringValue(), QLatin1String("ValueA3 << 1"));
+ QCOMPARE(valueA7.name(), u"ValueA7");
+ QCOMPARE(valueA7.stringValue(), u"ValueA3 << 1");
QCOMPARE(valueA7.value().unsignedValue(), 0xf0u << 1);
- const auto enumB = classA->findEnum(QLatin1String("EnumB"));
+ const auto enumB = classA->findEnum(u"EnumB"_s);
QVERIFY(enumB.has_value());
QVERIFY(enumB->isSigned());
- QCOMPARE(enumB->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumB"));
+ QCOMPARE(enumB->typeEntry()->qualifiedCppName(), u"A::EnumB");
QCOMPARE(enumB->values().size(), 1);
const AbstractMetaEnumValue valueB0 = enumB->values().at(0);
- QCOMPARE(valueB0.name(), QLatin1String("ValueB0"));
- QCOMPARE(valueB0.stringValue(), QLatin1String("~3"));
+ QCOMPARE(valueB0.name(), u"ValueB0");
+ QCOMPARE(valueB0.stringValue(), u"~3");
QCOMPARE(valueB0.value().value(), ~3);
}
void TestEnum::testPrivateEnum()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
class A {\n\
private:\n\
enum PrivateEnum { Priv0 = 0x0f, Priv1 = 0xf0 };\n\
public:\n\
enum PublicEnum { Pub0 = Priv0, Pub1 = A::Priv1 };\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<value-type name='A'>\n\
<enum-type name='PublicEnum'/>\n\
@@ -380,60 +362,60 @@ void TestEnum::testPrivateEnum()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
- AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
- QCOMPARE(classA->enums().count(), 2);
+ QCOMPARE(classA->enums().size(), 2);
- auto privateEnum = classA->findEnum(QLatin1String("PrivateEnum"));
+ auto privateEnum = classA->findEnum(u"PrivateEnum"_s);
QVERIFY(privateEnum.has_value());
QVERIFY(privateEnum->isPrivate());
- QCOMPARE(privateEnum->typeEntry()->qualifiedCppName(), QLatin1String("A::PrivateEnum"));
+ QCOMPARE(privateEnum->typeEntry()->qualifiedCppName(), u"A::PrivateEnum");
- auto publicEnum = classA->findEnum(QLatin1String("PublicEnum"));
+ auto publicEnum = classA->findEnum(u"PublicEnum"_s);
QVERIFY(publicEnum.has_value());
- QCOMPARE(publicEnum->typeEntry()->qualifiedCppName(), QLatin1String("A::PublicEnum"));
+ QCOMPARE(publicEnum->typeEntry()->qualifiedCppName(), u"A::PublicEnum");
AbstractMetaEnumValue pub0 = publicEnum->values().constFirst();
- QCOMPARE(pub0.name(), QLatin1String("Pub0"));
+ QCOMPARE(pub0.name(), u"Pub0");
QCOMPARE(pub0.value().value(), 0x0f);
- QCOMPARE(pub0.stringValue(), QLatin1String("Priv0"));
+ QCOMPARE(pub0.stringValue(), u"Priv0");
AbstractMetaEnumValue pub1 = publicEnum->values().constLast();
- QCOMPARE(pub1.name(), QLatin1String("Pub1"));
+ QCOMPARE(pub1.name(), u"Pub1");
QCOMPARE(pub1.value().value(), 0xf0);
- QCOMPARE(pub1.stringValue(), QLatin1String("A::Priv1"));
+ QCOMPARE(pub1.stringValue(), u"A::Priv1");
}
void TestEnum::testTypedefEnum()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
typedef enum EnumA {\n\
A0,\n\
A1,\n\
} EnumA;\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<enum-type name='EnumA'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaEnumList globalEnums = builder->globalEnums();
- QCOMPARE(globalEnums.count(), 1);
+ QCOMPARE(globalEnums.size(), 1);
AbstractMetaEnum enumA = globalEnums.constFirst();
- QCOMPARE(enumA.typeEntry()->qualifiedCppName(), QLatin1String("EnumA"));
+ QCOMPARE(enumA.typeEntry()->qualifiedCppName(), u"EnumA");
AbstractMetaEnumValue enumValueA0 = enumA.values().constFirst();
- QCOMPARE(enumValueA0.name(), QLatin1String("A0"));
+ QCOMPARE(enumValueA0.name(), u"A0");
QCOMPARE(enumValueA0.value().value(), 0);
- QCOMPARE(enumValueA0.stringValue(), QLatin1String(""));
+ QCOMPARE(enumValueA0.stringValue(), u"");
AbstractMetaEnumValue enumValueA1 = enumA.values().constLast();
- QCOMPARE(enumValueA1.name(), QLatin1String("A1"));
+ QCOMPARE(enumValueA1.name(), u"A1");
QCOMPARE(enumValueA1.value().value(), 1);
QCOMPARE(enumValueA1.stringValue(), QString());
}
@@ -444,7 +426,7 @@ void TestEnum::testTypedefEnum()
struct EnumDefaultValuesFixture
{
- QSharedPointer<AbstractMetaBuilder> builder;
+ std::shared_ptr<AbstractMetaBuilder> builder;
AbstractMetaType globalEnum;
AbstractMetaType testEnum;
@@ -480,18 +462,18 @@ 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();
- if (globalEnums.count() != 1)
+ if (globalEnums.size() != 1)
return -2;
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;
@@ -501,11 +483,11 @@ namespace Test2
return -3;
const auto namespaceEnums = testNamespace->enums();
- if (namespaceEnums.count() != 2)
+ if (namespaceEnums.size() != 2)
return -4;
- QList<const EnumTypeEntry *> enumTypeEntries{
- static_cast<const EnumTypeEntry *>(namespaceEnums.at(0).typeEntry()),
- static_cast<const EnumTypeEntry *>(namespaceEnums.at(1).typeEntry())};
+ QList<EnumTypeEntryCPtr > enumTypeEntries{
+ 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/testenum.h b/sources/shiboken6/ApiExtractor/tests/testenum.h
index 20dbac79f..452755490 100644
--- a/sources/shiboken6/ApiExtractor/tests/testenum.h
+++ b/sources/shiboken6/ApiExtractor/tests/testenum.h
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTENUM_H
#define TESTENUM_H
-#include <QObject>
+
+#include <QtCore/QObject>
class TestEnum : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testextrainclude.cpp b/sources/shiboken6/ApiExtractor/tests/testextrainclude.cpp
index 90a6cd312..fcc409a42 100644
--- a/sources/shiboken6/ApiExtractor/tests/testextrainclude.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testextrainclude.cpp
@@ -1,41 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testextrainclude.h"
#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetalang.h>
-#include <typesystem.h>
+#include <complextypeentry.h>
+#include <typesystemtypeentry.h>
void TestExtraInclude::testClassExtraInclude()
{
- const char* cppCode ="struct A {};\n";
- const char* xmlCode = "\
+ const char cppCode[] = "struct A {};\n";
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<value-type name='A'>\n\
<extra-includes>\n\
@@ -45,20 +21,20 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QList<Include> includes = classA->typeEntry()->extraIncludes();
- QCOMPARE(includes.count(), 1);
- QCOMPARE(includes.constFirst().name(), QLatin1String("header.h"));
+ QCOMPARE(includes.size(), 1);
+ QCOMPARE(includes.constFirst().name(), u"header.h");
}
void TestExtraInclude::testGlobalExtraIncludes()
{
- const char* cppCode ="struct A {};\n";
- const char* xmlCode = "\
+ const char cppCode[] = "struct A {};\n";
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<extra-includes>\n\
<include file-name='header1.h' location='global'/>\n\
@@ -68,19 +44,19 @@ 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, QLatin1String("A")));
+ QVERIFY(AbstractMetaClass::findClass(classes, "A"));
- TypeDatabase* td = TypeDatabase::instance();
- const TypeSystemTypeEntry *module = td->defaultTypeSystemType();
+ auto *td = TypeDatabase::instance();
+ TypeSystemTypeEntryCPtr module = td->defaultTypeSystemType();
QVERIFY(module);
- QCOMPARE(module->name(), QLatin1String("Foo"));
+ QCOMPARE(module->name(), u"Foo");
QList<Include> includes = module->extraIncludes();
- QCOMPARE(includes.count(), 2);
- QCOMPARE(includes.constFirst().name(), QLatin1String("header1.h"));
- QCOMPARE(includes.constLast().name(), QLatin1String("header2.h"));
+ QCOMPARE(includes.size(), 2);
+ QCOMPARE(includes.constFirst().name(), u"header1.h");
+ QCOMPARE(includes.constLast().name(), u"header2.h");
}
QTEST_APPLESS_MAIN(TestExtraInclude)
diff --git a/sources/shiboken6/ApiExtractor/tests/testextrainclude.h b/sources/shiboken6/ApiExtractor/tests/testextrainclude.h
index 33c5377c7..6bcb57993 100644
--- a/sources/shiboken6/ApiExtractor/tests/testextrainclude.h
+++ b/sources/shiboken6/ApiExtractor/tests/testextrainclude.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTEXTRAINCLUDE_H
#define TESTEXTRAINCLUDE_H
-#include <QObject>
+#include <QtCore/QObject>
class TestExtraInclude : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp b/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp
index f58ea6f64..18eaf5774 100644
--- a/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testfunctiontag.cpp
@@ -1,38 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testfunctiontag.h"
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetafunction.h>
#include <modifications.h>
#include <typesystem.h>
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
void TestFunctionTag::testFunctionTagForSpecificSignature()
{
const char cppCode[] = "void globalFunction(int); void globalFunction(float); void dummy();\n";
@@ -43,9 +23,9 @@ void TestFunctionTag::testFunctionTagForSpecificSignature()
<function signature='globalFunction(int)'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
- const TypeEntry *func = TypeDatabase::instance()->findType(QLatin1String("globalFunction"));
+ TypeEntryCPtr func = TypeDatabase::instance()->findType(u"globalFunction"_s);
QVERIFY(func);
QCOMPARE(builder->globalFunctions().size(), 1);
}
@@ -61,24 +41,24 @@ void TestFunctionTag::testFunctionTagForAllSignatures()
<function signature='globalFunction(float)'/>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
- const TypeEntry *func = TypeDatabase::instance()->findType(QLatin1String("globalFunction"));
+ TypeEntryCPtr func = TypeDatabase::instance()->findType(u"globalFunction"_s);
QVERIFY(func);
QCOMPARE(builder->globalFunctions().size(), 2);
}
void TestFunctionTag::testRenameGlobalFunction()
{
- const char* cppCode ="void global_function_with_ugly_name();\n";
- const char* xmlCode = "\
+ const char cppCode[] = "void global_function_with_ugly_name();\n";
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<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);
- const TypeEntry *func = TypeDatabase::instance()->findType(QLatin1String("global_function_with_ugly_name"));
+ TypeEntryCPtr func = TypeDatabase::instance()->findType(u"global_function_with_ugly_name"_s);
QVERIFY(func);
QCOMPARE(builder->globalFunctions().size(), 1);
@@ -88,11 +68,11 @@ void TestFunctionTag::testRenameGlobalFunction()
QCOMPARE(metaFunc->modifications().size(), 1);
QVERIFY(metaFunc->modifications().constFirst().isRenameModifier());
QCOMPARE(metaFunc->modifications().constFirst().renamedToName(),
- QLatin1String("smooth"));
+ u"smooth");
- QCOMPARE(metaFunc->name(), QLatin1String("smooth"));
- QCOMPARE(metaFunc->originalName(), QLatin1String("global_function_with_ugly_name"));
- QCOMPARE(metaFunc->minimalSignature(), QLatin1String("global_function_with_ugly_name()"));
+ QCOMPARE(metaFunc->name(), u"smooth");
+ QCOMPARE(metaFunc->originalName(), u"global_function_with_ugly_name");
+ QCOMPARE(metaFunc->minimalSignature(), u"global_function_with_ugly_name()");
}
QTEST_APPLESS_MAIN(TestFunctionTag)
diff --git a/sources/shiboken6/ApiExtractor/tests/testfunctiontag.h b/sources/shiboken6/ApiExtractor/tests/testfunctiontag.h
index d68499cd9..7c60cb4e0 100644
--- a/sources/shiboken6/ApiExtractor/tests/testfunctiontag.h
+++ b/sources/shiboken6/ApiExtractor/tests/testfunctiontag.h
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTFUNCTIONTAG_H
#define TESTFUNCTIONTAG_H
-#include <QObject>
+
+#include <QtCore/QObject>
class TestFunctionTag : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp b/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp
index 9dcdec975..899d00ad4 100644
--- a/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.cpp
@@ -1,41 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testimplicitconversions.h"
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
-#include <typesystem.h>
+#include <abstractmetatype.h>
+#include <complextypeentry.h>
#include <QtTest/QTest>
void TestImplicitConversions::testWithPrivateCtors()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
class B;\n\
class C;\n\
class A {\n\
@@ -45,35 +22,35 @@ void TestImplicitConversions::testWithPrivateCtors()
};\n\
class B {};\n\
class C {};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<value-type name='A'/>\n\
<value-type name='B'/>\n\
<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.count(), 3);
+ QCOMPARE(classes.size(), 3);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
- const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, QLatin1String("C"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classC = AbstractMetaClass::findClass(classes, "C");
const auto implicitConvs = classA->implicitConversions();
- QCOMPARE(implicitConvs.count(), 1);
+ QCOMPARE(implicitConvs.size(), 1);
QCOMPARE(implicitConvs.constFirst()->arguments().constFirst().type().typeEntry(),
classC->typeEntry());
}
void TestImplicitConversions::testWithModifiedVisibility()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
class B;\n\
class A {\n\
public:\n\
A(const B&);\n\
};\n\
class B {};\n";
- const char* xmlCode = R"(
+ const char xmlCode[] = R"(
<typesystem package='Foo'>
<value-type name='A'>
<modify-function signature='A(const B&amp;)' access='private'/>
@@ -82,13 +59,13 @@ void TestImplicitConversions::testWithModifiedVisibility()
</typesystem>
)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QCOMPARE(classes.size(), 2);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
const auto implicitConvs = classA->implicitConversions();
- QCOMPARE(implicitConvs.count(), 1);
+ QCOMPARE(implicitConvs.size(), 1);
QCOMPARE(implicitConvs.constFirst()->arguments().constFirst().type().typeEntry(),
classB->typeEntry());
}
@@ -96,7 +73,7 @@ void TestImplicitConversions::testWithModifiedVisibility()
void TestImplicitConversions::testWithAddedCtor()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
class B;\n\
class A {\n\
public:\n\
@@ -104,7 +81,7 @@ void TestImplicitConversions::testWithAddedCtor()
};\n\
class B {};\n\
class C {};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<custom-type name='TARGETLANGTYPE'/>\n\
<value-type name='A'>\n\
@@ -116,49 +93,49 @@ 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.count(), 3);
+ QCOMPARE(classes.size(), 3);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
auto implicitConvs = classA->implicitConversions();
- QCOMPARE(implicitConvs.count(), 2);
+ QCOMPARE(implicitConvs.size(), 2);
// Added constructors with custom types should never result in implicit converters.
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
implicitConvs = classB->implicitConversions();
- QCOMPARE(implicitConvs.count(), 0);
+ QCOMPARE(implicitConvs.size(), 0);
}
void TestImplicitConversions::testWithExternalConversionOperator()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
class A {};\n\
struct B {\n\
operator A() const;\n\
};\n";
- const char* xmlCode = "\n\
+ const char xmlCode[] = "\n\
<typesystem package='Foo'>\n\
<value-type name='A'/>\n\
<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.count(), 2);
- AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
- AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QCOMPARE(classes.size(), 2);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
const auto implicitConvs = classA->implicitConversions();
- QCOMPARE(implicitConvs.count(), 1);
+ QCOMPARE(implicitConvs.size(), 1);
const auto &externalConvOps = classA->externalConversionOperators();
- QCOMPARE(externalConvOps.count(), 1);
+ QCOMPARE(externalConvOps.size(), 1);
AbstractMetaFunctionCPtr convOp;
for (const auto &func : classB->functions()) {
if (func->isConversionOperator())
convOp = func;
}
- QVERIFY(!convOp.isNull());
+ QVERIFY(convOp);
QCOMPARE(implicitConvs.constFirst(), convOp);
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.h b/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.h
index da8ae4597..e0678c5f5 100644
--- a/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.h
+++ b/sources/shiboken6/ApiExtractor/tests/testimplicitconversions.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTIMPLICITCONVERSIONS_H
#define TESTIMPLICITCONVERSIONS_H
-#include <QObject>
+#include <QtCore/QObject>
class AbstractMetaBuilder;
diff --git a/sources/shiboken6/ApiExtractor/tests/testinserttemplate.cpp b/sources/shiboken6/ApiExtractor/tests/testinserttemplate.cpp
index fda6614f0..23cf0f9ea 100644
--- a/sources/shiboken6/ApiExtractor/tests/testinserttemplate.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testinserttemplate.cpp
@@ -1,42 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testinserttemplate.h"
#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetalang.h>
+#include <codesnip.h>
#include <modifications.h>
-#include <typesystem.h>
+#include <complextypeentry.h>
+#include <typesystemtypeentry.h>
void TestInsertTemplate::testInsertTemplateOnClassInjectCode()
{
- const char* cppCode ="struct A{};\n";
- const char* xmlCode = "\
+ const char cppCode[] = "struct A{};\n";
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<template name='code_template'>\n\
code template content\n\
@@ -48,20 +25,20 @@ 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.count(), 1);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classes.size(), 1);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- QCOMPARE(classA->typeEntry()->codeSnips().count(), 1);
+ QCOMPARE(classA->typeEntry()->codeSnips().size(), 1);
QString code = classA->typeEntry()->codeSnips().constFirst().code();
- QVERIFY(code.contains(QLatin1String("code template content")));
+ QVERIFY(code.contains(u"code template content"));
}
void TestInsertTemplate::testInsertTemplateOnModuleInjectCode()
{
- const char* cppCode ="";
- const char* xmlCode = "\
+ const char cppCode[] = "";
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<template name='code_template'>\n\
code template content\n\
@@ -71,17 +48,16 @@ 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());
- const TypeSystemTypeEntry *module = TypeDatabase::instance()->defaultTypeSystemType();
+ TypeSystemTypeEntryCPtr module = TypeDatabase::instance()->defaultTypeSystemType();
QVERIFY(module);
- QCOMPARE(module->name(), QLatin1String("Foo"));
- QVERIFY(module);
- QCOMPARE(module->codeSnips().count(), 1);
+ QCOMPARE(module->name(), u"Foo");
+ QCOMPARE(module->codeSnips().size(), 1);
QString code = module->codeSnips().constFirst().code().trimmed();
- QVERIFY(code.contains(QLatin1String("code template content")));
+ QVERIFY(code.contains(u"code template content"));
}
QTEST_APPLESS_MAIN(TestInsertTemplate)
diff --git a/sources/shiboken6/ApiExtractor/tests/testinserttemplate.h b/sources/shiboken6/ApiExtractor/tests/testinserttemplate.h
index 99b171933..f4f67abc0 100644
--- a/sources/shiboken6/ApiExtractor/tests/testinserttemplate.h
+++ b/sources/shiboken6/ApiExtractor/tests/testinserttemplate.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTINSERTTEMPLATE_H
#define TESTINSERTTEMPLATE_H
-#include <QObject>
+#include <QtCore/QObject>
class TestInsertTemplate : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp b/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp
index 521f8d665..9cf2e0cc7 100644
--- a/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.cpp
@@ -1,46 +1,26 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testmodifydocumentation.h"
-
-#include <QCoreApplication>
-#include <QtCore/QTemporaryDir>
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetalang.h>
+#include <abstractmetafunction.h>
#include <documentation.h>
#include <modifications.h>
-#include <typesystem.h>
+#include <complextypeentry.h>
#include <qtdocparser.h>
+#include <qtcompat.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QTemporaryDir>
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
void TestModifyDocumentation::testModifyDocumentation()
{
- const char* cppCode ="struct B { void b(); }; class A {};\n";
+ const char cppCode[] = "struct B { void b(); }; class A {};\n";
const char xmlCode[] =
R"(<typesystem package="Foo">
<value-type name='B'>
@@ -53,22 +33,22 @@ R"(<typesystem package="Foo">
</typesystem>
)";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
- AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A"));
+ QVERIFY(builder);
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
QVERIFY(classA);
DocModificationList docMods = classA->typeEntry()->docModifications();
- QCOMPARE(docMods.count(), 2);
- QCOMPARE(docMods[0].code().trimmed(), QLatin1String("<brief>Modified Brief</brief>"));
+ QCOMPARE(docMods.size(), 2);
+ QCOMPARE(docMods[0].code().trimmed(), u"<brief>Modified Brief</brief>");
QCOMPARE(docMods[0].signature(), QString());
- QCOMPARE(docMods[1].code().trimmed(), QLatin1String("<para>Some changed contents here</para>"));
+ QCOMPARE(docMods[1].code().trimmed(), u"<para>Some changed contents here</para>");
QCOMPARE(docMods[1].signature(), QString());
// Create a temporary directory for the documentation file since libxml2
// cannot handle Qt resources.
- QTemporaryDir tempDir(QDir::tempPath() + QLatin1String("/shiboken_testmodifydocXXXXXX"));
+ QTemporaryDir tempDir(QDir::tempPath() + u"/shiboken_testmodifydocXXXXXX"_s);
QVERIFY2(tempDir.isValid(), qPrintable(tempDir.errorString()));
- const QString docFileName = QLatin1String("a.xml");
- QVERIFY(QFile::copy(QLatin1String(":/") + docFileName, tempDir.filePath(docFileName)));
+ constexpr auto docFileName = "a.xml"_L1;
+ QVERIFY(QFile::copy(u":/"_s + docFileName, tempDir.filePath(docFileName)));
QtDocParser docParser;
docParser.setDocumentationDataDirectory(tempDir.path());
@@ -89,7 +69,7 @@ R"(<?xml version="1.0"?>
)";
const QString expectedDocSimplified = QString::fromLatin1(expectedDoc).simplified();
// Check whether the first modification worked.
- QVERIFY(actualBriefSimplified.contains(QLatin1String("Modified Brief")));
+ QVERIFY(actualBriefSimplified.contains(u"Modified Brief"));
#ifndef HAVE_LIBXSLT
// QtXmlPatterns is unable to handle para[3] in style sheets,
@@ -99,6 +79,33 @@ R"(<?xml version="1.0"?>
QCOMPARE(actualDocSimplified, expectedDocSimplified);
}
+void TestModifyDocumentation::testInjectAddedFunctionDocumentation()
+{
+ const char cppCode[] ="class A {};\n";
+ const char xmlCode[] = R"XML(
+<typesystem package="Foo">
+ <value-type name='A'>
+ <add-function signature="foo(int@parameter_name@)">
+ <inject-documentation format="target" mode="append">
+ Injected documentation of added function foo.
+ </inject-documentation>
+ </add-function>
+ </value-type>
+</typesystem>
+)XML";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
+ QVERIFY(builder);
+ const auto classA = AbstractMetaClass::findClass(builder->classes(), "A");
+ QVERIFY(classA);
+ const auto f = classA->findFunction("foo");
+ QVERIFY(f);
+ QVERIFY(f->isUserAdded());
+ auto docMods = f->addedFunctionDocModifications();
+ QCOMPARE(docMods.size(), 1);
+ const QString code = docMods.constFirst().code();
+ QVERIFY(code.contains(u"Injected documentation of added function foo."));
+}
+
// We expand QTEST_MAIN macro but using QCoreApplication instead of QApplication
// because this test needs an event loop but can't use QApplication to avoid a crash
// on our ARMEL/FRAMANTLE buildbot
diff --git a/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.h b/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.h
index 6428a5697..c1cc8f480 100644
--- a/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.h
+++ b/sources/shiboken6/ApiExtractor/tests/testmodifydocumentation.h
@@ -1,41 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTMODIFYDOCUMENTATION_H
#define TESTMODIFYDOCUMENTATION_H
-#include <QObject>
+#include <QtCore/QObject>
class TestModifyDocumentation : public QObject
{
Q_OBJECT
private slots:
void testModifyDocumentation();
+ void testInjectAddedFunctionDocumentation();
};
#endif
diff --git a/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp b/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp
index 0d95d5abb..a7d40f70a 100644
--- a/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.cpp
@@ -1,40 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testmodifyfunction.h"
-#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetabuilder_p.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
+#include <abstractmetatype.h>
#include <modifications.h>
#include <typesystem.h>
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
void TestModifyFunction::testRenameArgument_data()
{
QTest::addColumn<QByteArray>("pattern");
@@ -46,7 +28,7 @@ void TestModifyFunction::testRenameArgument()
{
QFETCH(QByteArray, pattern);
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
void method(int=0);\n\
};\n";
@@ -64,23 +46,23 @@ 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, QLatin1String("A"));
- const auto func = classA->findFunction(QLatin1String("method"));
- QVERIFY(!func.isNull());
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
+ const auto func = classA->findFunction("method");
+ QVERIFY(func);
- QCOMPARE(func->argumentName(1), QLatin1String("otherArg"));
+ QCOMPARE(func->argumentName(1), u"otherArg");
}
void TestModifyFunction::testOwnershipTransfer()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {};\n\
struct B {\n\
virtual A* method();\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<object-type name='A' />\n\
<object-type name='B'>\n\
@@ -92,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, QLatin1String("B"));
- const auto func = classB->findFunction(QLatin1String("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);
@@ -105,7 +87,7 @@ void TestModifyFunction::testOwnershipTransfer()
void TestModifyFunction::invalidateAfterUse()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
virtual void call(int *a);\n\
};\n\
@@ -119,7 +101,7 @@ void TestModifyFunction::invalidateAfterUse()
};\n\
struct E : D {\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='int'/>\n\
<object-type name='A'>\n\
@@ -141,48 +123,48 @@ void TestModifyFunction::invalidateAfterUse()
<object-type name='E' />\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
- false, QLatin1String("0.1")));
- QVERIFY(!builder.isNull());
+ false, u"0.1"_s));
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
- auto func = classB->findFunction(QLatin1String("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, QLatin1String("C"));
+ const auto classC = AbstractMetaClass::findClass(classes, "C");
QVERIFY(classC);
- func = classC->findFunction(QLatin1String("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(QLatin1String("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, QLatin1String("D"));
+ AbstractMetaClassCPtr classD = AbstractMetaClass::findClass(classes, "D");
QVERIFY(classD);
- func = classD->findFunction(QLatin1String("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(QLatin1String("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, QLatin1String("E"));
+ const auto classE = AbstractMetaClass::findClass(classes, "E");
QVERIFY(classE);
- func = classE->findFunction(QLatin1String("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(QLatin1String("call2"));
+ func = classE->findFunction("call2");
QVERIFY(func);
QCOMPARE(func->modifications().size(), 1);
QCOMPARE(func->modifications().at(0).argument_mods().size(), 1);
@@ -191,13 +173,13 @@ void TestModifyFunction::invalidateAfterUse()
void TestModifyFunction::testWithApiVersion()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {};\n\
struct B {\n\
virtual A* method();\n\
virtual B* methodB();\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<object-type name='A' />\n\
<object-type name='B'>\n\
@@ -214,16 +196,16 @@ void TestModifyFunction::testWithApiVersion()
</object-type>\n\
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
- false, QLatin1String("0.1")));
- QVERIFY(!builder.isNull());
+ false, u"0.1"_s));
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
- auto func = classB->findFunction(QLatin1String("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(QLatin1String("methodB"));
+ func = classB->findFunction("methodB");
returnOwnership = func->argumentTargetOwnership(func->ownerClass(), 0);
QVERIFY(returnOwnership != TypeSystem::CppOwnership);
}
@@ -253,44 +235,44 @@ struct A {
</typesystem>
)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
- false, QLatin1String("0.1")));
- QVERIFY(!builder.isNull());
+ false, u"0.1"_s));
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
// Nothing specified, true
- const auto f1 = classA->findFunction(QLatin1String("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(QLatin1String("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(QLatin1String("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(QLatin1String("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(QLatin1String("getter2"));
- QVERIFY(!getter2.isNull());
+ const auto getter2 = classA->findFunction("getter2");
+ QVERIFY(getter2);
QVERIFY(getter2->allowThread()); // Forced to true simple getter
}
void TestModifyFunction::testGlobalFunctionModification()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {};\n\
void function(A* a = 0);\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='A'/>\n\
<function signature='function(A*)'>\n\
@@ -304,23 +286,24 @@ void TestModifyFunction::testGlobalFunctionModification()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
QCOMPARE(builder->globalFunctions().size(), 1);
- FunctionModificationList mods = TypeDatabase::instance()->functionModifications(QLatin1String("function(A*)"));
- QCOMPARE(mods.count(), 1);
+ auto *td = TypeDatabase::instance();
+ FunctionModificationList mods = td->globalFunctionModifications({u"function(A*)"_s});
+ QCOMPARE(mods.size(), 1);
const QList<ArgumentModification> &argMods = mods.constFirst().argument_mods();
- QCOMPARE(argMods.count(), 1);
+ QCOMPARE(argMods.size(), 1);
ArgumentModification argMod = argMods.constFirst();
- QCOMPARE(argMod.replacedDefaultExpression(), QLatin1String("A()"));
+ QCOMPARE(argMod.replacedDefaultExpression(), u"A()");
QVERIFY(!builder->globalFunctions().isEmpty());
const auto func = builder->globalFunctions().constFirst();
- QCOMPARE(func->arguments().count(), 1);
+ QCOMPARE(func->arguments().size(), 1);
const AbstractMetaArgument &arg = func->arguments().constFirst();
- QCOMPARE(arg.type().cppSignature(), QLatin1String("A *"));
- QCOMPARE(arg.originalDefaultValueExpression(), QLatin1String("0"));
- QCOMPARE(arg.defaultValueExpression(), QLatin1String("A()"));
+ QCOMPARE(arg.type().cppSignature(), u"A *");
+ QCOMPARE(arg.originalDefaultValueExpression(), u"0");
+ QCOMPARE(arg.defaultValueExpression(), u"A()");
}
// Tests modifications of exception handling and allow-thread
@@ -451,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(), QLatin1String("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/testmodifyfunction.h b/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.h
index a9a13a82b..8a4f5d826 100644
--- a/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.h
+++ b/sources/shiboken6/ApiExtractor/tests/testmodifyfunction.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTABSTRACTMETACLASS_H
#define TESTABSTRACTMETACLASS_H
-#include <QObject>
+#include <QtCore/QObject>
class TestModifyFunction : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp b/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp
index 748adfc39..1cf4c8e0f 100644
--- a/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testmultipleinheritance.h"
#include <QtTest/QTest>
@@ -35,7 +10,7 @@
void TestMultipleInheritance::testVirtualClass()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {\n\
virtual ~A();\n\
virtual void theBug();\n\
@@ -47,7 +22,7 @@ void TestMultipleInheritance::testVirtualClass()
};\n\
struct D : C {\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<object-type name='A' />\n\
<object-type name='B' />\n\
@@ -56,14 +31,14 @@ void TestMultipleInheritance::testVirtualClass()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 4);
+ QCOMPARE(classes.size(), 4);
- const AbstractMetaClass *classD = AbstractMetaClass::findClass(classes, QLatin1String("D"));
+ const auto classD = AbstractMetaClass::findClass(classes, "D");
bool functionFound = false;
for (const auto &f : classD->functions()) {
- if (f->name() == QLatin1String("theBug")) {
+ if (f->name() == u"theBug") {
functionFound = true;
break;
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.h b/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.h
index 5ee8a21ea..ec9935305 100644
--- a/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.h
+++ b/sources/shiboken6/ApiExtractor/tests/testmultipleinheritance.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTMULTIPLEINHERITANCE_H
#define TESTMULTIPLEINHERITANCE_H
-#include <QObject>
+#include <QtCore/QObject>
class AbstractMetaBuilder;
diff --git a/sources/shiboken6/ApiExtractor/tests/testnamespace.cpp b/sources/shiboken6/ApiExtractor/tests/testnamespace.cpp
index 99aabe780..3773e614a 100644
--- a/sources/shiboken6/ApiExtractor/tests/testnamespace.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testnamespace.cpp
@@ -1,41 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testnamespace.h"
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetalang.h>
#include <abstractmetaenum.h>
#include <typesystem.h>
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
void NamespaceTest::testNamespaceMembers()
{
- const char* cppCode = "\
+ const char cppCode[] = "\
namespace Namespace\n\
{\n\
enum Option {\n\
@@ -44,26 +24,26 @@ void NamespaceTest::testNamespaceMembers()
};\n\
void foo(Option opt);\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<namespace-type name='Namespace'>\n\
<enum-type name='Option' />\n\
</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, QLatin1String("Namespace"));
+ const auto ns = AbstractMetaClass::findClass(classes, "Namespace");
QVERIFY(ns);
- auto metaEnum = ns->findEnum(QLatin1String("Option"));
+ auto metaEnum = ns->findEnum(u"Option"_s);
QVERIFY(metaEnum.has_value());
- const auto func = ns->findFunction(QLatin1String("foo"));
- QVERIFY(!func.isNull());
+ const auto func = ns->findFunction("foo");
+ QVERIFY(func);
}
void NamespaceTest::testNamespaceInnerClassMembers()
{
- const char* cppCode = "\
+ const char cppCode[] = "\
namespace OuterNamespace\n\
{\n\
namespace InnerNamespace {\n\
@@ -72,7 +52,7 @@ void NamespaceTest::testNamespaceInnerClassMembers()
};\n\
};\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<namespace-type name='OuterNamespace'>\n\
<namespace-type name='InnerNamespace'>\n\
@@ -81,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, QLatin1String("OuterNamespace"));
+ const auto ons = AbstractMetaClass::findClass(classes, "OuterNamespace");
QVERIFY(ons);
- const AbstractMetaClass *ins = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace"));
+ const auto ins = AbstractMetaClass::findClass(classes, "OuterNamespace::InnerNamespace");
QVERIFY(ins);
- const AbstractMetaClass *sc = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace::SomeClass"));
+ const auto sc = AbstractMetaClass::findClass(classes, "OuterNamespace::InnerNamespace::SomeClass");
QVERIFY(sc);
- const auto meth = sc->findFunction(QLatin1String("method"));
- QVERIFY(!meth.isNull());
+ const auto meth = sc->findFunction("method");
+ QVERIFY(meth);
}
QTEST_APPLESS_MAIN(NamespaceTest)
diff --git a/sources/shiboken6/ApiExtractor/tests/testnamespace.h b/sources/shiboken6/ApiExtractor/tests/testnamespace.h
index 5153a28a3..af46bdea3 100644
--- a/sources/shiboken6/ApiExtractor/tests/testnamespace.h
+++ b/sources/shiboken6/ApiExtractor/tests/testnamespace.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTNAMESPACE_H
#define TESTNAMESPACE_H
-#include <QObject>
+#include <QtCore/QObject>
// The class is named 'NamespaceTest' to avoid clashes with Qt COIN using
// '-qtnamespace TestNamespace'.
diff --git a/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp b/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp
index d536c0538..10ca1a0f6 100644
--- a/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testnestedtypes.cpp
@@ -1,42 +1,25 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testnestedtypes.h"
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
+#include <abstractmetatype.h>
+#include <codesnip.h>
#include <modifications.h>
-#include <typesystem.h>
+#include <complextypeentry.h>
+#include <primitivetypeentry.h>
+
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
void TestNestedTypes::testNestedTypesModifications()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
namespace OuterNamespace {\n\
namespace InnerNamespace {\n\
struct SomeClass {\n\
@@ -44,7 +27,7 @@ void TestNestedTypes::testNestedTypesModifications()
};\n\
};\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<namespace-type name='OuterNamespace'>\n\
<namespace-type name='InnerNamespace'>\n\
@@ -60,34 +43,35 @@ void TestNestedTypes::testNestedTypesModifications()
</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, QLatin1String("OuterNamespace"));
+ const auto ons = AbstractMetaClass::findClass(classes, "OuterNamespace");
QVERIFY(ons);
- const AbstractMetaClass *ins = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace"));
+ const auto ins = AbstractMetaClass::findClass(classes, "OuterNamespace::InnerNamespace");
QVERIFY(ins);
- QCOMPARE(ins->functions().count(), 1);
- QCOMPARE(ins->typeEntry()->codeSnips().count(), 1);
+ QCOMPARE(ins->functions().size(), 1);
+ QCOMPARE(ins->typeEntry()->codeSnips().size(), 1);
CodeSnip snip = ins->typeEntry()->codeSnips().constFirst();
- QCOMPARE(snip.code().trimmed(), QLatin1String("custom_code1();"));
+ QCOMPARE(snip.code().trimmed(), u"custom_code1();");
const auto addedFunc = ins->functions().constFirst();
QVERIFY(addedFunc->isUserAdded());
QCOMPARE(addedFunc->access(), Access::Public);
QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction);
QCOMPARE(addedFunc->type().minimalSignature(),
- QLatin1String("OuterNamespace::InnerNamespace::SomeClass"));
+ u"OuterNamespace::InnerNamespace::SomeClass");
QCOMPARE(addedFunc->modifications().size(), 1);
QVERIFY(addedFunc->modifications().constFirst().isCodeInjection());
snip = addedFunc->modifications().constFirst().snips().constFirst();
- QCOMPARE(snip.code().trimmed(), QLatin1String("custom_code2();"));
+ QCOMPARE(snip.code().trimmed(), u"custom_code2();");
- const AbstractMetaClass *sc = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace::SomeClass"));
- QVERIFY(ins);
- QCOMPARE(sc->functions().count(), 2); // default constructor and removed method
+ 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());
}
@@ -95,11 +79,11 @@ void TestNestedTypes::testNestedTypesModifications()
void TestNestedTypes::testDuplicationOfNestedTypes()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
namespace Namespace {\n\
class SomeClass {};\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<namespace-type name='Namespace'>\n\
<value-type name='SomeClass'>\n\
@@ -109,22 +93,22 @@ void TestNestedTypes::testDuplicationOfNestedTypes()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- QCOMPARE(classes.count(), 2);
- const AbstractMetaClass *nspace = AbstractMetaClass::findClass(classes, QLatin1String("Namespace"));
+ QCOMPARE(classes.size(), 2);
+ const auto nspace = AbstractMetaClass::findClass(classes, "Namespace");
QVERIFY(nspace);
- const AbstractMetaClass *cls1 = AbstractMetaClass::findClass(classes, QLatin1String("SomeClass"));
+ const auto cls1 = AbstractMetaClass::findClass(classes, "SomeClass");
QVERIFY(cls1);
- const AbstractMetaClass *cls2 = AbstractMetaClass::findClass(classes, QLatin1String("Namespace::SomeClass"));
+ const auto cls2 = AbstractMetaClass::findClass(classes, "Namespace::SomeClass");
QVERIFY(cls2);
QCOMPARE(cls1, cls2);
- QCOMPARE(cls1->name(), QLatin1String("SomeClass"));
- QCOMPARE(cls1->qualifiedCppName(), QLatin1String("Namespace::SomeClass"));
+ QCOMPARE(cls1->name(), u"SomeClass");
+ QCOMPARE(cls1->qualifiedCppName(), u"Namespace::SomeClass");
- TypeEntry* t1 = TypeDatabase::instance()->findType(QLatin1String("Namespace::SomeClass"));
+ auto t1 = TypeDatabase::instance()->findType(u"Namespace::SomeClass"_s);
QVERIFY(t1);
- TypeEntry* t2 = TypeDatabase::instance()->findType(QLatin1String("SomeClass"));
+ auto t2 = TypeDatabase::instance()->findType(u"SomeClass"_s);
QVERIFY(!t2);
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testnestedtypes.h b/sources/shiboken6/ApiExtractor/tests/testnestedtypes.h
index a870511ff..544ea05ab 100644
--- a/sources/shiboken6/ApiExtractor/tests/testnestedtypes.h
+++ b/sources/shiboken6/ApiExtractor/tests/testnestedtypes.h
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTNESTEDTYPES_H
#define TESTNESTEDTYPES_H
-#include <QObject>
+
+#include <QtCore/QObject>
class TestNestedTypes : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp b/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp
index de2f30135..9eef7ec47 100644
--- a/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.cpp
@@ -1,45 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testnumericaltypedef.h"
#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
+#include <abstractmetatype.h>
#include <typesystem.h>
void TestNumericalTypedef::testNumericalTypedef()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
typedef double real;\n\
void funcDouble(double);\n\
void funcReal(real);\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='double'/>\n\
<primitive-type name='real'/>\n\
@@ -47,37 +24,37 @@ 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();
auto funcReal = builder->globalFunctions().constLast();
QVERIFY(funcReal);
- if (funcDouble->name() == QLatin1String("funcReal"))
+ if (funcDouble->name() == u"funcReal")
std::swap(funcDouble, funcReal);
- QCOMPARE(funcDouble->minimalSignature(), QLatin1String("funcDouble(double)"));
- QCOMPARE(funcReal->minimalSignature(), QLatin1String("funcReal(real)"));
+ QCOMPARE(funcDouble->minimalSignature(), u"funcDouble(double)");
+ QCOMPARE(funcReal->minimalSignature(), u"funcReal(real)");
const AbstractMetaType doubleType = funcDouble->arguments().constFirst().type();
- QCOMPARE(doubleType.cppSignature(), QLatin1String("double"));
+ QCOMPARE(doubleType.cppSignature(), u"double");
QVERIFY(doubleType.isPrimitive());
- QVERIFY(doubleType.typeEntry()->isCppPrimitive());
+ QVERIFY(isCppPrimitive(doubleType.typeEntry()));
const AbstractMetaType realType = funcReal->arguments().constFirst().type();
- QCOMPARE(realType.cppSignature(), QLatin1String("real"));
+ QCOMPARE(realType.cppSignature(), u"real");
QVERIFY(realType.isPrimitive());
- QVERIFY(realType.typeEntry()->isCppPrimitive());
+ QVERIFY(isCppPrimitive(realType.typeEntry()));
}
void TestNumericalTypedef::testUnsignedNumericalTypedef()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
typedef unsigned short custom_ushort;\n\
void funcUnsignedShort(unsigned short);\n\
void funcUShort(custom_ushort);\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package='Foo'>\n\
<primitive-type name='short'/>\n\
<primitive-type name='unsigned short'/>\n\
@@ -86,27 +63,27 @@ 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();
auto funcUShort = builder->globalFunctions().constLast();
- if (funcUnsignedShort->name() == QLatin1String("funcUShort"))
+ if (funcUnsignedShort->name() == u"funcUShort")
std::swap(funcUnsignedShort, funcUShort);
- QCOMPARE(funcUnsignedShort->minimalSignature(), QLatin1String("funcUnsignedShort(unsigned short)"));
- QCOMPARE(funcUShort->minimalSignature(), QLatin1String("funcUShort(custom_ushort)"));
+ QCOMPARE(funcUnsignedShort->minimalSignature(), u"funcUnsignedShort(unsigned short)");
+ QCOMPARE(funcUShort->minimalSignature(), u"funcUShort(custom_ushort)");
const AbstractMetaType unsignedShortType = funcUnsignedShort->arguments().constFirst().type();
- QCOMPARE(unsignedShortType.cppSignature(), QLatin1String("unsigned short"));
+ QCOMPARE(unsignedShortType.cppSignature(), u"unsigned short");
QVERIFY(unsignedShortType.isPrimitive());
- QVERIFY(unsignedShortType.typeEntry()->isCppPrimitive());
+ QVERIFY(isCppPrimitive(unsignedShortType.typeEntry()));
const AbstractMetaType ushortType = funcUShort->arguments().constFirst().type();
- QCOMPARE(ushortType.cppSignature(), QLatin1String("custom_ushort"));
+ QCOMPARE(ushortType.cppSignature(), u"custom_ushort");
QVERIFY(ushortType.isPrimitive());
- QVERIFY(ushortType.typeEntry()->isCppPrimitive());
+ QVERIFY(isCppPrimitive(ushortType.typeEntry()));
}
QTEST_APPLESS_MAIN(TestNumericalTypedef)
diff --git a/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.h b/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.h
index e4e051077..32f549836 100644
--- a/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.h
+++ b/sources/shiboken6/ApiExtractor/tests/testnumericaltypedef.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTNUMERICALTYPEDEF_H
#define TESTNUMERICALTYPEDEF_H
-#include <QObject>
+#include <QtCore/QObject>
class TestNumericalTypedef : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.cpp b/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.cpp
index e78f9f274..99cced09d 100644
--- a/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.cpp
@@ -1,59 +1,39 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testprimitivetypetag.h"
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetalang.h>
-#include <typesystem.h>
+#include <primitivetypeentry.h>
+
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
void TestPrimitiveTypeTag::testPrimitiveTypeDefaultConstructor()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {};\n\
struct B {};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<primitive-type name='A' default-constructor='A()'/>\n\
<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.count(), 1);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ QCOMPARE(classes.size(), 1);
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
- PrimitiveTypeEntry* typeEntry = TypeDatabase::instance()->findPrimitiveType(QLatin1String("A"));
+ auto typeEntry = TypeDatabase::instance()->findPrimitiveType(u"A"_s);
QVERIFY(typeEntry);
QVERIFY(typeEntry->hasDefaultConstructor());
- QCOMPARE(typeEntry->defaultConstructor(), QLatin1String("A()"));
+ QCOMPARE(typeEntry->defaultConstructor(), u"A()");
}
QTEST_APPLESS_MAIN(TestPrimitiveTypeTag)
diff --git a/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.h b/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.h
index ee5f5159f..3a0e05138 100644
--- a/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.h
+++ b/sources/shiboken6/ApiExtractor/tests/testprimitivetypetag.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTPRIMITIVETYPETAG_H
#define TESTPRIMITIVETYPETAG_H
-#include <QObject>
+#include <QtCore/QObject>
class TestPrimitiveTypeTag : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp b/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp
index f3ffd0edf..f2e261624 100644
--- a/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testrefcounttag.cpp
@@ -1,46 +1,26 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testrefcounttag.h"
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
#include <modifications.h>
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
void TestRefCountTag::testReferenceCountTag()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {};\n\
struct B {\n\
void keepObject(B* b);\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<object-type name='A'/>\n\
<object-type name='B'>\n\
@@ -52,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, QLatin1String("B"));
- const auto func = classB->findFunction(QLatin1String("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);
@@ -64,12 +44,12 @@ void TestRefCountTag::testReferenceCountTag()
void TestRefCountTag::testWithApiVersion()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {};\n\
struct B {\n\
void keepObject(B*, B*);\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<object-type name='A'/>\n\
<object-type name='B'>\n\
@@ -85,12 +65,12 @@ void TestRefCountTag::testWithApiVersion()
</typesystem>\n";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode,
- false, QLatin1String("0.1")));
- QVERIFY(!builder.isNull());
+ false, u"0.1"_s));
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
- const auto func = classB->findFunction(QLatin1String("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/testrefcounttag.h b/sources/shiboken6/ApiExtractor/tests/testrefcounttag.h
index 4acbddcfc..6093c6f7b 100644
--- a/sources/shiboken6/ApiExtractor/tests/testrefcounttag.h
+++ b/sources/shiboken6/ApiExtractor/tests/testrefcounttag.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTREFCOUNTTAG_H
#define TESTREFCOUNTTAG_H
-#include <QObject>
+#include <QtCore/QObject>
class TestRefCountTag : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp b/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp
index b929ebd66..ae85c5a86 100644
--- a/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.cpp
@@ -1,58 +1,35 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testreferencetopointer.h"
#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
+#include <abstractmetatype.h>
#include <typesystem.h>
void TestReferenceToPointer::testReferenceToPointerArgument()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {};\n\
struct B {\n\
void dummy(A*&);\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<object-type name='A'/>\n\
<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, QLatin1String("B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
- const auto func = classB->findFunction(QLatin1String("dummy"));
- QVERIFY(!func.isNull());
- QCOMPARE(func->arguments().constFirst().type().minimalSignature(), QLatin1String("A*&"));
+ const auto func = classB->findFunction("dummy");
+ QVERIFY(func);
+ QCOMPARE(func->arguments().constFirst().type().minimalSignature(), u"A*&");
}
QTEST_APPLESS_MAIN(TestReferenceToPointer)
diff --git a/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.h b/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.h
index 0f717b55d..2a7b34807 100644
--- a/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.h
+++ b/sources/shiboken6/ApiExtractor/tests/testreferencetopointer.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTREFERENCETOPOINTER_H
#define TESTREFERENCETOPOINTER_H
-#include <QObject>
+#include <QtCore/QObject>
class TestReferenceToPointer : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp b/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp
index 5fb2ff687..2cc82071b 100644
--- a/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testremovefield.cpp
@@ -1,46 +1,26 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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 ="\
+ const char cppCode[] = "\
struct A {\n\
int fieldA;\n\
int fieldB;\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<primitive-type name='int'/>\n\
<value-type name='A'>\n\
@@ -48,13 +28,47 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->fields().size(), 1);
const AbstractMetaField &fieldA = classA->fields().constFirst();
- QCOMPARE(fieldA.name(), QLatin1String("fieldA"));
+ 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 8b52cc32f..05912d99e 100644
--- a/sources/shiboken6/ApiExtractor/tests/testremovefield.h
+++ b/sources/shiboken6/ApiExtractor/tests/testremovefield.h
@@ -1,41 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTREMOVEFIELD_H
#define TESTREMOVEFIELD_H
-#include <QObject>
+#include <QtCore/QObject>
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 41103c24e..87e318e95 100644
--- a/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.cpp
@@ -1,50 +1,27 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testremoveimplconv.h"
#include "testutil.h"
#include <QtTest/QTest>
+#include <abstractmetaargument.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
-#include <typesystem.h>
+#include <abstractmetatype.h>
+#include <complextypeentry.h>
// When a constructor able to trigger implicity conversions is removed
// it should not appear in the implicity conversion list.
void TestRemoveImplConv::testRemoveImplConv()
{
- const char* cppCode ="\
+ const char cppCode[] = "\
struct A {};\n\
struct B {};\n\
struct C {\n\
C(const A&);\n\
C(const B&);\n\
};\n";
- const char* xmlCode = "\
+ const char xmlCode[] = "\
<typesystem package=\"Foo\">\n\
<value-type name='A'/>\n\
<value-type name='B'/>\n\
@@ -53,17 +30,17 @@ 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.count(), 3);
- const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ QCOMPARE(classes.size(), 3);
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
- const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, QLatin1String("C"));
+ const auto classC = AbstractMetaClass::findClass(classes, "C");
QVERIFY(classC);
const auto implConv = classC->implicitConversions();
- QCOMPARE(implConv.count(), 1);
+ QCOMPARE(implConv.size(), 1);
QCOMPARE(implConv.constFirst()->arguments().constFirst().type().typeEntry(),
classB->typeEntry());
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.h b/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.h
index 9e96dc2e9..d11d30633 100644
--- a/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.h
+++ b/sources/shiboken6/ApiExtractor/tests/testremoveimplconv.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTREMOVEIMPLCONV_H
#define TESTREMOVEIMPLCONV_H
-#include <QObject>
+#include <QtCore/QObject>
class TestRemoveImplConv : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp b/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp
index 9824d1bf0..17a069b5e 100644
--- a/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.cpp
@@ -1,63 +1,44 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testremoveoperatormethod.h"
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
#include <typesystem.h>
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+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* xmlCode = "\
+ 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\
<primitive-type name='short'/>\n\
@@ -87,25 +68,25 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QCOMPARE(classA->functions().size(), 14);
QStringList removedSignatures;
- removedSignatures.append(QLatin1String("operator>>(char&)"));
- removedSignatures.append(QLatin1String("operator>>(char*)"));
- removedSignatures.append(QLatin1String("operator>>(short&)"));
- removedSignatures.append(QLatin1String("operator>>(unsigned short&)"));
- removedSignatures.append(QLatin1String("operator>>(int&)"));
- removedSignatures.append(QLatin1String("operator>>(unsigned int&)"));
- removedSignatures.append(QLatin1String("operator>>(int64_t&)"));
- removedSignatures.append(QLatin1String("operator>>(uint64_t&)"));
- removedSignatures.append(QLatin1String("operator>>(float&)"));
- removedSignatures.append(QLatin1String("operator>>(double&)"));
- removedSignatures.append(QLatin1String("operator>>(Char&)"));
- removedSignatures.append(QLatin1String("operator>>(String&)"));
- int notRemoved = classA->functions().size();
+ removedSignatures.append(u"operator>>(char&)"_s);
+ removedSignatures.append(u"operator>>(char*)"_s);
+ removedSignatures.append(u"operator>>(short&)"_s);
+ removedSignatures.append(u"operator>>(unsigned short&)"_s);
+ removedSignatures.append(u"operator>>(int&)"_s);
+ removedSignatures.append(u"operator>>(unsigned int&)"_s);
+ removedSignatures.append(u"operator>>(int64_t&)"_s);
+ removedSignatures.append(u"operator>>(uint64_t&)"_s);
+ removedSignatures.append(u"operator>>(float&)"_s);
+ removedSignatures.append(u"operator>>(double&)"_s);
+ removedSignatures.append(u"operator>>(Char&)"_s);
+ removedSignatures.append(u"operator>>(String&)"_s);
+ auto notRemoved = classA->functions().size();
for (const auto &f : classA->functions()) {
QCOMPARE(f->isModifiedRemoved(), bool(removedSignatures.contains(f->minimalSignature())));
notRemoved -= int(f->isModifiedRemoved());
diff --git a/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.h b/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.h
index 23c3e5144..6ec335e0c 100644
--- a/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.h
+++ b/sources/shiboken6/ApiExtractor/tests/testremoveoperatormethod.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTREMOVEOPERATORMETHOD_H
#define TESTREMOVEOPERATORMETHOD_H
-#include <QObject>
+#include <QtCore/QObject>
class TestRemoveOperatorMethod : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testresolvetype.cpp b/sources/shiboken6/ApiExtractor/tests/testresolvetype.cpp
index 4c2930234..67ebcc606 100644
--- a/sources/shiboken6/ApiExtractor/tests/testresolvetype.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testresolvetype.cpp
@@ -1,40 +1,33 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testresolvetype.h"
-#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
+#include <abstractmetaenum.h>
+#include <abstractmetafunction.h>
#include <abstractmetalang.h>
-#include <typesystem.h>
+#include <abstractmetatype.h>
+#include <complextypeentry.h>
+#include <enumtypeentry.h>
+#include <primitivetypeentry.h>
+#include <typedatabase.h>
+
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
+void TestResolveType::initTestCase()
+{
+ // For enum lookup in testFixDefaultArguments()
+ AbstractMetaBuilder::setCodeModelTestMode(true);
+}
void TestResolveType::testResolveReturnTypeFromParentScope()
{
- const char* cppCode = "\n\
+ const char cppCode[] = "\n\
namespace A {\n\
struct B {\n\
struct C {};\n\
@@ -44,7 +37,7 @@ void TestResolveType::testResolveReturnTypeFromParentScope()
C* method();\n\
};\n\
};";
- const char* xmlCode = R"XML(
+ const char xmlCode[] = R"XML(
<typesystem package='Foo'>
<namespace-type name='A'>
<value-type name='B'>
@@ -54,14 +47,235 @@ 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, QLatin1String("A::D"));
+ const auto classD = AbstractMetaClass::findClass(classes, "A::D");
QVERIFY(classD);
- const auto meth = classD->findFunction(QLatin1String("method"));
- QVERIFY(!meth.isNull());
+ const auto meth = classD->findFunction("method");
+ QVERIFY(meth);
QVERIFY(meth);
}
-QTEST_APPLESS_MAIN(TestResolveType)
+// Helper classes and functions for testing default value fixing.
+// Put the AbstractMetaBuilder into test fixture struct to avoid having
+// to re-parse for each data row.
+
+struct DefaultValuesFixture
+{
+ std::shared_ptr<AbstractMetaBuilder> builder;
+
+ AbstractMetaType intType;
+ AbstractMetaType stringType;
+ AbstractMetaType classType;
+ AbstractMetaType listType;
+ AbstractMetaType enumType;
+ AbstractMetaClassCPtr klass{};
+};
+
+Q_DECLARE_METATYPE(DefaultValuesFixture)
+Q_DECLARE_METATYPE(AbstractMetaType)
+
+static int populateDefaultValuesFixture(DefaultValuesFixture *fixture)
+{
+ static const char cppCode[] =R"(
+#include <string>
+#include <list>
+
+namespace Namespace {
+class Test
+{
+public:
+ enum Enum { enumValue1, enumValue2 };
+
+ explicit Test(int x = INT_FIELD_1);
+ explicit Test(const std::string &t = std::string(CHAR_FIELD_1));
+
+ static void listFunc(std::list<Test> list = std::list<Test>());
+
+ static const int INT_FIELD_1 = 42;
+ static const char *CHAR_FIELD_1;
+ static const Enum DefaultValue = enumValue1;
+};
+} // Namespace
+)";
+ static const char xmlCode[] = R"(
+<typesystem package="Foo">
+ <namespace-type name='Namespace'>
+ <value-type name='Test'>
+ <enum-type name='Enum'/>
+ </value-type>
+ </namespace-type>
+ <container-type name="std::list" type="list"/>
+</typesystem>
+)";
+
+ fixture->builder.reset(TestUtil::parse(cppCode, xmlCode, false));
+ if (!fixture->builder)
+ return -1;
+
+ for (const auto &klass : fixture->builder->classes()) {
+ if (klass->name() == u"Test") {
+ fixture->klass = klass;
+ break;
+ }
+ }
+ if (!fixture->klass)
+ return -2;
+
+ fixture->classType = AbstractMetaType(fixture->klass->typeEntry());
+ fixture->classType.decideUsagePattern();
+
+ for (const auto &f : fixture->klass->findFunctions("Test")) {
+ if (f->functionType() == AbstractMetaFunction::ConstructorFunction
+ && f->arguments().size() == 1) {
+ const auto type = f->arguments().constFirst().type();
+ if (type.name() == u"int")
+ fixture->intType = type;
+ else
+ fixture->stringType = type;
+ }
+ }
+ if (fixture->intType.isVoid() || fixture->stringType.isVoid())
+ return -3;
+
+ 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;
+}
+
+void TestResolveType::testFixDefaultArguments_data()
+{
+ DefaultValuesFixture fixture;
+ const int setupOk = populateDefaultValuesFixture(&fixture);
+
+ QTest::addColumn<DefaultValuesFixture>("fixture");
+ QTest::addColumn<int>("setupOk"); // To verify setup
+ QTest::addColumn<AbstractMetaType>("metaType"); // Type and parameters for fixup
+ QTest::addColumn<QString>("input");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("int") << fixture << setupOk
+ << fixture.intType << "1" << "1";
+ QTest::newRow("int-macro") << fixture << setupOk
+ << fixture.intType << "GL_MACRO" << "GL_MACRO";
+ QTest::newRow("int-enum") << fixture << setupOk
+ << fixture.intType << "enumValue1" << "Namespace::Test::Enum::enumValue1";
+
+ // Test expansion of container types
+ QString expected = u"std::list<Namespace::Test>()"_s;
+ QTest::newRow("list")
+ << fixture << setupOk << fixture.listType
+ << expected << expected;
+ QTest::newRow("partially qualified list")
+ << fixture << setupOk << fixture.listType
+ << "std::list<Test>()" << expected;
+
+ // Test field expansion
+ expected = u"Namespace::Test::INT_FIELD_1"_s;
+ QTest::newRow("qualified class field")
+ << fixture << setupOk << fixture.intType
+ << expected << expected;
+ QTest::newRow("partially qualified class field")
+ << fixture << setupOk << fixture.intType
+ << "Test::INT_FIELD_1" << expected;
+ QTest::newRow("unqualified class field")
+ << fixture << setupOk << fixture.intType
+ << "INT_FIELD_1" << expected;
+
+ // Test field expansion when constructing some class
+ expected = u"QLatin1String(Namespace::Test::CHAR_FIELD_1)"_s;
+ QTest::newRow("class from qualified class field")
+ << fixture << setupOk << fixture.classType
+ << expected << expected;
+ QTest::newRow("class from partially qualified class field")
+ << fixture << setupOk << fixture.classType
+ << "QLatin1String(Test::CHAR_FIELD_1)" << expected;
+ QTest::newRow("class from unqualified class field")
+ << fixture << setupOk << fixture.classType
+ << "QLatin1String(CHAR_FIELD_1)" << expected;
+
+ // Test field expansion when constructing class itself
+ expected = u"Namespace::Test(Namespace::Test::CHAR_FIELD_1)"_s;
+ QTest::newRow("self from qualified class field")
+ << fixture << setupOk << fixture.classType
+ << expected << expected;
+ QTest::newRow("self from partially qualified class field")
+ << fixture << setupOk << fixture.classType
+ << "Test(Test::CHAR_FIELD_1)" << expected;
+ QTest::newRow("self from unqualified class field")
+ << fixture << setupOk << fixture.classType
+ << "Test(CHAR_FIELD_1)" << expected;
+
+ // Test enum expansion when constructing class itself
+ expected = u"Namespace::Test(Namespace::Test::Enum::enumValue1)"_s;
+ QTest::newRow("self from qualified enum")
+ << fixture << setupOk << fixture.classType
+ << expected << expected;
+ 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()
+{
+ QFETCH(DefaultValuesFixture, fixture);
+ QFETCH(int, setupOk);
+ QFETCH(AbstractMetaType, metaType);
+ QFETCH(QString, input);
+ QFETCH(QString, expected);
+ QCOMPARE(setupOk, 0);
+ const QString actual = fixture.builder->fixDefaultValue(input, metaType, fixture.klass);
+ QCOMPARE(actual, expected);
+}
+
+// Verify that the typedefs of the C++ 11 integer types (int32_t, ...)
+// are seen by the C++ parser, otherwise they are handled as unknown
+// primitive types, causing invalid code to be generated.
+// (see BuilderPrivate::visitHeader(),
+// sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp).
+void TestResolveType::testCppTypes()
+{
+ static const char cppCode[] =R"(
+#include <cstdint>
+
+class Test
+{
+public:
+ explicit Test(int32_t v);
+};
+)";
+ static const char xmlCode[] = R"(
+<typesystem package="Foo">
+ <value-type name='Test'/>
+ <primitive-type name='int32_t'/>
+</typesystem>
+)";
+
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
+ QVERIFY(builder);
+ AbstractMetaClassList classes = builder->classes();
+ const auto testClass = AbstractMetaClass::findClass(classes, "Test");
+ QVERIFY(testClass);
+
+ auto *tdb = TypeDatabase::instance();
+ auto int32TEntry = tdb->findType(u"int32_t"_s);
+ QVERIFY2(int32TEntry, "int32_t not found");
+ QVERIFY(int32TEntry->isPrimitive());
+ 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.");
+}
+
+QTEST_APPLESS_MAIN(TestResolveType)
diff --git a/sources/shiboken6/ApiExtractor/tests/testresolvetype.h b/sources/shiboken6/ApiExtractor/tests/testresolvetype.h
index 62c08bcd7..a07855eab 100644
--- a/sources/shiboken6/ApiExtractor/tests/testresolvetype.h
+++ b/sources/shiboken6/ApiExtractor/tests/testresolvetype.h
@@ -1,41 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTRESOLVETYPE_H
#define TESTRESOLVETYPE_H
-#include <QObject>
+#include <QtCore/QObject>
class TestResolveType : public QObject
{
Q_OBJECT
private slots:
+ void initTestCase();
+
void testResolveReturnTypeFromParentScope();
+ void testFixDefaultArguments_data();
+ void testFixDefaultArguments();
+ void testCppTypes();
};
#endif
diff --git a/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp b/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp
index 3ad77c86f..f4eecff2c 100644
--- a/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testreverseoperators.cpp
@@ -1,37 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testreverseoperators.h"
#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
#include <typesystem.h>
+#include <clangparser/compilersupport.h>
+
+#include <algorithm>
void TestReverseOperators::testReverseSum()
{
@@ -46,16 +25,16 @@ void TestReverseOperators::testReverseSum()
</typesystem>";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- QCOMPARE(classA->functions().count(), 4);
+ QCOMPARE(classA->functions().size(), 4);
AbstractMetaFunctionCPtr reverseOp;
AbstractMetaFunctionCPtr normalOp;
for (const auto &func : classA->functions()) {
- if (func->name() == QLatin1String("operator+")) {
+ if (func->name() == u"operator+") {
if (func->isReverseOperator())
reverseOp = func;
else
@@ -63,12 +42,12 @@ void TestReverseOperators::testReverseSum()
}
}
- QVERIFY(!normalOp.isNull());
+ QVERIFY(normalOp);
QVERIFY(!normalOp->isReverseOperator());
- QCOMPARE(normalOp->arguments().count(), 1);
- QVERIFY(!reverseOp.isNull());
+ QCOMPARE(normalOp->arguments().size(), 1);
+ QVERIFY(reverseOp);
QVERIFY(reverseOp->isReverseOperator());
- QCOMPARE(reverseOp->arguments().count(), 1);
+ QCOMPARE(reverseOp->arguments().size(), 1);
}
void TestReverseOperators::testReverseSumWithAmbiguity()
@@ -88,37 +67,63 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- QCOMPARE(classA->functions().count(), 4);
+ QCOMPARE(classA->functions().size(), 4);
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
- QCOMPARE(classB->functions().count(), 4);
+ QCOMPARE(classB->functions().size(), 4);
AbstractMetaFunctionCPtr reverseOp;
AbstractMetaFunctionCPtr normalOp;
for (const auto &func : classB->functions()) {
- if (func->name() == QLatin1String("operator+")) {
+ if (func->name() == u"operator+") {
if (func->isReverseOperator())
reverseOp = func;
else
normalOp = func;
}
}
- QVERIFY(!normalOp.isNull());
+ QVERIFY(normalOp);
QVERIFY(!normalOp->isReverseOperator());
- QCOMPARE(normalOp->arguments().count(), 1);
- QCOMPARE(normalOp->minimalSignature(), QLatin1String("operator+(B,A)"));
- QVERIFY(!reverseOp.isNull());
+ QCOMPARE(normalOp->arguments().size(), 1);
+ QCOMPARE(normalOp->minimalSignature(), u"operator+(B,A)");
+ QVERIFY(reverseOp);
QVERIFY(reverseOp->isReverseOperator());
- QCOMPARE(reverseOp->arguments().count(), 1);
- QCOMPARE(reverseOp->minimalSignature(), QLatin1String("operator+(A,B)"));
+ QCOMPARE(reverseOp->arguments().size(), 1);
+ QCOMPARE(reverseOp->minimalSignature(), u"operator+(A,B)");
}
-
+void TestReverseOperators::testSpaceshipOperator()
+{
+ const char cppCode[] = R"(
+ class Test {
+ public:
+ explicit Test(int v);
+ int operator<=>(const Test &rhs) const = default;
+ };)";
+ const char xmlCode[] = R"(
+ <typesystem package="Foo">
+ <value-type name='Test'/>
+ </typesystem>)";
+ QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false,
+ {}, {}, LanguageLevel::Cpp20));
+ QVERIFY(builder);
+ AbstractMetaClassList classes = builder->classes();
+ QCOMPARE(classes.size(), 1);
+ const auto testClass = AbstractMetaClass::findClass(classes, "Test");
+ QVERIFY(testClass);
+ const auto &functions = testClass->functions();
+ // 6 operators should be synthesized
+ const auto count = std::count_if(functions.cbegin(), functions.cend(),
+ [](const AbstractMetaFunctionCPtr &f) {
+ return f->isComparisonOperator();
+ });
+ QCOMPARE(count, 6);
+}
QTEST_APPLESS_MAIN(TestReverseOperators)
diff --git a/sources/shiboken6/ApiExtractor/tests/testreverseoperators.h b/sources/shiboken6/ApiExtractor/tests/testreverseoperators.h
index ba3b43cfb..fb8d97c97 100644
--- a/sources/shiboken6/ApiExtractor/tests/testreverseoperators.h
+++ b/sources/shiboken6/ApiExtractor/tests/testreverseoperators.h
@@ -1,34 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTREVERSEOPERATORS_H
#define TESTREVERSEOPERATORS_H
-#include <QObject>
+#include <QtCore/QObject>
class TestReverseOperators : public QObject
{
@@ -36,6 +11,7 @@ class TestReverseOperators : public QObject
private slots:
void testReverseSum();
void testReverseSumWithAmbiguity();
+ void testSpaceshipOperator();
};
#endif
diff --git a/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp
index aa1d0414c..ea37c6255 100644
--- a/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testtemplates.cpp
@@ -1,40 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testtemplates.h"
-#include <QtTest/QTest>
-#include <QtCore/QTextStream>
-#include <QTemporaryFile>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetafield.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
-#include <typesystem.h>
+#include <abstractmetatype.h>
+#include <complextypeentry.h>
+#include <containertypeentry.h>
+
+#include <qtcompat.h>
+
+#include <QtCore/QTemporaryFile>
+#include <QtCore/QTextStream>
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
void TestTemplates::testTemplateWithNamespace()
{
@@ -72,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();
- AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("Bookmarks"));
+ const auto classB = AbstractMetaClass::findClass(classes, "Bookmarks");
QVERIFY(classB);
- const auto func = classB->findFunction(QLatin1String("list"));
- QVERIFY(!func.isNull());
+ const auto func = classB->findFunction("list");
+ QVERIFY(func);
AbstractMetaType funcType = func->type();
QVERIFY(!funcType.isVoid());
- QCOMPARE(funcType.cppSignature(), QLatin1String("QList<Internet::Url >"));
+ QCOMPARE(funcType.cppSignature(), u"QList<Internet::Url>");
}
void TestTemplates::testTemplateOnContainers()
@@ -110,26 +93,26 @@ namespace Namespace {
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
QVERIFY(!classB->baseClass());
QVERIFY(classB->baseClassName().isEmpty());
- const auto func = classB->findFunction(QLatin1String("foo"));
- QVERIFY(!func.isNull());
+ const auto func = classB->findFunction("foo");
+ QVERIFY(func);
AbstractMetaType argType = func->arguments().constFirst().type();
- QCOMPARE(argType.instantiations().count(), 1);
- QCOMPARE(argType.typeEntry()->qualifiedCppName(), QLatin1String("QList"));
+ QCOMPARE(argType.instantiations().size(), 1);
+ QCOMPARE(argType.typeEntry()->qualifiedCppName(), u"QList");
const AbstractMetaType &instance1 = argType.instantiations().constFirst();
- QCOMPARE(instance1.instantiations().count(), 1);
- QCOMPARE(instance1.typeEntry()->qualifiedCppName(), QLatin1String("Namespace::A"));
+ QCOMPARE(instance1.instantiations().size(), 1);
+ QCOMPARE(instance1.typeEntry()->qualifiedCppName(), u"Namespace::A");
const AbstractMetaType &instance2 = instance1.instantiations().constFirst();
- QCOMPARE(instance2.instantiations().count(), 0);
- QCOMPARE(instance2.typeEntry()->qualifiedCppName(), QLatin1String("Namespace::E1"));
+ QCOMPARE(instance2.instantiations().size(), 0);
+ QCOMPARE(instance2.typeEntry()->qualifiedCppName(), u"Namespace::E1");
}
void TestTemplates::testTemplateValueAsArgument()
@@ -147,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.count(), 1);
+ QCOMPARE(globalFuncs.size(), 1);
const auto func = globalFuncs.constFirst();
- QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>)"));
+ QCOMPARE(func->minimalSignature(), u"func(List<int>)");
QCOMPARE(func->arguments().constFirst().type().cppSignature(),
- QLatin1String("List<int >"));
+ u"List<int>");
}
void TestTemplates::testTemplatePointerAsArgument()
@@ -172,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.count(), 1);
+ QCOMPARE(globalFuncs.size(), 1);
const auto func = globalFuncs.constFirst();
- QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>*)"));
+ QCOMPARE(func->minimalSignature(), u"func(List<int>*)");
QCOMPARE(func->arguments().constFirst().type().cppSignature(),
- QLatin1String("List<int > *"));
+ u"List<int> *");
}
void TestTemplates::testTemplateReferenceAsArgument()
@@ -197,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.count(), 1);
+ QCOMPARE(globalFuncs.size(), 1);
const auto func = globalFuncs.constFirst();
- QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>&)"));
+ QCOMPARE(func->minimalSignature(), u"func(List<int>&)");
QCOMPARE(func->arguments().constFirst().type().cppSignature(),
- QLatin1String("List<int > &"));
+ u"List<int> &");
}
void TestTemplates::testTemplateParameterFixup()
@@ -226,22 +209,21 @@ struct List {
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
const AbstractMetaClassList templates = builder->templates();
- QCOMPARE(templates.count(), 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());
+ QCOMPARE(templates.size(), 1);
+ 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(), QLatin1String("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(), QLatin1String("List::Iterator"));
+ QCOMPARE(erase->arguments().at(0).type().cppSignature(), u"List::Iterator");
}
void TestTemplates::testInheritanceFromContainterTemplate()
@@ -267,17 +249,17 @@ 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.count(), 2);
- QCOMPARE(templates.count(), 1);
+ QCOMPARE(classes.size(), 2);
+ QCOMPARE(templates.size(), 1);
- const AbstractMetaClass* foobars = AbstractMetaClass::findClass(classes, QLatin1String("FooBars"));
- QCOMPARE(foobars->functions().count(), 4);
+ const auto foobars = AbstractMetaClass::findClass(classes, "FooBars");
+ QCOMPARE(foobars->functions().size(), 4);
- const AbstractMetaClass *lc = templates.constFirst();
- QCOMPARE(lc->functions().count(), 2);
+ AbstractMetaClassCPtr lc = templates.constFirst();
+ QCOMPARE(lc->functions().size(), 2);
}
void TestTemplates::testTemplateInheritanceMixedWithForwardDeclaration()
@@ -304,15 +286,15 @@ template<SomeEnum type> struct Future {};
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
QVERIFY(!classB->baseClass());
QVERIFY(classB->baseClassName().isEmpty());
// 3 functions: simple constructor, copy constructor and "method()".
- QCOMPARE(classB->functions().count(), 3);
+ QCOMPARE(classB->functions().size(), 3);
}
void TestTemplates::testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration()
@@ -343,15 +325,15 @@ template<SomeEnum type> struct Future {};
</typesystem>)XML";
QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false));
- QVERIFY(!builder.isNull());
+ QVERIFY(builder);
AbstractMetaClassList classes = builder->classes();
- AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("Namespace::B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "Namespace::B");
QVERIFY(classB);
QVERIFY(!classB->baseClass());
QVERIFY(classB->baseClassName().isEmpty());
// 3 functions: simple constructor, copy constructor and "method()".
- QCOMPARE(classB->functions().count(), 3);
+ QCOMPARE(classB->functions().size(), 3);
}
void TestTemplates::testTypedefOfInstantiationOfTemplateClass()
@@ -363,7 +345,7 @@ enum ClassType {
};
template<ClassType CLASS_TYPE>
struct BaseTemplateClass {
- inline ClassType getClassType() const { CLASS_TYPE; }
+ inline ClassType getClassType() const { return CLASS_TYPE; }
};
typedef BaseTemplateClass<TypeOne> TypeOneClass;
}
@@ -379,30 +361,30 @@ 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.count(), 3);
+ QCOMPARE(classes.size(), 3);
- const AbstractMetaClass* base = AbstractMetaClass::findClass(classes, QLatin1String("BaseTemplateClass"));
+ const auto base = AbstractMetaClass::findClass(classes, "BaseTemplateClass");
QVERIFY(base);
- const AbstractMetaClass* one = AbstractMetaClass::findClass(classes, QLatin1String("TypeOneClass"));
+ const auto one = AbstractMetaClass::findClass(classes, "TypeOneClass");
QVERIFY(one);
QCOMPARE(one->templateBaseClass(), base);
- QCOMPARE(one->functions().count(), base->functions().count());
+ QCOMPARE(one->functions().size(), base->functions().size());
QVERIFY(one->isTypeDef());
- const ComplexTypeEntry* oneType = one->typeEntry();
- const ComplexTypeEntry* baseType = base->typeEntry();
+ auto oneType = one->typeEntry();
+ auto baseType = base->typeEntry();
QCOMPARE(oneType->baseContainerType(), baseType);
- QCOMPARE(one->baseClassNames(), QStringList(QLatin1String("BaseTemplateClass<TypeOne>")));
+ QCOMPARE(one->baseClassNames(), QStringList(u"NSpace::BaseTemplateClass<NSpace::TypeOne>"_s));
QVERIFY(one->hasTemplateBaseClassInstantiations());
AbstractMetaTypeList instantiations = one->templateBaseClassInstantiations();
- QCOMPARE(instantiations.count(), 1);
+ QCOMPARE(instantiations.size(), 1);
const AbstractMetaType &inst = instantiations.constFirst();
QVERIFY(!inst.isEnum());
QVERIFY(!inst.typeEntry()->isEnum());
QVERIFY(inst.typeEntry()->isEnumValue());
- QCOMPARE(inst.cppSignature(), QLatin1String("NSpace::TypeOne"));
+ QCOMPARE(inst.cppSignature(), u"NSpace::TypeOne");
}
void TestTemplates::testContainerTypeIncompleteArgument()
@@ -428,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.count(), 1);
+ QCOMPARE(classes.size(), 1);
- AbstractMetaClass* vector = AbstractMetaClass::findClass(classes, QLatin1String("IntVector"));
+ const auto vector = AbstractMetaClass::findClass(classes, "IntVector");
QVERIFY(vector);
auto baseContainer = vector->typeEntry()->baseContainerType();
QVERIFY(baseContainer);
- QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer)->containerKind(),
+ QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer.get())->containerKind(),
ContainerTypeEntry::ListContainer);
- QCOMPARE(vector->functions().count(), 4);
+ QCOMPARE(vector->functions().size(), 4);
- const auto method = vector->findFunction(QLatin1String("method"));
- QVERIFY(!method.isNull());
- QCOMPARE(method->signature(), QLatin1String("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(QLatin1String("otherMethod"));
- QVERIFY(!otherMethod.isNull());
- QCOMPARE(otherMethod->signature(), QLatin1String("otherMethod()"));
+ const auto otherMethod = vector->findFunction("otherMethod");
+ QVERIFY(otherMethod);
+ QCOMPARE(otherMethod->signature(), u"otherMethod()");
QVERIFY(!otherMethod->type().isVoid());
- QCOMPARE(otherMethod->type().cppSignature(), QLatin1String("Vector<int >"));
+ QCOMPARE(otherMethod->type().cppSignature(), u"Vector<int>");
}
void TestTemplates::testNonTypeTemplates()
@@ -472,12 +454,12 @@ 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.count(), 1);
+ QCOMPARE(functions.size(), 1);
auto foo = functions.constFirst();
- QCOMPARE(foo->name(), QLatin1String("foo"));
- QCOMPARE(foo->type().name(), QLatin1String("Array"));
+ QCOMPARE(foo->name(), u"foo");
+ QCOMPARE(foo->type().name(), u"Array");
}
// Perform checks on template inheritance; a typedef of a template class
@@ -555,44 +537,42 @@ 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, QLatin1String("Optional"));
+ const auto optional = AbstractMetaClass::findClass(classes, "Optional");
QVERIFY(optional);
// Find the typedef'ed class
- const AbstractMetaClass *optionalInt =
- AbstractMetaClass::findClass(classes, QLatin1String("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, QLatin1String("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(QLatin1String("value"));
- QVERIFY(!valueMethod.isNull());
- QCOMPARE(valueMethod->type().cppSignature(), QLatin1String("int"));
+ const auto valueMethod = optionalInt->findFunction("value");
+ QVERIFY(valueMethod);
+ QCOMPARE(valueMethod->type().cppSignature(), u"int");
// ditto for typesystem XML
- const auto xmlValueMethod = xmlOptionalInt->findFunction(QLatin1String("value"));
- QVERIFY(!xmlValueMethod.isNull());
- QCOMPARE(xmlValueMethod->type().cppSignature(), QLatin1String("int"));
+ const auto xmlValueMethod = xmlOptionalInt->findFunction("value");
+ QVERIFY(xmlValueMethod);
+ QCOMPARE(xmlValueMethod->type().cppSignature(), u"int");
// Check whether the m_value field is of type 'int'
- const auto valueField = optionalInt->findField(QLatin1String("m_value"));
+ const auto valueField = optionalInt->findField(u"m_value");
QVERIFY(valueField.has_value());
- QCOMPARE(valueField->type().cppSignature(), QLatin1String("int"));
+ QCOMPARE(valueField->type().cppSignature(), u"int");
// ditto for typesystem XML
const auto xmlValueField =
- xmlOptionalInt->findField(QLatin1String("m_value"));
+ xmlOptionalInt->findField(u"m_value");
QVERIFY(xmlValueField.has_value());
- QCOMPARE(xmlValueField->type().cppSignature(), QLatin1String("int"));
+ QCOMPARE(xmlValueField->type().cppSignature(), u"int");
}
void TestTemplates::testTemplateTypeAliases()
@@ -626,22 +606,23 @@ 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, QLatin1String("Test"));
+ const auto testClass = AbstractMetaClass::findClass(classes, "Test");
QVERIFY(testClass);
auto fields = testClass->fields();
- QCOMPARE(fields.count(), 1);
+ QCOMPARE(fields.size(), 1);
auto fieldType = testClass->fields().at(0).type();
- QCOMPARE(fieldType.name(), QLatin1String("Container1"));
+ QCOMPARE(fieldType.name(), u"Container1");
QCOMPARE(fieldType.instantiations().size(), 1);
- auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived"));
+ const auto derived = AbstractMetaClass::findClass(classes, "Derived");
QVERIFY(derived);
auto base = derived->templateBaseClass();
- QCOMPARE(base->name(), QLatin1String("Container1"));
+ QVERIFY(base);
+ QCOMPARE(base->name(), u"Container1");
}
QTEST_APPLESS_MAIN(TestTemplates)
diff --git a/sources/shiboken6/ApiExtractor/tests/testtemplates.h b/sources/shiboken6/ApiExtractor/tests/testtemplates.h
index c96e7fe4a..36800f723 100644
--- a/sources/shiboken6/ApiExtractor/tests/testtemplates.h
+++ b/sources/shiboken6/ApiExtractor/tests/testtemplates.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTTEMPLATES_H
#define TESTTEMPLATES_H
-#include <QObject>
+#include <QtCore/QObject>
class TestTemplates : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testtoposort.cpp b/sources/shiboken6/ApiExtractor/tests/testtoposort.cpp
index 6126c2b42..50cefcfe9 100644
--- a/sources/shiboken6/ApiExtractor/tests/testtoposort.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testtoposort.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "testtoposort.h"
#include "graph.h"
diff --git a/sources/shiboken6/ApiExtractor/tests/testtoposort.h b/sources/shiboken6/ApiExtractor/tests/testtoposort.h
index 012156dc9..4271d6a0e 100644
--- a/sources/shiboken6/ApiExtractor/tests/testtoposort.h
+++ b/sources/shiboken6/ApiExtractor/tests/testtoposort.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTTOPOSORT_H
#define TESTTOPOSORT_H
-#include <QObject>
+#include <QtCore/QObject>
class TestTopoSort : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp b/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp
index d8170f5e8..72dae8cc5 100644
--- a/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testtyperevision.cpp
@@ -1,45 +1,27 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testtyperevision.h"
-#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetaenum.h>
#include <abstractmetalang.h>
-#include <typesystem.h>
+#include <complextypeentry.h>
+#include <enumtypeentry.h>
+#include <flagstypeentry.h>
#include <typedatabase.h>
+#include <qtcompat.h>
+
+#include <QtTest/QTest>
+
+using namespace Qt::StringLiterals;
+
void TestTypeRevision::testRevisionAttr()
{
- const char* cppCode = "class Rev_0 {};"
+ const char cppCode[] = "class Rev_0 {};"
"class Rev_1 {};"
"class Rev_2 { public: enum Rev_3 { X }; enum Rev_5 { Y }; };";
- const char* xmlCode = "<typesystem package=\"Foo\">"
+ const char xmlCode[] = "<typesystem package=\"Foo\">"
"<value-type name=\"Rev_0\"/>"
"<value-type name=\"Rev_1\" revision=\"1\"/>"
"<object-type name=\"Rev_2\" revision=\"2\">"
@@ -48,25 +30,25 @@ 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, QLatin1String("Rev_0"));
+ const auto rev0 = AbstractMetaClass::findClass(classes, "Rev_0");
QCOMPARE(rev0->typeEntry()->revision(), 0);
- const AbstractMetaClass *rev1 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_1"));
+ const auto rev1 = AbstractMetaClass::findClass(classes, "Rev_1");
QCOMPARE(rev1->typeEntry()->revision(), 1);
- AbstractMetaClass *rev2 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_2"));
+ const auto rev2 = AbstractMetaClass::findClass(classes, "Rev_2");
QCOMPARE(rev2->typeEntry()->revision(), 2);
- auto rev3 = rev2->findEnum(QLatin1String("Rev_3"));
+ auto rev3 = rev2->findEnum(u"Rev_3"_s);
QVERIFY(rev3.has_value());
QCOMPARE(rev3->typeEntry()->revision(), 3);
- FlagsTypeEntry* rev4 = rev3->typeEntry()->flags();
+ auto rev4 = rev3->typeEntry()->flags();
QCOMPARE(rev4->revision(), 4);
- auto rev5 = rev2->findEnum(QLatin1String("Rev_5"));
+ auto rev5 = rev2->findEnum(u"Rev_5"_s);
QVERIFY(rev5.has_value());
- const EnumTypeEntry *revEnumTypeEntry = rev5->typeEntry();
+ EnumTypeEntryCPtr revEnumTypeEntry = rev5->typeEntry();
QCOMPARE(revEnumTypeEntry->revision(), 5);
QCOMPARE(revEnumTypeEntry->flags()->revision(), 5);
}
@@ -100,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/testtyperevision.h b/sources/shiboken6/ApiExtractor/tests/testtyperevision.h
index 3832c3883..84af839d2 100644
--- a/sources/shiboken6/ApiExtractor/tests/testtyperevision.h
+++ b/sources/shiboken6/ApiExtractor/tests/testtyperevision.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTTYPEREVISION_H
#define TESTTYPEREVISION_H
-#include <QObject>
+#include <QtCore/QObject>
class TestTypeRevision : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testutil.h b/sources/shiboken6/ApiExtractor/tests/testutil.h
index 56ce8a72e..dc4e3b2da 100644
--- a/sources/shiboken6/ApiExtractor/tests/testutil.h
+++ b/sources/shiboken6/ApiExtractor/tests/testutil.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTUTIL_H
#define TESTUTIL_H
@@ -43,27 +18,28 @@ namespace TestUtil
{
static AbstractMetaBuilder *parse(const char *cppCode, const char *xmlCode,
bool silent = true,
- const QString &apiVersion = QString(),
- const QStringList &dropTypeEntries = QStringList())
+ const QString &apiVersion = {},
+ const QStringList &dropTypeEntries = {},
+ LanguageLevel languageLevel = LanguageLevel::Default)
{
ReportHandler::setSilent(silent);
ReportHandler::startTimer();
- TypeDatabase* td = TypeDatabase::instance(true);
+ auto *td = TypeDatabase::instance(true);
if (apiVersion.isEmpty())
TypeDatabase::clearApiVersions();
- else if (!TypeDatabase::setApiVersion(QLatin1String("*"), 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() + QLatin1String("/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();
@@ -76,7 +52,7 @@ namespace TestUtil
auto builder = std::make_unique<AbstractMetaBuilder>();
try {
- if (!builder->build(arguments))
+ if (!builder->build(arguments, {}, true, languageLevel))
return nullptr;
} catch (const std::exception &e) {
qWarning("%s", e.what());
diff --git a/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.cpp b/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.cpp
index 1850025d6..98e30eac2 100644
--- a/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.cpp
@@ -1,62 +1,37 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testvaluetypedefaultctortag.h"
#include <QtTest/QTest>
#include "testutil.h"
#include <abstractmetalang.h>
-#include <typesystem.h>
+#include <complextypeentry.h>
void TestValueTypeDefaultCtorTag::testValueTypeDefaultCtorTagArgument()
{
- const char* cppCode ="\n\
+ const char cppCode[] = "\n\
struct A {\n\
A(int,int);\n\
};\n\
struct B {};\n\
";
- const char* xmlCode = "\n\
+ const char xmlCode[] = "\n\
<typesystem package='Foo'>\n\
<primitive-type name='int' />\n\
<value-type name='A' default-constructor='A(0, 0)' />\n\
<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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
QVERIFY(classA->typeEntry()->hasDefaultConstructor());
- QCOMPARE(classA->typeEntry()->defaultConstructor(), QLatin1String("A(0, 0)"));
+ QCOMPARE(classA->typeEntry()->defaultConstructor(), u"A(0, 0)");
- const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B"));
+ const auto classB = AbstractMetaClass::findClass(classes, "B");
QVERIFY(classB);
QVERIFY(!classB->typeEntry()->hasDefaultConstructor());
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.h b/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.h
index 244181707..192c07c1d 100644
--- a/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.h
+++ b/sources/shiboken6/ApiExtractor/tests/testvaluetypedefaultctortag.h
@@ -1,35 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTVALUETYPEDEFAULTCTORTAG_H
#define TESTVALUETYPEDEFAULTCTORTAG_H
-#include <QObject>
+#include <QtCore/QObject>
class TestValueTypeDefaultCtorTag : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp b/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp
index 6d155dacc..a600181a5 100644
--- a/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testvoidarg.cpp
@@ -1,34 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "testvoidarg.h"
#include <QtTest/QTest>
#include "testutil.h"
+#include <abstractmetaargument.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
#include <typesystem.h>
@@ -41,13 +17,13 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(QLatin1String("a"));
- QVERIFY(!addedFunc.isNull());
- QCOMPARE(addedFunc->arguments().count(), 0);
+ const auto addedFunc = classA->findFunction("a");
+ QVERIFY(addedFunc);
+ QCOMPARE(addedFunc->arguments().size(), 0);
}
void TestVoidArg::testVoidAddedFunction()
@@ -60,13 +36,13 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(QLatin1String("a"));
- QVERIFY(!addedFunc.isNull());
- QCOMPARE(addedFunc->arguments().count(), 0);
+ const auto addedFunc = classA->findFunction("a");
+ QVERIFY(addedFunc);
+ QCOMPARE(addedFunc->arguments().size(), 0);
}
@@ -78,13 +54,13 @@ 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, QLatin1String("A"));
+ const auto classA = AbstractMetaClass::findClass(classes, "A");
QVERIFY(classA);
- const auto addedFunc = classA->findFunction(QLatin1String("a"));
- QVERIFY(!addedFunc.isNull());
- QCOMPARE(addedFunc->arguments().count(), 1);
+ const auto addedFunc = classA->findFunction("a");
+ QVERIFY(addedFunc);
+ QCOMPARE(addedFunc->arguments().size(), 1);
}
diff --git a/sources/shiboken6/ApiExtractor/tests/testvoidarg.h b/sources/shiboken6/ApiExtractor/tests/testvoidarg.h
index 44d90d075..191b9cfb2 100644
--- a/sources/shiboken6/ApiExtractor/tests/testvoidarg.h
+++ b/sources/shiboken6/ApiExtractor/tests/testvoidarg.h
@@ -1,34 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TESTVOIDARG_H
#define TESTVOIDARG_H
-#include <QObject>
+#include <QtCore/QObject>
class TestVoidArg : public QObject
{
diff --git a/sources/shiboken6/ApiExtractor/textstream.cpp b/sources/shiboken6/ApiExtractor/textstream.cpp
index 364634f2d..83d981b2b 100644
--- a/sources/shiboken6/ApiExtractor/textstream.cpp
+++ b/sources/shiboken6/ApiExtractor/textstream.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "textstream.h"
@@ -75,6 +50,12 @@ qint64 TextStream::pos() const
return m_str.pos();
}
+void TextStream::setString(QString *string, QIODeviceBase::OpenMode openMode)
+{
+ m_str.setString(string, openMode);
+ m_rstFormattingEnd = false;
+}
+
void TextStream::putRepetitiveChars(char c, int count)
{
if (count > 0) {
@@ -87,6 +68,11 @@ void TextStream::putRepetitiveChars(char c, int count)
}
}
+void TextStream::_setRstFormattingEnd()
+{
+ m_rstFormattingEnd = true;
+}
+
void TextStream::setLastCharClass(CharClass c)
{
m_lastCharClass = c;
@@ -110,6 +96,11 @@ static TextStream::CharClass charClassHelper(Char c)
return TextStream::CharClass::NewLine;
case '#':
return TextStream::CharClass::Hash;
+ case ' ':
+ case '\t':
+ return TextStream::CharClass::Space;
+ case '\\':
+ return TextStream::CharClass::BackSlash;
default:
break;
}
@@ -124,6 +115,13 @@ static inline TextStream::CharClass charClass(QChar c)
void TextStream::checkIndent(CharClass upComingCharClass)
{
+ if (m_rstFormattingEnd) {
+ if (upComingCharClass != CharClass::Space && upComingCharClass != CharClass::NewLine
+ && upComingCharClass != CharClass::BackSlash) {
+ m_str << '\\';
+ }
+ m_rstFormattingEnd = false;
+ }
if (m_indentationEnabled && m_lastCharClass == CharClass::NewLine
&& (upComingCharClass != CharClass::NewLine
&& (m_language != Language::Cpp || upComingCharClass != CharClass::Hash))) {
@@ -135,7 +133,8 @@ void TextStream::checkIndent(CharClass upComingCharClass)
template <class Char>
void TextStream::putCharHelper(Char c)
{
- checkIndent(charClass(c));
+ const auto klass = charClass(c);
+ checkIndent(klass);
m_str << c;
}
@@ -150,7 +149,8 @@ void TextStream::putString(QStringView v)
// If there is no newline, write as a blob. This is important to make
// field formatting (alignment/width) working, else each char will be
// considered a field.
- checkIndent(charClass(*v.cbegin()));
+ const auto klass = charClass(*v.cbegin());
+ checkIndent(klass);
m_str << v;
m_lastCharClass = CharClass::Other;
}
@@ -225,6 +225,39 @@ void disableIndent(TextStream &s)
void ensureEndl(TextStream &s)
{
- if (s.lastChar() != QLatin1Char('\n'))
+ if (s.lastChar() != u'\n')
s << '\n';
}
+
+void rstBold(TextStream &s)
+{
+ s.putRawString("**");
+}
+
+void rstBoldOff(TextStream &s)
+{
+ s.putRawString("**");
+ s._setRstFormattingEnd();
+}
+
+void rstItalic(TextStream &s)
+{
+ s.putRawChar('*');
+}
+
+void rstItalicOff(TextStream &s)
+{
+ s.putRawChar('*');
+ s._setRstFormattingEnd();
+}
+
+void rstCode(TextStream &s)
+{
+ s.putRawString("``");
+}
+
+void rstCodeOff(TextStream &s)
+{
+ s.putRawString("``");
+ s._setRstFormattingEnd();
+}
diff --git a/sources/shiboken6/ApiExtractor/textstream.h b/sources/shiboken6/ApiExtractor/textstream.h
index dff79b939..228f36405 100644
--- a/sources/shiboken6/ApiExtractor/textstream.h
+++ b/sources/shiboken6/ApiExtractor/textstream.h
@@ -1,35 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TEXTSTREAM_H
#define TEXTSTREAM_H
#include <QtCore/QTextStream>
+#include <QtCore/QString>
/// A text stream based on QTextStream with built-in indent.
class TextStream
@@ -46,7 +22,7 @@ public:
enum class CharClass
{
- Other, NewLine, Hash
+ Other, NewLine, Space, Hash, BackSlash
};
explicit TextStream(QIODevice *device, Language l = Language::None);
@@ -55,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)
@@ -79,8 +55,7 @@ public:
{ return m_str.fieldAlignment(); }
void setFieldAlignment(QTextStream::FieldAlignment al)
{ m_str.setFieldAlignment(al); }
- void setString(QString *string, QIODeviceBase::OpenMode openMode = QIODeviceBase::ReadWrite)
- { m_str.setString(string, openMode); }
+ void setString(QString *string, QIODeviceBase::OpenMode openMode = QIODeviceBase::ReadWrite);
QString *string() const { return m_str.string(); }
void flush() { m_str.flush(); }
void setDevice(QIODevice *device) { m_str.setDevice(device); }
@@ -98,7 +73,14 @@ public:
void putInt(int t);
void putSizeType(qsizetype t);
+ void putRawString(const char *s) { m_str << s; }
+ 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; }
@@ -107,11 +89,13 @@ 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);
+ void _setRstFormattingEnd();
+
protected:
void setLastCharClass(CharClass c);
@@ -126,6 +110,7 @@ private:
int m_tabWidth = 4;
int m_indentation = 0;
bool m_indentationEnabled = true;
+ bool m_rstFormattingEnd = false; // just past some **bla** where '\' needs to be enforced
Language m_language;
};
@@ -152,6 +137,19 @@ void disableIndent(TextStream &s);
// Works only for streams on strings
void ensureEndl(TextStream &s);
+void rstBold(TextStream &s);
+void rstBoldOff(TextStream &s);
+void rstCode(TextStream &s);
+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
@@ -191,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 4606848c3..61fd22418 100644
--- a/sources/shiboken6/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken6/ApiExtractor/typedatabase.cpp
@@ -1,59 +1,63 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "typedatabase.h"
#include "abstractmetatype.h"
-#include "typesystem.h"
-#include "typesystemparser.h"
+#include "addedfunction.h"
+#include "messages.h"
+#include "typesystemparser_p.h"
+#include "complextypeentry.h"
+#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"
+#include "typesystemtypeentry.h"
+#include "varargstypeentry.h"
+#include "voidtypeentry.h"
#include "conditionalstreamreader.h"
+#include "predefined_templates.h"
+#include "clangparser/compilersupport.h"
+#include "modifications.h"
+#include "qtcompat.h"
+
+#include <QtCore/QBuffer>
#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 = std::shared_ptr<TypeDatabaseParserContext>;
// package -> api-version
static QString wildcardToRegExp(QString w)
{
- w.replace(QLatin1Char('?'), QLatin1Char('.'));
- w.replace(QLatin1Char('*'), QStringLiteral(".*"));
+ w.replace(u'?', u'.');
+ 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)
@@ -72,44 +76,243 @@ static const PythonTypes &builtinPythonTypes()
static const PythonTypes result{
// "Traditional" custom types
// numpy
- {u"PyArrayObject"_qs, u"PyArray_Check"_qs, TypeSystem::CPythonType::Other},
- {u"PyBuffer"_qs, u"Shiboken::Buffer::checkType"_qs, TypeSystem::CPythonType::Other},
- {u"PyByteArray"_qs, u"PyByteArray_Check"_qs, TypeSystem::CPythonType::Other},
- {u"PyBytes"_qs, u"PyBytes_Check"_qs, TypeSystem::CPythonType::Other},
- {u"PyCallable"_qs, u"PyCallable_Check"_qs, TypeSystem::CPythonType::Other},
- {u"PyDate"_qs, u"PyDate_Check"_qs, TypeSystem::CPythonType::Other},
- {u"PyDateTime"_qs, u"PyDateTime_Check_Check"_qs, TypeSystem::CPythonType::Other},
- {u"PyDict"_qs, u"PyDict_Check"_qs, TypeSystem::CPythonType::Other},
+ {u"PyArrayObject"_s, u"PyArray_Check"_s, TypeSystem::CPythonType::Other},
+ {u"PyBuffer"_s, u"Shiboken::Buffer::checkType"_s, TypeSystem::CPythonType::Other},
+ {u"PyByteArray"_s, u"PyByteArray_Check"_s, TypeSystem::CPythonType::Other},
+ {u"PyBytes"_s, u"PyBytes_Check"_s, TypeSystem::CPythonType::Other},
+ {u"PyCallable"_s, u"PyCallable_Check"_s, TypeSystem::CPythonType::Other},
+ {u"PyDate"_s, u"PyDate_Check"_s, TypeSystem::CPythonType::Other},
+ {u"PyDateTime"_s, u"PyDateTime_Check_Check"_s, TypeSystem::CPythonType::Other},
+ {u"PyDict"_s, u"PyDict_Check"_s, TypeSystem::CPythonType::Other},
// Convenience macro in sbkconverter.h
- {u"PyObject"_qs, u"true"_qs, TypeSystem::CPythonType::Other},
+ {u"PyObject"_s, u"true"_s, TypeSystem::CPythonType::Other},
// shiboken-specific
- {u"PyPathLike"_qs, u"Shiboken::String::checkPath"_qs, TypeSystem::CPythonType::Other},
- {u"PySequence"_qs, u"Shiboken::String::checkIterable"_qs, TypeSystem::CPythonType::Other},
- {u"PyUnicode"_qs, u"PyUnicode_Check"_qs, TypeSystem::CPythonType::String},
- {u"PyTypeObject"_qs, u"PyType_Check"_qs, TypeSystem::CPythonType::Other},
- {u"str"_qs, u"Shiboken::String::check"_qs, TypeSystem::CPythonType::String},
+ {u"PyPathLike"_s, u"Shiboken::String::checkPath"_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},
// Types used as target lang API types for primitive types
- {u"PyBool"_qs, u"PyBool_Check"_qs, TypeSystem::CPythonType::Bool},
- {u"PyComplex"_qs, u"PyComplex_Check"_qs, TypeSystem::CPythonType::Other},
- {u"PyLong"_qs, u"PyLong_Check"_qs, TypeSystem::CPythonType::Integer},
- {u"PyFloat"_qs, u"PyFloat_Check"_qs, TypeSystem::CPythonType::Float},
+ {u"PyBool"_s, u"PyBool_Check"_s, TypeSystem::CPythonType::Bool},
+ {u"PyComplex"_s, u"PyComplex_Check"_s, TypeSystem::CPythonType::Other},
+ {u"PyLong"_s, u"PyLong_Check"_s, TypeSystem::CPythonType::Integer},
+ {u"PyFloat"_s, u"PyFloat_Check"_s, TypeSystem::CPythonType::Float},
// Single character strings to match C++ char types
- {u"SbkChar"_qs, u"SbkChar_Check"_qs, TypeSystem::CPythonType::String}
+ {u"SbkChar"_s, u"SbkChar_Check"_s, TypeSystem::CPythonType::String}
};
return result;
}
-TypeDatabase::TypeDatabase()
+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;
+ TypeEntryCList findCppTypes(const QString &name) const;
+ bool addType(TypeEntryPtr e, QString *errorMessage = nullptr);
+ bool parseFile(QIODevice *device, TypeDatabase *db, bool generate = true);
+ static bool parseFile(const TypeDatabaseParserContextPtr &context,
+ QIODevice *device, bool generate = true);
+ bool parseFile(const TypeDatabaseParserContextPtr &context,
+ const QString &filename, const QString &currentPath, bool generate);
+ bool prepareParsing(QFile &file, const QString &origFileName,
+ const QString &currentPath = {});
+
+ QString modifiedTypesystemFilepath(const QString& tsFile,
+ const QString &currentPath) const;
+ void addBuiltInType(const TypeEntryPtr &e);
+ PrimitiveTypeEntryPtr addBuiltInPrimitiveType(const QString &name,
+ const TypeSystemTypeEntryCPtr &root,
+ const QString &rootPackage,
+ const CustomTypeEntryPtr &targetLang);
+ void addBuiltInCppStringPrimitiveType(const QString &name,
+ const QString &viewName,
+ const TypeSystemTypeEntryCPtr &root,
+ const QString &rootPackage,
+ 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<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;
+ bool resolveSmartPointerInstantiations(const TypeDatabaseParserContextPtr &context);
+ void formatDebug(QDebug &d) const;
+ void formatBuiltinTypes(QDebug &d) const;
+
+ TypeEntryMultiMap m_entries; // Contains duplicate entries (cf addInlineNamespaceLookups).
+ TypeEntryMap m_flagsEntries;
+ TypedefEntryMap m_typedefEntries;
+ TemplateEntryMap m_templates;
+ QList<SuppressedWarning> m_suppressedWarnings;
+ QList<TypeSystemTypeEntryCPtr > m_typeSystemEntries; // maintain order, default is first.
+
+ AddedFunctionList m_globalUserFunctions;
+ FunctionModificationList m_functionMods;
+
+ QStringList m_requiredTargetImports;
+
+ QHash<QString, bool> m_parsedTypesystemFiles;
+
+ QList<TypeRejection> m_rejections;
+};
+
+static const char ENV_TYPESYSTEMPATH[] = "TYPESYSTEMPATH";
+
+TypeDatabase::TypeDatabase() : d(new TypeDatabasePrivate)
{
- addBuiltInType(new VoidTypeEntry());
- addBuiltInType(new VarargsTypeEntry());
+ // 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())
- addBuiltInType(new PythonTypeEntry(pt.name, pt.checkFunction, pt.type));
+ d->addBuiltInType(TypeEntryPtr(new PythonTypeEntry(pt.name, pt.checkFunction, pt.type)));
+
+ for (const auto &p : predefinedTemplates())
+ addTemplate(p.name, p.content);
}
-TypeDatabase::~TypeDatabase() = default;
+TypeDatabase::~TypeDatabase()
+{
+ delete d;
+}
-TypeDatabase* TypeDatabase::instance(bool newInstance)
+std::shared_ptr<OptionsParser> TypeDatabase::createOptionsParser()
+{
+ return std::make_shared<TypeDatabaseOptionsParser>(d);
+}
+
+TypeDatabase *TypeDatabase::instance(bool newInstance)
{
static TypeDatabase *db = nullptr;
if (!db || newInstance) {
@@ -135,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 = QLatin1String(t);
- if (!TypeDatabase::instance()->findType(QLatin1Char('u') + intType)) {
+ 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);
}
@@ -203,9 +405,10 @@ QString TypeDatabase::normalizedSignature(const QString &signature)
{
// QMetaObject::normalizedSignature() changes const-ref to value and
// changes "unsigned int" to "uint" which is undone by the below code
- QString normalized = QLatin1String(QMetaObject::normalizedSignature(signature.toUtf8().constData()));
+ QByteArray normalizedB = QMetaObject::normalizedSignature(signature.toUtf8().constData());
+ QString normalized = QLatin1StringView(normalizedB);
- if (instance() && signature.contains(QLatin1String("unsigned"))) {
+ if (instance() && signature.contains(u"unsigned")) {
const IntTypeNormalizationEntries &entries = intTypeNormalizationEntries();
for (const auto &entry : entries)
normalized.replace(entry.regex, entry.replacement);
@@ -216,141 +419,185 @@ QString TypeDatabase::normalizedSignature(const QString &signature)
QStringList TypeDatabase::requiredTargetImports() const
{
- return m_requiredTargetImports;
+ return d->m_requiredTargetImports;
}
void TypeDatabase::addRequiredTargetImport(const QString& moduleName)
{
- if (!m_requiredTargetImports.contains(moduleName))
- 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
- m_typesystemPaths += typesystem_paths.split(QLatin1Char(path_splitter));
+ if (!d->m_requiredTargetImports.contains(moduleName))
+ d->m_requiredTargetImports << moduleName;
}
QStringList TypeDatabase::typesystemKeywords() const
{
- QStringList result = m_typesystemKeywords;
- for (const auto &d : m_dropTypeEntries)
- result.append(QStringLiteral("no_") + d);
+ QStringList result = d->m_typesystemKeywords;
+ for (const auto &d : d->m_dropTypeEntries)
+ result.append("no_"_L1 + d);
+
+ switch (clang::emulatedCompilerLanguageLevel()) {
+ case LanguageLevel::Cpp11:
+ result.append(u"c++11"_s);
+ break;
+ case LanguageLevel::Cpp14:
+ result.append(u"c++14"_s);
+ break;
+ case LanguageLevel::Cpp17:
+ result.append(u"c++17"_s);
+ break;
+ case LanguageLevel::Cpp20:
+ result.append(u"c++20"_s);
+ break;
+ default:
+ break;
+ }
return result;
}
IncludeList TypeDatabase::extraIncludes(const QString& className) const
{
- ComplexTypeEntry* typeEntry = findComplexType(className);
- return typeEntry ? typeEntry->extraIncludes() : IncludeList();
+ auto typeEntry = findComplexType(className);
+ return typeEntry ? typeEntry->extraIncludes() : IncludeList();
+}
+
+const QStringList &TypeDatabase::forceProcessSystemIncludes() const
+{
+ return d->m_forceProcessSystemIncludes;
}
-void TypeDatabase::addSystemInclude(const QString &name)
+void TypeDatabase::addForceProcessSystemInclude(const QString &name)
{
- m_systemIncludes.append(name);
+ d->m_forceProcessSystemIncludes.append(name);
}
// Add a lookup for the short name excluding inline namespaces
// so that "std::shared_ptr" finds "std::__1::shared_ptr" as well.
-// Note: This inserts duplicate TypeEntry * into m_entries.
-void TypeDatabase::addInlineNamespaceLookups(const NamespaceTypeEntry *n)
+// Note: This inserts duplicate TypeEntryPtr into m_entries.
+void TypeDatabase::addInlineNamespaceLookups(const NamespaceTypeEntryCPtr &n)
{
TypeEntryList additionalEntries; // Store before modifying the hash
- for (TypeEntry *entry : qAsConst(m_entries)) {
+ for (const auto &entry : std::as_const(d->m_entries)) {
if (entry->isChildOf(n))
additionalEntries.append(entry);
}
- for (const auto &ae : qAsConst(additionalEntries))
- m_entries.insert(ae->shortName(), ae);
+ for (const auto &ae : std::as_const(additionalEntries))
+ d->m_entries.insert(ae->shortName(), ae);
}
-ContainerTypeEntry* TypeDatabase::findContainerType(const QString &name) const
+ContainerTypeEntryPtr TypeDatabase::findContainerType(const QString &name) const
{
QString template_name = name;
- int pos = name.indexOf(QLatin1Char('<'));
+ const auto pos = name.indexOf(u'<');
if (pos > 0)
template_name = name.left(pos);
- TypeEntry* type_entry = findType(template_name);
+ auto type_entry = findType(template_name);
if (type_entry && type_entry->isContainer())
- return static_cast<ContainerTypeEntry*>(type_entry);
- return nullptr;
+ return std::static_pointer_cast<ContainerTypeEntry>(type_entry);
+ return {};
}
-static bool inline useType(const TypeEntry *t)
+static bool inline useType(const TypeEntryCPtr &t)
{
return !t->isPrimitive()
- || static_cast<const PrimitiveTypeEntry *>(t)->preferredTargetLangType();
+ || std::static_pointer_cast<const PrimitiveTypeEntry>(t)->preferredTargetLangType();
}
-FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name) const
+FunctionTypeEntryPtr TypeDatabase::findFunctionType(const QString &name) const
{
- const auto entries = findTypeRange(name);
- for (TypeEntry *entry : entries) {
+ const auto entries = d->findTypeRange(name);
+ for (const TypeEntryPtr &entry : entries) {
if (entry->type() == TypeEntry::FunctionType && useType(entry))
- return static_cast<FunctionTypeEntry*>(entry);
+ return std::static_pointer_cast<FunctionTypeEntry>(entry);
}
- return nullptr;
+ return {};
}
-void TypeDatabase::addTypeSystemType(const TypeSystemTypeEntry *e)
+void TypeDatabase::addTypeSystemType(const TypeSystemTypeEntryCPtr &e)
{
- m_typeSystemEntries.append(e);
+ d->m_typeSystemEntries.append(e);
}
-const TypeSystemTypeEntry *TypeDatabase::findTypeSystemType(const QString &name) const
+TypeSystemTypeEntryCPtr TypeDatabase::findTypeSystemType(const QString &name) const
{
- for (auto entry : m_typeSystemEntries) {
+ for (auto entry : d->m_typeSystemEntries) {
if (entry->name() == name)
return entry;
}
- return nullptr;
+ return {};
+}
+
+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;
}
-const TypeSystemTypeEntry *TypeDatabase::defaultTypeSystemType() const
+TypeSystemTypeEntryCPtr TypeDatabasePrivate::defaultTypeSystemType() const
{
return m_typeSystemEntries.value(0, nullptr);
}
QString TypeDatabase::defaultPackageName() const
{
- Q_ASSERT(!m_typeSystemEntries.isEmpty());
- return m_typeSystemEntries.constFirst()->name();
+ Q_ASSERT(!d->m_typeSystemEntries.isEmpty());
+ return d->m_typeSystemEntries.constFirst()->name();
+}
+
+TypeEntryPtr TypeDatabase::findType(const QString& name) const
+{
+ return d->findType(name);
}
-TypeEntry* TypeDatabase::findType(const QString& name) const
+TypeEntryPtr TypeDatabasePrivate::findType(const QString& name) const
{
const auto entries = findTypeRange(name);
- for (TypeEntry *entry : entries) {
+ for (const auto &entry : entries) {
if (useType(entry))
return entry;
}
- return nullptr;
+ return {};
}
template <class Predicate>
-TypeEntries TypeDatabase::findTypesHelper(const QString &name, Predicate pred) const
+TypeEntryCList TypeDatabasePrivate::findTypesHelper(const QString &name, Predicate pred) const
{
- TypeEntries result;
+ TypeEntryCList result;
const auto entries = findTypeRange(name);
- for (TypeEntry *entry : entries) {
+ for (const auto &entry : entries) {
if (pred(entry))
result.append(entry);
}
return result;
}
-TypeEntries TypeDatabase::findTypes(const QString &name) const
+template<class Type, class Predicate>
+QList<std::shared_ptr<const Type> > TypeDatabasePrivate::findTypesByTypeHelper(Predicate pred) const
+{
+ QList<std::shared_ptr<const Type> > result;
+ for (const auto &entry : m_entries) {
+ if (pred(entry))
+ result.append(std::static_pointer_cast<const Type>(entry));
+ }
+ return result;
+}
+
+TypeEntryCList TypeDatabase::findTypes(const QString &name) const
{
- return findTypesHelper(name, useType);
+ return d->findTypesHelper(name, useType);
}
-static bool useCppType(const TypeEntry *t)
+static bool useCppType(const TypeEntryCPtr &t)
{
bool result = false;
switch (t->type()) {
@@ -374,37 +621,48 @@ static bool useCppType(const TypeEntry *t)
return result;
}
-TypeEntries TypeDatabase::findCppTypes(const QString &name) const
+TypeEntryCList TypeDatabase::findCppTypes(const QString &name) const
+{
+ return d->findCppTypes(name);
+}
+
+TypeEntryCList TypeDatabasePrivate::findCppTypes(const QString &name) const
{
return findTypesHelper(name, useCppType);
}
-TypeEntryMultiMapConstIteratorRange TypeDatabase::findTypeRange(const QString &name) const
+const TypeEntryMultiMap &TypeDatabase::entries() const
+{
+ return d->m_entries;
+}
+
+const TypedefEntryMap &TypeDatabase::typedefEntries() const
+{
+ return d->m_typedefEntries;
+}
+
+TypeEntryMultiMapConstIteratorRange TypeDatabasePrivate::findTypeRange(const QString &name) const
{
const auto range = m_entries.equal_range(name);
return {range.first, range.second};
}
-PrimitiveTypeEntryList TypeDatabase::primitiveTypes() const
+PrimitiveTypeEntryCList TypeDatabase::primitiveTypes() const
{
- PrimitiveTypeEntryList returned;
- for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it) {
- TypeEntry *typeEntry = it.value();
- if (typeEntry->isPrimitive())
- returned.append(static_cast<PrimitiveTypeEntry *>(typeEntry));
- }
- return returned;
+ auto pred = [](const TypeEntryCPtr &t) { return t->isPrimitive(); };
+ return d->findTypesByTypeHelper<PrimitiveTypeEntry>(pred);
}
-ContainerTypeEntryList TypeDatabase::containerTypes() const
+ContainerTypeEntryCList TypeDatabase::containerTypes() const
{
- ContainerTypeEntryList returned;
- for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it) {
- TypeEntry *typeEntry = it.value();
- if (typeEntry->isContainer())
- returned.append(static_cast<ContainerTypeEntry *>(typeEntry));
- }
- return returned;
+ auto pred = [](const TypeEntryCPtr &t) { return t->isContainer(); };
+ return d->findTypesByTypeHelper<ContainerTypeEntry>(pred);
+}
+
+SmartPointerTypeEntryList TypeDatabase::smartPointerTypes() const
+{
+ auto pred = [](const TypeEntryCPtr &t) { return t->isSmartPointer(); };
+ return d->findTypesByTypeHelper<SmartPointerTypeEntry>(pred);
}
#ifndef QT_NO_DEBUG_STREAM
@@ -421,36 +679,15 @@ QDebug operator<<(QDebug d, const TypeRejection &r)
void TypeDatabase::addRejection(const TypeRejection &r)
{
- m_rejections << r;
-}
-
-static inline QString msgRejectReason(const TypeRejection &r, const QString &needle = QString())
-{
- QString result;
- QTextStream str(&result);
- switch (r.matchType) {
- case TypeRejection::ExcludeClass:
- str << " matches class exclusion \"" << r.className.pattern() << '"';
- break;
- case TypeRejection::Function:
- case TypeRejection::Field:
- case TypeRejection::Enum:
- str << " matches class \"" << r.className.pattern() << "\" and \"" << r.pattern.pattern() << '"';
- break;
- case TypeRejection::ArgumentType:
- case TypeRejection::ReturnType:
- str << " matches class \"" << r.className.pattern() << "\" and \"" << needle
- << "\" matches \"" << r.pattern.pattern() << '"';
- break;
- }
- return result;
+ d->m_rejections << r;
}
// Match class name only
bool TypeDatabase::isClassRejected(const QString& className, QString *reason) const
{
- for (const TypeRejection& r : m_rejections) {
+ 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;
@@ -469,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;
@@ -479,24 +717,24 @@ static bool findRejection(const QList<TypeRejection> &rejections,
bool TypeDatabase::isEnumRejected(const QString& className, const QString& enumName, QString *reason) const
{
- return findRejection(m_rejections, TypeRejection::Enum, className, enumName, reason);
+ return findRejection(d->m_rejections, TypeRejection::Enum, className, enumName, reason);
}
-TypeEntry *TypeDatabase::resolveTypeDefEntry(TypedefEntry *typedefEntry,
+TypeEntryPtr TypeDatabasePrivate::resolveTypeDefEntry(const TypedefEntryPtr &typedefEntry,
QString *errorMessage)
{
QString sourceName = typedefEntry->sourceType();
- const int lessThanPos = sourceName.indexOf(QLatin1Char('<'));
+ const auto lessThanPos = sourceName.indexOf(u'<');
if (lessThanPos != -1)
sourceName.truncate(lessThanPos);
- ComplexTypeEntry *source = nullptr;
- for (TypeEntry *e : findTypeRange(sourceName)) {
+ ComplexTypeEntryPtr source;
+ for (const auto &e : findTypeRange(sourceName)) {
switch (e->type()) {
case TypeEntry::BasicValueType:
case TypeEntry::ContainerType:
case TypeEntry::ObjectType:
case TypeEntry::SmartPointerType:
- source = dynamic_cast<ComplexTypeEntry *>(e);
+ source = std::dynamic_pointer_cast<ComplexTypeEntry>(e);
Q_ASSERT(source);
break;
default:
@@ -505,23 +743,34 @@ TypeEntry *TypeDatabase::resolveTypeDefEntry(TypedefEntry *typedefEntry,
}
if (!source) {
if (errorMessage)
- *errorMessage = QLatin1String("Unable to resolve typedef \"")
- + typedefEntry->sourceType() + QLatin1Char('"');
+ *errorMessage = msgUnableToResolveTypedef(typedefEntry->sourceType(), sourceName);
return nullptr;
}
- auto *result = static_cast<ComplexTypeEntry *>(source->clone());
+ m_typedefEntries.insert(typedefEntry->qualifiedCppName(), typedefEntry);
+ return TypeDatabase::initializeTypeDefEntry(typedefEntry, source);
+}
+
+ComplexTypeEntryPtr
+ TypeDatabase::initializeTypeDefEntry(const TypedefEntryPtr &typedefEntry,
+ const ComplexTypeEntryCPtr &source)
+{
+ ComplexTypeEntryPtr result(static_cast<ComplexTypeEntry *>(source->clone()));
result->useAsTypedef(typedefEntry);
typedefEntry->setSource(source);
typedefEntry->setTarget(result);
- m_typedefEntries.insert(typedefEntry->qualifiedCppName(), typedefEntry);
return result;
}
-bool TypeDatabase::addType(TypeEntry *e, QString *errorMessage)
+bool TypeDatabase::addType(const TypeEntryPtr &e, QString *errorMessage)
+{
+ return d->addType(e, errorMessage);
+}
+
+bool TypeDatabasePrivate::addType(TypeEntryPtr e, QString *errorMessage)
{
if (e->type() == TypeEntry::TypedefType) {
- e = resolveTypeDefEntry(static_cast<TypedefEntry *>(e), errorMessage);
+ e = resolveTypeDefEntry(std::static_pointer_cast<TypedefEntry>(e), errorMessage);
if (Q_UNLIKELY(!e))
return false;
}
@@ -530,11 +779,11 @@ bool TypeDatabase::addType(TypeEntry *e, QString *errorMessage)
}
// Add a dummy value entry for non-type template parameters
-ConstantValueTypeEntry *
+ConstantValueTypeEntryPtr
TypeDatabase::addConstantValueTypeEntry(const QString &value,
- const TypeEntry *parent)
+ const TypeEntryCPtr &parent)
{
- auto result = new ConstantValueTypeEntry(value, parent);
+ auto result = std::make_shared<ConstantValueTypeEntry>(value, parent);
result->setCodeGeneration(TypeEntry::GenerateNothing);
addType(result);
return result;
@@ -543,35 +792,36 @@ ConstantValueTypeEntry *
bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName,
QString *reason) const
{
- return findRejection(m_rejections, TypeRejection::Function, className, functionName, reason);
+ return findRejection(d->m_rejections, TypeRejection::Function, className, functionName, reason);
}
bool TypeDatabase::isFieldRejected(const QString& className, const QString& fieldName,
QString *reason) const
{
- return findRejection(m_rejections, TypeRejection::Field, className, fieldName, reason);
+ return findRejection(d->m_rejections, TypeRejection::Field, className, fieldName, reason);
}
bool TypeDatabase::isArgumentTypeRejected(const QString& className, const QString& typeName,
QString *reason) const
{
- return findRejection(m_rejections, TypeRejection::ArgumentType, className, typeName, reason);
+ return findRejection(d->m_rejections, TypeRejection::ArgumentType, className, typeName, reason);
}
bool TypeDatabase::isReturnTypeRejected(const QString& className, const QString& typeName,
QString *reason) const
{
- return findRejection(m_rejections, TypeRejection::ReturnType, className, typeName, reason);
+ return findRejection(d->m_rejections, TypeRejection::ReturnType, className, typeName, reason);
}
-FlagsTypeEntry* TypeDatabase::findFlagsType(const QString &name) const
+FlagsTypeEntryPtr TypeDatabase::findFlagsType(const QString &name) const
{
- TypeEntry *fte = findType(name);
+ TypeEntryPtr fte = findType(name);
if (!fte) {
- fte = m_flagsEntries.value(name);
+ fte = d->m_flagsEntries.value(name);
if (!fte) {
//last hope, search for flag without scope inside of flags hash
- for (auto it = m_flagsEntries.cbegin(), end = m_flagsEntries.cend(); it != end; ++it) {
+ const auto end = d->m_flagsEntries.cend();
+ for (auto it = d->m_flagsEntries.cbegin(); it != end; ++it) {
if (it.key().endsWith(name)) {
fte = it.value();
break;
@@ -579,28 +829,45 @@ FlagsTypeEntry* TypeDatabase::findFlagsType(const QString &name) const
}
}
}
- return static_cast<FlagsTypeEntry *>(fte);
+ return std::static_pointer_cast<FlagsTypeEntry>(fte);
+}
+
+void TypeDatabase::addFlagsType(const FlagsTypeEntryPtr &fte)
+{
+ d->m_flagsEntries[fte->originalName()] = fte;
+}
+
+TemplateEntryPtr TypeDatabase::findTemplate(const QString &name) const
+{
+ return d->m_templates[name];
+}
+
+void TypeDatabase::addTemplate(const TemplateEntryPtr &t)
+{
+ d->m_templates[t->name()] = t;
}
-void TypeDatabase::addFlagsType(FlagsTypeEntry *fte)
+void TypeDatabase::addTemplate(const QString &name, const QString &code)
{
- m_flagsEntries[fte->originalName()] = fte;
+ auto te = std::make_shared<TemplateEntry>(name);
+ te->addCode(code);
+ addTemplate(te);
}
-void TypeDatabase::addTemplate(TemplateEntry *t)
+AddedFunctionList TypeDatabase::globalUserFunctions() const
{
- m_templates[t->name()] = t;
+ return d->m_globalUserFunctions;
}
void TypeDatabase::addGlobalUserFunctions(const AddedFunctionList &functions)
{
- m_globalUserFunctions << functions;
+ d->m_globalUserFunctions << functions;
}
AddedFunctionList TypeDatabase::findGlobalUserFunctions(const QString& name) const
{
AddedFunctionList addedFunctions;
- for (const AddedFunctionPtr &func : m_globalUserFunctions) {
+ for (const AddedFunctionPtr &func : d->m_globalUserFunctions) {
if (func->name() == name)
addedFunctions.append(func);
}
@@ -609,153 +876,384 @@ AddedFunctionList TypeDatabase::findGlobalUserFunctions(const QString& name) con
void TypeDatabase::addGlobalUserFunctionModifications(const FunctionModificationList &functionModifications)
{
- m_functionMods << functionModifications;
+ d->m_functionMods << functionModifications;
}
-QString TypeDatabase::globalNamespaceClassName(const TypeEntry * /*entry*/)
+QString TypeDatabase::globalNamespaceClassName(const TypeEntryCPtr & /*entry*/)
{
- return QLatin1String("Global");
+ return u"Global"_s;
}
-FunctionModificationList TypeDatabase::functionModifications(const QString& signature) const
+FunctionModificationList
+ TypeDatabase::globalFunctionModifications(const QStringList &signatures) const
{
FunctionModificationList lst;
- for (int i = 0; i < m_functionMods.count(); ++i) {
- const FunctionModification& mod = m_functionMods.at(i);
- if (mod.matches(signature))
+ for (const auto &mod : d->m_functionMods) {
+ if (mod.matches(signatures))
lst << mod;
}
return lst;
}
-bool TypeDatabase::addSuppressedWarning(const QString &warning, QString *errorMessage)
+bool TypeDatabase::addSuppressedWarning(const QString &warning, bool generate,
+ QString *errorMessage)
{
QString pattern;
- if (warning.startsWith(QLatin1Char('^')) && warning.endsWith(QLatin1Char('$'))) {
+ if (warning.startsWith(u'^') && warning.endsWith(u'$')) {
pattern = warning;
} else {
// Legacy syntax: Use wildcards '*' (unless escaped by '\')
- QList<int> asteriskPositions;
- const int warningSize = warning.size();
- for (int i = 0; i < warningSize; ++i) {
- if (warning.at(i) == QLatin1Char('\\'))
+ QList<qsizetype> asteriskPositions;
+ const auto warningSize = warning.size();
+ for (qsizetype i = 0, warningSize = warning.size(); i < warningSize; ++i) {
+ if (warning.at(i) == u'\\')
++i;
- else if (warning.at(i) == QLatin1Char('*'))
+ else if (warning.at(i) == u'*')
asteriskPositions.append(i);
}
asteriskPositions.append(warningSize);
- pattern.append(QLatin1Char('^'));
- int lastPos = 0;
- for (int a = 0, aSize = asteriskPositions.size(); a < aSize; ++a) {
+ pattern.append(u'^');
+ qsizetype lastPos = 0;
+ for (qsizetype a = 0, aSize = asteriskPositions.size(); a < aSize; ++a) {
if (a)
- pattern.append(QStringLiteral(".*"));
- const int nextPos = asteriskPositions.at(a);
+ pattern.append(".*"_L1);
+ const auto nextPos = asteriskPositions.at(a);
if (nextPos > lastPos)
pattern.append(QRegularExpression::escape(warning.mid(lastPos, nextPos - lastPos)));
lastPos = nextPos + 1;
}
- pattern.append(QLatin1Char('$'));
+ pattern.append(u'$');
}
QRegularExpression expression(pattern);
if (!expression.isValid()) {
- *errorMessage = QLatin1String("Invalid message pattern \"") + warning
- + QLatin1String("\": ") + expression.errorString();
+ *errorMessage = u"Invalid message pattern \""_s + warning
+ + u"\": "_s + expression.errorString();
return false;
}
expression.setPatternOptions(expression.patternOptions() | QRegularExpression::MultilineOption);
- m_suppressedWarnings.append(expression);
+ d->m_suppressedWarnings.append({expression, warning, generate});
return true;
}
bool TypeDatabase::isSuppressedWarning(QStringView s) const
{
- if (!m_suppressWarnings)
+ if (!d->m_suppressWarnings)
return false;
- return std::any_of(m_suppressedWarnings.cbegin(), m_suppressedWarnings.end(),
- [&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
{
+ 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
+{
const QFileInfo tsFi(tsFile);
if (tsFi.isAbsolute()) // No point in further lookups
return tsFi.absoluteFilePath();
if (tsFi.isFile()) // Make path absolute
return tsFi.absoluteFilePath();
if (!currentPath.isEmpty()) {
- const QFileInfo fi(currentPath + QLatin1Char('/') + tsFile);
+ const QFileInfo fi(currentPath + u'/' + tsFile);
if (fi.isFile())
return fi.absoluteFilePath();
}
for (const QString &path : m_typesystemPaths) {
- const QFileInfo fi(path + QLatin1Char('/') + tsFile);
+ const QFileInfo fi(path + u'/' + tsFile);
if (fi.isFile())
return fi.absoluteFilePath();
}
return tsFile;
}
-bool TypeDatabase::parseFile(const QString &filename, bool generate)
-{
- return parseFile(filename, QString(), generate);
+void TypeDatabasePrivate::addBuiltInContainerTypes(const TypeDatabaseParserContextPtr &context)
+{
+ // 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",
+ "shiboken_conversion_cpppair_to_pytuple",
+ "PySequence", "shiboken_conversion_pysequence_to_cpppair");
+ }
+ if (!hasStdList) {
+ ts += containerTypeSystemSnippet(
+ "std::list", "list", "list",
+ "shiboken_conversion_cppsequence_to_pylist",
+ "PySequence",
+ "shiboken_conversion_pyiterable_to_cppsequentialcontainer");
+ }
+ if (!hasStdVector) {
+ ts += containerTypeSystemSnippet(
+ "std::vector", "list", "vector",
+ "shiboken_conversion_cppsequence_to_pylist",
+ "PySequence",
+ "shiboken_conversion_pyiterable_to_cppsequentialcontainer_reserve");
+ }
+ if (!hasStdMap) {
+ ts += containerTypeSystemSnippet(
+ "std::map", "map", "map",
+ "shiboken_conversion_stdmap_to_pydict",
+ "PyDict", "shiboken_conversion_pydict_to_stdmap");
+ }
+ if (!hasStdUnorderedMap) {
+ ts += containerTypeSystemSnippet(
+ "std::unordered_map", "map", "unordered_map",
+ "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);
+ const bool ok = parseFile(context, &buffer, true);
+ Q_ASSERT(ok);
}
-bool TypeDatabase::parseFile(const QString &filename, const QString &currentPath, bool generate)
+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;
+}
- QString filepath = modifiedTypesystemFilepath(filename, currentPath);
- if (m_parsedTypesystemFiles.contains(filepath))
- return m_parsedTypesystemFiles[filepath];
+bool TypeDatabase::parseFile(const QString &filename, bool generate)
+{
+ QString filepath = modifiedTypesystemFilepath(filename, {});
+ QFile file(filepath);
+ return d->prepareParsing(file, filename) && d->parseFile(&file, this, generate);
+}
- m_parsedTypesystemFiles[filepath] = true; // Prevent recursion when including self.
+bool TypeDatabase::parseFile(const TypeDatabaseParserContextPtr &context,
+ const QString &filename, const QString &currentPath,
+ bool generate)
+{
+ return d->parseFile(context, filename, currentPath, generate);
+}
- QFile file(filepath);
+bool TypeDatabasePrivate::prepareParsing(QFile &file, const QString &origFileName,
+ const QString &currentPath)
+{
+ const QString &filepath = file.fileName();
if (!file.exists()) {
m_parsedTypesystemFiles[filepath] = false;
- QString message = QLatin1String("Can't find ") + filename;
+ QString message = u"Can't find "_s + origFileName;
if (!currentPath.isEmpty())
- message += QLatin1String(", current path: ") + currentPath;
- message += QLatin1String(", typesystem paths: ") + m_typesystemPaths.join(QLatin1String(", "));
- qCWarning(lcShiboken).noquote().nospace() << message;
+ message += u", current path: "_s + currentPath;
+ message += u", typesystem paths: "_s + m_typesystemPaths.join(u", "_s);
+ qCWarning(lcShiboken, "%s", qPrintable(message));
return false;
}
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_parsedTypesystemFiles[filepath] = false;
- qCWarning(lcShiboken).noquote().nospace()
- << "Can't open " << QDir::toNativeSeparators(filename) << ": " << file.errorString();
+ qCWarning(lcShiboken, "%s", qPrintable(msgCannotOpenForReading(file)));
return false;
}
- bool ok = parseFile(&file, generate);
+ m_parsedTypesystemFiles[filepath] = true;
+ return true;
+}
+
+bool TypeDatabasePrivate::parseFile(const TypeDatabaseParserContextPtr &context,
+ const QString &filename, const QString &currentPath,
+ bool generate)
+{
+ // Prevent recursion when including self.
+ QString filepath = modifiedTypesystemFilepath(filename, currentPath);
+ const auto it = m_parsedTypesystemFiles.constFind(filepath);
+ if (it != m_parsedTypesystemFiles.cend())
+ return it.value();
+
+ QFile file(filepath);
+ if (!prepareParsing(file, filename, currentPath))
+ return false;
+
+ const bool ok = parseFile(context, &file, generate);
m_parsedTypesystemFiles[filepath] = ok;
return ok;
}
-bool TypeDatabase::parseFile(QIODevice* device, bool generate)
+bool TypeDatabase::parseFile(QIODevice *device, bool generate)
+{
+ return d->parseFile(device, this, generate);
+}
+
+bool TypeDatabasePrivate::parseFile(QIODevice *device, TypeDatabase *db, bool generate)
+{
+ const auto context = std::make_shared<TypeDatabaseParserContext>();
+ context->db = db;
+
+ if (!parseFile(context, device, generate))
+ return false;
+
+ addBuiltInPrimitiveTypes();
+ addBuiltInContainerTypes(context);
+ return addOpaqueContainers(context)
+ && resolveSmartPointerInstantiations(context);
+}
+
+bool TypeDatabase::parseFile(const TypeDatabaseParserContextPtr &context,
+ QIODevice *device, bool generate)
+{
+ return d->parseFile(context, device, generate);
+}
+
+bool TypeDatabasePrivate::parseFile(const TypeDatabaseParserContextPtr &context,
+ QIODevice *device, bool generate)
{
ConditionalStreamReader reader(device);
- reader.setConditions(TypeDatabase::instance()->typesystemKeywords());
- TypeSystemParser handler(this, generate);
+ reader.setConditions(context->db->typesystemKeywords());
+ TypeSystemParser handler(context, generate);
const bool result = handler.parse(reader);
- if (result)
- addBuiltInPrimitiveTypes();
- else
+ if (!result) {
qCWarning(lcShiboken, "%s", qPrintable(handler.errorString()));
+ return false;
+ }
return result;
}
-PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
+// Split a type list potentially with template types
+// "A<B,C>,D" -> ("A<B,C>", "D")
+static QStringList splitTypeList(const QString &s)
{
- const auto entries = findTypeRange(name);
- for (TypeEntry *entry : entries) {
+ QStringList result;
+ int templateDepth = 0;
+ qsizetype lastPos = 0;
+ const auto size = s.size();
+ for (qsizetype i = 0; i < size; ++i) {
+ switch (s.at(i).toLatin1()) {
+ case '<':
+ ++templateDepth;
+ break;
+ case '>':
+ --templateDepth;
+ break;
+ case ',':
+ if (templateDepth == 0) {
+ result.append(s.mid(lastPos, i - lastPos).trimmed());
+ lastPos = i + 1;
+ }
+ break;
+ }
+ }
+ if (lastPos < size)
+ result.append(s.mid(lastPos, size - lastPos).trimmed());
+ return result;
+}
+
+bool TypeDatabasePrivate::resolveSmartPointerInstantiations(const TypeDatabaseParserContextPtr &context)
+{
+ const auto &instantiations = context->smartPointerInstantiations;
+ for (auto it = instantiations.cbegin(), end = instantiations.cend(); it != end; ++it) {
+ auto smartPointerEntry = it.key();
+ const auto instantiationNames = splitTypeList(it.value());
+ SmartPointerTypeEntry::Instantiations instantiations;
+ instantiations.reserve(instantiationNames.size());
+ for (const auto &instantiation : instantiationNames) {
+ QString name;
+ QString type = instantiation;
+ const auto equalsPos = instantiation.indexOf(u'=');
+ if (equalsPos != -1) {
+ type.truncate(equalsPos);
+ name = instantiation.mid(equalsPos + 1);
+ }
+
+ const auto typeEntries = findCppTypes(type);
+ if (typeEntries.isEmpty()) {
+ const QString m = msgCannotFindTypeEntryForSmartPointer(type,
+ smartPointerEntry->name());
+ qCWarning(lcShiboken, "%s", qPrintable(m));
+ return false;
+ }
+ if (typeEntries.size() > 1) {
+ const QString m = msgAmbiguousTypesFound(type, typeEntries);
+ qCWarning(lcShiboken, "%s", qPrintable(m));
+ return false;
+ }
+ instantiations.append({name, typeEntries.constFirst()});
+ }
+ smartPointerEntry->setInstantiations(instantiations);
+ }
+ return true;
+}
+
+PrimitiveTypeEntryPtr TypeDatabase::findPrimitiveType(const QString& name) const
+{
+ const auto entries = d->findTypeRange(name);
+ for (const auto &entry : entries) {
if (entry->isPrimitive()) {
- auto *pe = static_cast<PrimitiveTypeEntry *>(entry);
+ auto pe = std::static_pointer_cast<PrimitiveTypeEntry>(entry);
if (pe->preferredTargetLangType())
return pe;
}
@@ -764,22 +1262,22 @@ PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const
return nullptr;
}
-ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const
+ComplexTypeEntryPtr TypeDatabase::findComplexType(const QString& name) const
{
- const auto entries = findTypeRange(name);
- for (TypeEntry *entry : entries) {
+ const auto entries = d->findTypeRange(name);
+ for (const auto &entry : entries) {
if (entry->isComplex() && useType(entry))
- return static_cast<ComplexTypeEntry*>(entry);
+ return std::static_pointer_cast<ComplexTypeEntry>(entry);
}
return nullptr;
}
-ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
+ObjectTypeEntryPtr TypeDatabase::findObjectType(const QString& name) const
{
- const auto entries = findTypeRange(name);
- for (TypeEntry *entry : entries) {
+ const auto entries = d->findTypeRange(name);
+ for (const auto &entry : entries) {
if (entry && entry->isObject() && useType(entry))
- return static_cast<ObjectTypeEntry*>(entry);
+ return std::static_pointer_cast<ObjectTypeEntry>(entry);
}
return nullptr;
}
@@ -787,26 +1285,26 @@ ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const
NamespaceTypeEntryList TypeDatabase::findNamespaceTypes(const QString& name) const
{
NamespaceTypeEntryList result;
- const auto entries = findTypeRange(name);
- for (TypeEntry *entry : entries) {
+ const auto entries = d->findTypeRange(name);
+ for (const auto &entry : entries) {
if (entry->isNamespace())
- result.append(static_cast<NamespaceTypeEntry*>(entry));
+ result.append(std::static_pointer_cast<NamespaceTypeEntry>(entry));
}
return result;
}
-NamespaceTypeEntry *TypeDatabase::findNamespaceType(const QString& name,
+NamespaceTypeEntryPtr TypeDatabase::findNamespaceType(const QString& name,
const QString &fileName) const
{
const auto entries = findNamespaceTypes(name);
// Preferably check on matching file name first, if a pattern was given.
if (!fileName.isEmpty()) {
- for (NamespaceTypeEntry *entry : entries) {
+ for (const auto &entry : entries) {
if (entry->hasPattern() && entry->matchesFile(fileName))
return entry;
}
}
- for (NamespaceTypeEntry *entry : entries) {
+ for (const auto &entry : entries) {
if (!entry->hasPattern())
return entry;
}
@@ -815,19 +1313,19 @@ NamespaceTypeEntry *TypeDatabase::findNamespaceType(const QString& name,
bool TypeDatabase::shouldDropTypeEntry(const QString& fullTypeName) const
{
- return m_dropTypeEntries.contains(fullTypeName);
+ return d->m_dropTypeEntries.contains(fullTypeName);
}
-void TypeDatabase::setDropTypeEntries(QStringList dropTypeEntries)
+void TypeDatabase::setDropTypeEntries(const QStringList &dropTypeEntries)
{
- m_dropTypeEntries = dropTypeEntries;
- m_dropTypeEntries.sort();
+ d->m_dropTypeEntries = dropTypeEntries;
+ d->m_dropTypeEntries.sort();
}
static bool computeTypeIndexes = true;
static int maxTypeIndex;
-static bool typeEntryLessThan(const TypeEntry* t1, const TypeEntry* t2)
+static bool typeEntryLessThan(const TypeEntryCPtr &t1, const TypeEntryCPtr &t2)
{
if (t1->revision() < t2->revision())
return true;
@@ -837,7 +1335,7 @@ static bool typeEntryLessThan(const TypeEntry* t1, const TypeEntry* t2)
static void _computeTypeIndexes()
{
- TypeDatabase* tdb = TypeDatabase::instance();
+ auto *tdb = TypeDatabase::instance();
TypeEntryList list;
@@ -845,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) {
- TypeEntry *entry = tit.value();
+ const TypeEntryPtr &entry = tit.value();
if (entry->isPrimitive()
|| entry->isContainer()
|| entry->isFunction()
@@ -864,7 +1362,7 @@ static void _computeTypeIndexes()
std::sort(list.begin(), list.end(), typeEntryLessThan);
maxTypeIndex = 0;
- for (TypeEntry *e : qAsConst(list))
+ for (const TypeEntryPtr &e : std::as_const(list))
e->setSbkIndex(maxTypeIndex++);
computeTypeIndexes = false;
}
@@ -901,7 +1399,7 @@ bool TypeDatabase::setApiVersion(const QString& packageWildcardPattern, const QS
if (versionNumber.isNull())
return false;
ApiVersions &versions = *apiVersions();
- for (int i = 0, size = versions.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = versions.size(); i < size; ++i) {
if (versions.at(i).first.pattern() == packagePattern) {
versions[i].second = versionNumber;
return true;
@@ -910,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;
}
@@ -920,7 +1418,7 @@ bool TypeDatabase::checkApiVersion(const QString &package,
const ApiVersions &versions = *apiVersions();
if (versions.isEmpty()) // Nothing specified: use latest.
return true;
- for (int i = 0, size = versions.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = versions.size(); i < size; ++i) {
if (versions.at(i).first.match(package).hasMatch())
return versions.at(i).second >= vr.since
&& versions.at(i).second <= vr.until;
@@ -928,23 +1426,18 @@ bool TypeDatabase::checkApiVersion(const QString &package,
return false;
}
-#ifndef QT_NO_DEBUG_STREAM
+bool TypeDatabase::hasDroppedTypeEntries() const
+{
+ return !d->m_dropTypeEntries.isEmpty();
+}
-template <class Container, class Separator>
-static void formatList(QDebug &d, const char *name, const Container &c, Separator sep)
+#ifndef QT_NO_DEBUG_STREAM
+void TypeDatabase::formatDebug(QDebug &debug) const
{
- if (const int size = c.size()) {
- d << ", " << name << '[' << size << "]=(";
- for (int i = 0; i < size; ++i) {
- if (i)
- d << sep;
- d << c.at(i);
- }
- d << ')';
- }
+ d->formatDebug(debug);
}
-void TypeDatabase::formatDebug(QDebug &d) const
+void TypeDatabasePrivate::formatDebug(QDebug &d) const
{
d << "TypeDatabase("
<< "entries[" << m_entries.size() << "]=";
@@ -981,62 +1474,148 @@ void TypeDatabase::formatDebug(QDebug &d) const
d << ")\n";
}
d <<"\nglobalUserFunctions=" << m_globalUserFunctions << '\n';
- formatList(d, "globalFunctionMods", m_functionMods, '\n');
+ formatList(d, "globalFunctionMods", m_functionMods, "\n");
d << ')';
}
-void TypeDatabase::addBuiltInType(TypeEntry *e)
+// Helpers for dumping out primitive type info
+
+struct formatPrimitiveEntry
+{
+ explicit formatPrimitiveEntry(const PrimitiveTypeEntryCPtr &e) : m_pe(e) {}
+
+ PrimitiveTypeEntryCPtr m_pe;
+};
+
+QDebug operator<<(QDebug debug, const formatPrimitiveEntry &fe)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ const QString &name = fe.m_pe->name();
+ const QString &targetLangName = fe.m_pe->targetLangApiName();
+ debug << '"' << name << '"';
+ if (name != targetLangName)
+ debug << " (\"" << targetLangName << "\")";
+ if (fe.m_pe->isBuiltIn())
+ debug << " [builtin]";
+ if (isExtendedCppPrimitive(fe.m_pe)) {
+ debug << " [";
+ if (!isCppPrimitive(fe.m_pe))
+ debug << "extended ";
+ debug << "C++]";
+ }
+ return debug;
+}
+
+// Sort primitive types for displaying; base type and typedef'ed types
+struct PrimitiveFormatListEntry
+{
+ PrimitiveTypeEntryCPtr baseType;
+ PrimitiveTypeEntryCList typedefs;
+};
+
+static bool operator<(const PrimitiveFormatListEntry &e1, const PrimitiveFormatListEntry &e2)
+{
+ return e1.baseType->name() < e2.baseType->name();
+}
+
+using PrimitiveFormatListEntries = QList<PrimitiveFormatListEntry>;
+
+static qsizetype indexOf(const PrimitiveFormatListEntries &e, const PrimitiveTypeEntryCPtr &needle)
+{
+ for (qsizetype i = 0, size = e.size(); i < size; ++i) {
+ if (e.at(i).baseType == needle)
+ return i;
+ }
+ return -1;
+}
+
+void TypeDatabase::formatBuiltinTypes(QDebug debug) const
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+
+ // Determine base types and their typedef'ed types
+ QList<PrimitiveFormatListEntry> primitiveEntries;
+ for (const auto &e : std::as_const(d->m_entries)) {
+ if (e->isPrimitive()) {
+ auto pe = std::static_pointer_cast<const PrimitiveTypeEntry>(e);
+ auto basic = basicReferencedTypeEntry(pe);
+ if (basic != pe) {
+ const auto idx = indexOf(primitiveEntries, basic);
+ if (idx != -1)
+ primitiveEntries[idx].typedefs.append(pe);
+ else
+ primitiveEntries.append(PrimitiveFormatListEntry{basic, {pe}});
+ } else {
+ primitiveEntries.append(PrimitiveFormatListEntry{pe, {}});
+ }
+ }
+ }
+
+ std::sort(primitiveEntries.begin(), primitiveEntries.end());
+
+ for (const auto &e : std::as_const(primitiveEntries)) {
+ debug << "Primitive: " << formatPrimitiveEntry(e.baseType) << '\n';
+ for (const auto &pe : e.typedefs)
+ debug << " " << formatPrimitiveEntry(pe) << '\n';
+ }
+}
+
+void TypeDatabasePrivate::addBuiltInType(const TypeEntryPtr &e)
{
e->setBuiltIn(true);
addType(e);
}
-PrimitiveTypeEntry *
- TypeDatabase::addBuiltInPrimitiveType(const QString &name,
- const TypeSystemTypeEntry *root,
+PrimitiveTypeEntryPtr
+ TypeDatabasePrivate::addBuiltInPrimitiveType(const QString &name,
+ const TypeSystemTypeEntryCPtr &root,
const QString &rootPackage,
- CustomTypeEntry *targetLang)
+ const CustomTypeEntryPtr &targetLang)
{
- auto *result = new PrimitiveTypeEntry(name, {}, root);
+ auto result = std::make_shared<PrimitiveTypeEntry>(name, QVersionNumber{}, root);
result->setTargetLangApiType(targetLang);
result->setTargetLangPackage(rootPackage);
addBuiltInType(result);
return result;
}
-void TypeDatabase::addBuiltInCppStringPrimitiveType(const QString &name,
+void TypeDatabasePrivate::addBuiltInCppStringPrimitiveType(const QString &name,
const QString &viewName,
- const TypeSystemTypeEntry *root,
+ const TypeSystemTypeEntryCPtr &root,
const QString &rootPackage,
- CustomTypeEntry *targetLang)
+ const CustomTypeEntryPtr &targetLang)
{
- auto *stringType = addBuiltInPrimitiveType(name, root, rootPackage,
- targetLang);
- auto *viewType = addBuiltInPrimitiveType(viewName, root, rootPackage,
- nullptr);
+ auto stringType = addBuiltInPrimitiveType(name, root, rootPackage,
+ targetLang);
+ auto viewType = addBuiltInPrimitiveType(viewName, root, rootPackage,
+ nullptr);
viewType->setViewOn(stringType);
}
-void TypeDatabase::addBuiltInPrimitiveTypes()
+void TypeDatabasePrivate::addBuiltInPrimitiveTypes()
{
- auto *root = defaultTypeSystemType();
+ auto root = defaultTypeSystemType();
const QString &rootPackage = root->name();
// C++ primitive types
- auto *pyLongEntry = findType(u"PyLong"_qs);
+ auto pyLongEntry = findType(u"PyLong"_s);
Q_ASSERT(pyLongEntry && pyLongEntry->isCustom());
- auto *pyLongCustomEntry = static_cast<CustomTypeEntry *>(pyLongEntry);
- auto *pyBoolEntry = findType(u"PyBool"_qs);
+ auto pyLongCustomEntry = std::static_pointer_cast<CustomTypeEntry>(pyLongEntry);
+ auto pyBoolEntry = findType(u"PyBool"_s);
Q_ASSERT(pyBoolEntry && pyBoolEntry->isCustom());
- auto *sbkCharEntry = findType(u"SbkChar"_qs);
+ auto sbkCharEntry = findType(u"SbkChar"_s);
Q_ASSERT(sbkCharEntry && sbkCharEntry->isCustom());
- auto *sbkCharCustomEntry = static_cast<CustomTypeEntry *>(sbkCharEntry);
+ auto sbkCharCustomEntry = std::static_pointer_cast<CustomTypeEntry>(sbkCharEntry);
- auto *pyBoolCustomEntry = static_cast<CustomTypeEntry *>(pyBoolEntry);
+ auto pyBoolCustomEntry = std::static_pointer_cast<CustomTypeEntry>(pyBoolEntry);
for (const auto &t : AbstractMetaType::cppIntegralTypes()) {
if (!m_entries.contains(t)) {
- CustomTypeEntry *targetLangApi = pyLongCustomEntry;
+ CustomTypeEntryPtr targetLangApi = pyLongCustomEntry;
if (t == u"bool")
targetLangApi = pyBoolCustomEntry;
else if (AbstractMetaType::cppCharTypes().contains(t))
@@ -1045,27 +1624,27 @@ void TypeDatabase::addBuiltInPrimitiveTypes()
}
}
- auto *pyFloatEntry = findType(u"PyFloat"_qs);
+ auto pyFloatEntry = findType(u"PyFloat"_s);
Q_ASSERT(pyFloatEntry && pyFloatEntry->isCustom());
- auto *pyFloatCustomEntry = static_cast<CustomTypeEntry *>(pyFloatEntry);
+ 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"_qs);
+ auto pyUnicodeEntry = findType(u"PyUnicode"_s);
Q_ASSERT(pyUnicodeEntry && pyUnicodeEntry->isCustom());
- auto *pyUnicodeCustomEntry = static_cast<CustomTypeEntry *>(pyUnicodeEntry);
+ auto pyUnicodeCustomEntry = std::static_pointer_cast<CustomTypeEntry>(pyUnicodeEntry);
- const QString stdString = u"std::string"_qs;
+ constexpr auto stdString = "std::string"_L1;
if (!m_entries.contains(stdString)) {
- addBuiltInCppStringPrimitiveType(stdString, u"std::string_view"_qs,
+ addBuiltInCppStringPrimitiveType(stdString, u"std::string_view"_s,
root, rootPackage,
pyUnicodeCustomEntry);
}
- const QString stdWString = u"std::wstring"_qs;
+ constexpr auto stdWString = "std::wstring"_L1;
if (!m_entries.contains(stdWString)) {
- addBuiltInCppStringPrimitiveType(stdWString, u"std::wstring_view"_qs,
+ addBuiltInCppStringPrimitiveType(stdWString, u"std::wstring_view"_s,
root, rootPackage,
pyUnicodeCustomEntry);
}
diff --git a/sources/shiboken6/ApiExtractor/typedatabase.h b/sources/shiboken6/ApiExtractor/typedatabase.h
index 2eab21f32..d5adca324 100644
--- a/sources/shiboken6/ApiExtractor/typedatabase.h
+++ b/sources/shiboken6/ApiExtractor/typedatabase.h
@@ -1,65 +1,30 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TYPEDATABASE_H
#define TYPEDATABASE_H
#include "include.h"
+#include "modifications_typedefs.h"
#include "typedatabase_typedefs.h"
-#include "typesystem_enums.h"
-#include "typesystem_typedefs.h"
#include <QtCore/QRegularExpression>
#include <QtCore/QStringList>
#include <QtCore/QVersionNumber>
-QT_FORWARD_DECLARE_CLASS(QIODevice)
+#include <memory>
-class ComplexTypeEntry;
-class ContainerTypeEntry;
-class CustomTypeEntry;
-class FlagsTypeEntry;
-class FunctionTypeEntry;
-class NamespaceTypeEntry;
-class ObjectTypeEntry;
-class TemplateEntry;
-class TypeEntry;
+QT_FORWARD_DECLARE_CLASS(QIODevice)
-struct TypeRejection;
+struct OptionDescription;
+class OptionsParser;
+struct TypeDatabasePrivate;
+struct TypeDatabaseParserContext;
QT_FORWARD_DECLARE_CLASS(QDebug)
int getMaxTypeIndex();
-class ContainerTypeEntry;
-class PrimitiveTypeEntry;
-class TypeSystemTypeEntry;
-
struct VersionRange
{
bool isNull() const
@@ -86,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
@@ -96,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
@@ -114,39 +85,39 @@ public:
void addRequiredTargetImport(const QString &moduleName);
- void addTypesystemPath(const QString &typesystem_paths);
-
- void setTypesystemKeywords(const QStringList &keywords) { m_typesystemKeywords = keywords; }
QStringList typesystemKeywords() const;
IncludeList extraIncludes(const QString &className) const;
- const QStringList &systemIncludes() const { return m_systemIncludes; }
- void addSystemInclude(const QString &name);
+ const QStringList &forceProcessSystemIncludes() const;
+ void addForceProcessSystemInclude(const QString &name);
- void addInlineNamespaceLookups(const NamespaceTypeEntry *n);
+ void addInlineNamespaceLookups(const NamespaceTypeEntryCPtr &n);
- PrimitiveTypeEntry *findPrimitiveType(const QString &name) const;
- ComplexTypeEntry *findComplexType(const QString &name) const;
- ObjectTypeEntry *findObjectType(const QString &name) const;
+ PrimitiveTypeEntryPtr findPrimitiveType(const QString &name) const;
+ ComplexTypeEntryPtr findComplexType(const QString &name) const;
+ ObjectTypeEntryPtr findObjectType(const QString &name) const;
NamespaceTypeEntryList findNamespaceTypes(const QString &name) const;
- NamespaceTypeEntry *findNamespaceType(const QString &name, const QString &fileName = QString()) const;
- ContainerTypeEntry *findContainerType(const QString &name) const;
- FunctionTypeEntry *findFunctionType(const QString &name) const;
- const TypeSystemTypeEntry *findTypeSystemType(const QString &name) const;
- const TypeSystemTypeEntry *defaultTypeSystemType() const;
+ NamespaceTypeEntryPtr findNamespaceType(const QString &name, const QString &fileName = QString()) const;
+ ContainerTypeEntryPtr findContainerType(const QString &name) const;
+ FunctionTypeEntryPtr findFunctionType(const QString &name) const;
+ TypeSystemTypeEntryCPtr findTypeSystemType(const QString &name) const;
+ TypeSystemTypeEntryCPtr defaultTypeSystemType() const;
+ QString loadedTypeSystemNames() const;
QString defaultPackageName() const;
- TypeEntry *findType(const QString &name) const;
- TypeEntries findTypes(const QString &name) const;
- TypeEntries findCppTypes(const QString &name) const;
+ TypeEntryPtr findType(const QString &name) const;
+ TypeEntryCList findTypes(const QString &name) const;
+ TypeEntryCList findCppTypes(const QString &name) const;
- const TypeEntryMultiMap &entries() const { return m_entries; }
- const TypedefEntryMap &typedefEntries() const { return m_typedefEntries; }
+ const TypeEntryMultiMap &entries() const;
+ const TypedefEntryMap &typedefEntries() const;
- PrimitiveTypeEntryList primitiveTypes() const;
+ PrimitiveTypeEntryCList primitiveTypes() const;
- ContainerTypeEntryList containerTypes() const;
+ ContainerTypeEntryCList containerTypes() const;
+
+ SmartPointerTypeEntryList smartPointerTypes() const;
void addRejection(const TypeRejection &);
bool isClassRejected(const QString &className, QString *reason = nullptr) const;
@@ -161,19 +132,24 @@ public:
bool isReturnTypeRejected(const QString &className, const QString &typeName,
QString *reason = nullptr) const;
- bool addType(TypeEntry *e, QString *errorMessage = nullptr);
- ConstantValueTypeEntry *addConstantValueTypeEntry(const QString &value,
- const TypeEntry *parent);
- void addTypeSystemType(const TypeSystemTypeEntry *e);
+ bool addType(const TypeEntryPtr &e, QString *errorMessage = nullptr);
+ ConstantValueTypeEntryPtr addConstantValueTypeEntry(const QString &value,
+ const TypeEntryCPtr &parent);
+ void addTypeSystemType(const TypeSystemTypeEntryCPtr &e);
+
+ static ComplexTypeEntryPtr
+ initializeTypeDefEntry(const TypedefEntryPtr &typedefEntry,
+ const ComplexTypeEntryCPtr &source);
- FlagsTypeEntry *findFlagsType(const QString &name) const;
- void addFlagsType(FlagsTypeEntry *fte);
+ FlagsTypeEntryPtr findFlagsType(const QString &name) const;
+ void addFlagsType(const FlagsTypeEntryPtr &fte);
- TemplateEntry *findTemplate(const QString &name) const { return m_templates[name]; }
+ TemplateEntryPtr findTemplate(const QString &name) const;
- void addTemplate(TemplateEntry *t);
+ void addTemplate(const TemplateEntryPtr &t);
+ void addTemplate(const QString &name, const QString &code);
- AddedFunctionList globalUserFunctions() const { return m_globalUserFunctions; }
+ AddedFunctionList globalUserFunctions() const;
void addGlobalUserFunctions(const AddedFunctionList &functions);
@@ -181,80 +157,51 @@ public:
void addGlobalUserFunctionModifications(const FunctionModificationList &functionModifications);
- FunctionModificationList functionModifications(const QString &signature) const;
-
- void setSuppressWarnings(bool on) { m_suppressWarnings = on; }
+ FunctionModificationList
+ globalFunctionModifications(const QStringList &signatures) const;
- bool addSuppressedWarning(const QString &warning, QString *errorMessage);
+ bool addSuppressedWarning(const QString &warning, bool generate, QString *errorMessage);
bool isSuppressedWarning(QStringView s) const;
- static QString globalNamespaceClassName(const TypeEntry *te);
+ static QString globalNamespaceClassName(const TypeEntryCPtr &te);
+ // Top level file parsing
bool parseFile(const QString &filename, bool generate = true);
- bool parseFile(const QString &filename, const QString &currentPath, bool generate);
+ 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 std::shared_ptr<TypeDatabaseParserContext> &context,
+ QIODevice *device, bool generate = true);
static bool setApiVersion(const QString &package, const QString &version);
static void clearApiVersions();
static bool checkApiVersion(const QString &package, const VersionRange &vr);
- bool hasDroppedTypeEntries() const { return !m_dropTypeEntries.isEmpty(); }
+ bool hasDroppedTypeEntries() const;
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
+ void formatBuiltinTypes(QDebug debug) const;
+
private:
- void addBuiltInType(TypeEntry *e);
- PrimitiveTypeEntry *addBuiltInPrimitiveType(const QString &name,
- const TypeSystemTypeEntry *root,
- const QString &rootPackage,
- CustomTypeEntry *targetLang);
- void addBuiltInCppStringPrimitiveType(const QString &name,
- const QString &viewName,
- const TypeSystemTypeEntry *root,
- const QString &rootPackage,
- CustomTypeEntry *targetLang);
- void addBuiltInPrimitiveTypes();
- TypeEntryMultiMapConstIteratorRange findTypeRange(const QString &name) const;
- template <class Predicate>
- TypeEntries findTypesHelper(const QString &name, Predicate pred) const;
- TypeEntry *resolveTypeDefEntry(TypedefEntry *typedefEntry, QString *errorMessage);
- template <class String>
- bool isSuppressedWarningHelper(const String &s) 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<const TypeSystemTypeEntry *> m_typeSystemEntries; // maintain order, default is first.
-
- AddedFunctionList m_globalUserFunctions;
- FunctionModificationList m_functionMods;
-
- QStringList m_requiredTargetImports;
-
- QStringList m_typesystemPaths;
- QStringList m_typesystemKeywords;
- QHash<QString, bool> m_parsedTypesystemFiles;
-
- QList<TypeRejection> m_rejections;
-
- QStringList m_dropTypeEntries;
- QStringList m_systemIncludes;
+ TypeDatabasePrivate *d;
};
#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, const TypeEntryCPtr &te);
QDebug operator<<(QDebug d, const TypeEntry *te);
QDebug operator<<(QDebug d, const TypeDatabase &db);
#endif
diff --git a/sources/shiboken6/ApiExtractor/typedatabase_p.h b/sources/shiboken6/ApiExtractor/typedatabase_p.h
new file mode 100644
index 000000000..fc56c7961
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/typedatabase_p.h
@@ -0,0 +1,25 @@
+// 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 TYPEDATABASE_P_H
+#define TYPEDATABASE_P_H
+
+#include "typesystem_typedefs.h"
+#include "containertypeentry.h"
+
+#include <QtCore/QHash>
+#include <QtCore/QString>
+
+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/typedatabase_typedefs.h b/sources/shiboken6/ApiExtractor/typedatabase_typedefs.h
index 03ad90463..f00c61570 100644
--- a/sources/shiboken6/ApiExtractor/typedatabase_typedefs.h
+++ b/sources/shiboken6/ApiExtractor/typedatabase_typedefs.h
@@ -1,48 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TYPEDATABASE_TYPEDEFS_H
#define TYPEDATABASE_TYPEDEFS_H
+#include "typesystem_typedefs.h"
+
#include <QtCore/QMultiMap>
#include <QtCore/QString>
#include <QtCore/QList>
-class ConstantValueTypeEntry;
-class ContainerTypeEntry;
-class NamespaceTypeEntry;
-class PrimitiveTypeEntry;
-class TemplateEntry;
-class TypeEntry;
-class TypedefEntry;
-
-using TypeEntryList = QList<TypeEntry *>;
-using TemplateEntryMap =QMap<QString, TemplateEntry *>;
+using TemplateEntryMap =QMap<QString, TemplateEntryPtr>;
template <class Key, class Value>
struct QMultiMapConstIteratorRange // A range of iterator for a range-based for loop
@@ -56,14 +24,10 @@ struct QMultiMapConstIteratorRange // A range of iterator for a range-based for
ConstIterator m_end;
};
-using TypeEntryMultiMap = QMultiMap<QString, TypeEntry *>;
-using TypeEntryMultiMapConstIteratorRange = QMultiMapConstIteratorRange<QString, TypeEntry *>;
-
-using TypeEntryMap = QMap<QString, TypeEntry *>;
-using TypedefEntryMap = QMap<QString, TypedefEntry *>;
+using TypeEntryMultiMap = QMultiMap<QString, TypeEntryPtr>;
+using TypeEntryMultiMapConstIteratorRange = QMultiMapConstIteratorRange<QString, TypeEntryPtr>;
-using ContainerTypeEntryList = QList<const ContainerTypeEntry *>;
-using NamespaceTypeEntryList = QList<NamespaceTypeEntry *>;
-using PrimitiveTypeEntryList = QList<const PrimitiveTypeEntry *>;
+using TypeEntryMap = QMap<QString, TypeEntryPtr>;
+using TypedefEntryMap = QMap<QString, TypedefEntryPtr>;
#endif // TYPEDATABASE_TYPEDEFS_H
diff --git a/sources/shiboken6/ApiExtractor/typedefentry.h b/sources/shiboken6/ApiExtractor/typedefentry.h
new file mode 100644
index 000000000..44646972c
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/typedefentry.h
@@ -0,0 +1,37 @@
+// 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 TYPEDEFENTRY_H
+#define TYPEDEFENTRY_H
+
+#include "complextypeentry.h"
+
+class TypedefEntryPrivate;
+
+class TypedefEntry : public ComplexTypeEntry
+{
+public:
+ explicit TypedefEntry(const QString &entryName,
+ const QString &sourceType,
+ const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ QString sourceType() const;
+ void setSourceType(const QString &s);
+
+ TypeEntry *clone() const override;
+
+ ComplexTypeEntryCPtr source() const;
+ void setSource(const ComplexTypeEntryCPtr &source);
+
+ ComplexTypeEntryPtr target() const;
+ void setTarget(ComplexTypeEntryPtr target);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void formatDebug(QDebug &d) const override;
+#endif
+protected:
+ explicit TypedefEntry(TypedefEntryPrivate *d);
+};
+
+#endif // TYPEDEFENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/typeparser.cpp b/sources/shiboken6/ApiExtractor/typeparser.cpp
index fba3a8801..11d7bf641 100644
--- a/sources/shiboken6/ApiExtractor/typeparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typeparser.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "typeparser.h"
#include <typeinfo.h>
@@ -33,6 +8,8 @@
#include <QtCore/QStack>
#include <QtCore/QTextStream>
+using namespace Qt::StringLiterals;
+
class Scanner
{
public:
@@ -60,7 +37,7 @@ public:
{
}
- Token nextToken(QString *errorMessage = Q_NULLPTR);
+ Token nextToken(QString *errorMessage = nullptr);
QString identifier() const;
QString msgParseError(const QString &why) const;
@@ -82,7 +59,7 @@ Scanner::Token Scanner::nextToken(QString *errorMessage)
Token tok = NoToken;
// remove whitespace
- while (m_pos < m_length && m_chars[m_pos] == QLatin1Char(' '))
+ while (m_pos < m_length && m_chars[m_pos] == u' ')
++m_pos;
m_tokenStart = m_pos;
@@ -108,7 +85,7 @@ Scanner::Token Scanner::nextToken(QString *errorMessage)
++m_pos;
break;
default:
- if (c.isLetterOrNumber() || c == QLatin1Char('_')) {
+ if (c.isLetterOrNumber() || c == u'_') {
tok = Identifier;
} else {
QString message;
@@ -131,7 +108,7 @@ Scanner::Token Scanner::nextToken(QString *errorMessage)
}
if (tok == Identifier) {
- if (c.isLetterOrNumber() || c == QLatin1Char('_'))
+ if (c.isLetterOrNumber() || c == u'_')
++m_pos;
else
break;
@@ -141,23 +118,23 @@ Scanner::Token Scanner::nextToken(QString *errorMessage)
if (tok == Identifier) {
switch (m_pos - m_tokenStart) {
case 5:
- if (m_chars[m_tokenStart] == QLatin1Char('c')
- && m_chars[m_tokenStart + 1] == QLatin1Char('o')
- && m_chars[m_tokenStart + 2] == QLatin1Char('n')
- && m_chars[m_tokenStart + 3] == QLatin1Char('s')
- && m_chars[m_tokenStart + 4] == QLatin1Char('t')) {
+ if (m_chars[m_tokenStart] == u'c'
+ && m_chars[m_tokenStart + 1] == u'o'
+ && m_chars[m_tokenStart + 2] == u'n'
+ && m_chars[m_tokenStart + 3] == u's'
+ && m_chars[m_tokenStart + 4] == u't') {
tok = ConstToken;
}
break;
case 8:
- if (m_chars[m_tokenStart] == QLatin1Char('v')
- && m_chars[m_tokenStart + 1] == QLatin1Char('o')
- && m_chars[m_tokenStart + 2] == QLatin1Char('l')
- && m_chars[m_tokenStart + 3] == QLatin1Char('a')
- && m_chars[m_tokenStart + 4] == QLatin1Char('t')
- && m_chars[m_tokenStart + 5] == QLatin1Char('i')
- && m_chars[m_tokenStart + 6] == QLatin1Char('l')
- && m_chars[m_tokenStart + 7] == QLatin1Char('e')) {
+ if (m_chars[m_tokenStart] == u'v'
+ && m_chars[m_tokenStart + 1] == u'o'
+ && m_chars[m_tokenStart + 2] == u'l'
+ && m_chars[m_tokenStart + 3] == u'a'
+ && m_chars[m_tokenStart + 4] == u't'
+ && m_chars[m_tokenStart + 5] == u'i'
+ && m_chars[m_tokenStart + 6] == u'l'
+ && m_chars[m_tokenStart + 7] == u'e') {
tok = VolatileToken;
}
break;
@@ -170,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)
@@ -189,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;
@@ -222,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:
@@ -269,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:
@@ -285,7 +262,7 @@ TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
colon_prefix = false;
} else {
QStringList qualifiedName = stack.top().qualifiedName();
- qualifiedName.last().append(QLatin1Char(' ') + scanner.identifier());
+ qualifiedName.last().append(u' ' + scanner.identifier());
stack.top().setQualifiedName(qualifiedName);
}
break;
@@ -304,11 +281,11 @@ TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
break;
}
- tok = scanner.nextToken();
+ tok = scanner.nextToken(errorMessage);
}
if (stack.isEmpty() || stack.constFirst().qualifiedName().isEmpty()) {
- *errorMessage = u"Unable to parse type \""_qs + str + u"\"."_qs;
+ *errorMessage = u"Unable to parse type \""_s + str + u"\"."_s;
return {};
}
return stack.constFirst();
diff --git a/sources/shiboken6/ApiExtractor/typeparser.h b/sources/shiboken6/ApiExtractor/typeparser.h
index 2359da7b2..97634b5db 100644
--- a/sources/shiboken6/ApiExtractor/typeparser.h
+++ b/sources/shiboken6/ApiExtractor/typeparser.h
@@ -1,36 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TYPEPARSER_H
#define TYPEPARSER_H
-#include "parser/codemodel_enums.h"
-
#include <QtCore/QString>
class TypeInfo;
diff --git a/sources/shiboken6/ApiExtractor/typesystem.cpp b/sources/shiboken6/ApiExtractor/typesystem.cpp
index 50f80c244..99d42b668 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystem.cpp
@@ -1,46 +1,49 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "typesystem.h"
+#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"
+#include "functiontypeentry.h"
+#include "include.h"
+#include "namespacetypeentry.h"
+#include "objecttypeentry.h"
+#include "primitivetypeentry.h"
+#include "pythontypeentry.h"
+#include "smartpointertypeentry.h"
+#include "templateargumententry.h"
+#include "typedefentry.h"
+#include "typesystemtypeentry.h"
+#include "valuetypeentry.h"
+#include "varargstypeentry.h"
+#include "voidtypeentry.h"
#include "abstractmetatype.h"
#include "typedatabase.h"
#include "modifications.h"
-#include "messages.h"
#include "sourcelocation.h"
+#include "qtcompat.h"
+
#include <QtCore/QDebug>
#include <QtCore/QRegularExpression>
#include <QtCore/QSet>
+#include <QtCore/QVarLengthArray>
+
+using namespace Qt::StringLiterals;
-static QString buildName(const QString &entryName, const TypeEntry *parent)
+static QString buildName(const QString &entryName, const TypeEntryCPtr &parent)
{
return parent == nullptr || parent->type() == TypeEntry::TypeSystemType
- ? entryName : parent->name() + QLatin1String("::") + entryName;
+ ? entryName : parent->name() + u"::"_s + entryName;
}
// Access private class as 'd', cf macro Q_D()
@@ -49,32 +52,31 @@ static QString buildName(const QString &entryName, const TypeEntry *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 TypeEntry *parent);
- virtual ~TypeEntryPrivate();
+ const TypeEntryCPtr &parent);
+ virtual ~TypeEntryPrivate() = default;
QString shortName() const;
- const TypeEntry *m_parent;
+ TypeEntryCPtr m_parent;
QString m_name; // C++ fully qualified
mutable QString m_cachedShortName; // C++ excluding inline namespaces
QString m_entryName;
QString m_targetLangPackage;
mutable QString m_cachedTargetLangName; // "Foo.Bar"
mutable QString m_cachedTargetLangEntryName; // "Bar"
- CustomFunction m_customConstructor;
- CustomFunction m_customDestructor;
- CodeSnipList m_codeSnips;
- DocModificationList m_docModifications;
IncludeList m_extraIncludes;
Include m_include;
- QString m_targetConversionRule;
QVersionNumber m_version;
- CustomConversion *m_customConversion = nullptr;
SourceLocation m_sourceLocation; // XML file
TypeEntry::CodeGeneration m_codeGeneration = TypeEntry::GenerateCode;
- TypeEntry *m_viewOn = nullptr;
- CustomTypeEntry *m_targetLangApiType = nullptr;
+ TypeEntryPtr m_viewOn;
+ CustomTypeEntryPtr m_targetLangApiType;
int m_revision = 0;
int m_sbkIndex = 0;
TypeEntry::Type m_type;
@@ -84,7 +86,7 @@ public:
};
TypeEntryPrivate::TypeEntryPrivate(const QString &entryName, TypeEntry::Type t, const QVersionNumber &vr,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
m_parent(parent),
m_name(buildName(entryName, parent)),
m_entryName(entryName),
@@ -93,13 +95,8 @@ TypeEntryPrivate::TypeEntryPrivate(const QString &entryName, TypeEntry::Type t,
{
}
-TypeEntryPrivate::~TypeEntryPrivate()
-{
- delete m_customConversion;
-}
-
TypeEntry::TypeEntry(const QString &entryName, TypeEntry::Type t, const QVersionNumber &vr,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
TypeEntry(new TypeEntryPrivate(entryName, t, vr, parent))
{
}
@@ -110,31 +107,6 @@ TypeEntry::TypeEntry(TypeEntryPrivate *d) : m_d(d)
TypeEntry::~TypeEntry() = default;
-CodeSnipList TypeEntry::codeSnips() const
-{
- return m_d->m_codeSnips;
-}
-
-void TypeEntry::setCodeSnips(const CodeSnipList &codeSnips)
-{
- m_d->m_codeSnips = codeSnips;
-}
-
-void TypeEntry::addCodeSnip(const CodeSnip &codeSnip)
-{
- m_d->m_codeSnips << codeSnip;
-}
-
-void TypeEntry::setDocModification(const DocModificationList &docMods)
-{
- m_d->m_docModifications << docMods;
-}
-
-DocModificationList TypeEntry::docModifications() const
-{
- return m_d->m_docModifications;
-}
-
const IncludeList &TypeEntry::extraIncludes() const
{
return m_d->m_extraIncludes;
@@ -161,45 +133,29 @@ void TypeEntry::setInclude(const Include &inc)
// This is a workaround for preventing double inclusion of the QSharedPointer implementation
// header, which does not use header guards. In the previous parser this was not a problem
// because the Q_QDOC define was set, and the implementation header was never included.
- if (inc.name().endsWith(QLatin1String("qsharedpointer_impl.h"))) {
+ if (inc.name().endsWith(u"qsharedpointer_impl.h")) {
QString path = inc.name();
- path.remove(QLatin1String("_impl"));
+ path.remove(u"_impl"_s);
m_d->m_include = Include(inc.type(), path);
} else {
m_d->m_include = inc;
}
}
-void TypeEntry::setTargetConversionRule(const QString &conversionRule)
-{
- m_d->m_targetConversionRule = conversionRule;
-}
-
-QString TypeEntry::targetConversionRule() const
-{
- return m_d->m_targetConversionRule;
-}
-
QVersionNumber TypeEntry::version() const
{
return m_d->m_version;
}
-bool TypeEntry::hasTargetConversionRule() const
-{
- return !m_d->m_targetConversionRule.isEmpty();
-}
-
-bool TypeEntry::isCppPrimitive() const
+bool isCppPrimitive(const TypeEntryCPtr &e)
{
- if (!isPrimitive())
+ if (!e->isPrimitive())
return false;
- if (m_d->m_type == VoidType)
+ if (e->type() == TypeEntry::VoidType)
return true;
- const PrimitiveTypeEntry *referencedType =
- static_cast<const PrimitiveTypeEntry *>(this)->basicReferencedTypeEntry();
+ PrimitiveTypeEntryCPtr referencedType = basicReferencedTypeEntry(e);
const QString &typeName = referencedType->name();
return AbstractMetaType::cppPrimitiveTypes().contains(typeName);
}
@@ -209,17 +165,17 @@ TypeEntry::Type TypeEntry::type() const
return m_d->m_type;
}
-const TypeEntry *TypeEntry::parent() const
+TypeEntryCPtr TypeEntry::parent() const
{
return m_d->m_parent;
}
-void TypeEntry::setParent(const TypeEntry *p)
+void TypeEntry::setParent(const TypeEntryCPtr &p)
{
m_d->m_parent = p;
}
-bool TypeEntry::isChildOf(const TypeEntry *p) const
+bool TypeEntry::isChildOf(const TypeEntryCPtr &p) const
{
for (auto e = m_d->m_parent; e; e = e->parent()) {
if (e == p)
@@ -228,18 +184,18 @@ bool TypeEntry::isChildOf(const TypeEntry *p) const
return false;
}
-const TypeSystemTypeEntry *TypeEntry::typeSystemTypeEntry() const
+TypeSystemTypeEntryCPtr typeSystemTypeEntry(TypeEntryCPtr e)
{
- for (auto e = this; e; e = e->parent()) {
+ for (; e; e = e->parent()) {
if (e->type() == TypeEntry::TypeSystemType)
- return static_cast<const TypeSystemTypeEntry *>(e);
+ return std::static_pointer_cast<const TypeSystemTypeEntry>(e);
}
- return nullptr;
+ return {};
}
-const TypeEntry *TypeEntry::targetLangEnclosingEntry() const
+TypeEntryCPtr targetLangEnclosingEntry(const TypeEntryCPtr &e)
{
- auto result = m_d->m_parent;
+ auto result = e->parent();
while (result && result->type() != TypeEntry::TypeSystemType
&& !NamespaceTypeEntry::isVisibleScope(result)) {
result = result->parent();
@@ -282,6 +238,14 @@ bool TypeEntry::isSmartPointer() const
return m_d->m_type == SmartPointerType;
}
+bool TypeEntry::isUniquePointer() const
+{
+ if (m_d->m_type != SmartPointerType)
+ return false;
+ auto *ste = static_cast<const SmartPointerTypeEntry *>(this);
+ return ste->smartPointerType() == TypeSystem::SmartPointerType::Unique;
+}
+
bool TypeEntry::isArray() const
{
return m_d->m_type == ArrayType;
@@ -362,11 +326,11 @@ QString TypeEntry::name() const
QString TypeEntryPrivate::shortName() const
{
if (m_cachedShortName.isEmpty()) {
- QVarLengthArray<const TypeEntry *> parents;
+ QVarLengthArray<TypeEntryCPtr > parents;
bool foundInlineNamespace = false;
for (auto p = m_parent; p != nullptr && p->type() != TypeEntry::TypeSystemType; p = p->parent()) {
if (p->type() == TypeEntry::NamespaceType
- && static_cast<const NamespaceTypeEntry *>(p)->isInlineNamespace()) {
+ && std::static_pointer_cast<const NamespaceTypeEntry>(p)->isInlineNamespace()) {
foundInlineNamespace = true;
} else {
parents.append(p);
@@ -374,9 +338,9 @@ QString TypeEntryPrivate::shortName() const
}
if (foundInlineNamespace) {
m_cachedShortName.reserve(m_name.size());
- for (int i = parents.size() - 1; i >= 0; --i) {
+ for (auto i = parents.size() - 1; i >= 0; --i) {
m_cachedShortName.append(parents.at(i)->entryName());
- m_cachedShortName.append(QLatin1String("::"));
+ m_cachedShortName.append(u"::"_s);
}
m_cachedShortName.append(m_entryName);
} else {
@@ -411,6 +375,11 @@ bool TypeEntry::generateCode() const
return m_d->m_codeGeneration == GenerateCode;
}
+bool TypeEntry::shouldGenerate() const
+{
+ return generateCode() && NamespaceTypeEntry::isVisibleScope(this);
+}
+
int TypeEntry::revision() const
{
return m_d->m_revision;
@@ -426,7 +395,7 @@ QString TypeEntry::qualifiedCppName() const
return m_d->m_name;
}
-const CustomTypeEntry *TypeEntry::targetLangApiType() const
+CustomTypeEntryCPtr TypeEntry::targetLangApiType() const
{
return m_d->m_targetLangApiType;
}
@@ -436,7 +405,7 @@ bool TypeEntry::hasTargetLangApiType() const
return m_d->m_targetLangApiType != nullptr;
}
-void TypeEntry::setTargetLangApiType(CustomTypeEntry *cte)
+void TypeEntry::setTargetLangApiType(const CustomTypeEntryPtr &cte)
{
m_d->m_targetLangApiType = cte;
}
@@ -465,9 +434,9 @@ QString TypeEntry::buildTargetLangName() const
for (auto p = parent(); p && p->type() != TypeEntry::TypeSystemType; p = p->parent()) {
if (NamespaceTypeEntry::isVisibleScope(p)) {
if (!result.isEmpty())
- result.prepend(QLatin1Char('.'));
+ result.prepend(u'.');
QString n = p->m_d->m_entryName;
- n.replace(QLatin1String("::"), QLatin1String(".")); // Primitive types may have "std::"
+ n.replace(u"::"_s, u"."_s); // Primitive types may have "std::"
result.prepend(n);
}
}
@@ -496,18 +465,12 @@ void TypeEntry::setSourceLocation(const SourceLocation &sourceLocation)
m_d->m_sourceLocation = sourceLocation;
}
-const PrimitiveTypeEntry *TypeEntry::asPrimitive() const
+bool isUserPrimitive(const TypeEntryCPtr &e)
{
- Q_ASSERT(m_d->m_type == PrimitiveType);
- return static_cast<const PrimitiveTypeEntry *>(this);
-}
-
-bool TypeEntry::isUserPrimitive() const
-{
- if (!isPrimitive())
+ if (!e->isPrimitive())
return false;
- const auto *type = asPrimitive()->basicReferencedTypeEntry();
- return !type->isCppPrimitive()
+ const auto type = basicReferencedTypeEntry(e);
+ return !isCppPrimitive(type)
&& type->qualifiedCppName() != u"std::string";
}
@@ -516,21 +479,21 @@ bool TypeEntry::isWrapperType() const
return isObject() || isValue() || isSmartPointer();
}
-bool TypeEntry::isCppIntegralPrimitive() const
+bool isCppIntegralPrimitive(const TypeEntryCPtr &e)
{
- if (!isCppPrimitive())
+ if (!isCppPrimitive(e))
return false;
- const auto *type = asPrimitive()->basicReferencedTypeEntry();
+ const auto type = basicReferencedTypeEntry(e);
return AbstractMetaType::cppIntegralTypes().contains(type->qualifiedCppName());
}
-bool TypeEntry::isExtendedCppPrimitive() const
+bool isExtendedCppPrimitive(const TypeEntryCPtr &e)
{
- if (isCppPrimitive())
+ if (isCppPrimitive(e))
return true;
- if (!isPrimitive())
+ if (!e->isPrimitive())
return false;
- const auto *type = asPrimitive()->basicReferencedTypeEntry();
+ const auto type = basicReferencedTypeEntry(e);
const QString &name = type->qualifiedCppName();
return name == u"std::string" || name == u"std::wstring";
}
@@ -549,7 +512,7 @@ QString TypeEntry::targetLangEntryName() const
{
if (m_d->m_cachedTargetLangEntryName.isEmpty()) {
m_d->m_cachedTargetLangEntryName = targetLangName();
- const int lastDot = m_d->m_cachedTargetLangEntryName.lastIndexOf(QLatin1Char('.'));
+ const int lastDot = m_d->m_cachedTargetLangEntryName.lastIndexOf(u'.');
if (lastDot != -1)
m_d->m_cachedTargetLangEntryName.remove(0, lastDot + 1);
}
@@ -568,27 +531,7 @@ void TypeEntry::setTargetLangPackage(const QString &p)
QString TypeEntry::qualifiedTargetLangName() const
{
- return targetLangPackage() + QLatin1Char('.') + targetLangName();
-}
-
-void TypeEntry::setCustomConstructor(const CustomFunction &func)
-{
- m_d->m_customConstructor = func;
-}
-
-CustomFunction TypeEntry::customConstructor() const
-{
- return m_d->m_customConstructor;
-}
-
-void TypeEntry::setCustomDestructor(const CustomFunction &func)
-{
- m_d->m_customDestructor = func;
-}
-
-CustomFunction TypeEntry::customDestructor() const
-{
- return m_d->m_customDestructor;
+ return targetLangPackage() + u'.' + targetLangName();
}
bool TypeEntry::isValue() const
@@ -601,27 +544,12 @@ bool TypeEntry::isComplex() const
return false;
}
-bool TypeEntry::hasCustomConversion() const
-{
- return m_d->m_customConversion != nullptr;
-}
-
-void TypeEntry::setCustomConversion(CustomConversion* customConversion)
-{
- m_d->m_customConversion = customConversion;
-}
-
-CustomConversion* TypeEntry::customConversion() const
-{
- return m_d->m_customConversion;
-}
-
-TypeEntry *TypeEntry::viewOn() const
+TypeEntryPtr TypeEntry::viewOn() const
{
return m_d->m_viewOn;
}
-void TypeEntry::setViewOn(TypeEntry *v)
+void TypeEntry::setViewOn(const TypeEntryPtr &v)
{
m_d->m_viewOn = v;
}
@@ -632,13 +560,15 @@ TypeEntry *TypeEntry::clone() const
}
// Take over parameters relevant for typedefs
-void TypeEntry::useAsTypedef(const TypeEntry *source)
+void TypeEntry::useAsTypedef(const TypeEntryCPtr &source)
{
// XML Typedefs are in the global namespace for now.
- m_d->m_parent = source->typeSystemTypeEntry();
+ m_d->m_parent = typeSystemTypeEntry(source);
m_d->m_entryName = source->m_d->m_entryName;
m_d->m_name = source->m_d->m_name;
m_d->m_targetLangPackage = source->m_d->m_targetLangPackage;
+ m_d->m_cachedTargetLangName.clear(); // Clear cached names.
+ m_d->m_cachedTargetLangEntryName.clear();
m_d->m_codeGeneration = source->m_d->m_codeGeneration;
m_d->m_version = source->m_d->m_version;
}
@@ -653,7 +583,7 @@ public:
};
CustomTypeEntry::CustomTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
TypeEntry(new CustomTypeEntryPrivate(entryName, CustomType, vr, parent))
{
}
@@ -734,11 +664,15 @@ class TypeSystemTypeEntryPrivate : public TypeEntryPrivate
public:
using TypeEntryPrivate::TypeEntryPrivate;
+ 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,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
TypeEntry(new TypeSystemTypeEntryPrivate(entryName, TypeSystemType, vr, parent))
{
}
@@ -754,6 +688,60 @@ TypeEntry *TypeSystemTypeEntry::clone() const
return new TypeSystemTypeEntry(new TypeSystemTypeEntryPrivate(*d));
}
+const CodeSnipList &TypeSystemTypeEntry::codeSnips() const
+{
+ S_D(const TypeSystemTypeEntry);
+ return d->m_codeSnips;
+}
+
+CodeSnipList &TypeSystemTypeEntry::codeSnips()
+{
+ S_D(TypeSystemTypeEntry);
+ return d->m_codeSnips;
+}
+
+void TypeSystemTypeEntry::addCodeSnip(const CodeSnip &codeSnip)
+{
+ S_D(TypeSystemTypeEntry);
+ 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);
@@ -768,7 +756,7 @@ void TypeSystemTypeEntry::setSnakeCase(TypeSystem::SnakeCase sc)
// ----------------- VoidTypeEntry
VoidTypeEntry::VoidTypeEntry() :
- TypeEntry(QLatin1String("void"), VoidType, QVersionNumber(0, 0), nullptr)
+ TypeEntry(u"void"_s, VoidType, QVersionNumber(0, 0), nullptr)
{
}
@@ -783,7 +771,7 @@ TypeEntry *VoidTypeEntry::clone() const
}
VarargsTypeEntry::VarargsTypeEntry() :
- TypeEntry(QLatin1String("..."), VarargsType, QVersionNumber(0, 0), nullptr)
+ TypeEntry(u"..."_s, VarargsType, QVersionNumber(0, 0), nullptr)
{
}
@@ -808,7 +796,7 @@ public:
};
TemplateArgumentEntry::TemplateArgumentEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
TypeEntry(new TemplateArgumentEntryPrivate(entryName, TemplateArgumentType, vr, parent))
{
}
@@ -840,30 +828,30 @@ TemplateArgumentEntry::TemplateArgumentEntry(TemplateArgumentEntryPrivate *d) :
class ArrayTypeEntryPrivate : public TypeEntryPrivate
{
public:
- explicit ArrayTypeEntryPrivate(const TypeEntry *nested_type, const QVersionNumber &vr,
- const TypeEntry *parent) :
- TypeEntryPrivate(QLatin1String("Array"), TypeEntry::ArrayType, vr, parent),
+ explicit ArrayTypeEntryPrivate(const TypeEntryCPtr &nested_type, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent) :
+ TypeEntryPrivate(u"Array"_s, TypeEntry::ArrayType, vr, parent),
m_nestedType(nested_type)
{
}
- const TypeEntry *m_nestedType;
+ TypeEntryCPtr m_nestedType;
};
-ArrayTypeEntry::ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr,
- const TypeEntry *parent) :
+ArrayTypeEntry::ArrayTypeEntry(const TypeEntryCPtr &nested_type, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent) :
TypeEntry(new ArrayTypeEntryPrivate(nested_type, vr, parent))
{
Q_ASSERT(nested_type);
}
-void ArrayTypeEntry::setNestedTypeEntry(TypeEntry *nested)
+void ArrayTypeEntry::setNestedTypeEntry(const TypeEntryPtr &nested)
{
S_D(ArrayTypeEntry);
d->m_nestedType = nested;
}
-const TypeEntry *ArrayTypeEntry::nestedTypeEntry() const
+TypeEntryCPtr ArrayTypeEntry::nestedTypeEntry() const
{
S_D(const ArrayTypeEntry);
return d->m_nestedType;
@@ -872,7 +860,7 @@ const TypeEntry *ArrayTypeEntry::nestedTypeEntry() const
QString ArrayTypeEntry::buildTargetLangName() const
{
S_D(const ArrayTypeEntry);
- return d->m_nestedType->targetLangName() + QLatin1String("[]");
+ return d->m_nestedType->targetLangName() + u"[]"_s;
}
TypeEntry *ArrayTypeEntry::clone() const
@@ -891,19 +879,20 @@ class PrimitiveTypeEntryPrivate : public TypeEntryPrivate
{
public:
PrimitiveTypeEntryPrivate(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
TypeEntryPrivate(entryName, TypeEntry::PrimitiveType, vr, parent),
m_preferredTargetLangType(true)
{
}
QString m_defaultConstructor;
+ CustomConversionPtr m_customConversion;
+ PrimitiveTypeEntryPtr m_referencedTypeEntry;
uint m_preferredTargetLangType : 1;
- PrimitiveTypeEntry* m_referencedTypeEntry = nullptr;
};
PrimitiveTypeEntry::PrimitiveTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
TypeEntry(new PrimitiveTypeEntryPrivate(entryName, vr, parent))
{
}
@@ -926,29 +915,35 @@ bool PrimitiveTypeEntry::hasDefaultConstructor() const
return !d->m_defaultConstructor.isEmpty();
}
-PrimitiveTypeEntry *PrimitiveTypeEntry::referencedTypeEntry() const
+PrimitiveTypeEntryPtr PrimitiveTypeEntry::referencedTypeEntry() const
{
S_D(const PrimitiveTypeEntry);
return d->m_referencedTypeEntry;
}
-void PrimitiveTypeEntry::setReferencedTypeEntry(PrimitiveTypeEntry *referencedTypeEntry)
+void PrimitiveTypeEntry::setReferencedTypeEntry(PrimitiveTypeEntryPtr referencedTypeEntry)
{
S_D(PrimitiveTypeEntry);
d->m_referencedTypeEntry = referencedTypeEntry;
}
-const PrimitiveTypeEntry *PrimitiveTypeEntry::basicReferencedTypeEntry() const
+PrimitiveTypeEntryCPtr basicReferencedTypeEntry(const PrimitiveTypeEntryCPtr &e)
{
- auto *result = this;
- while (auto *referenced = result->referencedTypeEntry())
+ auto result = e;
+ while (auto referenced = result->referencedTypeEntry())
result = referenced;
return result;
}
-const PrimitiveTypeEntry *PrimitiveTypeEntry::basicReferencedNonBuiltinTypeEntry() const
+PrimitiveTypeEntryCPtr basicReferencedTypeEntry(const TypeEntryCPtr &e)
{
- auto *result = this;
+ Q_ASSERT(e->isPrimitive());
+ return basicReferencedTypeEntry(std::static_pointer_cast<const PrimitiveTypeEntry>(e));
+}
+
+PrimitiveTypeEntryCPtr basicReferencedNonBuiltinTypeEntry(const PrimitiveTypeEntryCPtr &e)
+{
+ auto result = e;
for (; result->referencedTypeEntry() ; result = result->referencedTypeEntry()) {
if (!result->isBuiltIn())
break;
@@ -974,6 +969,24 @@ void PrimitiveTypeEntry::setPreferredTargetLangType(bool b)
d->m_preferredTargetLangType = b;
}
+bool PrimitiveTypeEntry::hasCustomConversion() const
+{
+ S_D(const PrimitiveTypeEntry);
+ return bool(d->m_customConversion);
+}
+
+void PrimitiveTypeEntry::setCustomConversion(const CustomConversionPtr &customConversion)
+{
+ S_D(PrimitiveTypeEntry);
+ d->m_customConversion = customConversion;
+}
+
+CustomConversionPtr PrimitiveTypeEntry::customConversion() const
+{
+ S_D(const PrimitiveTypeEntry);
+ return d->m_customConversion;
+}
+
TypeEntry *PrimitiveTypeEntry::clone() const
{
S_D(const PrimitiveTypeEntry);
@@ -985,24 +998,87 @@ PrimitiveTypeEntry::PrimitiveTypeEntry(PrimitiveTypeEntryPrivate *d)
{
}
-// ----------------- EnumTypeEntry
-class EnumTypeEntryPrivate : public TypeEntryPrivate
+// ----------------- ConfigurableTypeEntry
+
+class ConfigurableTypeEntryPrivate : public TypeEntryPrivate
{
public:
using TypeEntryPrivate::TypeEntryPrivate;
- const EnumValueTypeEntry *m_nullValue = nullptr;
+ 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;
- FlagsTypeEntry *m_flags = nullptr;
+ 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 TypeEntry *parent) :
- TypeEntry(new EnumTypeEntryPrivate(entryName, EnumType, vr, parent))
+ const TypeEntryCPtr &parent) :
+ ConfigurableTypeEntry(new EnumTypeEntryPrivate(entryName, EnumType, vr, parent))
{
}
+TypeSystem::PythonEnumType EnumTypeEntry::pythonEnumType() const
+{
+ S_D(const EnumTypeEntry);
+ return d->m_pythonEnumType;
+}
+
+void EnumTypeEntry::setPythonEnumType(TypeSystem::PythonEnumType t)
+{
+ S_D(EnumTypeEntry);
+ d->m_pythonEnumType = t;
+}
+
QString EnumTypeEntry::targetLangQualifier() const
{
const QString q = qualifier();
@@ -1020,30 +1096,42 @@ QString EnumTypeEntry::qualifier() const
parentEntry->name() : QString();
}
-const EnumValueTypeEntry *EnumTypeEntry::nullValue() const
+EnumValueTypeEntryCPtr EnumTypeEntry::nullValue() const
{
S_D(const EnumTypeEntry);
return d->m_nullValue;
}
-void EnumTypeEntry::setNullValue(const EnumValueTypeEntry *n)
+void EnumTypeEntry::setNullValue(const EnumValueTypeEntryCPtr &n)
{
S_D(EnumTypeEntry);
d->m_nullValue = n;
}
-void EnumTypeEntry::setFlags(FlagsTypeEntry *flags)
+void EnumTypeEntry::setFlags(const FlagsTypeEntryPtr &flags)
{
S_D(EnumTypeEntry);
d->m_flags = flags;
}
-FlagsTypeEntry *EnumTypeEntry::flags() const
+FlagsTypeEntryPtr EnumTypeEntry::flags() const
{
S_D(const EnumTypeEntry);
return d->m_flags;
}
+QString EnumTypeEntry::cppType() const
+{
+ S_D(const EnumTypeEntry);
+ return d->m_cppType;
+}
+
+void EnumTypeEntry::setCppType(const QString &t)
+{
+ S_D(EnumTypeEntry);
+ d->m_cppType = t;
+}
+
bool EnumTypeEntry::isEnumValueRejected(const QString &name) const
{
S_D(const EnumTypeEntry);
@@ -1062,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);
@@ -1069,7 +1169,7 @@ TypeEntry *EnumTypeEntry::clone() const
}
EnumTypeEntry::EnumTypeEntry(EnumTypeEntryPrivate *d) :
- TypeEntry(d)
+ ConfigurableTypeEntry(d)
{
}
@@ -1078,7 +1178,7 @@ class EnumValueTypeEntryPrivate : public TypeEntryPrivate
{
public:
EnumValueTypeEntryPrivate(const QString &name, const QString &value,
- const EnumTypeEntry *enclosingEnum,
+ const EnumTypeEntryCPtr &enclosingEnum,
bool isScopedEnum,
const QVersionNumber &vr) :
TypeEntryPrivate(name, TypeEntry::EnumValue, vr,
@@ -1089,11 +1189,11 @@ public:
}
QString m_value;
- const EnumTypeEntry *m_enclosingEnum;
+ EnumTypeEntryCPtr m_enclosingEnum;
};
EnumValueTypeEntry::EnumValueTypeEntry(const QString &name, const QString &value,
- const EnumTypeEntry *enclosingEnum,
+ const EnumTypeEntryCPtr &enclosingEnum,
bool isScopedEnum,
const QVersionNumber &vr) :
TypeEntry(new EnumValueTypeEntryPrivate(name, value, enclosingEnum, isScopedEnum, vr))
@@ -1106,7 +1206,7 @@ QString EnumValueTypeEntry::value() const
return d->m_value;
}
-const EnumTypeEntry *EnumValueTypeEntry::enclosingEnum() const
+EnumTypeEntryCPtr EnumValueTypeEntry::enclosingEnum() const
{
S_D(const EnumValueTypeEntry);
return d->m_enclosingEnum;
@@ -1131,11 +1231,11 @@ public:
QString m_originalName;
QString m_flagsName;
- EnumTypeEntry *m_enum = nullptr;
+ EnumTypeEntryPtr m_enum;
};
FlagsTypeEntry::FlagsTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
TypeEntry(new FlagsTypeEntryPrivate(entryName, FlagsType, vr, parent))
{
}
@@ -1144,7 +1244,7 @@ QString FlagsTypeEntry::buildTargetLangName() const
{
S_D(const FlagsTypeEntry);
QString on = d->m_originalName;
- on.replace(QLatin1String("::"), QLatin1String("."));
+ on.replace(u"::"_s, u"."_s);
return on;
}
@@ -1177,13 +1277,13 @@ void FlagsTypeEntry::setFlagsName(const QString &name)
d->m_flagsName = name;
}
-EnumTypeEntry *FlagsTypeEntry::originator() const
+EnumTypeEntryPtr FlagsTypeEntry::originator() const
{
S_D(const FlagsTypeEntry);
return d->m_enum;
}
-void FlagsTypeEntry::setOriginator(EnumTypeEntry *e)
+void FlagsTypeEntry::setOriginator(const EnumTypeEntryPtr &e)
{
S_D(FlagsTypeEntry);
d->m_enum = e;
@@ -1197,7 +1297,7 @@ TypeEntry *FlagsTypeEntry::clone() const
// ----------------- ConstantValueTypeEntry
ConstantValueTypeEntry::ConstantValueTypeEntry(const QString& name,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
TypeEntry(name, ConstantValueType, QVersionNumber(0, 0), parent)
{
}
@@ -1208,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 TypeEntry *parent) :
- TypeEntryPrivate(entryName, t, vr, parent),
+ const TypeEntryCPtr &parent) :
+ ConfigurableTypeEntryPrivate(entryName, t, vr, parent),
m_qualifiedCppName(buildName(entryName, parent)),
m_polymorphicBase(false),
m_genericClass(false),
@@ -1224,8 +1324,14 @@ public:
AddedFunctionList m_addedFunctions;
FunctionModificationList m_functionMods;
+ CodeSnipList m_codeSnips;
+ DocModificationList m_docModifications;
+ DocModificationList m_functionDocModifications;
+ IncludeList m_argumentIncludes;
+ QSet<QString> m_generateFunctions;
FieldModificationList m_fieldMods;
QList<TypeSystemProperty> m_properties;
+ QList<TypeSystemPyMethodDefEntry> m_PyMethodDefEntrys;
QString m_defaultConstructor;
QString m_defaultSuperclass;
QString m_qualifiedCppName;
@@ -1235,26 +1341,29 @@ public:
uint m_deleteInMainThread : 1;
QString m_polymorphicIdValue;
+ QString m_polymorphicNameFunction;
QString m_targetType;
ComplexTypeEntry::TypeFlags m_typeFlags;
ComplexTypeEntry::CopyableFlag m_copyableFlag = ComplexTypeEntry::Unknown;
QString m_hashFunction;
- const ComplexTypeEntry* m_baseContainerType = nullptr;
+ ComplexTypeEntryCPtr m_baseContainerType;
// For class functions
TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
TypeSystem::AllowThread m_allowThread = TypeSystem::AllowThread::Unspecified;
TypeSystem::SnakeCase m_snakeCase = TypeSystem::SnakeCase::Unspecified;
TypeSystem::BoolCast m_operatorBoolMode = TypeSystem::BoolCast::Unspecified;
TypeSystem::BoolCast m_isNullMode = TypeSystem::BoolCast::Unspecified;
+ TypeSystem::QtMetaTypeRegistration m_qtMetaTypeRegistration =
+ TypeSystem::QtMetaTypeRegistration::Unspecified;
// Determined by AbstractMetaBuilder from the code model.
bool m_isValueTypeWithCopyConstructorOnly = false;
};
ComplexTypeEntry::ComplexTypeEntry(const QString &entryName, TypeEntry::Type t,
const QVersionNumber &vr,
- const TypeEntry *parent) :
- TypeEntry(new ComplexTypeEntryPrivate(entryName, t, vr, parent))
+ const TypeEntryCPtr &parent) :
+ ConfigurableTypeEntry(new ComplexTypeEntryPrivate(entryName, t, vr, parent))
{
}
@@ -1317,18 +1426,77 @@ void ComplexTypeEntry::addFunctionModification(const FunctionModification &funct
d->m_functionMods << functionModification;
}
-FunctionModificationList ComplexTypeEntry::functionModifications(const QString &signature) const
+FunctionModificationList
+ ComplexTypeEntry::functionModifications(const QStringList &signatures) const
{
S_D(const ComplexTypeEntry);
FunctionModificationList lst;
- for (int i = 0; i < d->m_functionMods.count(); ++i) {
- const FunctionModification &mod = d->m_functionMods.at(i);
- if (mod.matches(signature))
+ for (const auto &mod : std::as_const(d->m_functionMods)) {
+ if (mod.matches(signatures))
lst << mod;
}
return lst;
}
+const CodeSnipList &ComplexTypeEntry::codeSnips() const
+{
+ S_D(const ComplexTypeEntry);
+ return d->m_codeSnips;
+}
+
+CodeSnipList &ComplexTypeEntry::codeSnips()
+{
+ S_D(ComplexTypeEntry);
+ return d->m_codeSnips;
+}
+
+void ComplexTypeEntry::setCodeSnips(const CodeSnipList &codeSnips)
+{
+ S_D(ComplexTypeEntry);
+ d->m_codeSnips = codeSnips;
+}
+
+void ComplexTypeEntry::addCodeSnip(const CodeSnip &codeSnip)
+{
+ S_D(ComplexTypeEntry);
+ d->m_codeSnips << codeSnip;
+}
+
+void ComplexTypeEntry::setDocModification(const DocModificationList &docMods)
+{
+ S_D(ComplexTypeEntry);
+ for (const auto &m : docMods) {
+ if (m.signature().isEmpty())
+ d->m_docModifications << m;
+ else
+ d->m_functionDocModifications << m;
+ }
+}
+
+DocModificationList ComplexTypeEntry::docModifications() const
+{
+ S_D(const ComplexTypeEntry);
+ return d->m_docModifications;
+}
+
+DocModificationList ComplexTypeEntry::functionDocModifications() const
+{
+ S_D(const ComplexTypeEntry);
+ return d->m_functionDocModifications;
+}
+
+const IncludeList &ComplexTypeEntry::argumentIncludes() const
+{
+ S_D(const ComplexTypeEntry);
+ return d->m_argumentIncludes;
+}
+
+void ComplexTypeEntry::addArgumentInclude(const Include &newInclude)
+{
+ S_D(ComplexTypeEntry);
+ IncludeGroup::appendInclude(newInclude, &d->m_argumentIncludes);
+}
+
AddedFunctionList ComplexTypeEntry::addedFunctions() const
{
S_D(const ComplexTypeEntry);
@@ -1347,6 +1515,30 @@ void ComplexTypeEntry::addNewFunction(const AddedFunctionPtr &addedFunction)
d->m_addedFunctions << addedFunction;
}
+const QList<TypeSystemPyMethodDefEntry> &ComplexTypeEntry::addedPyMethodDefEntrys() const
+{
+ S_D(const ComplexTypeEntry);
+ return d->m_PyMethodDefEntrys;
+}
+
+void ComplexTypeEntry::addPyMethodDef(const TypeSystemPyMethodDefEntry &p)
+{
+ S_D(ComplexTypeEntry);
+ d->m_PyMethodDefEntrys.append(p);
+}
+
+const QSet<QString> &ComplexTypeEntry::generateFunctions() const
+{
+ S_D(const ComplexTypeEntry);
+ return d->m_generateFunctions;
+}
+
+void ComplexTypeEntry::setGenerateFunctions(const QSet<QString> &f)
+{
+ S_D(ComplexTypeEntry);
+ d->m_generateFunctions = f;
+}
+
void ComplexTypeEntry::setFieldModifications(const FieldModificationList &mods)
{
S_D(ComplexTypeEntry);
@@ -1413,6 +1605,18 @@ QString ComplexTypeEntry::polymorphicIdValue() const
return d->m_polymorphicIdValue;
}
+QString ComplexTypeEntry::polymorphicNameFunction() const
+{
+ S_D(const ComplexTypeEntry);
+ return d->m_polymorphicNameFunction;
+}
+
+void ComplexTypeEntry::setPolymorphicNameFunction(const QString &n)
+{
+ S_D(ComplexTypeEntry);
+ d->m_polymorphicNameFunction = n;
+}
+
QString ComplexTypeEntry::targetType() const
{
S_D(const ComplexTypeEntry);
@@ -1461,6 +1665,18 @@ void ComplexTypeEntry::setCopyable(ComplexTypeEntry::CopyableFlag flag)
d->m_copyableFlag = flag;
}
+TypeSystem::QtMetaTypeRegistration ComplexTypeEntry::qtMetaTypeRegistration() const
+{
+ S_D(const ComplexTypeEntry);
+ return d->m_qtMetaTypeRegistration;
+}
+
+void ComplexTypeEntry::setQtMetaTypeRegistration(TypeSystem::QtMetaTypeRegistration r)
+{
+ S_D(ComplexTypeEntry);
+ d->m_qtMetaTypeRegistration = r;
+}
+
QString ComplexTypeEntry::hashFunction() const
{
S_D(const ComplexTypeEntry);
@@ -1473,13 +1689,13 @@ void ComplexTypeEntry::setHashFunction(const QString &hashFunction)
d->m_hashFunction = hashFunction;
}
-void ComplexTypeEntry::setBaseContainerType(const ComplexTypeEntry *baseContainer)
+void ComplexTypeEntry::setBaseContainerType(const ComplexTypeEntryCPtr &baseContainer)
{
S_D(ComplexTypeEntry);
d->m_baseContainerType = baseContainer;
}
-const ComplexTypeEntry *ComplexTypeEntry::baseContainerType() const
+ComplexTypeEntryCPtr ComplexTypeEntry::baseContainerType() const
{
S_D(const ComplexTypeEntry);
return d->m_baseContainerType;
@@ -1551,6 +1767,19 @@ void ComplexTypeEntry::setValueTypeWithCopyConstructorOnly(bool v)
d->m_isValueTypeWithCopyConstructorOnly = v;
}
+// FIXME PYSIDE 7: Remove this and make "true" the default
+static bool parentManagementEnabled = false;
+
+bool ComplexTypeEntry::isParentManagementEnabled()
+{
+ return parentManagementEnabled;
+}
+
+void ComplexTypeEntry::setParentManagementEnabled(bool e)
+{
+ parentManagementEnabled = e;
+}
+
TypeEntry *ComplexTypeEntry::clone() const
{
S_D(const ComplexTypeEntry);
@@ -1558,16 +1787,17 @@ TypeEntry *ComplexTypeEntry::clone() const
}
// Take over parameters relevant for typedefs
-void ComplexTypeEntry::useAsTypedef(const ComplexTypeEntry *source)
+void ComplexTypeEntry::useAsTypedef(const ComplexTypeEntryCPtr &source)
{
S_D(ComplexTypeEntry);
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)
{
}
@@ -1586,7 +1816,7 @@ public:
TypedefEntryPrivate(const QString &entryName,
const QString &sourceType,
const QVersionNumber &vr,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
ComplexTypeEntryPrivate(entryName, TypeEntry::TypedefType,
vr, parent),
m_sourceType(sourceType)
@@ -1594,12 +1824,12 @@ public:
}
QString m_sourceType;
- ComplexTypeEntry *m_source = nullptr;
- ComplexTypeEntry *m_target = nullptr;
+ ComplexTypeEntryCPtr m_source;
+ ComplexTypeEntryPtr m_target;
};
TypedefEntry::TypedefEntry(const QString &entryName, const QString &sourceType,
- const QVersionNumber &vr, const TypeEntry *parent) :
+ const QVersionNumber &vr, const TypeEntryCPtr &parent) :
ComplexTypeEntry(new TypedefEntryPrivate(entryName, sourceType, vr, parent))
{
}
@@ -1622,25 +1852,25 @@ TypeEntry *TypedefEntry::clone() const
return new TypedefEntry(new TypedefEntryPrivate(*d));
}
-ComplexTypeEntry *TypedefEntry::source() const
+ComplexTypeEntryCPtr TypedefEntry::source() const
{
S_D(const TypedefEntry);
return d->m_source;
}
-void TypedefEntry::setSource(ComplexTypeEntry *source)
+void TypedefEntry::setSource(const ComplexTypeEntryCPtr &source)
{
S_D(TypedefEntry);
d->m_source = source;
}
-ComplexTypeEntry *TypedefEntry::target() const
+ComplexTypeEntryPtr TypedefEntry::target() const
{
S_D(const TypedefEntry);
return d->m_target;
}
-void TypedefEntry::setTarget(ComplexTypeEntry *target)
+void TypedefEntry::setTarget(ComplexTypeEntryPtr target)
{
S_D(TypedefEntry);
d->m_target = target;
@@ -1655,33 +1885,44 @@ 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,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
ComplexTypeEntryPrivate(entryName, TypeEntry::ContainerType, vr, parent),
m_containerKind(containerKind)
{
}
- 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;
});
}
OpaqueContainers m_opaqueContainers;
+ CustomConversionPtr m_customConversion;
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 TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
ComplexTypeEntry(new ContainerTypeEntryPrivate(entryName, containerKind, vr, parent))
{
setCodeGeneration(GenerateForSubclass);
@@ -1693,36 +1934,67 @@ 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 bool(d->m_customConversion);
+}
+
+void ContainerTypeEntry::setCustomConversion(const CustomConversionPtr &customConversion)
+{
+ S_D(ContainerTypeEntry);
+ d->m_customConversion = customConversion;
+}
+
+CustomConversionPtr ContainerTypeEntry::customConversion() const
+{
+ S_D(const ContainerTypeEntry);
+ return d->m_customConversion;
+}
+
TypeEntry *ContainerTypeEntry::clone() const
{
S_D(const ContainerTypeEntry);
@@ -1740,32 +2012,53 @@ class SmartPointerTypeEntryPrivate : public ComplexTypeEntryPrivate
public:
SmartPointerTypeEntryPrivate(const QString &entryName,
const QString &getterName,
- const QString &smartPointerType,
+ TypeSystem::SmartPointerType type,
const QString &refCountMethodName,
- const QVersionNumber &vr, const TypeEntry *parent) :
+ const QVersionNumber &vr, const TypeEntryCPtr &parent) :
ComplexTypeEntryPrivate(entryName, TypeEntry::SmartPointerType, vr, parent),
m_getterName(getterName),
- m_smartPointerType(smartPointerType),
- m_refCountMethodName(refCountMethodName)
+ m_refCountMethodName(refCountMethodName),
+ m_smartPointerType(type)
{
}
+ qsizetype instantiationIndex(const TypeEntryCPtr &t) const;
+
QString m_getterName;
- QString m_smartPointerType;
QString m_refCountMethodName;
+ QString m_valueCheckMethod;
+ QString m_nullCheckMethod;
+ QString m_resetMethod;
SmartPointerTypeEntry::Instantiations m_instantiations;
+ TypeSystem::SmartPointerType m_smartPointerType;
};
+qsizetype SmartPointerTypeEntryPrivate::instantiationIndex(const TypeEntryCPtr &t) const
+{
+ for (qsizetype i = 0, size = m_instantiations.size(); i < size; ++i) {
+ if (m_instantiations.at(i).typeEntry == t)
+ return i;
+ }
+ return -1;
+}
+
SmartPointerTypeEntry::SmartPointerTypeEntry(const QString &entryName,
const QString &getterName,
- const QString &smartPointerType,
+ TypeSystem::SmartPointerType smartPointerType,
const QString &refCountMethodName,
- const QVersionNumber &vr, const TypeEntry *parent) :
+ const QVersionNumber &vr,
+ const TypeEntryCPtr &parent) :
ComplexTypeEntry(new SmartPointerTypeEntryPrivate(entryName, getterName, smartPointerType,
refCountMethodName, vr, parent))
{
}
+TypeSystem::SmartPointerType SmartPointerTypeEntry::smartPointerType() const
+{
+ S_D(const SmartPointerTypeEntry);
+ return d->m_smartPointerType;
+}
+
QString SmartPointerTypeEntry::getter() const
{
S_D(const SmartPointerTypeEntry);
@@ -1778,13 +2071,49 @@ QString SmartPointerTypeEntry::refCountMethodName() const
return d->m_refCountMethodName;
}
+QString SmartPointerTypeEntry::valueCheckMethod() const
+{
+ S_D(const SmartPointerTypeEntry);
+ return d->m_valueCheckMethod;
+}
+
+void SmartPointerTypeEntry::setValueCheckMethod(const QString &m)
+{
+ S_D(SmartPointerTypeEntry);
+ d->m_valueCheckMethod = m;
+}
+
+QString SmartPointerTypeEntry::nullCheckMethod() const
+{
+ S_D(const SmartPointerTypeEntry);
+ return d->m_nullCheckMethod;
+}
+
+void SmartPointerTypeEntry::setNullCheckMethod(const QString &f)
+{
+ S_D(SmartPointerTypeEntry);
+ d->m_nullCheckMethod = f;
+}
+
+QString SmartPointerTypeEntry::resetMethod() const
+{
+ S_D(const SmartPointerTypeEntry);
+ return d->m_resetMethod;
+}
+
+void SmartPointerTypeEntry::setResetMethod(const QString &f)
+{
+ S_D(SmartPointerTypeEntry);
+ d->m_resetMethod = f;
+}
+
TypeEntry *SmartPointerTypeEntry::clone() const
{
S_D(const SmartPointerTypeEntry);
return new SmartPointerTypeEntry(new SmartPointerTypeEntryPrivate(*d));
}
-SmartPointerTypeEntry::Instantiations SmartPointerTypeEntry::instantiations() const
+const SmartPointerTypeEntry::Instantiations &SmartPointerTypeEntry::instantiations() const
{
S_D(const SmartPointerTypeEntry);
return d->m_instantiations;
@@ -1801,10 +2130,38 @@ SmartPointerTypeEntry::SmartPointerTypeEntry(SmartPointerTypeEntryPrivate *d) :
{
}
-bool SmartPointerTypeEntry::matchesInstantiation(const TypeEntry *e) const
+bool SmartPointerTypeEntry::matchesInstantiation(const TypeEntryCPtr &e) const
+{
+ S_D(const SmartPointerTypeEntry);
+ // No instantiations specified, or match
+ return d->m_instantiations.isEmpty() || d->instantiationIndex(e) != -1;
+}
+
+static QString fixSmartPointerName(QString name)
+{
+ name.replace(u"::"_s, u"_"_s);
+ name.replace(u'<', u'_');
+ name.remove(u'>');
+ name.remove(u' ');
+ return name;
+}
+
+QString SmartPointerTypeEntry::getTargetName(const AbstractMetaType &metaType) const
{
S_D(const SmartPointerTypeEntry);
- return d->m_instantiations.isEmpty() || d->m_instantiations.contains(e);
+ auto instantiatedTe = metaType.instantiations().constFirst().typeEntry();
+ const auto index = d->instantiationIndex(instantiatedTe);
+ if (index != -1 && !d->m_instantiations.at(index).name.isEmpty())
+ return d->m_instantiations.at(index).name;
+
+ QString name = metaType.cppSignature();
+ const auto templatePos = name.indexOf(u'<');
+ if (templatePos != -1) { // "std::shared_ptr<A::B>" -> "shared_ptr<A::B>"
+ const auto colonPos = name.lastIndexOf(u"::"_s, templatePos);
+ if (colonPos != -1)
+ name.remove(0, colonPos + 2);
+ }
+ return fixSmartPointerName(name);
}
// ----------------- NamespaceTypeEntry
@@ -1814,7 +2171,7 @@ public:
using ComplexTypeEntryPrivate::ComplexTypeEntryPrivate;
QRegularExpression m_filePattern;
- const NamespaceTypeEntry *m_extends = nullptr;
+ NamespaceTypeEntryCPtr m_extends;
TypeSystem::Visibility m_visibility = TypeSystem::Visibility::Auto;
bool m_hasPattern = false;
bool m_inlineNamespace = false;
@@ -1822,7 +2179,7 @@ public:
};
NamespaceTypeEntry::NamespaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
ComplexTypeEntry(new NamespaceTypeEntryPrivate(entryName, NamespaceType, vr, parent))
{
}
@@ -1833,13 +2190,13 @@ TypeEntry *NamespaceTypeEntry::clone() const
return new NamespaceTypeEntry(new NamespaceTypeEntryPrivate(*d));
}
-const NamespaceTypeEntry *NamespaceTypeEntry::extends() const
+NamespaceTypeEntryCPtr NamespaceTypeEntry::extends() const
{
S_D(const NamespaceTypeEntry);
return d->m_extends;
}
-void NamespaceTypeEntry::setExtends(const NamespaceTypeEntry *e)
+void NamespaceTypeEntry::setExtends(const NamespaceTypeEntryCPtr &e)
{
S_D(NamespaceTypeEntry);
d->m_extends = e;
@@ -1902,6 +2259,11 @@ void NamespaceTypeEntry::setInlineNamespace(bool i)
d->m_inlineNamespace = i;
}
+bool NamespaceTypeEntry::isVisibleScope(const TypeEntryCPtr &e)
+{
+ return isVisibleScope(e.get());
+}
+
bool NamespaceTypeEntry::isVisibleScope(const TypeEntry *e)
{
return e->type() != TypeEntry::NamespaceType
@@ -1921,180 +2283,78 @@ void NamespaceTypeEntry::setGenerateUsing(bool generateUsing)
}
// ----------------- ValueTypeEntry
-ValueTypeEntry::ValueTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent) :
- ComplexTypeEntry(entryName, BasicValueType, vr, parent)
-{
-}
-
-bool ValueTypeEntry::isValue() const
-{
- return true;
-}
-
-TypeEntry *ValueTypeEntry::clone() const
-{
- S_D(const ComplexTypeEntry);
- return new ValueTypeEntry(new ComplexTypeEntryPrivate(*d));
-}
-
-ValueTypeEntry::ValueTypeEntry(ComplexTypeEntryPrivate *d) :
- ComplexTypeEntry(d)
-{
-}
-
-ValueTypeEntry::ValueTypeEntry(const QString &entryName, Type t, const QVersionNumber &vr,
- const TypeEntry *parent) :
- ComplexTypeEntry(entryName, t, vr, parent)
-{
-}
-// ----------------- CustomConversion
-struct CustomConversion::CustomConversionPrivate
+class ValueTypeEntryPrivate : public ComplexTypeEntryPrivate
{
- CustomConversionPrivate(const TypeEntry* ownerType)
- : ownerType(ownerType), replaceOriginalTargetToNativeConversions(false)
- {
- }
- const TypeEntry* ownerType;
- QString nativeToTargetConversion;
- bool replaceOriginalTargetToNativeConversions;
- TargetToNativeConversions targetToNativeConversions;
-};
+public:
+ using ComplexTypeEntryPrivate::ComplexTypeEntryPrivate;
-struct CustomConversion::TargetToNativeConversion::TargetToNativeConversionPrivate
-{
- TargetToNativeConversionPrivate()
- : sourceType(nullptr)
- {
- }
- const TypeEntry* sourceType;
- QString sourceTypeName;
- QString sourceTypeCheck;
- QString conversion;
+ QString m_targetConversionRule;
+ CustomConversionPtr m_customConversion;
};
-CustomConversion::CustomConversion(TypeEntry* ownerType)
-{
- m_d = new CustomConversionPrivate(ownerType);
- if (ownerType)
- ownerType->setCustomConversion(this);
-}
-
-CustomConversion::~CustomConversion()
-{
- qDeleteAll(m_d->targetToNativeConversions);
- delete m_d;
-}
-
-const TypeEntry* CustomConversion::ownerType() const
-{
- return m_d->ownerType;
-}
-
-QString CustomConversion::nativeToTargetConversion() const
-{
- return m_d->nativeToTargetConversion;
-}
-
-void CustomConversion::setNativeToTargetConversion(const QString& nativeToTargetConversion)
-{
- m_d->nativeToTargetConversion = nativeToTargetConversion;
-}
-
-bool CustomConversion::replaceOriginalTargetToNativeConversions() const
-{
- return m_d->replaceOriginalTargetToNativeConversions;
-}
-
-void CustomConversion::setReplaceOriginalTargetToNativeConversions(bool replaceOriginalTargetToNativeConversions)
-{
- m_d->replaceOriginalTargetToNativeConversions = replaceOriginalTargetToNativeConversions;
-}
-
-bool CustomConversion::hasTargetToNativeConversions() const
-{
- return !(m_d->targetToNativeConversions.isEmpty());
-}
-
-CustomConversion::TargetToNativeConversions& CustomConversion::targetToNativeConversions()
-{
- return m_d->targetToNativeConversions;
-}
-
-const CustomConversion::TargetToNativeConversions& CustomConversion::targetToNativeConversions() const
+ValueTypeEntry::ValueTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent) :
+ ComplexTypeEntry(new ValueTypeEntryPrivate(entryName, BasicValueType, vr, parent))
{
- return m_d->targetToNativeConversions;
}
-void CustomConversion::addTargetToNativeConversion(const QString& sourceTypeName,
- const QString& sourceTypeCheck,
- const QString& conversion)
+bool ValueTypeEntry::hasCustomConversion() const
{
- m_d->targetToNativeConversions.append(new TargetToNativeConversion(sourceTypeName, sourceTypeCheck, conversion));
+ S_D(const ValueTypeEntry);
+ return bool(d->m_customConversion);
}
-CustomConversion::TargetToNativeConversion::TargetToNativeConversion(const QString& sourceTypeName,
- const QString& sourceTypeCheck,
- const QString& conversion)
+void ValueTypeEntry::setCustomConversion(const CustomConversionPtr &customConversion)
{
- m_d = new TargetToNativeConversionPrivate;
- m_d->sourceTypeName = sourceTypeName;
- m_d->sourceTypeCheck = sourceTypeCheck;
- m_d->conversion = conversion;
+ S_D(ValueTypeEntry);
+ d->m_customConversion = customConversion;
}
-CustomConversion::TargetToNativeConversion::~TargetToNativeConversion()
+CustomConversionPtr ValueTypeEntry::customConversion() const
{
- delete m_d;
+ S_D(const ValueTypeEntry);
+ return d->m_customConversion;
}
-const TypeEntry* CustomConversion::TargetToNativeConversion::sourceType() const
+void ValueTypeEntry::setTargetConversionRule(const QString &conversionRule)
{
- return m_d->sourceType;
+ S_D(ValueTypeEntry);
+ d->m_targetConversionRule = conversionRule;
}
-void CustomConversion::TargetToNativeConversion::setSourceType(const TypeEntry* sourceType)
+QString ValueTypeEntry::targetConversionRule() const
{
- m_d->sourceType = sourceType;
+ S_D(const ValueTypeEntry);
+ return d->m_targetConversionRule;
}
-bool CustomConversion::TargetToNativeConversion::isCustomType() const
+bool ValueTypeEntry::hasTargetConversionRule() const
{
- return !(m_d->sourceType);
+ S_D(const ValueTypeEntry);
+ return !d->m_targetConversionRule.isEmpty();
}
-QString CustomConversion::TargetToNativeConversion::sourceTypeName() const
+bool ValueTypeEntry::isValue() const
{
- return m_d->sourceTypeName;
+ return true;
}
-QString CustomConversion::TargetToNativeConversion::sourceTypeCheck() const
+TypeEntry *ValueTypeEntry::clone() const
{
- if (!m_d->sourceTypeCheck.isEmpty())
- return m_d->sourceTypeCheck;
-
- if (m_d->sourceType != nullptr && m_d->sourceType->isCustom()) {
- const auto *cte = static_cast<const CustomTypeEntry *>(m_d->sourceType);
- if (cte->hasCheckFunction()) {
- QString result = cte->checkFunction();
- if (result != u"true") // For PyObject, which is always true
- result += u"(%in)"_qs;
- return result;
- }
- }
-
- return {};
+ S_D(const ValueTypeEntry);
+ return new ValueTypeEntry(new ValueTypeEntryPrivate(*d));
}
-QString CustomConversion::TargetToNativeConversion::conversion() const
+ValueTypeEntry::ValueTypeEntry(ComplexTypeEntryPrivate *d) :
+ ComplexTypeEntry(d)
{
- return m_d->conversion;
}
-void CustomConversion::TargetToNativeConversion::setConversion(const QString& conversion)
+ValueTypeEntry::ValueTypeEntry(const QString &entryName, Type t, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent) :
+ ComplexTypeEntry(entryName, t, vr, parent)
{
- m_d->conversion = conversion;
}
// ----------------- FunctionTypeEntry
@@ -2103,19 +2363,19 @@ class FunctionTypeEntryPrivate : public TypeEntryPrivate
public:
FunctionTypeEntryPrivate(const QString &entryName, const QString &signature,
const QVersionNumber &vr,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
TypeEntryPrivate(entryName, TypeEntry::FunctionType, vr, parent),
m_signatures(signature)
{
}
QStringList m_signatures;
- TypeSystem::SnakeCase m_snakeCase = TypeSystem::SnakeCase::Unspecified;
+ QString m_docFile;
};
FunctionTypeEntry::FunctionTypeEntry(const QString &entryName, const QString &signature,
const QVersionNumber &vr,
- const TypeEntry *parent) :
+ const TypeEntryCPtr &parent) :
TypeEntry(new FunctionTypeEntryPrivate(entryName, signature, vr, parent))
{
}
@@ -2138,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
@@ -2163,7 +2423,7 @@ FunctionTypeEntry::FunctionTypeEntry(FunctionTypeEntryPrivate *d) :
// ----------------- ObjectTypeEntry
ObjectTypeEntry::ObjectTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent)
+ const TypeEntryCPtr &parent)
: ComplexTypeEntry(entryName, ObjectType, vr, parent)
{
}
@@ -2193,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 int size = c.size()) {
- d << ", " << name << '[' << size << "]=(";
- for (int i = 0; i < size; ++i) {
- if (i)
- d << sep;
- d << c.at(i);
- }
- d << ')';
- }
-}
-
void TypeEntry::formatDebug(QDebug &debug) const
{
const QString cppName = qualifiedCppName();
@@ -2221,8 +2467,6 @@ void TypeEntry::formatDebug(QDebug &debug) const
FORMAT_NONEMPTY_STRING("package", m_d->m_targetLangPackage)
FORMAT_BOOL("stream", m_d->m_stream)
FORMAT_BOOL("built-in", m_d->m_builtin)
- FORMAT_LIST_SIZE("codeSnips", m_d->m_codeSnips)
- FORMAT_NONEMPTY_STRING("targetConversionRule", m_d->m_targetConversionRule)
if (m_d->m_viewOn)
debug << ", views=" << m_d->m_viewOn->name();
if (!m_d->m_version.isNull() && m_d->m_version > QVersionNumber(0, 0))
@@ -2241,9 +2485,9 @@ void TypeEntry::formatDebug(QDebug &debug) const
void PrimitiveTypeEntry::formatDebug(QDebug &debug) const
{
TypeEntry::formatDebug(debug);
- if (auto *e = referencedTypeEntry()) {
+ if (auto e = referencedTypeEntry()) {
debug << ", references";
- for (; e != nullptr; e = e->referencedTypeEntry())
+ for (; e ; e = e->referencedTypeEntry())
debug << ":\"" << e->qualifiedCppName() <<'"';
}
}
@@ -2267,6 +2511,7 @@ void ComplexTypeEntry::formatDebug(QDebug &debug) const
FORMAT_NONEMPTY_STRING("hash", d->m_hashFunction)
FORMAT_LIST_SIZE("addedFunctions", d->m_addedFunctions)
formatList(debug, "functionMods", d->m_functionMods, ", ");
+ FORMAT_LIST_SIZE("codeSnips", d->m_codeSnips)
FORMAT_LIST_SIZE("fieldMods", d->m_fieldMods)
}
@@ -2290,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
@@ -2308,6 +2552,8 @@ void EnumTypeEntry::formatDebug(QDebug &debug) const
S_D(const EnumTypeEntry);
TypeEntry::formatDebug(debug);
+ if (d->m_pythonEnumType != TypeSystem::PythonEnumType::Unspecified)
+ debug << ", python-type=" << int(d->m_pythonEnumType);
if (d->m_flags)
debug << ", flags=(" << d->m_flags << ')';
}
@@ -2324,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
@@ -2344,9 +2595,13 @@ void SmartPointerTypeEntry::formatDebug(QDebug &debug) const
ComplexTypeEntry::formatDebug(debug);
if (!d->m_instantiations.isEmpty()) {
- debug << ", instantiations[" << d->m_instantiations.size() << "]=(";
- for (auto i : d->m_instantiations)
- debug << i->name() << ',';
+ debug << "type=" << d->m_type << ", instantiations["
+ << d->m_instantiations.size() << "]=(";
+ for (const auto &i : d->m_instantiations) {
+ debug << i.typeEntry->name() << ',';
+ if (!i.name.isEmpty())
+ debug << "=\"" << i.name << '"';
+ }
debug << ')';
}
}
@@ -2365,6 +2620,12 @@ QDebug operator<<(QDebug d, const TypeEntry *te)
return d;
}
+QDebug operator<<(QDebug d, const TypeEntryCPtr &te)
+{
+ d << te.get();
+ return d;
+}
+
QDebug operator<<(QDebug d, const TemplateEntry *te)
{
QDebugStateSaver saver(d);
@@ -2379,4 +2640,10 @@ QDebug operator<<(QDebug d, const TemplateEntry *te)
d << ')';
return d;
}
+
+QDebug operator<<(QDebug d, const TemplateEntryCPtr &te)
+{
+ d << te.get();
+ return d;
+}
#endif // QT_NO_DEBUG_STREAM
diff --git a/sources/shiboken6/ApiExtractor/typesystem.h b/sources/shiboken6/ApiExtractor/typesystem.h
index 652a0d3cf..a2e4debc8 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.h
+++ b/sources/shiboken6/ApiExtractor/typesystem.h
@@ -1,86 +1,29 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TYPESYSTEM_H
#define TYPESYSTEM_H
-#include "typesystem_enums.h"
-#include "typesystem_typedefs.h"
#include "include.h"
+#include "typesystem_typedefs.h"
-#include <QtCore/QStringList>
+#include <QtCore/qobjectdefs.h>
+#include <QtCore/QString>
#include <QtCore/QScopedPointer>
-class CustomFunction;
-class CustomConversion;
-class EnumValueTypeEntry;
-class FlagsTypeEntry;
-class SourceLocation;
+class AbstractMetaType;
+class CustomTypeEntry;
class PrimitiveTypeEntry;
+class SourceLocation;
class TypeSystemTypeEntry;
-class CustomTypeEntry;
class TypeEntryPrivate;
-class TemplateArgumentEntryPrivate;
-class ArrayTypeEntryPrivate;
-class PrimitiveTypeEntryPrivate;
-class EnumTypeEntryPrivate;
-class EnumValueTypeEntryPrivate;
-class FlagsTypeEntryPrivate;
-class ComplexTypeEntryPrivate;
-class TypedefEntryPrivate;
-class ContainerTypeEntryPrivate;
-class SmartPointerTypeEntryPrivate;
-class NamespaceTypeEntryPrivate;
-class FunctionTypeEntryPrivate;
-struct TargetToNativeConversionPrivate;
QT_BEGIN_NAMESPACE
class QDebug;
-class QRegularExpression;
-class QTextStream;
class QVersionNumber;
QT_END_NAMESPACE
-struct TypeSystemProperty
-{
- bool isValid() const { return !name.isEmpty() && !read.isEmpty() && !type.isEmpty(); }
-
- QString type;
- QString name;
- QString read;
- QString write;
- QString reset;
- QString designable;
- // Indicates whether actual code is generated instead of relying on libpyside.
- bool generateGetSetDef = false;
-};
-
class TypeEntry
{
Q_GADGET
@@ -119,17 +62,14 @@ public:
Q_ENUM(CodeGeneration)
explicit TypeEntry(const QString &entryName, Type t, const QVersionNumber &vr,
- const TypeEntry *parent);
+ const TypeEntryCPtr &parent);
virtual ~TypeEntry();
Type type() const;
- const TypeEntry *parent() const;
- void setParent(const TypeEntry *p);
- bool isChildOf(const TypeEntry *p) const;
- const TypeSystemTypeEntry *typeSystemTypeEntry() const;
- // cf AbstractMetaClass::targetLangEnclosingClass()
- const TypeEntry *targetLangEnclosingEntry() const;
+ TypeEntryCPtr parent() const;
+ void setParent(const TypeEntryCPtr &);
+ bool isChildOf(const TypeEntryCPtr &p) const;
bool isPrimitive() const;
bool isEnum() const;
@@ -138,6 +78,7 @@ public:
bool isNamespace() const;
bool isContainer() const;
bool isSmartPointer() const;
+ bool isUniquePointer() const;
bool isArray() const;
bool isTemplateArgument() const;
bool isVoid() const;
@@ -173,6 +114,9 @@ public:
// on 'load-typesystem' tag
bool generateCode() const;
+ /// Returns whether the C++ generators should generate this entry
+ bool shouldGenerate() const;
+
int revision() const;
void setRevision(int r); // see typedatabase.cpp
int sbkIndex() const; // see typedatabase.cpp
@@ -186,9 +130,9 @@ public:
/// be a JNI name, for Python it should represent the CPython type name.
/// \return string representing the target language API name
/// Currently used only for PrimitiveTypeEntry (attribute "target").
- const CustomTypeEntry *targetLangApiType() const;
+ CustomTypeEntryCPtr targetLangApiType() const;
bool hasTargetLangApiType() const;
- void setTargetLangApiType(CustomTypeEntry *cte);
+ void setTargetLangApiType(const CustomTypeEntryPtr &cte);
QString targetLangApiName() const;
// The type's name in TargetLang
@@ -202,22 +146,9 @@ public:
QString qualifiedTargetLangName() const;
- void setCustomConstructor(const CustomFunction &func);
- CustomFunction customConstructor() const;
-
- void setCustomDestructor(const CustomFunction &func);
- CustomFunction customDestructor() const;
-
virtual bool isValue() const;
virtual bool isComplex() const;
- CodeSnipList codeSnips() const;
- void setCodeSnips(const CodeSnipList &codeSnips);
- void addCodeSnip(const CodeSnip &codeSnip);
-
- void setDocModification(const DocModificationList& docMods);
- DocModificationList docModifications() const;
-
const IncludeList &extraIncludes() const;
void setExtraIncludes(const IncludeList &includes);
void addExtraInclude(const Include &newInclude);
@@ -225,51 +156,25 @@ public:
Include include() const;
void setInclude(const Include &inc);
- // FIXME PYSIDE7: Remove
- /// Set the target type conversion rule
- void setTargetConversionRule(const QString& conversionRule);
-
- /// Returns the target type conversion rule
- QString targetConversionRule() const;
-
QVersionNumber version() const;
- /// TODO-CONVERTER: mark as deprecated
- bool hasTargetConversionRule() const;
-
- bool isCppPrimitive() const;
-
- bool hasCustomConversion() const;
- void setCustomConversion(CustomConversion* customConversion);
- CustomConversion* customConversion() const;
-
// View on: Type to use for function argument conversion, fex
// std::string_view -> std::string for foo(std::string_view).
// cf AbstractMetaType::viewOn()
- TypeEntry *viewOn() const;
- void setViewOn(TypeEntry *v);
+ TypeEntryPtr viewOn() const;
+ void setViewOn(const TypeEntryPtr &v);
virtual TypeEntry *clone() const;
- void useAsTypedef(const TypeEntry *source);
+ void useAsTypedef(const TypeEntryCPtr &source);
SourceLocation sourceLocation() const;
void setSourceLocation(const SourceLocation &sourceLocation);
- const PrimitiveTypeEntry *asPrimitive() const;
-
// Query functions for generators
- /// Returns true if the type is a primitive but not a C++ primitive.
- bool isUserPrimitive() const;
/// Returns true if the type passed has a Python wrapper for it.
/// Although namespace has a Python wrapper, it's not considered a type.
bool isWrapperType() const;
- /// Returns true if the type is a C++ integral primitive,
- /// i.e. bool, char, int, long, and their unsigned counterparts.
- bool isCppIntegralPrimitive() const;
- /// Returns true if the type is an extended C++ primitive, a void*,
- /// a const char*, or a std::string (cf isCppPrimitive()).
- bool isExtendedCppPrimitive() const;
#ifndef QT_NO_DEBUG_STREAM
virtual void formatDebug(QDebug &d) const;
@@ -289,593 +194,22 @@ private:
QScopedPointer<TypeEntryPrivate> m_d;
};
-class CustomTypeEntry : public TypeEntry
-{
-public:
- explicit CustomTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- TypeEntry *clone() const override;
-
- bool hasCheckFunction() const;
- QString checkFunction() const;
- void setCheckFunction(const QString &f);
-
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &d) const override;
-#endif
-
-protected:
- explicit CustomTypeEntry(TypeEntryPrivate *d);
-};
-
-class PythonTypeEntry : public CustomTypeEntry
-{
-public:
- explicit PythonTypeEntry(const QString &entryName,
- const QString &checkFunction,
- TypeSystem::CPythonType type);
-
- TypeEntry *clone() const override;
-
- TypeSystem::CPythonType cPythonType() const;
-
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &d) const override;
-#endif
-
-protected:
- explicit PythonTypeEntry(TypeEntryPrivate *d);
-};
-
-class TypeSystemTypeEntry : public TypeEntry
-{
-public:
- explicit TypeSystemTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- TypeEntry *clone() const override;
-
- TypeSystem::SnakeCase snakeCase() const;
- void setSnakeCase(TypeSystem::SnakeCase sc);
-
-protected:
- explicit TypeSystemTypeEntry(TypeEntryPrivate *d);
-};
-
-class VoidTypeEntry : public TypeEntry
-{
-public:
- VoidTypeEntry();
-
- TypeEntry *clone() const override;
-
-protected:
- explicit VoidTypeEntry(TypeEntryPrivate *d);
-};
-
-class VarargsTypeEntry : public TypeEntry
-{
-public:
- VarargsTypeEntry();
-
- TypeEntry *clone() const override;
+TypeSystemTypeEntryCPtr typeSystemTypeEntry(TypeEntryCPtr e);
-protected:
- explicit VarargsTypeEntry(TypeEntryPrivate *d);
-};
+// cf AbstractMetaClass::targetLangEnclosingClass()
+TypeEntryCPtr targetLangEnclosingEntry(const TypeEntryCPtr &e);
-class TemplateArgumentEntry : public TypeEntry
-{
-public:
- explicit TemplateArgumentEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent);
+bool isCppPrimitive(const TypeEntryCPtr &e);
- int ordinal() const;
- void setOrdinal(int o);
+/// Returns true if the type is a primitive but not a C++ primitive.
+bool isUserPrimitive(const TypeEntryCPtr &e);
- TypeEntry *clone() const override;
+/// Returns true if the type is a C++ integral primitive,
+/// i.e. bool, char, int, long, and their unsigned counterparts.
+bool isCppIntegralPrimitive(const TypeEntryCPtr &e);
-protected:
- explicit TemplateArgumentEntry(TemplateArgumentEntryPrivate *d);
-};
-
-class ArrayTypeEntry : public TypeEntry
-{
-public:
- explicit ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- void setNestedTypeEntry(TypeEntry *nested);
- const TypeEntry *nestedTypeEntry() const;
-
- TypeEntry *clone() const override;
-
-protected:
- explicit ArrayTypeEntry(ArrayTypeEntryPrivate *d);
-
- QString buildTargetLangName() const override;
-};
-
-/// A PrimitiveTypeEntry is user-defined type with conversion rules, a C++
-/// primitive type for which a PrimitiveTypeConverter exists in libshiboken
-/// or a typedef to a C++ primitive type as determined by AbstractMetaBuilder.
-class PrimitiveTypeEntry : public TypeEntry
-{
-public:
- explicit PrimitiveTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- QString defaultConstructor() const;
- void setDefaultConstructor(const QString& defaultConstructor);
- bool hasDefaultConstructor() const;
-
- /**
- * The PrimitiveTypeEntry pointed by this type entry if it
- * represents a typedef).
- * \return the type referenced by the typedef, or a null pointer
- * if the current object is not an typedef
- */
- PrimitiveTypeEntry *referencedTypeEntry() const;
-
- /**
- * Defines type referenced by this entry.
- * \param referencedTypeEntry type referenced by this entry
- */
- void setReferencedTypeEntry(PrimitiveTypeEntry* referencedTypeEntry);
-
- /// Finds the most basic primitive type that the typedef represents,
- /// i.e. a type that is not an typedef'ed.
- /// \return the most basic non-typedef'ed primitive type represented
- /// by this typedef or self in case it is not a reference.
- const PrimitiveTypeEntry* basicReferencedTypeEntry() const;
-
- /// Finds the basic primitive type that the typedef represents
- /// and was explicitly specified in the type system.
- /// \return the basic primitive type that was explicitly specified in
- /// the type system.
- const PrimitiveTypeEntry* basicReferencedNonBuiltinTypeEntry() const;
-
- /// Returns whether this entry references another entry.
- bool referencesType() const;
-
- bool preferredTargetLangType() const;
- void setPreferredTargetLangType(bool b);
-
- TypeEntry *clone() const override;
-
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &d) const override;
-#endif
-
-protected:
- explicit PrimitiveTypeEntry(PrimitiveTypeEntryPrivate *d);
-};
-
-class EnumTypeEntry : public TypeEntry
-{
-public:
- explicit EnumTypeEntry(const QString &entryName,
- const QVersionNumber &vr,
- const TypeEntry *parent);
-
- QString targetLangQualifier() const;
-
- QString qualifier() const;
-
- const EnumValueTypeEntry *nullValue() const;
- void setNullValue(const EnumValueTypeEntry *n);
-
- void setFlags(FlagsTypeEntry *flags);
- FlagsTypeEntry *flags() const;
-
- bool isEnumValueRejected(const QString &name) const;
- void addEnumValueRejection(const QString &name);
- QStringList enumValueRejections() const;
-
- TypeEntry *clone() const override;
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &d) const override;
-#endif
-protected:
- explicit EnumTypeEntry(EnumTypeEntryPrivate *d);
-};
-
-// EnumValueTypeEntry is used for resolving integer type templates
-// like array<EnumValue>. Note: Dummy entries for integer values will
-// be created for non-type template parameters, where m_enclosingEnum==nullptr.
-class EnumValueTypeEntry : public TypeEntry
-{
-public:
- explicit EnumValueTypeEntry(const QString& name, const QString& value,
- const EnumTypeEntry* enclosingEnum,
- bool isScopedEnum, const QVersionNumber &vr);
-
- QString value() const;
- const EnumTypeEntry* enclosingEnum() const;
-
- TypeEntry *clone() const override;
-
-protected:
- explicit EnumValueTypeEntry(EnumValueTypeEntryPrivate *d);
-};
-
-class FlagsTypeEntry : public TypeEntry
-{
-public:
- explicit FlagsTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- QString originalName() const;
- void setOriginalName(const QString &s);
-
- QString flagsName() const;
- void setFlagsName(const QString &name);
-
- EnumTypeEntry *originator() const;
- void setOriginator(EnumTypeEntry *e);
-
- TypeEntry *clone() const override;
-
-protected:
- explicit FlagsTypeEntry(FlagsTypeEntryPrivate *d);
-
- QString buildTargetLangName() const override;
-};
-
-// For primitive values, typically to provide a dummy type for
-// example the '2' in non-type template 'Array<2>'.
-class ConstantValueTypeEntry : public TypeEntry
-{
-public:
- explicit ConstantValueTypeEntry(const QString& name,
- const TypeEntry *parent);
-
- TypeEntry *clone() const override;
-
-protected:
- explicit ConstantValueTypeEntry(TypeEntryPrivate *d);
-};
-
-class ComplexTypeEntry : public TypeEntry
-{
-public:
- enum TypeFlag {
- DisableWrapper = 0x1,
- Deprecated = 0x4,
- ForceAbstract = 0x8
- };
- Q_DECLARE_FLAGS(TypeFlags, TypeFlag)
-
- enum CopyableFlag {
- CopyableSet,
- NonCopyableSet,
- Unknown
- };
-
- explicit ComplexTypeEntry(const QString &entryName, Type t, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- bool isComplex() const override;
-
- TypeFlags typeFlags() const;
- void setTypeFlags(TypeFlags flags);
-
- // Override command line options to generate nb_bool from
- // operator bool or method isNull().
- TypeSystem::BoolCast operatorBoolMode() const;
- void setOperatorBoolMode(TypeSystem::BoolCast b);
- TypeSystem::BoolCast isNullMode() const;
- void setIsNullMode(TypeSystem::BoolCast b);
-
- FunctionModificationList functionModifications() const;
- void setFunctionModifications(const FunctionModificationList &functionModifications);
- void addFunctionModification(const FunctionModification &functionModification);
- FunctionModificationList functionModifications(const QString &signature) const;
-
- AddedFunctionList addedFunctions() const;
- void setAddedFunctions(const AddedFunctionList &addedFunctions);
- void addNewFunction(const AddedFunctionPtr &addedFunction);
-
- void setFieldModifications(const FieldModificationList &mods);
- FieldModificationList fieldModifications() const;
-
- const QList<TypeSystemProperty> &properties() const;
- void addProperty(const TypeSystemProperty &p);
-
- QString defaultSuperclass() const;
- void setDefaultSuperclass(const QString &sc);
-
- QString qualifiedCppName() const override;
-
- void setIsPolymorphicBase(bool on);
- bool isPolymorphicBase() const;
-
- void setPolymorphicIdValue(const QString &value);
- QString polymorphicIdValue() const;
-
- QString targetType() const;
- void setTargetType(const QString &code);
-
- bool isGenericClass() const;
- void setGenericClass(bool isGeneric);
-
- bool deleteInMainThread() const;
- void setDeleteInMainThread(bool d);
-
- CopyableFlag copyable() const;
- void setCopyable(CopyableFlag flag);
-
- QString hashFunction() const;
- void setHashFunction(const QString &hashFunction);
-
- void setBaseContainerType(const ComplexTypeEntry *baseContainer);
-
- const ComplexTypeEntry *baseContainerType() const;
-
- TypeSystem::ExceptionHandling exceptionHandling() const;
- void setExceptionHandling(TypeSystem::ExceptionHandling e);
-
- TypeSystem::AllowThread allowThread() const;
- void setAllowThread(TypeSystem::AllowThread allowThread);
-
- QString defaultConstructor() const;
- void setDefaultConstructor(const QString& defaultConstructor);
- bool hasDefaultConstructor() const;
-
- TypeEntry *clone() const override;
-
- void useAsTypedef(const ComplexTypeEntry *source);
-
- TypeSystem::SnakeCase snakeCase() const;
- void setSnakeCase(TypeSystem::SnakeCase sc);
-
- // Determined by AbstractMetaBuilder from the code model.
- bool isValueTypeWithCopyConstructorOnly() const;
- void setValueTypeWithCopyConstructorOnly(bool v);
-
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &debug) const override;
-#endif
-protected:
- explicit ComplexTypeEntry(ComplexTypeEntryPrivate *d);
-};
-
-Q_DECLARE_OPERATORS_FOR_FLAGS(ComplexTypeEntry::TypeFlags)
-
-class TypedefEntry : public ComplexTypeEntry
-{
-public:
- explicit TypedefEntry(const QString &entryName,
- const QString &sourceType,
- const QVersionNumber &vr,
- const TypeEntry *parent);
-
- QString sourceType() const;
- void setSourceType(const QString &s);
-
- TypeEntry *clone() const override;
-
- ComplexTypeEntry *source() const;
- void setSource(ComplexTypeEntry *source);
-
- ComplexTypeEntry *target() const;
- void setTarget(ComplexTypeEntry *target);
-
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &d) const override;
-#endif
-protected:
- explicit TypedefEntry(TypedefEntryPrivate *d);
-};
-
-class ContainerTypeEntry : public ComplexTypeEntry
-{
- Q_GADGET
-public:
- struct OpaqueContainer // Generate an opaque container for an instantiation under name
- {
- QString instantiation;
- QString name;
- };
- using OpaqueContainers = QList<OpaqueContainer>;
-
- enum ContainerKind {
- ListContainer,
- SetContainer,
- MapContainer,
- MultiMapContainer,
- PairContainer,
- };
- Q_ENUM(ContainerKind)
-
- explicit ContainerTypeEntry(const QString &entryName, ContainerKind containerKind,
- const QVersionNumber &vr, const TypeEntry *parent);
-
- ContainerKind containerKind() const;
-
- const OpaqueContainers &opaqueContainers() const;
- void addOpaqueContainer(OpaqueContainer r);
- bool generateOpaqueContainer(const QString &instantiation) const;
- QString opaqueContainerName(const QString &instantiation) const;
-
- TypeEntry *clone() const override;
-
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &d) const override;
-#endif
-protected:
- explicit ContainerTypeEntry(ContainerTypeEntryPrivate *d);
-};
-
-class SmartPointerTypeEntry : public ComplexTypeEntry
-{
-public:
- using Instantiations = QList<const TypeEntry *>;
-
- explicit SmartPointerTypeEntry(const QString &entryName,
- const QString &getterName,
- const QString &smartPointerType,
- const QString &refCountMethodName,
- const QVersionNumber &vr,
- const TypeEntry *parent);
-
- QString getter() const;
-
- QString refCountMethodName() const;
-
- TypeEntry *clone() const override;
-
- Instantiations instantiations() const;
- void setInstantiations(const Instantiations &i);
- bool matchesInstantiation(const TypeEntry *e) const;
-
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &d) const override;
-#endif
-protected:
- SmartPointerTypeEntry(SmartPointerTypeEntryPrivate *d);
-};
-
-class NamespaceTypeEntry : public ComplexTypeEntry
-{
-public:
- explicit NamespaceTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- TypeEntry *clone() const override;
-
- const NamespaceTypeEntry *extends() const;
- void setExtends(const NamespaceTypeEntry *e);
-
- const QRegularExpression &filePattern() const; // restrict files
- void setFilePattern(const QRegularExpression &r);
-
- bool hasPattern() const;
-
- bool matchesFile(const QString &needle) const;
-
- bool isVisible() const;
- void setVisibility(TypeSystem::Visibility v);
-
- // C++ 11 inline namespace, from code model
- bool isInlineNamespace() const;
- void setInlineNamespace(bool i);
-
- static bool isVisibleScope(const TypeEntry *e);
-
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &d) const override;
-#endif
-
- // Whether to generate "using namespace" into wrapper
- bool generateUsing() const;
- void setGenerateUsing(bool generateUsing);
-
-protected:
- explicit NamespaceTypeEntry(NamespaceTypeEntryPrivate *d);
-};
-
-class ValueTypeEntry : public ComplexTypeEntry
-{
-public:
- explicit ValueTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- bool isValue() const override;
-
- TypeEntry *clone() const override;
-
-protected:
- explicit ValueTypeEntry(const QString &entryName, Type t, const QVersionNumber &vr,
- const TypeEntry *parent);
- explicit ValueTypeEntry(ComplexTypeEntryPrivate *d);
-};
-
-class FunctionTypeEntry : public TypeEntry
-{
-public:
- explicit FunctionTypeEntry(const QString& name, const QString& signature,
- const QVersionNumber &vr,
- const TypeEntry *parent);
-
- const QStringList &signatures() const;
- bool hasSignature(const QString& signature) const;
- void addSignature(const QString& signature);
-
- TypeSystem::SnakeCase snakeCase() const;
- void setSnakeCase(TypeSystem::SnakeCase sc);
-
- TypeEntry *clone() const override;
-
-#ifndef QT_NO_DEBUG_STREAM
- void formatDebug(QDebug &d) const override;
-#endif
-
-protected:
- explicit FunctionTypeEntry(FunctionTypeEntryPrivate *d);
-};
-
-class ObjectTypeEntry : public ComplexTypeEntry
-{
-public:
- explicit ObjectTypeEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- TypeEntry *clone() const override;
-
-protected:
- explicit ObjectTypeEntry(ComplexTypeEntryPrivate *d);
-};
-
-class CustomConversion
-{
-public:
- CustomConversion(TypeEntry* ownerType);
- ~CustomConversion();
-
- const TypeEntry* ownerType() const;
- QString nativeToTargetConversion() const;
- void setNativeToTargetConversion(const QString& nativeToTargetConversion);
-
- class TargetToNativeConversion
- {
- public:
- TargetToNativeConversion(const QString& sourceTypeName,
- const QString& sourceTypeCheck,
- const QString& conversion = QString());
- ~TargetToNativeConversion();
-
- const TypeEntry* sourceType() const;
- void setSourceType(const TypeEntry* sourceType);
- bool isCustomType() const;
- QString sourceTypeName() const;
- QString sourceTypeCheck() const;
- QString conversion() const;
- void setConversion(const QString& conversion);
- private:
- struct TargetToNativeConversionPrivate;
- TargetToNativeConversionPrivate* m_d;
- };
-
- /**
- * Returns true if the target to C++ custom conversions should
- * replace the original existing ones, and false if the custom
- * conversions should be added to the original.
- */
- bool replaceOriginalTargetToNativeConversions() const;
- void setReplaceOriginalTargetToNativeConversions(bool replaceOriginalTargetToNativeConversions);
-
- using TargetToNativeConversions = QList<TargetToNativeConversion *>;
- bool hasTargetToNativeConversions() const;
- TargetToNativeConversions& targetToNativeConversions();
- const TargetToNativeConversions& targetToNativeConversions() const;
- void addTargetToNativeConversion(const QString& sourceTypeName,
- const QString& sourceTypeCheck,
- const QString& conversion = QString());
-private:
- struct CustomConversionPrivate;
- CustomConversionPrivate* m_d;
-};
+/// Returns true if the type is an extended C++ primitive, a void*,
+/// a const char*, or a std::string (cf isCppPrimitive()).
+bool isExtendedCppPrimitive(const TypeEntryCPtr &e);
#endif // TYPESYSTEM_H
diff --git a/sources/shiboken6/ApiExtractor/typesystem_enums.h b/sources/shiboken6/ApiExtractor/typesystem_enums.h
index d2b719e85..9ecbb08a1 100644
--- a/sources/shiboken6/ApiExtractor/typesystem_enums.h
+++ b/sources/shiboken6/ApiExtractor/typesystem_enums.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TYPESYSTEM_ENUMS_H
#define TYPESYSTEM_ENUMS_H
@@ -43,10 +18,10 @@ enum Language {
};
enum class AllowThread {
+ Unspecified,
Allow,
Disallow,
- Auto,
- Unspecified
+ Auto
};
enum Ownership {
@@ -60,6 +35,7 @@ enum CodeSnipPosition {
CodeSnipPositionBeginning,
CodeSnipPositionEnd,
CodeSnipPositionDeclaration,
+ CodeSnipPositionPyOverride,
CodeSnipPositionAny
};
@@ -107,6 +83,29 @@ enum class CPythonType
Other
};
+enum class QtMetaTypeRegistration
+{
+ Unspecified,
+ Enabled,
+ BaseEnabled, // Registration only for the base class of a hierarchy
+ Disabled
+};
+
+enum class SmartPointerType {
+ Shared,
+ Unique,
+ Handle,
+ ValueHandle
+};
+
+enum class PythonEnumType {
+ Unspecified,
+ Enum,
+ IntEnum,
+ Flag,
+ IntFlag
+};
+
enum : int { OverloadNumberUnset = -1, OverloadNumberDefault = 99999 };
} // namespace TypeSystem
diff --git a/sources/shiboken6/ApiExtractor/typesystem_typedefs.h b/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
index e6edd3a68..5a4e12ff2 100644
--- a/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
+++ b/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
@@ -1,52 +1,79 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TYPESYSTEM_TYPEDEFS_H
#define TYPESYSTEM_TYPEDEFS_H
-#include <QtCore/QHash>
-#include <QtCore/QList>
-#include <QtCore/QSharedPointer>
#include <QtCore/QList>
-class CodeSnip;
-class DocModification;
+#include <memory>
-struct AddedFunction;
-class FieldModification;
-class FunctionModification;
+class ArrayTypeEntry;
+class ComplexTypeEntry;
+class ConfigurableTypeEntry;
+class ConstantValueTypeEntry;
+class ContainerTypeEntry;
+class CustomTypeEntry;
+class EnumTypeEntry;
+class EnumValueTypeEntry;
+class FlagsTypeEntry;
+class FunctionTypeEntry;
+class NamespaceTypeEntry;
+class ObjectTypeEntry;
+class PrimitiveTypeEntry;
+class SmartPointerTypeEntry;
+class TemplateEntry;
class TypeEntry;
+class TypedefEntry;
+class TypeSystemTypeEntry;
+class 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 = 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>;
+using SmartPointerTypeEntryList = QList<SmartPointerTypeEntryCPtr>;
+using TypeEntryList = QList<TypeEntryPtr>;
+using TypeEntryCList = QList<TypeEntryCPtr>;
-using AddedFunctionPtr = QSharedPointer<AddedFunction>;
-using AddedFunctionList = QList<AddedFunctionPtr>;
-using CodeSnipList = QList<CodeSnip>;
-using DocModificationList = QList<DocModification>;
-using FieldModificationList = QList<FieldModification>;
-using FunctionModificationList = QList<FunctionModification>;
-using TypeEntries = QList<const TypeEntry *>;
#endif // TYPESYSTEM_TYPEDEFS_H
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index a3730ef29..2b686e997 100644
--- a/sources/shiboken6/ApiExtractor/typesystemparser.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
@@ -1,38 +1,33 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "typesystemparser.h"
+// Copyright (C) 2019 The Qt Company Ltd.
+// 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 "flagstypeentry.h"
+#include "functiontypeentry.h"
+#include "namespacetypeentry.h"
+#include "objecttypeentry.h"
+#include "primitivetypeentry.h"
+#include "smartpointertypeentry.h"
+#include "typedefentry.h"
+#include "typesystemtypeentry.h"
+#include "valuetypeentry.h"
+#include "modifications.h"
#include "typedatabase.h"
#include "messages.h"
#include "reporthandler.h"
#include "sourcelocation.h"
#include "conditionalstreamreader.h"
+#include "qtcompat.h"
+
+#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
@@ -49,75 +44,103 @@
#include <optional>
#include <memory>
-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 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 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 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"); }
-
-static QList<CustomConversion *> customConversionsForReview;
+using namespace Qt::StringLiterals;
+
+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)
+{
+ return el >= StackElement::FirstTypeEntry && el <= StackElement::LastTypeEntry;
+}
+
+static bool isComplexTypeEntry(StackElement el)
+{
+ return el >= StackElement::FirstTypeEntry && el <= StackElement::LastComplexTypeEntry;
+}
+
+static bool isDocumentation(StackElement el)
+{
+ return el >= StackElement::FirstDocumentation && el <= StackElement::LastDocumentation;
+}
+
+static QList<CustomConversionPtr> customConversionsForReview;
// Set a regular expression for rejection from text. By legacy, those are fixed
// strings, except for '*' meaning 'match all'. Enclosing in "^..$"
@@ -127,12 +150,12 @@ static bool setRejectionRegularExpression(const QString &patternIn,
QString *errorMessage)
{
QString pattern;
- if (patternIn.startsWith(QLatin1Char('^')) && patternIn.endsWith(QLatin1Char('$')))
+ if (patternIn.startsWith(u'^') && patternIn.endsWith(u'$'))
pattern = patternIn;
- else if (patternIn == QLatin1String("*"))
- pattern = QStringLiteral("^.*$");
+ else if (patternIn == u"*")
+ pattern = "^.*$"_L1;
else
- pattern = QLatin1Char('^') + QRegularExpression::escape(patternIn) + QLatin1Char('$');
+ pattern = u'^' + QRegularExpression::escape(patternIn) + u'$';
re->setPattern(pattern);
if (!re->isValid()) {
*errorMessage = msgInvalidRegularExpression(patternIn, re->errorString());
@@ -141,78 +164,66 @@ 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());
bool useLine = false;
bool foundLabel = false;
QString result;
- const auto lines = QStringView{code}.split(QLatin1Char('\n'));
+ 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)
break; // End of snippet reached
} else if (useLine)
- result += line.toString() + QLatin1Char('\n');
+ result += line.toString() + u'\n';
}
if (!foundLabel)
return {};
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,
@@ -224,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,
@@ -235,7 +246,28 @@ 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)
+ {
+ {u"Enum", TypeSystem::PythonEnumType::Enum},
+ {u"IntEnum", TypeSystem::PythonEnumType::IntEnum},
+ {u"Flag", TypeSystem::PythonEnumType::Flag},
+ {u"IntFlag", TypeSystem::PythonEnumType::IntFlag},
+ };
+ENUM_LOOKUP_LINEAR_SEARCH
+
+ENUM_LOOKUP_BEGIN(TypeSystem::QtMetaTypeRegistration, Qt::CaseSensitive,
+ qtMetaTypeFromAttribute)
+ {
+ {u"yes", TypeSystem::QtMetaTypeRegistration::Enabled},
+ {u"true", TypeSystem::QtMetaTypeRegistration::Enabled},
+ {u"base", TypeSystem::QtMetaTypeRegistration::BaseEnabled},
+ {u"no", TypeSystem::QtMetaTypeRegistration::Disabled},
+ {u"false", TypeSystem::QtMetaTypeRegistration::Disabled},
+ };
+ENUM_LOOKUP_LINEAR_SEARCH
ENUM_LOOKUP_BEGIN(TypeSystem::Language, Qt::CaseInsensitive,
languageFromAttribute)
@@ -245,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)
@@ -254,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)
@@ -262,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)
@@ -270,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)
@@ -286,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)
@@ -294,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)
@@ -312,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)
@@ -321,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)
@@ -337,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)
@@ -351,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)
@@ -363,28 +396,61 @@ 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(StackElement::ElementType, Qt::CaseInsensitive,
- elementFromTag)
- {
- {u"add-conversion", StackElement::AddConversion}, // sorted!
+ENUM_LOOKUP_BEGIN(TypeSystem::SmartPointerType, Qt::CaseSensitive,
+ smartPointerTypeFromAttribute)
+{
+ {u"handle", TypeSystem::SmartPointerType::Handle},
+ {u"unique", TypeSystem::SmartPointerType::Unique},
+ {u"value-handle", TypeSystem::SmartPointerType::ValueHandle},
+ {u"shared", TypeSystem::SmartPointerType::Shared}
+};
+ENUM_LOOKUP_LINEAR_SEARCH
+
+template <class EnumType>
+static std::optional<EnumType>
+ lookupHashElement(const QHash<QStringView, EnumType> &hash,
+ QStringView needle, Qt::CaseSensitivity cs = Qt::CaseSensitive)
+{
+ auto end = hash.cend();
+ auto it = hash.constFind(needle);
+ if (it != end)
+ return it.value();
+ if (cs == Qt::CaseInsensitive) { // brute force search for the unlikely case mismatch
+ for (it = hash.cbegin(); it != end; ++it) {
+ if (it.key().compare(needle, cs) == 0)
+ return it.value();
+ }
+ }
+ return std::nullopt;
+}
+
+using StackElementHash = QHash<QStringView, StackElement>;
+
+static const StackElementHash &stackElementHash()
+{
+ static const StackElementHash result{
+ {u"add-conversion", StackElement::AddConversion},
{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::CustomMetaConstructor},
- {u"custom-destructor", StackElement::CustomMetaDestructor},
+ {u"custom-constructor", StackElement::Unimplemented},
+ {u"custom-destructor", StackElement::Unimplemented},
{u"custom-type", StackElement::CustomTypeEntry},
{u"declare-function", StackElement::DeclareFunction},
{u"define-ownership", StackElement::DefineOwnership},
{u"enum-type", StackElement::EnumTypeEntry},
{u"extra-includes", StackElement::ExtraIncludes},
{u"function", StackElement::FunctionTypeEntry},
+ {u"import-file", StackElement::ImportFile},
{u"include", StackElement::Include},
{u"inject-code", StackElement::InjectCode},
{u"inject-documentation", StackElement::InjectDocumentation},
- {u"insert-template", StackElement::TemplateInstanceEnum},
+ {u"insert-template", StackElement::InsertTemplate},
{u"interface-type", StackElement::InterfaceTypeEntry},
{u"load-typesystem", StackElement::LoadTypesystem},
{u"modify-argument", StackElement::ModifyArgument},
@@ -395,6 +461,7 @@ ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
{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},
@@ -416,8 +483,30 @@ ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive,
{u"typesystem", StackElement::Root},
{u"value-type", StackElement::ValueTypeEntry},
};
-ENUM_LOOKUP_BINARY_SEARCH()
+ return result;
+}
+static std::optional<StackElement> elementFromTag(QStringView needle)
+{
+ return lookupHashElement(stackElementHash(), needle,
+ Qt::CaseInsensitive); // FIXME PYSIDE-7: case sensitive
+}
+
+static QStringView tagFromElement(StackElement st)
+{
+ return stackElementHash().key(st);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug d, StackElement st)
+{
+ QDebugStateSaver saver(d);
+ d.noquote();
+ d.nospace();
+ d << tagFromElement(st);
+ return d;
+}
+#endif // QT_NO_DEBUG_STREAM
ENUM_LOOKUP_BEGIN(TypeSystem::SnakeCase, Qt::CaseSensitive,
snakeCaseFromAttribute)
@@ -428,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)
@@ -439,12 +528,12 @@ 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 (int i = 0, size = atts.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = atts.size(); i < size; ++i) {
if (atts.at(i).qualifiedName() == name)
return i;
}
@@ -453,8 +542,8 @@ static int indexOfAttribute(const QXmlStreamAttributes &atts,
static QString msgMissingAttribute(const QString &a)
{
- return QLatin1String("Required attribute '") + a
- + QLatin1String("' missing.");
+ return u"Required attribute '"_s + a
+ + u"' missing."_s;
}
QTextStream &operator<<(QTextStream &str, const QXmlStreamAttribute &attribute)
@@ -475,7 +564,7 @@ static QString msgUnusedAttributes(QStringView tag, const QXmlStreamAttributes &
QString result;
QTextStream str(&result);
str << attributes.size() << " attributes(s) unused on <" << tag << ">: ";
- for (int i = 0, size = attributes.size(); i < size; ++i) {
+ for (qsizetype i = 0, size = attributes.size(); i < size; ++i) {
if (i)
str << ", ";
str << attributes.at(i);
@@ -502,25 +591,25 @@ private:
QString TypeSystemEntityResolver::readFile(const QString &entityName, QString *errorMessage) const
{
QString fileName = entityName;
- if (!fileName.contains(QLatin1Char('.')))
- fileName += QLatin1String(".xml");
+ if (!fileName.contains(u'.'))
+ fileName += u".xml"_s;
QString path = TypeDatabase::instance()->modifiedTypesystemFilepath(fileName, m_currentPath);
if (!QFileInfo::exists(path)) // PySide6-specific hack
- fileName.prepend(QLatin1String("typesystem_"));
+ fileName.prepend(u"typesystem_"_s);
path = TypeDatabase::instance()->modifiedTypesystemFilepath(fileName, m_currentPath);
if (!QFileInfo::exists(path)) {
- *errorMessage = QLatin1String("Unable to resolve: ") + entityName;
- return QString();
+ *errorMessage = u"Unable to resolve: "_s + entityName;
+ 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
- if (result.startsWith(QLatin1String("<!--"))) {
- const int commentEnd = result.indexOf(QLatin1String("-->"));
+ if (result.startsWith(u"<!--")) {
+ const auto commentEnd = result.indexOf(u"-->");
if (commentEnd != -1) {
result.remove(0, commentEnd + 3);
result = result.trimmed();
@@ -540,8 +629,24 @@ QString TypeSystemEntityResolver::resolveUndeclaredEntity(const QString &name)
return result;
}
-TypeSystemParser::TypeSystemParser(TypeDatabase *database, bool generate) :
- m_database(database),
+// State depending on element stack
+enum class ParserState
+{
+ None,
+ PrimitiveTypeNativeToTargetConversion,
+ PrimitiveTypeTargetToNativeConversion,
+ ArgumentConversion, // Argument conversion rule with class attribute
+ ArgumentNativeToTargetConversion,
+ ArgumentTargetToNativeConversion,
+ FunctionCodeInjection,
+ TypeEntryCodeInjection,
+ TypeSystemCodeInjection,
+ Template
+};
+
+TypeSystemParser::TypeSystemParser(const std::shared_ptr<TypeDatabaseParserContext> &context,
+ bool generate) :
+ m_context(context),
m_generate(generate ? TypeEntry::GenerateCode : TypeEntry::GenerateForSubclass)
{
}
@@ -582,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
@@ -607,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
@@ -624,21 +729,22 @@ static inline
attribute.value());
}
-static bool addRejection(TypeDatabase *database, QXmlStreamAttributes *attributes,
+static bool addRejection(TypeDatabase *database, bool generate, QXmlStreamAttributes *attributes,
QString *errorMessage)
{
- const int 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;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto &attribute = attributes->at(i);
const auto name = attribute.qualifiedName();
const auto typeOpt = typeRejectionFromAttribute(name);
@@ -665,9 +771,9 @@ static bool addRejection(TypeDatabase *database, QXmlStreamAttributes *attribute
}
// Special case: When all fields except class are empty, completely exclude class
- if (className == QLatin1String("*")) {
- *errorMessage = QLatin1String("bad reject entry, neither 'class', 'function-name'"
- " nor 'field' specified");
+ if (className == u"*") {
+ *errorMessage = u"bad reject entry, neither 'class', 'function-name'"
+ " nor 'field' specified"_s;
return false;
}
rejection.matchType = TypeRejection::ExcludeClass;
@@ -680,10 +786,7 @@ bool TypeSystemParser::parse(ConditionalStreamReader &reader)
m_error.clear();
m_currentPath.clear();
m_currentFile.clear();
- m_smartPointerInstantiations.clear();
- const bool result = parseXml(reader) && setupSmartPointerInstantiations();
- m_smartPointerInstantiations.clear();
- return result;
+ return parseXml(reader);
}
bool TypeSystemParser::parseXml(ConditionalStreamReader &reader)
@@ -703,18 +806,25 @@ bool TypeSystemParser::parseXml(ConditionalStreamReader &reader)
case QXmlStreamReader::Invalid:
m_error = msgReaderError(reader, reader.errorString());
return false;
- case QXmlStreamReader::StartElement:
- if (!startElement(reader)) {
+ case QXmlStreamReader::StartElement: {
+ const auto elementTypeOpt = elementFromTag(reader.name());
+ if (!elementTypeOpt.has_value()) {
+ m_error = u"Unknown tag name: '"_s + reader.name().toString() + u'\'';
+ return false;
+ }
+ m_stack.push(elementTypeOpt.value());
+ if (!startElement(reader, m_stack.top())) {
m_error = msgReaderError(reader, m_error);
return false;
}
-
+ }
break;
case QXmlStreamReader::EndElement:
- if (!endElement(reader.name())) {
+ if (!endElement(m_stack.top())) {
m_error = msgReaderError(reader, m_error);
return false;
}
+ m_stack.pop();
break;
case QXmlStreamReader::Characters:
if (!characters(reader.text())) {
@@ -734,326 +844,302 @@ bool TypeSystemParser::parseXml(ConditionalStreamReader &reader)
return true;
}
-// Split a type list potentially with template types
-// "A<B,C>,D" -> ("A<B,C>", "D")
-static QStringList splitTypeList(const QString &s)
-{
- QStringList result;
- int templateDepth = 0;
- int lastPos = 0;
- const int size = s.size();
- for (int i = 0; i < size; ++i) {
- switch (s.at(i).toLatin1()) {
- case '<':
- ++templateDepth;
- break;
- case '>':
- --templateDepth;
- break;
- case ',':
- if (templateDepth == 0) {
- result.append(s.mid(lastPos, i - lastPos).trimmed());
- lastPos = i + 1;
- }
- break;
- }
- }
- if (lastPos < size)
- result.append(s.mid(lastPos, size - lastPos).trimmed());
- return result;
-}
-
-bool TypeSystemParser::setupSmartPointerInstantiations()
-{
- for (auto it = m_smartPointerInstantiations.cbegin(),
- end = m_smartPointerInstantiations.cend(); it != end; ++it) {
- auto smartPointerEntry = it.key();
- const auto instantiationNames = splitTypeList(it.value());
- SmartPointerTypeEntry::Instantiations instantiations;
- instantiations.reserve(instantiationNames.size());
- for (const auto &instantiationName : instantiationNames) {
- const auto types = m_database->findCppTypes(instantiationName);
- if (types.isEmpty()) {
- m_error =
- msgCannotFindTypeEntryForSmartPointer(instantiationName,
- smartPointerEntry->name());
- return false;
- }
- if (types.size() > 1) {
- m_error = msgAmbiguousTypesFound(instantiationName, types);
- return false;
- }
- instantiations.append(types.constFirst());
- }
- smartPointerEntry->setInstantiations(instantiations);
- }
- return true;
-}
-
-bool TypeSystemParser::endElement(QStringView localName)
+bool TypeSystemParser::endElement(StackElement element)
{
if (m_ignoreDepth) {
--m_ignoreDepth;
return true;
}
- if (m_currentDroppedEntry) {
- if (m_currentDroppedEntryDepth == 1) {
- m_current = m_currentDroppedEntry->parent;
- delete m_currentDroppedEntry;
- m_currentDroppedEntry = nullptr;
- m_currentDroppedEntryDepth = 0;
- } else {
- --m_currentDroppedEntryDepth;
- }
+ if (m_currentDroppedEntryDepth != 0) {
+ --m_currentDroppedEntryDepth;
return true;
}
- if (!localName.compare(QLatin1String("import-file"), Qt::CaseInsensitive))
+ if (element == StackElement::ImportFile)
return true;
- if (!m_current)
+ if (m_contextStack.isEmpty())
return true;
- switch (m_current->type) {
+ const auto &top = m_contextStack.top();
+
+ switch (element) {
+ case StackElement::Unimplemented:
+ return true;
case StackElement::Root:
if (m_generate == TypeEntry::GenerateCode) {
- TypeDatabase::instance()->addGlobalUserFunctions(m_contextStack.top()->addedFunctions);
- TypeDatabase::instance()->addGlobalUserFunctionModifications(m_contextStack.top()->functionMods);
- for (CustomConversion *customConversion : qAsConst(customConversionsForReview)) {
- const CustomConversion::TargetToNativeConversions &toNatives = customConversion->targetToNativeConversions();
- for (CustomConversion::TargetToNativeConversion *toNative : toNatives)
- toNative->setSourceType(m_database->findType(toNative->sourceTypeName()));
+ TypeDatabase::instance()->addGlobalUserFunctions(top->addedFunctions);
+ TypeDatabase::instance()->addGlobalUserFunctionModifications(top->functionMods);
+ for (const auto &customConversion : std::as_const(customConversionsForReview)) {
+ TargetToNativeConversions &toNatives =
+ customConversion->targetToNativeConversions();
+ for (auto &toNative : toNatives)
+ toNative.setSourceType(m_context->db->findType(toNative.sourceTypeName()));
}
}
+ purgeEmptyCodeSnips(&std::static_pointer_cast<TypeSystemTypeEntry>(top->entry)->codeSnips());
+ break;
+ case StackElement::FunctionTypeEntry:
+ TypeDatabase::instance()->addGlobalUserFunctionModifications(top->functionMods);
break;
case StackElement::ObjectTypeEntry:
case StackElement::ValueTypeEntry:
case StackElement::InterfaceTypeEntry:
case StackElement::ContainerTypeEntry:
case StackElement::NamespaceTypeEntry: {
- auto *centry = static_cast<ComplexTypeEntry *>(m_current->entry);
- auto top = m_contextStack.top();
+ Q_ASSERT(top->entry);
+ Q_ASSERT(top->entry->isComplex());
+ auto centry = std::static_pointer_cast<ComplexTypeEntry>(top->entry);
+ purgeEmptyCodeSnips(&centry->codeSnips());
centry->setAddedFunctions(top->addedFunctions);
centry->setFunctionModifications(top->functionMods);
centry->setFieldModifications(top->fieldMods);
- centry->setCodeSnips(top->codeSnips);
centry->setDocModification(top->docModifications);
}
break;
case StackElement::TypedefTypeEntry: {
- auto *centry = static_cast<TypedefEntry *>(m_current->entry)->target();
- auto top = m_contextStack.top();
+ 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->setCodeSnips(centry->codeSnips() + top->codeSnips);
centry->setDocModification(centry->docModifications() + top->docModifications);
+ if (top->entry->isComplex()) {
+ auto cte = std::static_pointer_cast<const ComplexTypeEntry>(top->entry);
+ centry->setCodeSnips(centry->codeSnips() + cte->codeSnips());
+ }
}
break;
- case StackElement::AddFunction: {
+ case StackElement::AddFunction:
+ case StackElement::DeclareFunction: {
// Leaving add-function: Assign all modifications to the added function
- StackElementContext *top = m_contextStack.top();
const int modIndex = top->addedFunctionModificationIndex;
top->addedFunctionModificationIndex = -1;
Q_ASSERT(modIndex >= 0);
Q_ASSERT(!top->addedFunctions.isEmpty());
while (modIndex < top->functionMods.size())
- top->addedFunctions.last()->modifications.append(top->functionMods.takeAt(modIndex));
+ top->addedFunctions.last()->modifications().append(top->functionMods.takeAt(modIndex));
}
- break;
+ break;
case StackElement::NativeToTarget:
- case StackElement::AddConversion: {
- CustomConversion* customConversion = static_cast<TypeEntry*>(m_current->entry)->customConversion();
- if (!customConversion) {
- m_error = QLatin1String("CustomConversion object is missing.");
- return false;
- }
-
- QString code = m_contextStack.top()->codeSnips.takeLast().code();
- if (m_current->type == StackElement::AddConversion) {
- if (customConversion->targetToNativeConversions().isEmpty()) {
- m_error = QLatin1String("CustomConversion's target to native conversions missing.");
+ case StackElement::AddConversion:
+ switch (parserState()) {
+ case ParserState::PrimitiveTypeNativeToTargetConversion:
+ case ParserState::PrimitiveTypeTargetToNativeConversion: {
+ auto customConversion = CustomConversion::getCustomConversion(top->entry);
+ if (!customConversion) {
+ m_error = msgMissingCustomConversion(top->entry);
return false;
}
- customConversion->targetToNativeConversions().last()->setConversion(code);
- } else {
- customConversion->setNativeToTargetConversion(code);
- }
- }
- break;
- case StackElement::CustomMetaConstructor: {
- m_current->entry->setCustomConstructor(*m_current->value.customFunction);
- delete m_current->value.customFunction;
- }
- break;
- case StackElement::CustomMetaDestructor: {
- m_current->entry->setCustomDestructor(*m_current->value.customFunction);
- delete m_current->value.customFunction;
- }
- break;
- case StackElement::EnumTypeEntry:
- m_current->entry->setDocModification(m_contextStack.top()->docModifications);
- m_contextStack.top()->docModifications = DocModificationList();
- m_currentEnum = nullptr;
- break;
- case StackElement::Template:
- m_database->addTemplate(m_current->value.templateEntry);
- break;
- case StackElement::TemplateInstanceEnum:
- switch (m_current->parent->type) {
- case StackElement::InjectCode:
- if (m_current->parent->parent->type == StackElement::Root) {
- CodeSnipList snips = m_current->parent->entry->codeSnips();
- CodeSnip snip = snips.takeLast();
- TemplateInstancePtr ti(m_current->value.templateInstance);
- snip.addTemplateInstance(ti);
- snips.append(snip);
- m_current->parent->entry->setCodeSnips(snips);
- break;
+ QString code = top->conversionCodeSnips.constLast().code();
+ if (element == StackElement::AddConversion) {
+ if (customConversion->targetToNativeConversions().isEmpty()) {
+ m_error = u"CustomConversion's target to native conversions missing."_s;
+ return false;
+ }
+ customConversion->targetToNativeConversions().last().setConversion(code);
+ } else {
+ customConversion->setNativeToTargetConversion(code);
}
- Q_FALLTHROUGH();
- case StackElement::NativeToTarget:
- case StackElement::AddConversion: {
- TemplateInstancePtr ti(m_current->value.templateInstance);
- m_contextStack.top()->codeSnips.last().addTemplateInstance(ti);
- }
- break;
- case StackElement::Template: {
- TemplateInstancePtr ti(m_current->value.templateInstance);
- m_current->parent->value.templateEntry->addTemplateInstance(ti);
- }
- break;
- case StackElement::CustomMetaConstructor:
- case StackElement::CustomMetaDestructor: {
- TemplateInstancePtr ti(m_current->value.templateInstance);
- m_current->parent->value.customFunction->addTemplateInstance(ti);
}
break;
- case StackElement::ConversionRule: {
- TemplateInstancePtr ti(m_current->value.templateInstance);
- m_contextStack.top()->functionMods.last().argument_mods().last().conversionRules().last().addTemplateInstance(ti);
+
+ case ParserState::ArgumentNativeToTargetConversion: {
+ top->conversionCodeSnips.last().language = TypeSystem::TargetLangCode;
+ auto &lastArgMod = m_contextStack.top()->functionMods.last().argument_mods().last();
+ lastArgMod.conversionRules().append(top->conversionCodeSnips.constLast());
}
break;
- case StackElement::InjectCodeInFunction: {
- TemplateInstancePtr ti(m_current->value.templateInstance);
- m_contextStack.top()->functionMods.last().snips().last().addTemplateInstance(ti);
+ case ParserState::ArgumentTargetToNativeConversion: {
+ top->conversionCodeSnips.last().language = TypeSystem::NativeCode;
+ auto &lastArgMod = m_contextStack.top()->functionMods.last().argument_mods().last();
+ lastArgMod.conversionRules().append(top->conversionCodeSnips.constLast());
}
break;
default:
- break; // nada
+ break;
}
+ top->conversionCodeSnips.clear();
+ break;
+
+ case StackElement::EnumTypeEntry:
+ m_currentEnum = nullptr;
break;
+ case StackElement::Template:
+ m_context->db->addTemplate(m_templateEntry);
+ m_templateEntry = nullptr;
+ break;
+ case StackElement::InsertTemplate:
+ if (auto *snip = injectCodeTarget(1))
+ snip->addTemplateInstance(m_templateInstance);
+ m_templateInstance.reset();
+ break;
+
+ case StackElement::ModifyArgument:
+ purgeEmptyCodeSnips(&top->functionMods.last().argument_mods().last().conversionRules());
+ break;
+
default:
break;
}
- switch (m_current->type) {
- case StackElement::Root:
- case StackElement::NamespaceTypeEntry:
- case StackElement::InterfaceTypeEntry:
- case StackElement::ObjectTypeEntry:
- case StackElement::ValueTypeEntry:
- case StackElement::PrimitiveTypeEntry:
- case StackElement::TypedefTypeEntry:
- case StackElement::ContainerTypeEntry:
- delete m_contextStack.pop();
+ if (isTypeEntry(element) || element == StackElement::Root)
+ m_contextStack.pop();
+
+ return true;
+}
+
+ParserState TypeSystemParser::parserState(qsizetype offset) const
+{
+ const auto stackSize = m_stack.size() - offset;
+ if (stackSize <= 0 || m_contextStack.isEmpty())
+ return ParserState::None;
+
+ const auto last = stackSize - 1;
+
+ switch (m_stack.at(last)) {
+ // Primitive entry with conversion rule
+ case StackElement::NativeToTarget: // <conversion-rule><native-to-target>
+ if (stackSize > 2 && m_stack.at(last - 2) == StackElement::ModifyArgument)
+ return ParserState::ArgumentNativeToTargetConversion;
+ return ParserState::PrimitiveTypeNativeToTargetConversion;
+
+ case StackElement::AddConversion: // <conversion-rule><target-to-native><add-conversion>
+ if (stackSize > 3 && m_stack.at(last - 3) == StackElement::ModifyArgument)
+ return ParserState::ArgumentTargetToNativeConversion;
+ return ParserState::PrimitiveTypeTargetToNativeConversion;
+
+ case StackElement::ConversionRule:
+ if (stackSize > 1 && m_stack.at(last - 1) == StackElement::ModifyArgument)
+ return ParserState::ArgumentConversion;
break;
+
+ case StackElement::InjectCode:
+ switch (m_stack.value(last - 1, StackElement::None)) {
+ case StackElement::Root:
+ return ParserState::TypeSystemCodeInjection;
+ case StackElement::ModifyFunction:
+ case StackElement::AddFunction:
+ return ParserState::FunctionCodeInjection;
+ case StackElement::NamespaceTypeEntry:
+ case StackElement::ObjectTypeEntry:
+ case StackElement::ValueTypeEntry:
+ case StackElement::InterfaceTypeEntry:
+ return ParserState::TypeEntryCodeInjection;
+ default:
+ break;
+ }
+ break;
+
+ case StackElement::Template:
+ return ParserState::Template;
+
default:
break;
}
- StackElement *child = m_current;
- m_current = m_current->parent;
- delete(child);
+ return ParserState::None;
+}
- return true;
+// Return where to add injected code depending on elements.
+CodeSnipAbstract *TypeSystemParser::injectCodeTarget(qsizetype offset) const
+{
+ const auto state = parserState(offset);
+ if (state == ParserState::None)
+ return nullptr;
+
+ const auto &top = m_contextStack.top();
+ switch (state) {
+ case ParserState::PrimitiveTypeNativeToTargetConversion:
+ case ParserState::PrimitiveTypeTargetToNativeConversion:
+ case ParserState::ArgumentNativeToTargetConversion:
+ case ParserState::ArgumentTargetToNativeConversion:
+ return &top->conversionCodeSnips.last();
+ case ParserState::ArgumentConversion:
+ return &top->functionMods.last().argument_mods().last().conversionRules().last();
+ case ParserState::FunctionCodeInjection: {
+ auto &funcMod = top->functionMods.last();
+ funcMod.setModifierFlag(FunctionModification::CodeInjection);
+ return &funcMod.snips().last();
+ }
+ case ParserState::TypeEntryCodeInjection:
+ Q_ASSERT(top->entry->isComplex());
+ return &std::static_pointer_cast<ComplexTypeEntry>(top->entry)->codeSnips().last();
+ case ParserState::TypeSystemCodeInjection:
+ Q_ASSERT(top->entry->isTypeSystem());
+ return &std::static_pointer_cast<TypeSystemTypeEntry>(top->entry)->codeSnips().last();
+ case ParserState::Template:
+ return m_templateEntry.get();
+ default:
+ break;
+ }
+
+ return nullptr;
}
template <class String> // QString/QStringRef
bool TypeSystemParser::characters(const String &ch)
{
- if (m_currentDroppedEntry || m_ignoreDepth)
- return true;
-
- if (m_current->type == StackElement::Template) {
- m_current->value.templateEntry->addCode(ch);
+ const auto stackSize = m_stack.size();
+ if (m_currentDroppedEntryDepth != 0 || m_ignoreDepth != 0
+ || stackSize == 0 || m_stack.top() == StackElement::Unimplemented) {
return true;
}
- if (m_current->type == StackElement::CustomMetaConstructor || m_current->type == StackElement::CustomMetaDestructor) {
- m_current->value.customFunction->addCode(ch);
- return true;
- }
+ const StackElement type = m_stack.top();
- if (m_current->type == StackElement::ConversionRule
- && m_current->parent->type == StackElement::ModifyArgument) {
- m_contextStack.top()->functionMods.last().argument_mods().last().conversionRules().last().addCode(ch);
+ if (type == StackElement::Template) {
+ m_templateEntry->addCode(ch);
return true;
}
- if (m_current->type == StackElement::NativeToTarget || m_current->type == StackElement::AddConversion) {
- m_contextStack.top()->codeSnips.last().addCode(ch);
- return true;
+ if (m_contextStack.isEmpty()) {
+ m_error = msgNoRootTypeSystemEntry();
+ return false;
}
- if (m_current->parent) {
- if ((m_current->type & StackElement::CodeSnipMask)) {
- CodeSnipList snips;
- switch (m_current->parent->type) {
- case StackElement::Root:
- snips = m_current->parent->entry->codeSnips();
- snips.last().addCode(ch);
- m_current->parent->entry->setCodeSnips(snips);
- break;
- case StackElement::ModifyFunction:
- case StackElement::AddFunction:
- m_contextStack.top()->functionMods.last().snips().last().addCode(ch);
- m_contextStack.top()->functionMods.last().setModifierFlag(FunctionModification::CodeInjection);
- break;
- case StackElement::NamespaceTypeEntry:
- case StackElement::ObjectTypeEntry:
- case StackElement::ValueTypeEntry:
- case StackElement::InterfaceTypeEntry:
- m_contextStack.top()->codeSnips.last().addCode(ch);
- break;
- default:
- Q_ASSERT(false);
- }
- return true;
- }
+ if (auto *snip = injectCodeTarget()) {
+ snip->addCode(ch);
+ return true;
}
- if (m_current->type & StackElement::DocumentationMask)
- m_contextStack.top()->docModifications.last().setCode(ch);
+ if (isDocumentation(type)) {
+ const bool isAddedFunction = m_stack.value(m_stack.size() - 2, StackElement::None)
+ == StackElement::AddFunction;
+ const auto &top = m_contextStack.top();
+ auto &docModifications = isAddedFunction
+ ? top->addedFunctions.last()->docModifications()
+ : top->docModifications;
+ docModifications.last().setCode(ch);
+ }
return true;
}
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 = QLatin1String("Required attribute 'name' missing for include-file tag.");
+ m_error = u"Required attribute 'name' missing for include-file tag."_s;
return false;
}
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- file.setFileName(QLatin1String(":/trolltech/generator/") + fileName);
+ file.setFileName(u":/trolltech/generator/"_s + fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
m_error = msgCannotOpenForReading(file);
return false;
}
}
- 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;
@@ -1066,69 +1152,67 @@ bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts)
break;
}
if (from && to)
- characters(line + QLatin1Char('\n'));
+ characters(line + u'\n');
if (!from && line.contains(quoteFrom)) {
from = true;
foundFromOk = true;
}
}
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;
if (!foundFromOk)
m_error = fromError;
if (!foundFromOk && !foundToOk)
- m_error = fromError + QLatin1Char(' ') + toError;
+ m_error = fromError + u' ' + toError;
return false;
}
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
// name (match 'Class' and 'Module.Class').
static bool shouldDropTypeEntry(const TypeDatabase *db,
- const StackElement *element,
+ const TypeSystemParser::ContextStack &stack ,
QString name)
{
- for (auto e = element->parent; e ; e = e->parent) {
- if (e->entry) {
- if (e->entry->type() == TypeEntry::TypeSystemType) {
+ for (auto i = stack.size() - 1; i >= 0; --i) {
+ if (auto entry = stack.at(i)->entry) {
+ if (entry->type() == TypeEntry::TypeSystemType) {
if (db->shouldDropTypeEntry(name)) // Unqualified
return true;
}
- name.prepend(QLatin1Char('.'));
- name.prepend(e->entry->name());
+ name.prepend(u'.');
+ name.prepend(entry->name());
}
}
return db->shouldDropTypeEntry(name);
@@ -1137,10 +1221,10 @@ static bool shouldDropTypeEntry(const TypeDatabase *db,
// Returns empty string if there's no error.
static QString checkSignatureError(const QString& signature, const QString& tag)
{
- QString funcName = signature.left(signature.indexOf(QLatin1Char('('))).trimmed();
- static const QRegularExpression whiteSpace(QStringLiteral("\\s"));
+ QString funcName = signature.left(signature.indexOf(u'(')).trimmed();
+ static const QRegularExpression whiteSpace("\\s"_L1);
Q_ASSERT(whiteSpace.isValid());
- if (!funcName.startsWith(QLatin1String("operator ")) && funcName.contains(whiteSpace)) {
+ if (!funcName.startsWith(u"operator ") && funcName.contains(whiteSpace)) {
return QString::fromLatin1("Error in <%1> tag signature attribute '%2'.\n"
"White spaces aren't allowed in function names, "
"and return types should not be part of the signature.")
@@ -1149,20 +1233,24 @@ static QString checkSignatureError(const QString& signature, const QString& tag)
return QString();
}
-inline const TypeEntry *TypeSystemParser::currentParentTypeEntry() const
+inline TypeEntryCPtr TypeSystemParser::currentParentTypeEntry() const
{
- return m_current ? m_current->entry : nullptr;
+ const auto size = m_contextStack.size();
+ return size > 1 ? m_contextStack.at(size - 2)->entry : nullptr;
}
bool TypeSystemParser::checkRootElement()
{
- const bool ok = currentParentTypeEntry() != nullptr;
- if (!ok)
- m_error = msgNoRootTypeSystemEntry();
- return ok;
+ for (auto i = m_contextStack.size() - 1; i >= 0; --i) {
+ auto e = m_contextStack.at(i)->entry;
+ if (e && e->isTypeSystem())
+ return true;
+ }
+ m_error = msgNoRootTypeSystemEntry();
+ return false;
}
-static TypeEntry *findViewedType(const QString &name)
+static TypeEntryPtr findViewedType(const QString &name)
{
const auto range = TypeDatabase::instance()->entries().equal_range(name);
for (auto i = range.first; i != range.second; ++i) {
@@ -1179,20 +1267,21 @@ static TypeEntry *findViewedType(const QString &name)
return nullptr;
}
-bool TypeSystemParser::applyCommonAttributes(const ConditionalStreamReader &reader, TypeEntry *type,
+bool TypeSystemParser::applyCommonAttributes(const ConditionalStreamReader &reader,
+ const TypeEntryPtr &type,
QXmlStreamAttributes *attributes)
{
type->setSourceLocation(SourceLocation(m_currentFile,
reader.lineNumber()));
type->setCodeGeneration(m_generate);
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
if (name == u"revision") {
type->setRevision(attributes->takeAt(i).value().toInt());
} else if (name == u"view-on") {
const QString name = attributes->takeAt(i).value().toString();
- TypeEntry *views = findViewedType(name);
- if (views == nullptr) {
+ TypeEntryPtr views = findViewedType(name);
+ if (!views) {
m_error = msgCannotFindView(name, type->name());
return false;
}
@@ -1202,61 +1291,62 @@ bool TypeSystemParser::applyCommonAttributes(const ConditionalStreamReader &read
return true;
}
-CustomTypeEntry *TypeSystemParser::parseCustomTypeEntry(const ConditionalStreamReader &,
+CustomTypeEntryPtr TypeSystemParser::parseCustomTypeEntry(const ConditionalStreamReader &,
const QString &name,
const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- auto *result = new CustomTypeEntry(name, since, m_current->entry);
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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;
}
-FlagsTypeEntry *
+FlagsTypeEntryPtr
TypeSystemParser::parseFlagsEntry(const ConditionalStreamReader &reader,
- EnumTypeEntry *enumEntry, QString flagName,
+ const EnumTypeEntryPtr &enumEntry, QString flagName,
const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- auto ftype = new FlagsTypeEntry(QLatin1String("QFlags<") + enumEntry->name() + QLatin1Char('>'),
- since,
- currentParentTypeEntry()->typeSystemTypeEntry());
+ 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());
- const QString targetLangFlagName = QStringList(lst.mid(0, lst.size() - 1)).join(QLatin1Char('.'));
+ 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.constFirst(), targetLangFlagName);
+ qCWarning(lcShiboken, "enum %s and flags %s (%s) differ in qualifiers",
+ qPrintable(targetLangQualifier), qPrintable(lst.value(0)),
+ qPrintable(targetLangFlagName));
}
- ftype->setFlagsName(lst.constLast());
+ ftype->setFlagsName(name);
enumEntry->setFlags(ftype);
- m_database->addFlagsType(ftype);
- m_database->addType(ftype);
+ m_context->db->addFlagsType(ftype);
+ m_context->db->addType(ftype);
const int revisionIndex =
indexOfAttribute(*attributes, u"flags-revision");
@@ -1266,195 +1356,259 @@ FlagsTypeEntry *
return ftype;
}
-SmartPointerTypeEntry *
+SmartPointerTypeEntryPtr
TypeSystemParser::parseSmartPointerEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- QString smartPointerType;
+ TypeSystem::SmartPointerType smartPointerType = TypeSystem::SmartPointerType::Shared;
QString getter;
QString refCountMethodName;
+ QString valueCheckMethod;
+ QString nullCheckMethod;
+ QString resetMethod;
QString instantiations;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("type")) {
- smartPointerType = attributes->takeAt(i).value().toString();
- } else if (name == QLatin1String("getter")) {
+ if (name == u"type") {
+ const auto attribute = attributes->takeAt(i);
+ const auto typeOpt = smartPointerTypeFromAttribute(attribute.value());
+ if (!typeOpt.has_value()) {
+ m_error = msgInvalidAttributeValue(attribute);
+ return nullptr;
+ }
+ smartPointerType = typeOpt.value();
+ } else if (name == u"getter") {
getter = attributes->takeAt(i).value().toString();
- } else if (name == QLatin1String("ref-count-method")) {
+ } else if (name == u"ref-count-method") {
refCountMethodName = attributes->takeAt(i).value().toString();
- } else if (name == QLatin1String("instantiations")) {
+ } else if (name == u"instantiations") {
instantiations = attributes->takeAt(i).value().toString();
+ } else if (name == u"value-check-method") {
+ valueCheckMethod = attributes->takeAt(i).value().toString();
+ } else if (name == u"null-check-method") {
+ nullCheckMethod = attributes->takeAt(i).value().toString();
+ } else if (name == u"reset-method") {
+ resetMethod = attributes->takeAt(i).value().toString();
}
}
- if (smartPointerType.isEmpty()) {
- m_error = QLatin1String("No type specified for the smart pointer. Currently supported types: 'shared',");
- return nullptr;
- }
- if (smartPointerType != QLatin1String("shared")) {
- m_error = QLatin1String("Currently only the 'shared' type is supported.");
- return nullptr;
- }
-
if (getter.isEmpty()) {
- m_error = QLatin1String("No function getter name specified for getting the raw pointer held by the smart pointer.");
+ m_error = u"No function getter name specified for getting the raw pointer held by the smart pointer."_s;
return nullptr;
}
- QString signature = getter + QLatin1String("()");
+ QString signature = getter + u"()"_s;
signature = TypeDatabase::normalizedSignature(signature);
if (signature.isEmpty()) {
- m_error = QLatin1String("No signature for the smart pointer getter found.");
+ m_error = u"No signature for the smart pointer getter found."_s;
return nullptr;
}
QString errorString = checkSignatureError(signature,
- QLatin1String("smart-pointer-type"));
+ u"smart-pointer-type"_s);
if (!errorString.isEmpty()) {
m_error = errorString;
return nullptr;
}
- auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType,
- refCountMethodName, since, currentParentTypeEntry());
+ if (smartPointerType == TypeSystem::SmartPointerType::Unique && resetMethod.isEmpty()) {
+ m_error = u"Unique pointers require a reset() method."_s;
+ return nullptr;
+ }
+
+ auto type = std::make_shared<SmartPointerTypeEntry>(name, getter, smartPointerType,
+ refCountMethodName, since,
+ currentParentTypeEntry());
if (!applyCommonAttributes(reader, type, attributes))
return nullptr;
- m_smartPointerInstantiations.insert(type, instantiations);
+ applyComplexTypeAttributes(reader, type, attributes);
+ type->setNullCheckMethod(nullCheckMethod);
+ type->setValueCheckMethod(valueCheckMethod);
+ type->setResetMethod(resetMethod);
+ m_context->smartPointerInstantiations.insert(type, instantiations);
return type;
}
-PrimitiveTypeEntry *
+PrimitiveTypeEntryPtr
TypeSystemParser::parsePrimitiveTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- auto *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 (int i = attributes->size() - 1; i >= 0; --i) {
+ 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 == QLatin1String("target-lang-api-name")) {
+ } 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 == QLatin1String("default-constructor")) {
+ } else if (name == u"default-constructor") {
type->setDefaultConstructor(attributes->takeAt(i).value().toString());
}
}
if (!targetLangApiName.isEmpty()) {
- auto *e = m_database->findType(targetLangApiName);
- if (e == nullptr || !e->isCustom()) {
+ auto e = m_context->db->findType(targetLangApiName);
+ if (!e || !e->isCustom()) {
m_error = msgInvalidTargetLanguageApiName(targetLangApiName);
return nullptr;
}
- type->setTargetLangApiType(static_cast<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, ContainerTypeEntry *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;
}
-ContainerTypeEntry *
+ContainerTypeEntryPtr
TypeSystemParser::parseContainerTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- const int typeIndex = indexOfAttribute(*attributes, u"type");
+ const auto typeIndex = indexOfAttribute(*attributes, u"type");
if (typeIndex == -1) {
- m_error = QLatin1String("no 'type' attribute specified");
+ m_error = u"no 'type' attribute specified"_s;
return nullptr;
}
const auto typeName = attributes->at(typeIndex).value();
const auto containerTypeOpt = containerTypeFromAttribute(typeName);
if (!containerTypeOpt.has_value()) {
- m_error = QLatin1String("there is no container of type ") + typeName.toString();
+ m_error = u"there is no container of type "_s + typeName.toString();
return nullptr;
}
attributes->removeAt(typeIndex);
- auto *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 (int i = attributes->size() - 1; i >= 0; --i) {
+ 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: \""_qs
- + attribute.value().toString() + u"\"."_qs;
+ OpaqueContainers oc;
+ if (!parseOpaqueContainers(attribute.value(), &oc))
return nullptr;
- }
+ type->appendOpaqueContainers(oc);
}
}
return type;
}
-EnumTypeEntry *
+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,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- auto *entry = new EnumTypeEntry(name, since, currentParentTypeEntry());
+ auto entry = std::make_shared<EnumTypeEntry>(name, since, currentParentTypeEntry());
applyCommonAttributes(reader, entry, attributes);
entry->setTargetLangPackage(m_defaultPackage);
QString flagNames;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("upper-bound")) {
+ if (name == u"upper-bound") {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- } else if (name == QLatin1String("lower-bound")) {
+ } 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 == extensibleAttribute()) {
+ } else if (name == pythonEnumTypeAttribute) {
+ const auto attribute = attributes->takeAt(i);
+ const auto typeOpt = pythonEnumTypeFromAttribute(attribute.value());
+ if (typeOpt.has_value()) {
+ entry->setPythonEnumType(typeOpt.value());
+ } else {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgInvalidAttributeValue(attribute)));
+ }
+ } else if (name == cppEnumTypeAttribute) {
+ entry->setCppType(attributes->takeAt(i).value().toString());
+ } 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();
}
}
// put in the flags parallel...
if (!flagNames.isEmpty()) {
- const QStringList &flagNameList = flagNames.split(QLatin1Char(','));
+ const QStringList &flagNameList = flagNames.split(u',');
for (const QString &flagName : flagNameList)
parseFlagsEntry(reader, entry, flagName.trimmed(), since, attributes);
}
@@ -1462,19 +1616,19 @@ EnumTypeEntry *
}
-NamespaceTypeEntry *
+NamespaceTypeEntryPtr
TypeSystemParser::parseNamespaceTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- std::unique_ptr<NamespaceTypeEntry> result(new NamespaceTypeEntry(name, since, currentParentTypeEntry()));
+ auto result = std::make_shared<NamespaceTypeEntry>(name, since, currentParentTypeEntry());
auto visibility = TypeSystem::Visibility::Unspecified;
- applyCommonAttributes(reader, result.get(), attributes);
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ applyCommonAttributes(reader, result, attributes);
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto attributeName = attributes->at(i).qualifiedName();
- if (attributeName == QLatin1String("files")) {
+ if (attributeName == u"files") {
const QString pattern = attributes->takeAt(i).value().toString();
QRegularExpression re(pattern);
if (!re.isValid()) {
@@ -1482,11 +1636,11 @@ NamespaceTypeEntry *
return nullptr;
}
result->setFilePattern(re);
- } else if (attributeName == QLatin1String("extends")) {
+ } else if (attributeName == u"extends") {
const auto extendsPackageName = attributes->at(i).value();
auto allEntries = TypeDatabase::instance()->findNamespaceTypes(name);
auto extendsIt = std::find_if(allEntries.cbegin(), allEntries.cend(),
- [extendsPackageName] (const NamespaceTypeEntry *e) {
+ [extendsPackageName] (const NamespaceTypeEntryCPtr &e) {
return e->targetLangPackage() == extendsPackageName;
});
if (extendsIt == allEntries.cend()) {
@@ -1495,7 +1649,7 @@ NamespaceTypeEntry *
}
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()) {
@@ -1503,36 +1657,39 @@ NamespaceTypeEntry *
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));
}
}
if (visibility != TypeSystem::Visibility::Unspecified)
result->setVisibility(visibility);
// Handle legacy "generate" before the common handling
- applyComplexTypeAttributes(reader, result.get(), attributes);
+ applyComplexTypeAttributes(reader, result, attributes);
if (result->extends() && !result->hasPattern()) {
m_error = msgExtendingNamespaceRequiresPattern(name);
- return nullptr;
+ return {};
}
- return result.release();
+ return result;
}
-ValueTypeEntry *
+ValueTypeEntryPtr
TypeSystemParser::parseValueTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- auto *typeEntry = new ValueTypeEntry(name, since, currentParentTypeEntry());
- applyCommonAttributes(reader, typeEntry, attributes);
+ auto typeEntry = std::make_shared<ValueTypeEntry>(name, since, currentParentTypeEntry());
+ if (!applyCommonAttributes(reader, typeEntry, attributes))
+ return nullptr;
+ applyComplexTypeAttributes(reader, typeEntry, attributes);
const int defaultCtIndex =
indexOfAttribute(*attributes, u"default-constructor");
if (defaultCtIndex != -1)
@@ -1540,7 +1697,7 @@ ValueTypeEntry *
return typeEntry;
}
-FunctionTypeEntry *
+FunctionTypeEntryPtr
TypeSystemParser::parseFunctionTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
@@ -1548,75 +1705,84 @@ FunctionTypeEntry *
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;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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;
}
- TypeEntry *existingType = m_database->findType(name);
+ if (hasModification) {
+ mod.setOriginalSignature(originalSignature);
+ mod.setSignature(signature);
+ m_contextStack.top()->functionMods << mod;
+ }
+
+ TypeEntryPtr existingType = m_context->db->findType(name);
if (!existingType) {
- auto *result = new FunctionTypeEntry(name, signature, since, currentParentTypeEntry());
- result->setSnakeCase(snakeCase);
+ 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 = reinterpret_cast<FunctionTypeEntry *>(existingType);
+ auto result = std::static_pointer_cast<FunctionTypeEntry>(existingType);
result->addSignature(signature);
return result;
}
-TypedefEntry *
+TypedefEntryPtr
TypeSystemParser::parseTypedefEntry(const ConditionalStreamReader &reader,
- const QString &name,
+ const QString &name, StackElement topElement,
const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
if (!checkRootElement())
return nullptr;
- if (m_current && m_current->type != StackElement::Root
- && m_current->type != StackElement::NamespaceTypeEntry) {
- m_error = QLatin1String("typedef entries must be nested in namespaces or type system.");
+ if (topElement != StackElement::Root
+ && topElement != StackElement::NamespaceTypeEntry) {
+ m_error = u"typedef entries must be nested in namespaces or type system."_s;
return nullptr;
}
- const int 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();
- auto result = new TypedefEntry(name, sourceType, since, currentParentTypeEntry());
- applyCommonAttributes(reader, result, attributes);
+ auto result = std::make_shared<TypedefEntry>(name, sourceType, since,
+ currentParentTypeEntry());
+ if (!applyCommonAttributes(reader, result, attributes))
+ return nullptr;
+ applyComplexTypeAttributes(reader, result, attributes);
return result;
}
void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader &reader,
- ComplexTypeEntry *ctype,
+ const ComplexTypeEntryPtr &ctype,
QXmlStreamAttributes *attributes) const
{
bool generate = true;
@@ -1625,34 +1791,40 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
auto allowThread = m_allowThread;
QString package = m_defaultPackage;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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 == QLatin1String("polymorphic-base")) {
- ctype->setPolymorphicIdValue(attributes->takeAt(i).value().toString());
- } else if (name == QLatin1String("polymorphic-id-expression")) {
+ } 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()) {
@@ -1661,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()) {
@@ -1670,26 +1842,39 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
- } else if (name == QLatin1String("held-type")) {
+ } else if (name == u"held-type") {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
- } else if (name == QLatin1String("hash-function")) {
+ } 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 == QLatin1String("target-type")) {
+ } 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;
+ for (const auto &name : nameList)
+ nameSet.insert(name.trimmed().toString());
+ 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()) {
@@ -1698,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()) {
@@ -1707,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()) {
@@ -1716,6 +1901,20 @@ void TypeSystemParser::applyComplexTypeAttributes(const ConditionalStreamReader
qCWarning(lcShiboken, "%s",
qPrintable(msgInvalidAttributeValue(attribute)));
}
+ } else if (name == qtMetaTypeAttribute) {
+ const auto attribute = attributes->takeAt(i);
+ const auto qtMetaTypeOpt = qtMetaTypeFromAttribute(attribute.value());
+ if (qtMetaTypeOpt.has_value()) {
+ ctype->setQtMetaTypeRegistration(qtMetaTypeOpt.value());
+ } else {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgInvalidAttributeValue(attribute)));
+ }
+ } else if (name == parentManagementAttribute) {
+ const auto attribute = attributes->takeAt(i);
+ if (convertBoolean(attribute.value(), parentManagementAttribute, false))
+ ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::ParentManagement);
+ ComplexTypeEntry::setParentManagementEnabled(true);
}
}
@@ -1734,40 +1933,66 @@ 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)
{
QString signature;
QString rename;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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;
}
- *name = signature.left(signature.indexOf(QLatin1Char('('))).trimmed();
+ *name = signature.left(signature.indexOf(u'(')).trimmed();
- QString errorString = checkSignatureError(signature, QLatin1String("function"));
+ QString errorString = checkSignatureError(signature, u"function"_s);
if (!errorString.isEmpty()) {
m_error = errorString;
return false;
}
if (!rename.isEmpty()) {
- static const QRegularExpression functionNameRegExp(QLatin1String("^[a-zA-Z_][a-zA-Z0-9_]*$"));
+ static const QRegularExpression functionNameRegExp(u"^[a-zA-Z_][a-zA-Z0-9_]*$"_s);
Q_ASSERT(functionNameRegExp.isValid());
if (!functionNameRegExp.match(rename).hasMatch()) {
- m_error = QLatin1String("can not rename '") + signature + QLatin1String("', '")
- + rename + QLatin1String("' is not a valid function name");
+ m_error = u"can not rename '"_s + signature + u"', '"_s
+ + rename + u"' is not a valid function name"_s;
return false;
}
FunctionModification mod;
@@ -1780,23 +2005,25 @@ bool TypeSystemParser::parseRenameFunction(const ConditionalStreamReader &,
return true;
}
-bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &,
+bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &, StackElement topElement,
QXmlStreamAttributes *attributes)
{
- const int validParent = StackElement::TypeEntryMask
- | StackElement::ModifyFunction
- | StackElement::ModifyField;
- if (!m_current->parent || (m_current->parent->type & validParent) == 0) {
- m_error = QLatin1String("inject-documentation must be inside modify-function, "
- "modify-field or other tags that creates a type");
+ const bool isAddFunction = topElement == StackElement::AddFunction;
+ const bool validParent = isTypeEntry(topElement)
+ || topElement == StackElement::ModifyFunction
+ || topElement == StackElement::ModifyField
+ || isAddFunction;
+ if (!validParent) {
+ m_error = u"inject-documentation must be inside modify-function, add-function"
+ "modify-field or other tags that creates a type"_s;
return false;
}
TypeSystem::DocModificationMode mode = TypeSystem::DocModificationReplace;
TypeSystem::Language lang = TypeSystem::NativeCode;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("mode")) {
+ if (name == u"mode") {
const auto attribute = attributes->takeAt(i);
const auto modeOpt = docModificationFromAttribute(attribute.value());
if (!modeOpt.has_value()) {
@@ -1804,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()) {
@@ -1815,53 +2042,66 @@ bool TypeSystemParser::parseInjectDocumentation(const ConditionalStreamReader &,
}
}
- QString signature = m_current->type & StackElement::TypeEntryMask
- ? QString() : m_currentSignature;
+ QString signature = isTypeEntry(topElement) ? QString() : m_currentSignature;
DocModification mod(mode, signature);
mod.setFormat(lang);
- m_contextStack.top()->docModifications << mod;
+ 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);
+ else
+ top->docModifications << mod;
return true;
}
bool TypeSystemParser::parseModifyDocumentation(const ConditionalStreamReader &,
+ StackElement topElement,
QXmlStreamAttributes *attributes)
{
- const int validParent = StackElement::TypeEntryMask
- | StackElement::ModifyFunction
- | StackElement::ModifyField;
- if (!m_current->parent || (m_current->parent->type & validParent) == 0) {
- m_error = QLatin1String("modify-documentation must be inside modify-function, "
- "modify-field or other tags that creates a type");
+ const bool validParent = isTypeEntry(topElement)
+ || topElement == StackElement::ModifyFunction
+ || topElement == StackElement::ModifyField;
+ if (!validParent) {
+ m_error = u"modify-documentation must be inside modify-function, "
+ "modify-field or other tags that creates a type"_s;
return false;
}
- const int xpathIndex = indexOfAttribute(*attributes, xPathAttribute());
+ const auto xpathIndex = indexOfAttribute(*attributes, xPathAttribute);
if (xpathIndex == -1) {
- m_error = msgMissingAttribute(xPathAttribute());
+ m_error = msgMissingAttribute(xPathAttribute);
return false;
}
const QString xpath = attributes->takeAt(xpathIndex).value().toString();
- QString signature = (m_current->type & StackElement::TypeEntryMask) ? QString() : m_currentSignature;
+ QString signature = isTypeEntry(topElement) ? QString() : m_currentSignature;
m_contextStack.top()->docModifications
<< DocModification(xpath, signature);
return true;
}
// m_exceptionHandling
-TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const ConditionalStreamReader &,
+TypeSystemTypeEntryPtr TypeSystemParser::parseRootElement(const ConditionalStreamReader &,
const QVersionNumber &since,
QXmlStreamAttributes *attributes)
{
TypeSystem::SnakeCase snakeCase = TypeSystem::SnakeCase::Unspecified;
+ QString subModuleOf;
+ QString namespaceBegin;
+ QString namespaceEnd;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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()) {
@@ -1870,7 +2110,7 @@ TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const ConditionalStreamR
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()) {
@@ -1879,7 +2119,7 @@ TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const ConditionalStreamR
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()) {
@@ -1888,25 +2128,43 @@ TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const ConditionalStreamR
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();
}
}
- auto *moduleEntry =
- const_cast<TypeSystemTypeEntry *>(m_database->findTypeSystemType(m_defaultPackage));
- const bool add = moduleEntry == nullptr;
+ if (m_defaultPackage.isEmpty()) { // Extending default, see addBuiltInContainerTypes()
+ auto moduleEntry = std::const_pointer_cast<TypeSystemTypeEntry>(m_context->db->defaultTypeSystemType());
+ Q_ASSERT(moduleEntry);
+ m_defaultPackage = moduleEntry->name();
+ return moduleEntry;
+ }
+
+ auto moduleEntry =
+ std::const_pointer_cast<TypeSystemTypeEntry>(m_context->db->findTypeSystemType(m_defaultPackage));
+ const bool add = !moduleEntry;
if (add) {
- moduleEntry = new TypeSystemTypeEntry(m_defaultPackage, since,
- currentParentTypeEntry());
+ 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())
TypeDatabase::instance()->addRequiredTargetImport(m_defaultPackage);
if (add)
- m_database->addTypeSystemType(moduleEntry);
+ m_context->db->addTypeSystemType(moduleEntry);
return moduleEntry;
}
@@ -1915,22 +2173,22 @@ bool TypeSystemParser::loadTypesystem(const ConditionalStreamReader &,
{
QString typeSystemName;
bool generateChild = true;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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 = QLatin1String("No typesystem name specified");
+ m_error = u"No typesystem name specified"_s;
return false;
}
const bool result =
- m_database->parseFile(typeSystemName, m_currentPath, generateChild
- && m_generate == TypeEntry::GenerateCode);
+ m_context->db->parseFile(m_context, typeSystemName, m_currentPath,
+ generateChild && m_generate == TypeEntry::GenerateCode);
if (!result)
- m_error = u"Failed to parse: '"_qs + typeSystemName + u'\'';
+ m_error = u"Failed to parse: '"_s + typeSystemName + u'\'';
return result;
}
@@ -1938,12 +2196,12 @@ bool TypeSystemParser::parseRejectEnumValue(const ConditionalStreamReader &,
QXmlStreamAttributes *attributes)
{
if (!m_currentEnum) {
- m_error = QLatin1String("<reject-enum-value> node must be used inside a <enum-type> node");
+ m_error = u"<reject-enum-value> node must be used inside a <enum-type> node"_s;
return false;
}
- const int 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());
@@ -1951,16 +2209,16 @@ bool TypeSystemParser::parseRejectEnumValue(const ConditionalStreamReader &,
}
bool TypeSystemParser::parseReplaceArgumentType(const ConditionalStreamReader &,
- const StackElement &topElement,
+ StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("Type replacement can only be specified for argument modifications");
+ if (topElement != StackElement::ModifyArgument) {
+ m_error = u"Type replacement can only be specified for argument modifications"_s;
return false;
}
- const int modifiedTypeIndex = indexOfAttribute(*attributes, modifiedTypeAttribute());
+ const auto modifiedTypeIndex = indexOfAttribute(*attributes, modifiedTypeAttribute);
if (modifiedTypeIndex == -1) {
- m_error = QLatin1String("Type replacement requires 'modified-type' attribute");
+ m_error = u"Type replacement requires 'modified-type' attribute"_s;
return false;
}
m_contextStack.top()->functionMods.last().argument_mods().last().setModifiedType(
@@ -1969,24 +2227,24 @@ bool TypeSystemParser::parseReplaceArgumentType(const ConditionalStreamReader &,
}
bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
- const StackElement &topElement,
+ StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if (topElement.type != StackElement::ModifyArgument
- && topElement.type != StackElement::ValueTypeEntry
- && topElement.type != StackElement::PrimitiveTypeEntry
- && topElement.type != StackElement::ContainerTypeEntry) {
- m_error = QLatin1String("Conversion rules can only be specified for argument modification, "
- "value-type, primitive-type or container-type conversion.");
+ if (topElement != StackElement::ModifyArgument
+ && topElement != StackElement::ValueTypeEntry
+ && topElement != StackElement::PrimitiveTypeEntry
+ && topElement != StackElement::ContainerTypeEntry) {
+ m_error = u"Conversion rules can only be specified for argument modification, "
+ "value-type, primitive-type or container-type conversion."_s;
return false;
}
QString sourceFile;
QString snippetLabel;
TypeSystem::Language lang = TypeSystem::NativeCode;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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()) {
@@ -1994,28 +2252,33 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
return false;
}
lang = langOpt.value();
- } else if (name == QLatin1String("file")) {
+ } 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();
}
}
- if (topElement.type == StackElement::ModifyArgument) {
+ const auto &top = m_contextStack.top();
+ if (topElement == StackElement::ModifyArgument) {
CodeSnip snip;
snip.language = lang;
- m_contextStack.top()->functionMods.last().argument_mods().last().conversionRules().append(snip);
+ top->functionMods.last().argument_mods().last().conversionRules().append(snip);
return true;
}
- if (topElement.entry->hasTargetConversionRule() || topElement.entry->hasCustomConversion()) {
- m_error = QLatin1String("Types can have only one conversion rule");
- return false;
+ ValueTypeEntryPtr valueTypeEntry;
+ if (top->entry->isValue()) {
+ 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;
+ }
}
// The old conversion rule tag that uses a file containing the conversion
// will be kept temporarily for compatibility reasons. FIXME PYSIDE7: Remove
- if (!sourceFile.isEmpty()) {
+ if (valueTypeEntry != nullptr && !sourceFile.isEmpty()) {
if (m_generate != TypeEntry::GenerateForSubclass
&& m_generate != TypeEntry::GenerateNothing) {
qWarning(lcShiboken, "Specifying conversion rules by \"file\" is deprecated.");
@@ -2033,57 +2296,75 @@ bool TypeSystemParser::parseCustomConversion(const ConditionalStreamReader &,
m_error = msgCannotFindSnippet(sourceFile, snippetLabel);
return false;
}
- topElement.entry->setTargetConversionRule(conversionRuleOptional.value());
+ valueTypeEntry->setTargetConversionRule(conversionRuleOptional.value());
}
return true;
}
- auto *customConversion = new CustomConversion(m_current->entry);
+ auto customConversion = std::make_shared<CustomConversion>(top->entry);
+ if (top->entry->isPrimitive())
+ std::static_pointer_cast<PrimitiveTypeEntry>(top->entry)->setCustomConversion(customConversion);
+ else if (top->entry->isContainer())
+ std::static_pointer_cast<ContainerTypeEntry>(top->entry)->setCustomConversion(customConversion);
+ else if (top->entry->isValue())
+ std::static_pointer_cast<ValueTypeEntry>(top->entry)->setCustomConversion(customConversion);
customConversionsForReview.append(customConversion);
return true;
}
bool TypeSystemParser::parseNativeToTarget(const ConditionalStreamReader &,
- const StackElement &topElement,
+ StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if (topElement.type != StackElement::ConversionRule) {
- m_error = QLatin1String("Native to Target conversion code can only be specified for custom conversion rules.");
+ if (topElement != StackElement::ConversionRule) {
+ m_error = u"Native to Target conversion code can only be specified for custom conversion rules."_s;
return false;
}
CodeSnip snip;
- if (!readFileSnippet(attributes, &snip))
+ if (!readCodeSnippet(attributes, &snip))
return false;
- m_contextStack.top()->codeSnips.append(snip);
+ m_contextStack.top()->conversionCodeSnips.append(snip);
return true;
}
bool TypeSystemParser::parseAddConversion(const ConditionalStreamReader &,
- const StackElement &topElement,
+ StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if (topElement.type != StackElement::TargetToNative) {
- m_error = QLatin1String("Target to Native conversions can only be added inside 'target-to-native' tags.");
+ if (topElement != StackElement::TargetToNative) {
+ m_error = u"Target to Native conversions can only be added inside 'target-to-native' tags."_s;
return false;
}
QString sourceTypeName;
QString typeCheck;
CodeSnip snip;
- if (!readFileSnippet(attributes, &snip))
+ if (!readCodeSnippet(attributes, &snip))
return false;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+
+ const auto &top = m_contextStack.top();
+ top->conversionCodeSnips.append(snip);
+
+ if (parserState() == ParserState::ArgumentTargetToNativeConversion)
+ return true;
+
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("type"))
+ if (name == u"type")
sourceTypeName = attributes->takeAt(i).value().toString();
- else if (name == QLatin1String("check"))
+ else if (name == u"check")
typeCheck = attributes->takeAt(i).value().toString();
}
+
if (sourceTypeName.isEmpty()) {
- m_error = QLatin1String("Target to Native conversions must specify the input type with the 'type' attribute.");
+ m_error = u"Target to Native conversions must specify the input type with the 'type' attribute."_s;
return false;
}
- m_current->entry->customConversion()->addTargetToNativeConversion(sourceTypeName, typeCheck);
- m_contextStack.top()->codeSnips.append(snip);
+ auto customConversion = CustomConversion::getCustomConversion(top->entry);
+ if (!customConversion) {
+ m_error = msgMissingCustomConversion(top->entry);
+ return false;
+ }
+ customConversion->addTargetToNativeConversion(sourceTypeName, typeCheck);
return true;
}
@@ -2092,17 +2373,17 @@ 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;
}
static bool parseArgumentIndex(const QString &index, int *result, QString *errorMessage)
{
- if (index == QLatin1String("return")) {
+ if (index == u"return") {
*result = 0;
return true;
}
- if (index == QLatin1String("this")) {
+ if (index == u"this") {
*result = -1;
return true;
}
@@ -2110,13 +2391,14 @@ static bool parseArgumentIndex(const QString &index, int *result, QString *error
}
bool TypeSystemParser::parseModifyArgument(const ConditionalStreamReader &,
- const StackElement &topElement, QXmlStreamAttributes *attributes)
-{
- if (topElement.type != StackElement::ModifyFunction
- && topElement.type != StackElement::AddFunction) {
- m_error = QString::fromLatin1("argument modification requires function"
- " modification as parent, was %1")
- .arg(topElement.type, 0, 16);
+ StackElement topElement, QXmlStreamAttributes *attributes)
+{
+ if (topElement != StackElement::ModifyFunction
+ && topElement != StackElement::AddFunction
+ && topElement != StackElement::DeclareFunction) {
+ m_error = u"Argument modification requires <modify-function>,"
+ " <add-function> or <declare-function> as parent, was "_s
+ + tagFromElement(topElement).toString();
return false;
}
@@ -2124,22 +2406,22 @@ bool TypeSystemParser::parseModifyArgument(const ConditionalStreamReader &,
QString renameTo;
QString pyiType;
bool resetAfterUse = false;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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;
}
@@ -2156,10 +2438,10 @@ bool TypeSystemParser::parseModifyArgument(const ConditionalStreamReader &,
}
bool TypeSystemParser::parseNoNullPointer(const ConditionalStreamReader &reader,
- const StackElement &topElement, QXmlStreamAttributes *attributes)
+ StackElement topElement, QXmlStreamAttributes *attributes)
{
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("no-null-pointer requires argument modification as parent");
+ if (topElement != StackElement::ModifyArgument) {
+ m_error = u"no-null-pointer requires argument modification as parent"_s;
return false;
}
@@ -2177,19 +2459,19 @@ bool TypeSystemParser::parseNoNullPointer(const ConditionalStreamReader &reader,
}
bool TypeSystemParser::parseDefineOwnership(const ConditionalStreamReader &,
- const StackElement &topElement,
+ StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("define-ownership requires argument modification as parent");
+ if (topElement != StackElement::ModifyArgument) {
+ m_error = u"define-ownership requires argument modification as parent"_s;
return false;
}
TypeSystem::Language lang = TypeSystem::TargetLangCode;
std::optional<TypeSystem::Ownership> ownershipOpt;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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) {
@@ -2197,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()) {
@@ -2208,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();
@@ -2227,17 +2509,17 @@ bool TypeSystemParser::parseDefineOwnership(const ConditionalStreamReader &,
// ### fixme PySide7: remove (replaced by attribute).
bool TypeSystemParser::parseRename(const ConditionalStreamReader &,
- const StackElement &topElement,
+ StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("Argument modification parent required");
+ if (topElement != StackElement::ModifyArgument) {
+ m_error = u"Argument modification parent required"_s;
return false;
}
- const int 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();
@@ -2249,22 +2531,22 @@ bool TypeSystemParser::parseModifyField(const ConditionalStreamReader &,
QXmlStreamAttributes *attributes)
{
FieldModification fm;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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()) {
@@ -2276,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;
@@ -2296,73 +2578,85 @@ static bool parseOverloadNumber(const QXmlStreamAttribute &attribute, int *overl
}
bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &,
- const StackElement &topElement,
- StackElement::ElementType t,
+ StackElement topElement,
+ StackElement t,
QXmlStreamAttributes *attributes)
{
- if (!(topElement.type
- & (StackElement::ComplexTypeEntryMask | StackElement::Root | StackElement::ContainerTypeEntry))) {
+ const bool validParent = isComplexTypeEntry(topElement)
+ || topElement == StackElement::Root
+ || topElement == StackElement::ContainerTypeEntry;
+ if (!validParent) {
m_error = QString::fromLatin1("Add/Declare function requires a complex/container type or a root tag as parent"
- ", was=%1").arg(topElement.type, 0, 16);
+ ", 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 (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("signature")) {
- originalSignature = attributes->takeAt(i).value().toString();
- } else if (name == QLatin1String("return-type")) {
+ 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);
}
}
QString signature = TypeDatabase::normalizedAddedFunctionSignature(originalSignature);
if (signature.isEmpty()) {
- m_error = QLatin1String("No signature for the added function");
+ m_error = u"No signature for the added function"_s;
return false;
}
- QString errorString = checkSignatureError(signature, QLatin1String("add-function"));
+ QString errorString = checkSignatureError(signature, u"add-function"_s);
if (!errorString.isEmpty()) {
m_error = errorString;
return false;
}
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);
- if (!signature.contains(QLatin1Char('(')))
- signature += QLatin1String("()");
+ if (!signature.contains(u'('))
+ signature += u"()"_s;
m_currentSignature = signature;
if (!access.isEmpty()) {
const auto acessOpt = addedFunctionAccessFromAttribute(access);
if (!acessOpt.has_value()) {
- m_error = u"Bad access type '"_qs + access + u'\'';
+ m_error = u"Bad access type '"_s + access + u'\'';
return false;
}
func->setAccess(acessOpt.value());
@@ -2373,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);
@@ -2382,156 +2674,217 @@ bool TypeSystemParser::parseAddFunction(const ConditionalStreamReader &,
return true;
}
-bool TypeSystemParser::parseProperty(const ConditionalStreamReader &, const StackElement &topElement,
+bool TypeSystemParser::parseAddPyMethodDef(const ConditionalStreamReader &,
+ StackElement topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (!isComplexTypeEntry(topElement)) {
+ m_error = u"add-pymethoddef requires a complex type as parent, was="_s
+ + tagFromElement(topElement).toString();
+ return false;
+ }
+
+ TypeSystemPyMethodDefEntry def;
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == nameAttribute) {
+ def.name = attributes->takeAt(i).value().toString();
+ } else if (name == u"doc") {
+ def.doc = attributes->takeAt(i).value().toString();
+ } else if (name == u"function") {
+ def.function = attributes->takeAt(i).value().toString();
+ } else if (name == u"flags") {
+ auto attribute = attributes->takeAt(i);
+ const auto flags = attribute.value().split(u'|', Qt::SkipEmptyParts);
+ for (const auto &flag : flags)
+ def.methFlags.append(flag.toString().toUtf8());
+ } else if (name == u"signatures") {
+ auto attribute = attributes->takeAt(i);
+ const auto signatures = attribute.value().split(u';', Qt::SkipEmptyParts);
+ for (const auto &signature : signatures)
+ def.signatures.append(signature.toString());
+ }
+ }
+
+ if (def.name.isEmpty() || def.function.isEmpty()) {
+ m_error = u"add-pymethoddef requires at least a name and a function attribute"_s;
+ return false;
+ }
+ std::static_pointer_cast<ComplexTypeEntry>(m_contextStack.top()->entry)->addPyMethodDef(def);
+ return true;
+}
+
+bool TypeSystemParser::parseProperty(const ConditionalStreamReader &, StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if ((topElement.type & StackElement::ComplexTypeEntryMask) == 0) {
+ if (!isComplexTypeEntry(topElement)) {
m_error = QString::fromLatin1("Add property requires a complex type as parent"
- ", was=%1").arg(topElement.type, 0, 16);
+ ", was=%1").arg(tagFromElement(topElement));
return false;
}
TypeSystemProperty property;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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 == QLatin1String("get")) {
+ } else if (name == u"get") {
property.read = attributes->takeAt(i).value().toString();
- } else if (name == QLatin1String("type")) {
+ } else if (name == u"type") {
property.type = attributes->takeAt(i).value().toString();
- } else if (name == QLatin1String("set")) {
+ } 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 = QLatin1String("<property> element is missing required attibutes (name/type/get).");
+ m_error = u"<property> element is missing required attibutes (name/type/get)."_s;
return false;
}
- static_cast<ComplexTypeEntry *>(topElement.entry)->addProperty(property);
+ std::static_pointer_cast<ComplexTypeEntry>(m_contextStack.top()->entry)->addProperty(property);
return true;
}
-bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader,
- const StackElement &topElement,
- QXmlStreamAttributes *attributes)
+// 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)
{
- if (!(topElement.type & StackElement::ComplexTypeEntryMask)) {
- m_error = QString::fromLatin1("Modify function requires complex type as parent"
- ", was=%1").arg(topElement.type, 0, 16);
- return false;
+ 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;
+}
- QString originalSignature;
- 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 (int i = attributes->size() - 1; i >= 0; --i) {
+// 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 == QLatin1String("signature")) {
- originalSignature = attributes->takeAt(i).value().toString();
- } else if (name == accessAttribute()) {
- access = attributes->takeAt(i).value().toString();
- } else if (name == renameAttribute()) {
- rename = attributes->takeAt(i).value().toString();
- } 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()) {
+ 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()) {
+ mod->setAllowThread(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))
+ if (!exceptionOpt.has_value()) {
+ m_error = msgInvalidAttributeValue(attribute);
return false;
- } else if (name == snakeCaseAttribute()) {
+ }
+ mod->setExceptionHandling(exceptionOpt.value());
+ } 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)));
+ if (!snakeCaseOpt.has_value()) {
+ m_error = msgInvalidAttributeValue(attribute);
+ return false;
}
- } else if (name == virtualSlotAttribute()) {
+ 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;
+}
+
+bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader,
+ StackElement topElement,
+ QXmlStreamAttributes *attributes)
+{
+ const bool validParent = isComplexTypeEntry(topElement)
+ || topElement == StackElement::TypedefTypeEntry
+ || topElement == StackElement::FunctionTypeEntry;
+ if (!validParent) {
+ m_error = QString::fromLatin1("Modify function requires complex type as parent"
+ ", was=%1").arg(tagFromElement(topElement));
+ return false;
+ }
+
+ QString originalSignature;
+ FunctionModification mod;
+ if (!parseModifyFunctionAttributes(attributes, &mod))
+ return false;
+
+ QString access;
+ bool removed = false;
+ QString rename;
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == signatureAttribute) {
+ originalSignature = attributes->takeAt(i).value().toString().simplified();
+ } else if (name == accessAttribute) {
+ access = attributes->takeAt(i).value().toString();
+ } else if (name == renameAttribute) {
+ rename = attributes->takeAt(i).value().toString();
+ } else if (name == removeAttribute) {
+ removed = convertRemovalAttribute(attributes->takeAt(i).value());
+ } else if (name == virtualSlotAttribute || name == threadAttribute) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedAttributeWarning(reader, name)));
}
}
// Child of global <function>
- if (originalSignature.isEmpty() && topElement.entry->isFunction()) {
- auto f = static_cast<const FunctionTypeEntry *>(topElement.entry);
+ const auto &top = m_contextStack.top();
+ if (originalSignature.isEmpty() && top->entry->isFunction()) {
+ auto f = std::static_pointer_cast<const FunctionTypeEntry>(top->entry);
originalSignature = f->signatures().value(0);
}
const QString signature = TypeDatabase::normalizedSignature(originalSignature);
if (signature.isEmpty()) {
- m_error = QLatin1String("No signature for modified function");
+ m_error = u"No signature for modified function"_s;
return false;
}
- QString errorString = checkSignatureError(signature, QLatin1String("modify-function"));
+ QString errorString = checkSignatureError(signature, u"modify-function"_s);
if (!errorString.isEmpty()) {
m_error = errorString;
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()) {
const auto modifierFlagOpt = modifierFromAttribute(access);
if (!modifierFlagOpt.has_value()) {
- m_error = u"Bad access type '"_qs + access + u'\'';
+ m_error = u"Bad access type '"_s + access + u'\'';
return false;
}
const FunctionModification::ModifierFlag m = modifierFlagOpt.value();
- if (m == FunctionModification::Final || m == FunctionModification::NonFinal) {
+ 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()) {
@@ -2539,25 +2892,21 @@ bool TypeSystemParser::parseModifyFunction(const ConditionalStreamReader &reader
mod.setModifierFlag(FunctionModification::Rename);
}
- mod.setIsThread(isThread);
- if (allowThread != TypeSystem::AllowThread::Unspecified)
- mod.setAllowThread(allowThread);
-
- m_contextStack.top()->functionMods << mod;
+ top->functionMods << mod;
return true;
}
bool TypeSystemParser::parseReplaceDefaultExpression(const ConditionalStreamReader &,
- const StackElement &topElement,
+ StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if (!(topElement.type & StackElement::ModifyArgument)) {
- m_error = QLatin1String("Replace default expression only allowed as child of argument modification");
+ if (!(topElement & StackElement::ModifyArgument)) {
+ m_error = u"Replace default expression only allowed as child of argument modification"_s;
return false;
}
- const int withIndex = indexOfAttribute(*attributes, u"with");
+ const auto withIndex = indexOfAttribute(*attributes, u"with");
if (withIndex == -1 || attributes->at(withIndex).value().isEmpty()) {
- m_error = QLatin1String("Default expression replaced with empty string. Use remove-default-expression instead.");
+ m_error = u"Default expression replaced with empty string. Use remove-default-expression instead."_s;
return false;
}
@@ -2566,41 +2915,19 @@ bool TypeSystemParser::parseReplaceDefaultExpression(const ConditionalStreamRead
return true;
}
-CustomFunction *
- TypeSystemParser::parseCustomMetaConstructor(const ConditionalStreamReader &,
- StackElement::ElementType type,
- const StackElement &topElement,
- QXmlStreamAttributes *attributes)
-{
- QString functionName = topElement.entry->name().toLower()
- + (type == StackElement::CustomMetaConstructor
- ? QLatin1String("_create") : QLatin1String("_delete"));
- QString paramName = QLatin1String("copy");
- for (int i = attributes->size() - 1; i >= 0; --i) {
- const auto name = attributes->at(i).qualifiedName();
- if (name == nameAttribute())
- functionName = attributes->takeAt(i).value().toString();
- else if (name == QLatin1String("param-name"))
- paramName = attributes->takeAt(i).value().toString();
- }
- auto *func = new CustomFunction(functionName);
- func->paramName = paramName;
- return func;
-}
-
bool TypeSystemParser::parseReferenceCount(const ConditionalStreamReader &reader,
- const StackElement &topElement,
+ StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("reference-count must be child of modify-argument");
+ if (topElement != StackElement::ModifyArgument) {
+ m_error = u"reference-count must be child of modify-argument"_s;
return false;
}
ReferenceCount rc;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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()) {
@@ -2617,7 +2944,7 @@ bool TypeSystemParser::parseReferenceCount(const ConditionalStreamReader &reader
default:
break;
}
- } else if (name == QLatin1String("variable-name")) {
+ } else if (name == u"variable-name") {
rc.varName = attributes->takeAt(i).value().toString();
}
}
@@ -2627,21 +2954,21 @@ bool TypeSystemParser::parseReferenceCount(const ConditionalStreamReader &reader
}
bool TypeSystemParser::parseParentOwner(const ConditionalStreamReader &,
- const StackElement &topElement,
+ StackElement topElement,
QXmlStreamAttributes *attributes)
{
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("parent-policy must be child of modify-argument");
+ if (topElement != StackElement::ModifyArgument) {
+ m_error = u"parent-policy must be child of modify-argument"_s;
return false;
}
ArgumentOwner ao;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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()) {
@@ -2655,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;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ Snippet result;
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("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_database->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 = QLatin1String("File for inject code not exist: ")
- + QDir::toNativeSeparators(fileName);
- return false;
+ m_error = u"File for inject code not exist: "_s
+ + 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;
+}
- QString source = fileName;
- if (!snippetLabel.isEmpty())
- source += QLatin1String(" (") + snippetLabel + QLatin1Char(')');
+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 = 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);
@@ -2702,25 +3045,25 @@ bool TypeSystemParser::readFileSnippet(QXmlStreamAttributes *attributes, CodeSni
}
bool TypeSystemParser::parseInjectCode(const ConditionalStreamReader &,
- const StackElement &topElement,
- StackElement* element, QXmlStreamAttributes *attributes)
-{
- if (!(topElement.type & StackElement::ComplexTypeEntryMask)
- && (topElement.type != StackElement::AddFunction)
- && (topElement.type != StackElement::ModifyFunction)
- && (topElement.type != StackElement::Root)) {
- m_error = QLatin1String("wrong parent type for code injection");
+ StackElement topElement,
+ QXmlStreamAttributes *attributes)
+{
+ if (!isComplexTypeEntry(topElement)
+ && (topElement != StackElement::AddFunction)
+ && (topElement != StackElement::ModifyFunction)
+ && (topElement != StackElement::Root)) {
+ m_error = u"wrong parent type for code injection"_s;
return false;
}
TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionBeginning;
TypeSystem::Language lang = TypeSystem::TargetLangCode;
CodeSnip snip;
- if (!readFileSnippet(attributes, &snip))
+ if (!readCodeSnippet(attributes, &snip))
return false;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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()) {
@@ -2728,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()) {
@@ -2742,32 +3085,36 @@ bool TypeSystemParser::parseInjectCode(const ConditionalStreamReader &,
snip.position = position;
snip.language = lang;
- if (topElement.type == StackElement::ModifyFunction
- || topElement.type == StackElement::AddFunction) {
+ switch (topElement) {
+ case StackElement::ModifyFunction:
+ case StackElement::AddFunction: {
FunctionModification &mod = m_contextStack.top()->functionMods.last();
mod.appendSnip(snip);
if (!snip.code().isEmpty())
mod.setModifierFlag(FunctionModification::CodeInjection);
- element->type = StackElement::InjectCodeInFunction;
- } else if (topElement.type == StackElement::Root) {
- element->entry->addCodeSnip(snip);
- } else if (topElement.type != StackElement::Root) {
- m_contextStack.top()->codeSnips << snip;
+ }
+ break;
+ case StackElement::Root:
+ std::static_pointer_cast<TypeSystemTypeEntry>(m_contextStack.top()->entry)->addCodeSnip(snip);
+ break;
+ default:
+ std::static_pointer_cast<ComplexTypeEntry>(m_contextStack.top()->entry)->addCodeSnip(snip);
+ break;
}
return true;
}
bool TypeSystemParser::parseInclude(const ConditionalStreamReader &,
- const StackElement &topElement,
- TypeEntry *entry, QXmlStreamAttributes *attributes)
+ StackElement topElement,
+ const TypeEntryPtr &entry, QXmlStreamAttributes *attributes)
{
QString fileName;
Include::IncludeType location = Include::IncludePath;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ 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()) {
@@ -2779,13 +3126,16 @@ bool TypeSystemParser::parseInclude(const ConditionalStreamReader &,
}
Include inc(location, fileName);
- if (topElement.type
- & (StackElement::ComplexTypeEntryMask | StackElement::PrimitiveTypeEntry)) {
+ if (isComplexTypeEntry(topElement)
+ || topElement == StackElement::PrimitiveTypeEntry
+ || topElement == StackElement::ContainerTypeEntry
+ || topElement == StackElement::SmartPointerTypeEntry
+ || topElement == StackElement::TypedefTypeEntry) {
entry->setInclude(inc);
- } else if (topElement.type == StackElement::ExtraIncludes) {
+ } else if (topElement == StackElement::ExtraIncludes) {
entry->addExtraInclude(inc);
} else {
- m_error = QLatin1String("Only supported parent tags are primitive-type, complex types or extra-includes");
+ m_error = u"Only supported parent tags are primitive-type, complex types or extra-includes"_s;
return false;
}
return true;
@@ -2794,57 +3144,54 @@ bool TypeSystemParser::parseInclude(const ConditionalStreamReader &,
bool TypeSystemParser::parseSystemInclude(const ConditionalStreamReader &,
QXmlStreamAttributes *attributes)
{
- const int 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;
}
TemplateInstance *
- TypeSystemParser::parseTemplateInstanceEnum(const ConditionalStreamReader &,
- const StackElement &topElement,
- QXmlStreamAttributes *attributes)
+ TypeSystemParser::parseInsertTemplate(const ConditionalStreamReader &,
+ StackElement topElement,
+ QXmlStreamAttributes *attributes)
{
- if (!(topElement.type & StackElement::CodeSnipMask) &&
- (topElement.type != StackElement::Template) &&
- (topElement.type != StackElement::CustomMetaConstructor) &&
- (topElement.type != StackElement::CustomMetaDestructor) &&
- (topElement.type != StackElement::NativeToTarget) &&
- (topElement.type != StackElement::AddConversion) &&
- (topElement.type != StackElement::ConversionRule)) {
- m_error = QLatin1String("Can only insert templates into code snippets, templates, custom-constructors, "\
- "custom-destructors, conversion-rule, native-to-target or add-conversion tags.");
+ if ((topElement != StackElement::InjectCode) &&
+ (topElement != StackElement::Template) &&
+ (topElement != StackElement::NativeToTarget) &&
+ (topElement != StackElement::AddConversion) &&
+ (topElement != StackElement::ConversionRule)) {
+ m_error = u"Can only insert templates into code snippets, templates, "\
+ "conversion-rule, native-to-target or add-conversion tags."_s;
return nullptr;
}
- const int 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());
}
bool TypeSystemParser::parseReplace(const ConditionalStreamReader &,
- const StackElement &topElement,
- StackElement *element, QXmlStreamAttributes *attributes)
+ StackElement topElement, QXmlStreamAttributes *attributes)
{
- if (topElement.type != StackElement::TemplateInstanceEnum) {
- m_error = QLatin1String("Can only insert replace rules into insert-template.");
+ if (topElement != StackElement::InsertTemplate) {
+ m_error = u"Can only insert replace rules into insert-template."_s;
return false;
}
QString from;
QString to;
- for (int i = attributes->size() - 1; i >= 0; --i) {
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
const auto name = attributes->at(i).qualifiedName();
- if (name == QLatin1String("from"))
+ if (name == u"from")
from = attributes->takeAt(i).value().toString();
- else if (name == toAttribute())
+ else if (name == toAttribute)
to = attributes->takeAt(i).value().toString();
}
- element->parent->value.templateInstance->addReplaceRule(from, to);
+ m_templateInstance->addReplaceRule(from, to);
return true;
}
@@ -2853,12 +3200,12 @@ bool TypeSystemParser::parseReplace(const ConditionalStreamReader &,
// or it's not possible to cover all primitive target language
// types (which we need to do in order to support fake meta objects)
bool TypeSystemParser::checkDuplicatedTypeEntry(const ConditionalStreamReader &reader,
- StackElement::ElementType t,
+ StackElement t,
const QString &name) const
{
if (t == StackElement::PrimitiveTypeEntry || t == StackElement::FunctionTypeEntry)
return true;
- const auto *duplicated = m_database->findType(name);
+ const auto duplicated = m_context->db->findType(name);
if (!duplicated || duplicated->isNamespace())
return true;
if (duplicated->isBuiltIn()) {
@@ -2884,7 +3231,7 @@ static bool parseVersion(const QString &versionSpec, const QString &package,
return true;
}
-bool TypeSystemParser::startElement(const ConditionalStreamReader &reader)
+bool TypeSystemParser::startElement(const ConditionalStreamReader &reader, StackElement element)
{
if (m_ignoreDepth) {
++m_ignoreDepth;
@@ -2895,14 +3242,14 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader)
QXmlStreamAttributes attributes = reader.attributes();
VersionRange versionRange;
- for (int i = attributes.size() - 1; i >= 0; --i) {
+ 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;
@@ -2911,89 +3258,76 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader)
}
if (!m_defaultPackage.isEmpty() && !versionRange.isNull()) {
- TypeDatabase* td = TypeDatabase::instance();
+ auto *td = TypeDatabase::instance();
if (!td->checkApiVersion(m_defaultPackage, versionRange)) {
++m_ignoreDepth;
return true;
}
}
- if (tagName.compare(QLatin1String("import-file"), Qt::CaseInsensitive) == 0)
+ if (element == StackElement::ImportFile)
return importFileElement(attributes);
- const auto elementTypeOpt = elementFromTag(tagName);
- if (!elementTypeOpt.has_value()) {
- m_error = u"Unknown tag name: '"_qs + tagName.toString() + u'\'';
- return false;
- }
-
- if (m_currentDroppedEntry) {
+ if (m_currentDroppedEntryDepth) {
++m_currentDroppedEntryDepth;
return true;
}
- std::unique_ptr<StackElement> element(new StackElement(m_current));
- element->type = elementTypeOpt.value();
-
- if (element->type == StackElement::Root && m_generate == TypeEntry::GenerateCode)
+ if (element == StackElement::Root && m_generate == TypeEntry::GenerateCode)
customConversionsForReview.clear();
- if (element->type == StackElement::CustomMetaConstructor
- || element->type == StackElement::CustomMetaDestructor) {
+ if (element == StackElement::Unimplemented) {
qCWarning(lcShiboken, "%s",
qPrintable(msgUnimplementedElementWarning(reader, tagName)));
+ return true;
}
- switch (element->type) {
- case StackElement::Root:
- case StackElement::NamespaceTypeEntry:
- case StackElement::InterfaceTypeEntry:
- case StackElement::ObjectTypeEntry:
- case StackElement::ValueTypeEntry:
- case StackElement::PrimitiveTypeEntry:
- case StackElement::TypedefTypeEntry:
- case StackElement::ContainerTypeEntry:
- m_contextStack.push(new StackElementContext());
- break;
- default:
- break;
+ if (isTypeEntry(element) || element == StackElement::Root)
+ m_contextStack.push(std::make_shared<StackElementContext>());
+
+ if (m_contextStack.isEmpty()) {
+ m_error = msgNoRootTypeSystemEntry();
+ return false;
}
- if (element->type & StackElement::TypeEntryMask) {
+ const auto &top = m_contextStack.top();
+ const StackElement topElement = m_stack.value(m_stack.size() - 2, StackElement::None);
+
+ if (isTypeEntry(element)) {
QString name;
- if (element->type != StackElement::FunctionTypeEntry) {
- const int nameIndex = indexOfAttribute(attributes, nameAttribute());
+ if (element != StackElement::FunctionTypeEntry) {
+ const auto nameIndex = indexOfAttribute(attributes, nameAttribute);
if (nameIndex != -1) {
name = attributes.takeAt(nameIndex).value().toString();
- } else if (element->type != StackElement::EnumTypeEntry) { // anonymous enum?
- m_error = msgMissingAttribute(nameAttribute());
+ } else if (element != StackElement::EnumTypeEntry) { // anonymous enum?
+ m_error = msgMissingAttribute(nameAttribute);
return false;
}
}
// Allow for primitive and/or std:: types only, else require proper nesting.
- if (element->type != StackElement::PrimitiveTypeEntry && name.contains(QLatin1Char(':'))
- && !name.contains(QLatin1String("std::"))) {
+ if (element != StackElement::PrimitiveTypeEntry && name.contains(u':')
+ && !name.contains(u"std::")) {
m_error = msgIncorrectlyNestedName(name);
return false;
}
- if (m_database->hasDroppedTypeEntries()) {
- const QString identifier = element->type == StackElement::FunctionTypeEntry
- ? attributes.value(signatureAttribute()).toString() : name;
- if (shouldDropTypeEntry(m_database, element.get(), identifier)) {
- m_currentDroppedEntry = element.release();
+ if (m_context->db->hasDroppedTypeEntries()) {
+ const QString identifier = element == StackElement::FunctionTypeEntry
+ ? attributes.value(signatureAttribute).toString().simplified() : name;
+ if (shouldDropTypeEntry(m_context->db, m_contextStack, identifier)) {
m_currentDroppedEntryDepth = 1;
if (ReportHandler::isDebug(ReportHandler::SparseDebug)) {
qCInfo(lcShiboken, "Type system entry '%s' was intentionally dropped from generation.",
qPrintable(identifier));
}
+ m_contextStack.pop();
return true;
}
}
// The top level tag 'function' has only the 'signature' tag
// and we should extract the 'name' value from it.
- if (element->type == StackElement::FunctionTypeEntry
+ if (element == StackElement::FunctionTypeEntry
&& !parseRenameFunction(reader, &name, &attributes)) {
return false;
}
@@ -3001,146 +3335,134 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader)
// We need to be able to have duplicate primitive type entries,
// or it's not possible to cover all primitive target language
// types (which we need to do in order to support fake meta objects)
- if (element->type != StackElement::PrimitiveTypeEntry
- && element->type != StackElement::FunctionTypeEntry) {
- TypeEntry *tmp = m_database->findType(name);
+ if (element != StackElement::PrimitiveTypeEntry
+ && element != StackElement::FunctionTypeEntry) {
+ TypeEntryPtr tmp = m_context->db->findType(name);
if (tmp && !tmp->isNamespace())
qCWarning(lcShiboken).noquote().nospace()
<< "Duplicate type entry: '" << name << '\'';
}
- if (element->type == StackElement::EnumTypeEntry) {
- const int enumIdentifiedByIndex = indexOfAttribute(attributes, enumIdentifiedByValueAttribute());
+ if (element == StackElement::EnumTypeEntry) {
+ const auto enumIdentifiedByIndex =
+ indexOfAttribute(attributes, enumIdentifiedByValueAttribute);
const QString identifiedByValue = enumIdentifiedByIndex != -1
? attributes.takeAt(enumIdentifiedByIndex).value().toString() : QString();
if (name.isEmpty()) {
name = identifiedByValue;
} else if (!identifiedByValue.isEmpty()) {
- m_error = QLatin1String("can't specify both 'name' and 'identified-by-value' attributes");
+ m_error = u"can't specify both 'name' and 'identified-by-value' attributes"_s;
return false;
}
}
if (name.isEmpty()) {
- m_error = QLatin1String("no 'name' attribute specified");
+ m_error = u"no 'name' attribute specified"_s;
return false;
}
- switch (element->type) {
+ switch (element) {
case StackElement::CustomTypeEntry:
- element->entry =
- parseCustomTypeEntry(reader, name, versionRange.since, &attributes);
- if (Q_UNLIKELY(!element->entry))
+ top->entry = parseCustomTypeEntry(reader, name, versionRange.since, &attributes);
+ if (Q_UNLIKELY(!top->entry))
return false;
break;
case StackElement::PrimitiveTypeEntry:
- element->entry = parsePrimitiveTypeEntry(reader, name, versionRange.since, &attributes);
- if (Q_UNLIKELY(!element->entry))
+ top->entry = parsePrimitiveTypeEntry(reader, name, versionRange.since, &attributes);
+ if (Q_UNLIKELY(!top->entry))
return false;
break;
case StackElement::ContainerTypeEntry:
- if (ContainerTypeEntry *ce = parseContainerTypeEntry(reader, name, versionRange.since, &attributes)) {
- applyComplexTypeAttributes(reader, ce, &attributes);
- element->entry = ce;
- } else {
+ top->entry = parseContainerTypeEntry(reader, name, versionRange.since, &attributes);
+ if (top->entry == nullptr)
return false;
- }
break;
case StackElement::SmartPointerTypeEntry:
- if (SmartPointerTypeEntry *se = parseSmartPointerEntry(reader, name, versionRange.since, &attributes)) {
- applyComplexTypeAttributes(reader, se, &attributes);
- element->entry = se;
- } else {
+ top->entry = parseSmartPointerEntry(reader, name, versionRange.since, &attributes);
+ if (top->entry == nullptr)
return false;
- }
break;
case StackElement::EnumTypeEntry:
m_currentEnum = parseEnumTypeEntry(reader, name, versionRange.since, &attributes);
if (Q_UNLIKELY(!m_currentEnum))
return false;
- element->entry = m_currentEnum;
+ top->entry = m_currentEnum;
break;
case StackElement::ValueTypeEntry:
- if (ValueTypeEntry *ve = parseValueTypeEntry(reader, name, versionRange.since, &attributes)) {
- applyComplexTypeAttributes(reader, ve, &attributes);
- element->entry = ve;
- } else {
+ top->entry = parseValueTypeEntry(reader, name, versionRange.since, &attributes);
+ if (top->entry == nullptr)
return false;
- }
break;
case StackElement::NamespaceTypeEntry:
- if (auto entry = parseNamespaceTypeEntry(reader, name, versionRange.since, &attributes))
- element->entry = entry;
- else
+ top->entry = parseNamespaceTypeEntry(reader, name, versionRange.since, &attributes);
+ if (top->entry == nullptr)
return false;
break;
case StackElement::ObjectTypeEntry:
- case StackElement::InterfaceTypeEntry:
+ case StackElement::InterfaceTypeEntry: {
if (!checkRootElement())
return false;
- element->entry = new ObjectTypeEntry(name, versionRange.since, currentParentTypeEntry());
- applyCommonAttributes(reader, element->entry, &attributes);
- applyComplexTypeAttributes(reader, static_cast<ComplexTypeEntry *>(element->entry), &attributes);
+ auto ce = std::make_shared<ObjectTypeEntry>(name, versionRange.since, currentParentTypeEntry());
+ top->entry = ce;
+ applyCommonAttributes(reader, top->entry, &attributes);
+ applyComplexTypeAttributes(reader, ce, &attributes);
+ }
break;
case StackElement::FunctionTypeEntry:
- element->entry = parseFunctionTypeEntry(reader, name, versionRange.since, &attributes);
- if (Q_UNLIKELY(!element->entry))
+ top->entry = parseFunctionTypeEntry(reader, name, versionRange.since, &attributes);
+ if (Q_UNLIKELY(!top->entry))
return false;
break;
case StackElement::TypedefTypeEntry:
- if (TypedefEntry *te = parseTypedefEntry(reader, name, versionRange.since, &attributes)) {
- applyComplexTypeAttributes(reader, te, &attributes);
- element->entry = te;
- } else {
+ top->entry = parseTypedefEntry(reader, name, topElement,
+ versionRange.since, &attributes);
+ if (top->entry == nullptr)
return false;
- }
break;
default:
Q_ASSERT(false);
}
- if (element->entry) {
- if (checkDuplicatedTypeEntry(reader, element->type, element->entry->name())
- && !m_database->addType(element->entry, &m_error)) {
+ if (top->entry) {
+ if (checkDuplicatedTypeEntry(reader, element, top->entry->name())
+ && !m_context->db->addType(top->entry, &m_error)) {
return false;
}
} else {
qCWarning(lcShiboken).noquote().nospace()
- << u"Type: "_qs + name + u" was rejected by typesystem"_qs;
+ << u"Type: "_s + name + u" was rejected by typesystem"_s;
}
- } else if (element->type == StackElement::InjectDocumentation) {
- if (!parseInjectDocumentation(reader, &attributes))
+ } else if (element == StackElement::InjectDocumentation) {
+ if (!parseInjectDocumentation(reader, topElement, &attributes))
return false;
- } else if (element->type == StackElement::ModifyDocumentation) {
- if (!parseModifyDocumentation(reader, &attributes))
+ } else if (element == StackElement::ModifyDocumentation) {
+ if (!parseModifyDocumentation(reader, topElement, &attributes))
return false;
- } else if (element->type != StackElement::None) {
- bool topLevel = element->type == StackElement::Root
- || element->type == StackElement::SuppressedWarning
- || element->type == StackElement::Rejection
- || element->type == StackElement::LoadTypesystem
- || element->type == StackElement::InjectCode
- || element->type == StackElement::ExtraIncludes
- || element->type == StackElement::SystemInclude
- || element->type == StackElement::ConversionRule
- || element->type == StackElement::AddFunction
- || element->type == StackElement::Template;
-
- if (!topLevel && m_current->type == StackElement::Root) {
- m_error = u"Tag requires parent: '"_qs + tagName.toString() + u'\'';
+ } else if (element != StackElement::None) {
+ bool topLevel = element == StackElement::Root
+ || element == StackElement::SuppressedWarning
+ || element == StackElement::Rejection
+ || element == StackElement::LoadTypesystem
+ || element == StackElement::InjectCode
+ || element == StackElement::ExtraIncludes
+ || element == StackElement::SystemInclude
+ || element == StackElement::ConversionRule
+ || element == StackElement::AddFunction
+ || element == StackElement::DeclareFunction
+ || 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'\'';
return false;
}
- StackElement topElement = !m_current ? StackElement(nullptr) : *m_current;
- element->entry = topElement.entry;
-
- switch (element->type) {
+ switch (element) {
case StackElement::Root:
- element->entry = parseRootElement(reader, versionRange.since, &attributes);
- element->type = StackElement::Root;
+ top->entry = parseRootElement(reader, versionRange.since, &attributes);
break;
case StackElement::LoadTypesystem:
if (!loadTypesystem(reader, &attributes))
@@ -3163,15 +3485,24 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader)
return false;
break;
case StackElement::TargetToNative: {
- if (topElement.type != StackElement::ConversionRule) {
- m_error = QLatin1String("Target to Native conversions can only be specified for custom conversion rules.");
+ if (topElement != StackElement::ConversionRule) {
+ m_error = u"Target to Native conversions can only be specified for custom conversion rules."_s;
return false;
}
- const int replaceIndex = indexOfAttribute(attributes, replaceAttribute());
- const bool replace = replaceIndex == -1
- || convertBoolean(attributes.takeAt(replaceIndex).value(),
- replaceAttribute(), true);
- m_current->entry->customConversion()->setReplaceOriginalTargetToNativeConversions(replace);
+
+ const auto topParent = m_stack.value(m_stack.size() - 3, StackElement::None);
+ if (isTypeEntry(topParent)) {
+ const auto replaceIndex = indexOfAttribute(attributes, replaceAttribute);
+ const bool replace = replaceIndex == -1
+ || convertBoolean(attributes.takeAt(replaceIndex).value(),
+ replaceAttribute, true);
+ auto customConversion = CustomConversion::getCustomConversion(top->entry);
+ if (!customConversion) {
+ m_error = msgMissingCustomConversion(top->entry);
+ return false;
+ }
+ customConversion->setReplaceOriginalTargetToNativeConversions(replace);
+ }
}
break;
case StackElement::AddConversion:
@@ -3191,14 +3522,17 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader)
return false;
break;
case StackElement::SuppressedWarning: {
- const int 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_database->addSuppressedWarning(suppressedWarning, &m_error))
+ if (!m_context->db->addSuppressedWarning(suppressedWarning,
+ m_generate == TypeEntry::GenerateCode,
+ &m_error)) {
return false;
+ }
}
}
break;
@@ -3207,12 +3541,12 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader)
return false;
break;
case StackElement::RemoveArgument:
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("Removing argument requires argument modification as parent");
+ if (topElement != StackElement::ModifyArgument) {
+ m_error = u"Removing argument requires argument modification as parent"_s;
return false;
}
- m_contextStack.top()->functionMods.last().argument_mods().last().setRemoved(true);
+ top->functionMods.last().argument_mods().last().setRemoved(true);
break;
case StackElement::ModifyField:
@@ -3221,7 +3555,11 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader)
break;
case StackElement::DeclareFunction:
case StackElement::AddFunction:
- if (!parseAddFunction(reader, topElement, element->type, &attributes))
+ if (!parseAddFunction(reader, topElement, element, &attributes))
+ return false;
+ break;
+ case StackElement::AddPyMethodDef:
+ if (!parseAddPyMethodDef(reader, topElement, &attributes))
return false;
break;
case StackElement::Property:
@@ -3237,12 +3575,7 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader)
return false;
break;
case StackElement::RemoveDefaultExpression:
- m_contextStack.top()->functionMods.last().argument_mods().last().setRemovedDefaultExpression(true);
- break;
- case StackElement::CustomMetaConstructor:
- case StackElement::CustomMetaDestructor:
- element->value.customFunction =
- parseCustomMetaConstructor(reader, element->type, topElement, &attributes);
+ top->functionMods.last().argument_mods().last().setRemovedDefaultExpression(true);
break;
case StackElement::ReferenceCount:
if (!parseReferenceCount(reader, topElement, &attributes))
@@ -3253,46 +3586,52 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader)
return false;
break;
case StackElement::Array:
- if (topElement.type != StackElement::ModifyArgument) {
- m_error = QLatin1String("array must be child of modify-argument");
+ if (topElement != StackElement::ModifyArgument) {
+ m_error = u"array must be child of modify-argument"_s;
return false;
}
- m_contextStack.top()->functionMods.last().argument_mods().last().setArray(true);
+ top->functionMods.last().argument_mods().last().setArray(true);
break;
case StackElement::InjectCode:
- if (!parseInjectCode(reader, topElement, element.get(), &attributes))
+ if (!parseInjectCode(reader, topElement, &attributes))
return false;
break;
case StackElement::Include:
- if (!parseInclude(reader, topElement, element->entry, &attributes))
+ if (!parseInclude(reader, topElement, top->entry, &attributes))
return false;
break;
case StackElement::Rejection:
- if (!addRejection(m_database, &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 int nameIndex = indexOfAttribute(attributes, nameAttribute());
+ const auto nameIndex = indexOfAttribute(attributes, nameAttribute);
if (nameIndex == -1) {
- m_error = msgMissingAttribute(nameAttribute());
+ m_error = msgMissingAttribute(nameAttribute);
return false;
}
- element->value.templateEntry =
- new TemplateEntry(attributes.takeAt(nameIndex).value().toString());
+ m_templateEntry.reset(new TemplateEntry(attributes.takeAt(nameIndex).value().toString()));
}
break;
- case StackElement::TemplateInstanceEnum:
- element->value.templateInstance =
- parseTemplateInstanceEnum(reader, topElement, &attributes);
- if (!element->value.templateInstance)
+ case StackElement::InsertTemplate:
+ m_templateInstance.reset(parseInsertTemplate(reader, topElement, &attributes));
+ if (!m_templateInstance)
return false;
break;
case StackElement::Replace:
- if (!parseReplace(reader, topElement, element.get(), &attributes))
+ 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:
@@ -3305,6 +3644,5 @@ bool TypeSystemParser::startElement(const ConditionalStreamReader &reader)
qCWarning(lcShiboken, "%s", qPrintable(msgReaderWarning(reader, message)));
}
- m_current = element.release();
return true;
}
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.h b/sources/shiboken6/ApiExtractor/typesystemparser.h
deleted file mode 100644
index 903e84421..000000000
--- a/sources/shiboken6/ApiExtractor/typesystemparser.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef TYPESYSTEMPARSER_H
-#define TYPESYSTEMPARSER_H
-
-#include "typesystem.h"
-#include "modifications.h"
-
-#include <QtCore/QStack>
-#include <QtCore/QHash>
-#include <QtCore/QScopedPointer>
-
-QT_FORWARD_DECLARE_CLASS(QVersionNumber)
-QT_FORWARD_DECLARE_CLASS(QXmlStreamAttributes)
-QT_FORWARD_DECLARE_CLASS(QXmlStreamReader)
-
-class ConditionalStreamReader;
-
-class TypeSystemEntityResolver;
-class TypeDatabase;
-class StackElement
-{
- public:
- enum ElementType {
- None = 0x0,
-
- // Type tags (0x1, ... , 0xff)
- ObjectTypeEntry = 0x1,
- ValueTypeEntry = 0x2,
- InterfaceTypeEntry = 0x3,
- NamespaceTypeEntry = 0x4,
- ComplexTypeEntryMask = 0x7,
-
- // Non-complex type tags (0x8, 0x9, ... , 0xf)
- PrimitiveTypeEntry = 0x8,
- EnumTypeEntry = 0x9,
- ContainerTypeEntry = 0xa,
- FunctionTypeEntry = 0xb,
- CustomTypeEntry = 0xc,
- SmartPointerTypeEntry = 0xd,
- TypedefTypeEntry = 0xe,
- TypeEntryMask = 0xf,
-
- // Documentation tags
- InjectDocumentation = 0x10,
- ModifyDocumentation = 0x20,
- DocumentationMask = 0xf0,
-
- // Simple tags (0x100, 0x200, ... , 0xf00)
- ExtraIncludes = 0x0100,
- Include = 0x0200,
- ModifyFunction = 0x0300,
- ModifyField = 0x0400,
- Root = 0x0500,
- CustomMetaConstructor = 0x0600,
- CustomMetaDestructor = 0x0700,
- SuppressedWarning = 0x0900,
- Rejection = 0x0a00,
- LoadTypesystem = 0x0b00,
- RejectEnumValue = 0x0c00,
- Template = 0x0d00,
- TemplateInstanceEnum = 0x0e00,
- Replace = 0x0f00,
- AddFunction = 0x1000,
- DeclareFunction = 0x1100,
- NativeToTarget = 0x1200,
- TargetToNative = 0x1300,
- AddConversion = 0x1400,
- SystemInclude = 0x1500,
- Property = 0x1600,
- SimpleMask = 0x3f00,
-
- // Code snip tags (0x1000, 0x2000, ... , 0xf000)
- InjectCode = 0x4000,
- InjectCodeInFunction = 0x8000,
- CodeSnipMask = 0xc000,
-
- // Function modifier tags (0x010000, 0x020000, ... , 0xf00000)
- Rename = 0x040000, // (modify-argument)
- ModifyArgument = 0x080000,
- Thread = 0x100000,
- FunctionModifiers = 0xff0000,
-
- // Argument modifier tags (0x01000000 ... 0xf0000000)
- ConversionRule = 0x01000000,
- ReplaceType = 0x02000000,
- ReplaceDefaultExpression = 0x04000000,
- RemoveArgument = 0x08000000,
- DefineOwnership = 0x10000000,
- RemoveDefaultExpression = 0x20000000,
- NoNullPointers = 0x40000000,
- ReferenceCount = 0x80000000,
- ParentOwner = 0x90000000,
- Array = 0xA0000000,
- ArgumentModifiers = 0xff000000
- };
-
- StackElement(StackElement *p) : entry(nullptr), type(None), parent(p) { }
-
- TypeEntry* entry;
- ElementType type;
- StackElement *parent;
-
- union {
- TemplateInstance* templateInstance;
- TemplateEntry* templateEntry;
- CustomFunction* customFunction;
- } value;
-};
-
-struct StackElementContext
-{
- CodeSnipList codeSnips;
- AddedFunctionList addedFunctions;
- FunctionModificationList functionMods;
- FieldModificationList fieldMods;
- DocModificationList docModifications;
- int addedFunctionModificationIndex = -1;
-};
-
-class TypeSystemParser
-{
-public:
- Q_DISABLE_COPY(TypeSystemParser)
-
- TypeSystemParser(TypeDatabase* database, bool generate);
- ~TypeSystemParser();
-
- bool parse(ConditionalStreamReader &reader);
-
- QString errorString() const { return m_error; }
-
-private:
- bool parseXml(ConditionalStreamReader &reader);
- bool setupSmartPointerInstantiations();
- bool startElement(const ConditionalStreamReader &reader);
- SmartPointerTypeEntry *parseSmartPointerEntry(const ConditionalStreamReader &,
- const QString &name,
- const QVersionNumber &since,
- QXmlStreamAttributes *attributes);
- bool endElement(QStringView localName);
- template <class String> // QString/QStringRef
- bool characters(const String &ch);
-
- bool importFileElement(const QXmlStreamAttributes &atts);
-
- const TypeEntry *currentParentTypeEntry() const;
- bool checkRootElement();
- bool applyCommonAttributes(const ConditionalStreamReader &reader, TypeEntry *type,
- QXmlStreamAttributes *attributes);
- PrimitiveTypeEntry *
- parsePrimitiveTypeEntry(const ConditionalStreamReader &, const QString &name,
- const QVersionNumber &since, QXmlStreamAttributes *);
- CustomTypeEntry *
- parseCustomTypeEntry(const ConditionalStreamReader &, const QString &name,
- const QVersionNumber &since, QXmlStreamAttributes *);
- ContainerTypeEntry *
- parseContainerTypeEntry(const ConditionalStreamReader &, const QString &name,
- const QVersionNumber &since, QXmlStreamAttributes *);
- EnumTypeEntry *
- parseEnumTypeEntry(const ConditionalStreamReader &, const QString &name,
- const QVersionNumber &since, QXmlStreamAttributes *);
- FlagsTypeEntry *
- parseFlagsEntry(const ConditionalStreamReader &, EnumTypeEntry *enumEntry,
- QString flagName, const QVersionNumber &since,
- QXmlStreamAttributes *);
-
- NamespaceTypeEntry *
- parseNamespaceTypeEntry(const ConditionalStreamReader &,
- const QString &name, const QVersionNumber &since,
- QXmlStreamAttributes *attributes);
-
- ValueTypeEntry *
- parseValueTypeEntry(const ConditionalStreamReader &, const QString &name,
- const QVersionNumber &since, QXmlStreamAttributes *);
- FunctionTypeEntry *
- parseFunctionTypeEntry(const ConditionalStreamReader &, const QString &name,
- const QVersionNumber &since, QXmlStreamAttributes *);
- TypedefEntry *
- parseTypedefEntry(const ConditionalStreamReader &, const QString &name,
- const QVersionNumber &since, QXmlStreamAttributes *);
- void applyComplexTypeAttributes(const ConditionalStreamReader &, ComplexTypeEntry *ctype,
- QXmlStreamAttributes *) const;
- bool parseRenameFunction(const ConditionalStreamReader &, QString *name,
- QXmlStreamAttributes *);
- bool parseInjectDocumentation(const ConditionalStreamReader &, QXmlStreamAttributes *);
- bool parseModifyDocumentation(const ConditionalStreamReader &, QXmlStreamAttributes *);
- TypeSystemTypeEntry *
- parseRootElement(const ConditionalStreamReader &, const QVersionNumber &since,
- QXmlStreamAttributes *);
- bool loadTypesystem(const ConditionalStreamReader &, QXmlStreamAttributes *);
- bool parseRejectEnumValue(const ConditionalStreamReader &, QXmlStreamAttributes *);
- bool parseReplaceArgumentType(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *);
- bool parseCustomConversion(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *);
- bool parseAddConversion(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *);
- bool parseNativeToTarget(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *attributes);
- bool parseModifyArgument(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *attributes);
- bool parseNoNullPointer(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *attributes);
- bool parseDefineOwnership(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *);
- bool parseRename(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *);
- bool parseModifyField(const ConditionalStreamReader &, QXmlStreamAttributes *);
- bool parseAddFunction(const ConditionalStreamReader &, const StackElement &topElement,
- StackElement::ElementType t, QXmlStreamAttributes *);
- bool parseProperty(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *);
- bool parseModifyFunction(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *);
- bool parseReplaceDefaultExpression(const ConditionalStreamReader &,
- const StackElement &topElement, QXmlStreamAttributes *);
- static CustomFunction *
- parseCustomMetaConstructor(const ConditionalStreamReader &,
- StackElement::ElementType type,
- const StackElement &topElement, QXmlStreamAttributes *);
- bool parseReferenceCount(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *);
- bool parseParentOwner(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *);
- bool readFileSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip);
- bool parseInjectCode(const ConditionalStreamReader &, const StackElement &topElement,
- StackElement* element, QXmlStreamAttributes *);
- bool parseInclude(const ConditionalStreamReader &, const StackElement &topElement,
- TypeEntry *entry, QXmlStreamAttributes *);
- bool parseSystemInclude(const ConditionalStreamReader &, QXmlStreamAttributes *);
- TemplateInstance
- *parseTemplateInstanceEnum(const ConditionalStreamReader &, const StackElement &topElement,
- QXmlStreamAttributes *);
- bool parseReplace(const ConditionalStreamReader &, const StackElement &topElement,
- StackElement *element, QXmlStreamAttributes *);
- bool checkDuplicatedTypeEntry(const ConditionalStreamReader &reader,
- StackElement::ElementType t, const QString &name) const;
-
- TypeDatabase* m_database;
- StackElement* m_current = nullptr;
- StackElement* m_currentDroppedEntry = nullptr;
- int m_currentDroppedEntryDepth = 0;
- int m_ignoreDepth = 0;
- QString m_defaultPackage;
- QString m_defaultSuperclass;
- TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
- TypeSystem::AllowThread m_allowThread = TypeSystem::AllowThread::Unspecified;
- QString m_error;
- const TypeEntry::CodeGeneration m_generate;
-
- EnumTypeEntry* m_currentEnum = nullptr;
- QStack<StackElementContext*> m_contextStack;
-
- QString m_currentSignature;
- QString m_currentPath;
- QString m_currentFile;
- QScopedPointer<TypeSystemEntityResolver> m_entityResolver;
- QHash<SmartPointerTypeEntry *, QString> m_smartPointerInstantiations;
-};
-
-#endif // TYPESYSTEMPARSER_H
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser_p.h b/sources/shiboken6/ApiExtractor/typesystemparser_p.h
new file mode 100644
index 000000000..4d9d4fd92
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/typesystemparser_p.h
@@ -0,0 +1,297 @@
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+#ifndef TYPESYSTEMPARSER_H
+#define TYPESYSTEMPARSER_H
+
+#include "typesystem.h"
+#include "containertypeentry.h"
+#include "typedatabase.h"
+#include "typedatabase_p.h"
+#include "typesystem_typedefs.h"
+#include "codesnip.h"
+
+#include <QtCore/QStack>
+#include <QtCore/QHash>
+#include <QtCore/QScopedPointer>
+
+#include <memory>
+#include <optional>
+
+QT_FORWARD_DECLARE_CLASS(QVersionNumber)
+QT_FORWARD_DECLARE_CLASS(QXmlStreamAttributes)
+QT_FORWARD_DECLARE_CLASS(QXmlStreamReader)
+
+class ConditionalStreamReader;
+
+class TypeSystemEntityResolver;
+class TypeDatabase;
+
+class FlagsTypeEntry;
+class TypeSystemTypeEntry;
+class ValueTypeEntry;
+class EnumTypeEntry;
+
+enum class ParserState;
+
+enum class StackElement {
+ None,
+
+ // Type tags
+ ObjectTypeEntry,
+ FirstTypeEntry = ObjectTypeEntry,
+ ValueTypeEntry,
+ InterfaceTypeEntry,
+ NamespaceTypeEntry,
+ LastComplexTypeEntry = NamespaceTypeEntry,
+
+ // Non-complex type tags
+ PrimitiveTypeEntry,
+ EnumTypeEntry,
+ ContainerTypeEntry,
+ FunctionTypeEntry,
+ CustomTypeEntry,
+ SmartPointerTypeEntry,
+ TypedefTypeEntry,
+ LastTypeEntry = TypedefTypeEntry,
+
+ // Documentation tags
+ InjectDocumentation,
+ FirstDocumentation = InjectDocumentation,
+ ModifyDocumentation,
+ LastDocumentation = ModifyDocumentation,
+
+ // Simple tags
+ ExtraIncludes,
+ Include,
+ ModifyFunction,
+ ModifyField,
+ Root,
+ SuppressedWarning,
+ Rejection,
+ LoadTypesystem,
+ RejectEnumValue,
+ Template,
+ InsertTemplate,
+ Replace,
+ AddFunction,
+ AddPyMethodDef,
+ DeclareFunction,
+ NativeToTarget,
+ TargetToNative,
+ AddConversion,
+ SystemInclude,
+ Property,
+
+ // Code snip tags
+ InjectCode,
+
+ // Function modifier tags
+ Rename, // (modify-argument)
+ ModifyArgument,
+ Thread,
+
+ // Argument modifier tags
+ ConversionRule,
+ ReplaceType,
+ ReplaceDefaultExpression,
+ RemoveArgument,
+ DefineOwnership,
+ RemoveDefaultExpression,
+ NoNullPointers,
+ ReferenceCount,
+ ParentOwner,
+ Array,
+ ArgumentModifiers,
+
+ ImportFile,
+ OpaqueContainer,
+ Configuration,
+ Unimplemented
+};
+
+inline uint64_t operator&(StackElement s1, StackElement s2)
+{
+ return uint64_t(s1) & uint64_t(s2);
+}
+
+inline StackElement operator|(StackElement s1, StackElement s2)
+{
+ return StackElement(uint64_t(s1) | uint64_t(s2));
+}
+
+struct StackElementContext
+{
+ CodeSnipList conversionCodeSnips;
+ AddedFunctionList addedFunctions;
+ FunctionModificationList functionMods;
+ FieldModificationList fieldMods;
+ DocModificationList docModifications;
+ TypeEntryPtr entry;
+ int addedFunctionModificationIndex = -1;
+};
+
+class TypeSystemParser
+{
+public:
+ Q_DISABLE_COPY_MOVE(TypeSystemParser)
+
+ using StackElementContextPtr = std::shared_ptr<StackElementContext>;
+ using ContextStack = QStack<StackElementContextPtr>;
+
+ explicit TypeSystemParser(const std::shared_ptr<TypeDatabaseParserContext> &context,
+ bool generate);
+ ~TypeSystemParser();
+
+ bool parse(ConditionalStreamReader &reader);
+
+ 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);
+ SmartPointerTypeEntryPtr parseSmartPointerEntry(const ConditionalStreamReader &,
+ const QString &name,
+ const QVersionNumber &since,
+ QXmlStreamAttributes *attributes);
+ bool endElement(StackElement element);
+ template <class String> // QString/QStringRef
+ bool characters(const String &ch);
+
+ bool importFileElement(const QXmlStreamAttributes &atts);
+
+ TypeEntryCPtr currentParentTypeEntry() const;
+ bool checkRootElement();
+ bool applyCommonAttributes(const ConditionalStreamReader &reader,
+ const TypeEntryPtr &type,
+ QXmlStreamAttributes *attributes);
+ PrimitiveTypeEntryPtr
+ parsePrimitiveTypeEntry(const ConditionalStreamReader &, const QString &name,
+ const QVersionNumber &since, QXmlStreamAttributes *);
+ 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 *);
+ FlagsTypeEntryPtr
+ parseFlagsEntry(const ConditionalStreamReader &, const EnumTypeEntryPtr &enumEntry,
+ QString flagName, const QVersionNumber &since,
+ QXmlStreamAttributes *);
+
+ NamespaceTypeEntryPtr
+ parseNamespaceTypeEntry(const ConditionalStreamReader &,
+ const QString &name, const QVersionNumber &since,
+ QXmlStreamAttributes *attributes);
+
+ ValueTypeEntryPtr
+ parseValueTypeEntry(const ConditionalStreamReader &, const QString &name,
+ const QVersionNumber &since, QXmlStreamAttributes *);
+ FunctionTypeEntryPtr
+ parseFunctionTypeEntry(const ConditionalStreamReader &, const QString &name,
+ const QVersionNumber &since, QXmlStreamAttributes *);
+ TypedefEntryPtr
+ parseTypedefEntry(const ConditionalStreamReader &, const QString &name,
+ StackElement topElement,
+ 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,
+ QXmlStreamAttributes *);
+ bool parseModifyDocumentation(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *);
+ TypeSystemTypeEntryPtr
+ parseRootElement(const ConditionalStreamReader &, const QVersionNumber &since,
+ QXmlStreamAttributes *);
+ bool loadTypesystem(const ConditionalStreamReader &, QXmlStreamAttributes *);
+ bool parseRejectEnumValue(const ConditionalStreamReader &, QXmlStreamAttributes *);
+ bool parseReplaceArgumentType(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *);
+ bool parseCustomConversion(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *);
+ bool parseAddConversion(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *);
+ bool parseNativeToTarget(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *attributes);
+ bool parseModifyArgument(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *attributes);
+ bool parseNoNullPointer(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *attributes);
+ bool parseDefineOwnership(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *);
+ bool parseRename(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *);
+ bool parseModifyField(const ConditionalStreamReader &, QXmlStreamAttributes *);
+ bool parseAddFunction(const ConditionalStreamReader &, StackElement topElement,
+ StackElement t, QXmlStreamAttributes *);
+ bool parseAddPyMethodDef(const ConditionalStreamReader &,
+ 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 &,
+ StackElement topElement, QXmlStreamAttributes *);
+ bool parseReferenceCount(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *);
+ bool parseParentOwner(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *);
+ 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 *);
+ bool parseSystemInclude(const ConditionalStreamReader &, QXmlStreamAttributes *);
+ TemplateInstance
+ *parseInsertTemplate(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *);
+ bool parseReplace(const ConditionalStreamReader &, StackElement topElement,
+ QXmlStreamAttributes *);
+ bool checkDuplicatedTypeEntry(const ConditionalStreamReader &reader,
+ StackElement t, const QString &name) const;
+ ParserState parserState(qsizetype offset = 0) const;
+ CodeSnipAbstract *injectCodeTarget(qsizetype offset = 0) const;
+
+ std::shared_ptr<TypeDatabaseParserContext> m_context;
+ QStack<StackElement> m_stack;
+ int m_currentDroppedEntryDepth = 0;
+ int m_ignoreDepth = 0;
+ QString m_defaultPackage;
+ QString m_defaultSuperclass;
+ TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified;
+ TypeSystem::AllowThread m_allowThread = TypeSystem::AllowThread::Unspecified;
+ QString m_error;
+ const TypeEntry::CodeGeneration m_generate;
+
+ EnumTypeEntryPtr m_currentEnum;
+ TemplateInstancePtr m_templateInstance;
+ TemplateEntryPtr m_templateEntry;
+ ContextStack m_contextStack;
+
+ QString m_currentSignature;
+ QString m_currentPath;
+ QString m_currentFile;
+ QScopedPointer<TypeSystemEntityResolver> m_entityResolver;
+};
+
+#endif // TYPESYSTEMPARSER_H
diff --git a/sources/shiboken6/ApiExtractor/typesystemtypeentry.h b/sources/shiboken6/ApiExtractor/typesystemtypeentry.h
new file mode 100644
index 000000000..9b9670696
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/typesystemtypeentry.h
@@ -0,0 +1,40 @@
+// 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 TYPESYSTEMTYPEENTRY_H
+#define TYPESYSTEMTYPEENTRY_H
+
+#include "typesystem.h"
+#include "modifications_typedefs.h"
+#include "typesystem_enums.h"
+#include "typesystem_typedefs.h"
+
+class TypeSystemTypeEntry : public TypeEntry
+{
+public:
+ explicit TypeSystemTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ TypeEntry *clone() const override;
+
+ TypeSystem::SnakeCase snakeCase() const;
+ void setSnakeCase(TypeSystem::SnakeCase sc);
+
+ const CodeSnipList &codeSnips() const;
+ 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);
+};
+
+#endif // TYPESYSTEMTYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/usingmember.h b/sources/shiboken6/ApiExtractor/usingmember.h
index e3354f16d..346eab13c 100644
--- a/sources/shiboken6/ApiExtractor/usingmember.h
+++ b/sources/shiboken6/ApiExtractor/usingmember.h
@@ -1,43 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef USINGMEMBER_H
#define USINGMEMBER_H
#include "abstractmetalang_typedefs.h"
-#include "parser/codemodel.h"
+#include "parser/codemodel_enums.h"
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/valuetypeentry.h b/sources/shiboken6/ApiExtractor/valuetypeentry.h
new file mode 100644
index 000000000..97bc26803
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/valuetypeentry.h
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef VALUETYPEENTRY_H
+#define VALUETYPEENTRY_H
+
+#include "complextypeentry.h"
+#include "customconversion_typedefs.h"
+
+class ValueTypeEntry : public ComplexTypeEntry
+{
+public:
+ explicit ValueTypeEntry(const QString &entryName, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+
+ bool hasCustomConversion() const;
+ void setCustomConversion(const CustomConversionPtr &customConversion);
+ CustomConversionPtr customConversion() const;
+
+ // FIXME PYSIDE7: Remove
+ /// Set the target type conversion rule
+ void setTargetConversionRule(const QString &conversionRule);
+
+ /// Returns the target type conversion rule
+ QString targetConversionRule() const;
+
+ /// TODO-CONVERTER: mark as deprecated
+ bool hasTargetConversionRule() const;
+
+ bool isValue() const override;
+
+ TypeEntry *clone() const override;
+
+protected:
+ explicit ValueTypeEntry(const QString &entryName, Type t, const QVersionNumber &vr,
+ const TypeEntryCPtr &parent);
+ explicit ValueTypeEntry(ComplexTypeEntryPrivate *d);
+};
+
+#endif // VALUETYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/varargstypeentry.h b/sources/shiboken6/ApiExtractor/varargstypeentry.h
new file mode 100644
index 000000000..b2a4f4d30
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/varargstypeentry.h
@@ -0,0 +1,20 @@
+// 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 VARARGSTYPEENTRY_H
+#define VARARGSTYPEENTRY_H
+
+#include "typesystem.h"
+
+class VarargsTypeEntry : public TypeEntry
+{
+public:
+ VarargsTypeEntry();
+
+ TypeEntry *clone() const override;
+
+protected:
+ explicit VarargsTypeEntry(TypeEntryPrivate *d);
+};
+
+#endif // VARARGSTYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/voidtypeentry.h b/sources/shiboken6/ApiExtractor/voidtypeentry.h
new file mode 100644
index 000000000..372c7c01f
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/voidtypeentry.h
@@ -0,0 +1,20 @@
+// 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 VOIDTYPEENTRY_H
+#define VOIDTYPEENTRY_H
+
+#include "typesystem.h"
+
+class VoidTypeEntry : public TypeEntry
+{
+public:
+ VoidTypeEntry();
+
+ TypeEntry *clone() const override;
+
+protected:
+ explicit VoidTypeEntry(TypeEntryPrivate *d);
+};
+
+#endif // VOIDTYPEENTRY_H
diff --git a/sources/shiboken6/ApiExtractor/xmlutils.cpp b/sources/shiboken6/ApiExtractor/xmlutils.cpp
index 6edca2fa5..ccacd4ce7 100644
--- a/sources/shiboken6/ApiExtractor/xmlutils.cpp
+++ b/sources/shiboken6/ApiExtractor/xmlutils.cpp
@@ -1,35 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "xmlutils.h"
#include "xmlutils_libxslt.h"
+#include "qtcompat.h"
+
+using namespace Qt::StringLiterals;
+
XQuery::XQuery() = default;
XQuery::~XQuery() = default;
@@ -37,18 +16,18 @@ XQuery::~XQuery() = default;
QString XQuery::evaluate(QString xPathExpression, QString *errorMessage)
{
// XQuery can't have invalid XML characters
- xPathExpression.replace(QLatin1Char('&'), QLatin1String("&amp;"));
- xPathExpression.replace(QLatin1Char('<'), QLatin1String("&lt;"));
+ xPathExpression.replace(u'&', u"&amp;"_s);
+ xPathExpression.replace(u'<', u"&lt;"_s);
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 = QLatin1String(__FUNCTION__) + QLatin1String(" is not implemented.");
- return QSharedPointer<XQuery>();
+ *errorMessage = QLatin1StringView(__FUNCTION__) + u" is not implemented."_s;
+ return std::shared_ptr<XQuery>();
#endif
}
@@ -57,7 +36,7 @@ QString xsl_transform(const QString &xml, const QString &xsl, QString *errorMess
#if defined(HAVE_LIBXSLT)
return libXslt_transform(xml, xsl, errorMessage);
#else
- *errorMessage = QLatin1String(__FUNCTION__) + QLatin1String(" is not implemented.");
+ *errorMessage = QLatin1StringView(__FUNCTION__) + u" is not implemented."_s;
return xml;
#endif
}
diff --git a/sources/shiboken6/ApiExtractor/xmlutils.h b/sources/shiboken6/ApiExtractor/xmlutils.h
index 879b7757a..ac23c9c9c 100644
--- a/sources/shiboken6/ApiExtractor/xmlutils.h
+++ b/sources/shiboken6/ApiExtractor/xmlutils.h
@@ -1,46 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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 e1e185130..5a9a26913 100644
--- a/sources/shiboken6/ApiExtractor/xmlutils_libxslt.cpp
+++ b/sources/shiboken6/ApiExtractor/xmlutils_libxslt.cpp
@@ -1,34 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "xmlutils_libxslt.h"
#include "xmlutils.h"
+#include "qtcompat.h"
+
#include <QtCore/QByteArray>
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
@@ -44,6 +21,8 @@
#include <cstdlib>
#include <memory>
+using namespace Qt::StringLiterals;
+
static void cleanup()
{
xsltCleanupGlobals();
@@ -61,8 +40,6 @@ static void ensureInitialized()
}
}
-namespace {
-
// RAI Helpers for cleaning up libxml2/libxslt data
struct XmlDocDeleter // for std::unique_ptr<xmlDoc>
@@ -85,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>;
@@ -109,13 +84,13 @@ static QByteArray formatNode(xmlNodePtr node, QString *errorMessage)
xmlSaveToIO(qbXmlOutputWriteCallback, qbXmlOutputCloseCallback,
&result, "UTF-8", 0);
if (!saveContext) {
- *errorMessage = QLatin1String("xmlSaveToIO() failed.");
+ *errorMessage = u"xmlSaveToIO() failed."_s;
return result;
}
const long saveResult = xmlSaveTree(saveContext, node);
xmlSaveClose(saveContext);
if (saveResult < 0)
- *errorMessage = QLatin1String("xmlSaveTree() failed.");
+ *errorMessage = u"xmlSaveTree() failed."_s;
return result;
}
@@ -144,8 +119,8 @@ QString LibXmlXQuery::doEvaluate(const QString &xPathExpression, QString *errorM
XmlPathObjectUniquePtr xPathObject(xmlXPathEvalExpression(xPathExpressionX, m_xpathContext.get()));
if (!xPathObject) {
- *errorMessage = QLatin1String("xmlXPathEvalExpression() failed for \"") + xPathExpression
- + QLatin1Char('"');
+ *errorMessage = u"xmlXPathEvalExpression() failed for \""_s + xPathExpression
+ + u'"';
return QString();
}
QString result;
@@ -162,39 +137,42 @@ 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 = QLatin1String("libxml2: Cannot set focus to ") + QDir::toNativeSeparators(focus);
+ *errorMessage = u"libxml2: Cannot set focus to "_s + QDir::toNativeSeparators(focus);
return {};
}
XmlXPathContextUniquePtr xpathContext(xmlXPathNewContext(doc.get()));
if (!xpathContext) {
- *errorMessage = QLatin1String("libxml2: xmlXPathNewContext() failed");
+ *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(QLatin1String("<?xml"))) {
- xsl.prepend(QLatin1String(xsltPrefix));
- xsl.append(QLatin1String("</xsl:transform>"));
+ if (!xsl.startsWith(u"<?xml")) {
+ 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 = QLatin1String("xmlParseMemory() failed for XML.");
+ *errorMessage = u"xmlParseMemory() failed for XML."_s;
return xml;
}
@@ -203,15 +181,14 @@ QString libXslt_transform(const QString &xml, QString xsl, QString *errorMessage
// xsltFreeStylesheet will delete this pointer
xmlDocPtr xslDoc = xmlParseMemory(xslData.constData(), xslData.size());
if (!xslDoc) {
- *errorMessage = QLatin1String("xmlParseMemory() failed for XSL \"")
- + xsl + QLatin1String("\".");
+ *errorMessage = u"xmlParseMemory() failed for XSL \""_s + xsl + u"\"."_s;
return xml;
};
// Parse XSL data
XmlStyleSheetUniquePtr xslt(xsltParseStylesheetDoc(xslDoc));
if (!xslt) {
- *errorMessage = QLatin1String("xsltParseStylesheetDoc() failed.");
+ *errorMessage = u"xsltParseStylesheetDoc() failed."_s;
return xml;
}
@@ -224,7 +201,7 @@ QString libXslt_transform(const QString &xml, QString xsl, QString *errorMessage
result = QString::fromUtf8(reinterpret_cast<char*>(buffer), bufferSize);
std::free(buffer);
} else {
- *errorMessage = QLatin1String("xsltSaveResultToString() failed.");
+ *errorMessage = u"xsltSaveResultToString() failed."_s;
result = xml;
}
return result.trimmed();
diff --git a/sources/shiboken6/ApiExtractor/xmlutils_libxslt.h b/sources/shiboken6/ApiExtractor/xmlutils_libxslt.h
index c32b3901d..0dd8eafcb 100644
--- a/sources/shiboken6/ApiExtractor/xmlutils_libxslt.h
+++ b/sources/shiboken6/ApiExtractor/xmlutils_libxslt.h
@@ -1,39 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef XMLUTILS_LIBXSLT_H
#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 a9c9adfa2..274827044 100644
--- a/sources/shiboken6/ApiExtractor/xmlutils_qt.h
+++ b/sources/shiboken6/ApiExtractor/xmlutils_qt.h
@@ -1,39 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef XMLUTILS_QT_H
#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 de4b51c09..9e1bb09b3 100644
--- a/sources/shiboken6/CMakeLists.txt
+++ b/sources/shiboken6/CMakeLists.txt
@@ -1,227 +1,36 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
Include(icecc.cmake)
-cmake_minimum_required(VERSION 3.16)
-cmake_policy(VERSION 3.16)
+cmake_minimum_required(VERSION 3.18)
+cmake_policy(VERSION 3.18)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build Type")
+include(".cmake.conf")
project(shiboken6)
-include(CheckIncludeFileCXX)
-
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake_helpers/")
-list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/data/")
-
-include(helpers)
-include(shiboken_helpers)
-
-option(BUILD_TESTS "Build tests." TRUE)
-option(USE_PYTHON_VERSION "Use specific python version to build shiboken6." "")
-option(DISABLE_DOCSTRINGS "Disable documentation extraction." FALSE)
-
-set (QT_MAJOR_VERSION 6)
-message(STATUS "Using Qt ${QT_MAJOR_VERSION}")
-find_package(Qt${QT_MAJOR_VERSION} 6.0 REQUIRED COMPONENTS Core)
-
-if (QUIET_BUILD)
- set_quiet_build()
-endif()
-
-if (USE_PYTHON_VERSION)
- shiboken_find_required_python(${USE_PYTHON_VERSION})
-else()
- shiboken_find_required_python()
-endif()
-
-setup_clang()
-
-set(SHIBOKEN_VERSION_FILE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/shiboken_version.py")
-set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
- ${SHIBOKEN_VERSION_FILE_PATH}
-)
-execute_process(
- COMMAND ${PYTHON_EXECUTABLE} "${SHIBOKEN_VERSION_FILE_PATH}"
- OUTPUT_VARIABLE SHIBOKEN_VERSION_OUTPUT
- ERROR_VARIABLE SHIBOKEN_VERSION_OUTPUT_ERROR
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-if (NOT SHIBOKEN_VERSION_OUTPUT)
- message(FATAL_ERROR "Could not identify shiboken version. \
- Error: ${SHIBOKEN_VERSION_OUTPUT_ERROR}")
-endif()
-
-list(GET SHIBOKEN_VERSION_OUTPUT 0 shiboken_MAJOR_VERSION)
-list(GET SHIBOKEN_VERSION_OUTPUT 1 shiboken_MINOR_VERSION)
-list(GET SHIBOKEN_VERSION_OUTPUT 2 shiboken_MICRO_VERSION)
-# a - alpha, b - beta, rc - rc
-list(GET SHIBOKEN_VERSION_OUTPUT 3 shiboken_PRE_RELEASE_VERSION_TYPE)
-# the number of the pre release (alpha1, beta3, rc7, etc.)
-list(GET SHIBOKEN_VERSION_OUTPUT 4 shiboken_PRE_RELEASE_VERSION)
-
-set(shiboken6_VERSION "${shiboken_MAJOR_VERSION}.${shiboken_MINOR_VERSION}.${shiboken_MICRO_VERSION}")
-set(shiboken6_library_so_version "${shiboken_MAJOR_VERSION}.${shiboken_MINOR_VERSION}")
-
-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})
-
-if (NOT PYTHON_EXTENSION_SUFFIX)
- get_python_extension_suffix()
-endif()
-
-option(FORCE_LIMITED_API "Enable the limited API." "yes")
-set(PYTHON_LIMITED_API 0)
-
-shiboken_check_if_limited_api()
-
-if (PYTHON_LIMITED_API)
- set_limited_api()
-endif()
-
-if (NOT PYTHON_CONFIG_SUFFIX)
- set_python_config_suffix()
-endif()
-
-set(PYTHON_SHARED_LIBRARY_SUFFIX "${PYTHON_CONFIG_SUFFIX}")
-
-if (NOT PYTHON_CONFIG_SUFFIX)
- message(FATAL_ERROR
- "PYTHON_CONFIG_SUFFIX is empty. It should never be empty. Please file a bug report.")
-endif()
-
-message(STATUS "PYTHON_EXTENSION_SUFFIX: ${PYTHON_EXTENSION_SUFFIX}")
-message(STATUS "PYTHON_CONFIG_SUFFIX: ${PYTHON_CONFIG_SUFFIX}")
-message(STATUS "PYTHON_SHARED_LIBRARY_SUFFIX: ${PYTHON_SHARED_LIBRARY_SUFFIX}")
-
+include(cmake/ShibokenSetup.cmake)
-if (NOT PYTHON_SITE_PACKAGES)
- set_python_site_packages()
-endif()
-
-set_cmake_cxx_flags()
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D QT_NO_CAST_FROM_ASCII -D QT_NO_CAST_TO_ASCII")
-
-# Force usage of the C++17 standard
-set(CMAKE_CXX_STANDARD 17)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
+get_rpath_base_token(base)
-set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
-set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install \
- prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE)
-set(BIN_INSTALL_DIR "bin" CACHE PATH "The subdirectory relative to the install prefix where \
- dlls will be installed (default is /bin)" FORCE)
+set(CMAKE_INSTALL_RPATH ${base}/)
-if (WIN32)
- set(PATH_SEP "\;")
-else()
- set(PATH_SEP ":")
+if(SHIBOKEN_BUILD_TOOLS)
+ add_subdirectory(ApiExtractor) # Uses libclang
+ add_subdirectory(generator) # Uses ApiExtractor And QtCore
endif()
-if(CMAKE_HOST_APPLE)
- set(OSX_USE_LIBCPP "OFF" CACHE BOOL "Explicitly link the libc++ standard library \
- (useful for osx deployment targets lower than 10.9.")
- if(OSX_USE_LIBCPP)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
- endif()
+if(SHIBOKEN_BUILD_LIBS)
+ add_subdirectory(libshiboken) # Uses Python
+ add_subdirectory(shibokenmodule) # Uses libshiboken
+ add_subdirectory(data)
endif()
-# Build with Address sanitizer enabled if requested.
-# This may break things, so use at your own risk.
-if (SANITIZE_ADDRESS AND NOT MSVC)
- setup_sanitize_address()
-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:
- import sys
- import sysconfig
- config_py_debug = sysconfig.get_config_var('Py_DEBUG')
- print(bool(config_py_debug))
- "
- OUTPUT_VARIABLE PYTHON_WITH_DEBUG
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
-# Detect if python interpeter was compiled with COUNT_ALLOCS define
-# Linux distros are inconsistent in setting the sysconfig.get_config_var('COUNT_ALLOCS') value
-execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c "if True:
- count_allocs = False
- import sys
- try:
- if sys.getcounts:
- count_allocs = True
- except:
- pass
-
- print(bool(count_allocs))
- "
- OUTPUT_VARIABLE PYTHON_WITH_COUNT_ALLOCS
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
-set(SHIBOKEN_BUILD_TYPE "${CMAKE_BUILD_TYPE}")
-
-if(CMAKE_BUILD_TYPE STREQUAL "Debug")
- set_debug_build()
-endif()
-
-######################################################################
-## Define the Python files involved in the build process.
-##
-## They are installed into the file system (see shibokenmodule)
-## and embedded into the libshiboken binary through a .zip file.
-######################################################################
-
-set(shiboken_python_files
- "signature/lib/__init__.py"
- "signature/lib/enum_sig.py"
- "signature/lib/pyi_generator.py"
- "signature/lib/tool.py"
- "signature/__init__.py"
- "signature/errorhandler.py"
- "signature/importhandler.py"
- "signature/layout.py"
- "signature/loader.py"
- "signature/mapping.py"
- "signature/parser.py"
- "__init__.py"
- "feature.py"
- )
-
-######################################################################
-# Adding sub directories to build
-######################################################################
-add_subdirectory(ApiExtractor)
-
-set(generator_plugin_DIR ${LIB_INSTALL_DIR}/generatorrunner${generator_SUFFIX})
-
-# uninstall target
-configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake"
- "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
- IMMEDIATE @ONLY)
-add_custom_target(uninstall "${CMAKE_COMMAND}"
- -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
-
-add_subdirectory(libshiboken)
add_subdirectory(doc)
-# deps found, compile the generator.
-if (Qt${QT_MAJOR_VERSION}Core_FOUND AND PYTHONINTERP_FOUND)
- add_subdirectory(generator)
- add_subdirectory(shibokenmodule)
-
- if (BUILD_TESTS)
- enable_testing()
- add_subdirectory(tests)
- endif()
-else()
- message(WARNING "Some dependencies were not found: shiboken6 generator compilation disabled!")
+if(BUILD_TESTS)
+ enable_testing()
+ add_subdirectory(tests)
endif()
-add_subdirectory(data)
diff --git a/sources/shiboken6/cmake/FindDocTools.cmake b/sources/shiboken6/cmake/FindDocTools.cmake
new file mode 100644
index 000000000..621a4ac15
--- /dev/null
+++ b/sources/shiboken6/cmake/FindDocTools.cmake
@@ -0,0 +1,39 @@
+# 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
+# if it exists.
+find_program(DOT_EXEC dot)
+
+# Lookup for qdoc and qhelpgenerator in multiple sources: ccache var, PATH or CMake package.
+set(qhelpgenerator_binary "")
+set(qdoc_binary "")
+if(QHELPGENERATOR_EXECUTABLE)
+ set(qhelpgenerator_binary "${QHELPGENERATOR_EXECUTABLE}")
+else()
+ find_package(Qt6 QUIET COMPONENTS Tools)
+ if(TARGET Qt6::qhelpgenerator)
+ get_target_property(qhelpgenerator_binary Qt6::qhelpgenerator IMPORTED_LOCATION)
+ else()
+ find_program(QHELPGENERATOR_EXECUTABLE qhelpgenerator DOC "Path to qhelpgenerator binary.")
+ if(QHELPGENERATOR_EXECUTABLE)
+ set(qhelpgenerator_binary "${QHELPGENERATOR_EXECUTABLE}")
+ endif()
+ endif()
+endif()
+
+if(QDOC_EXECUTABLE)
+ set(qdoc_binary "${QDOC_EXECUTABLE}")
+else()
+ find_package(Qt6 QUIET COMPONENTS Tools)
+ if(TARGET Qt6::qdoc)
+ get_target_property(qdoc_binary Qt6::qdoc IMPORTED_LOCATION)
+ else()
+ find_program(QDOC_EXECUTABLE qdoc DOC "Path to qdoc binary.")
+ if(QDOC_EXECUTABLE)
+ set(qdoc_binary "${QDOC_EXECUTABLE}")
+ endif()
+ endif()
+endif()
diff --git a/sources/shiboken6/cmake/ShibokenHelpers.cmake b/sources/shiboken6/cmake/ShibokenHelpers.cmake
new file mode 100644
index 000000000..cff6df95e
--- /dev/null
+++ b/sources/shiboken6/cmake/ShibokenHelpers.cmake
@@ -0,0 +1,889 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+include(CMakeParseArguments)
+
+macro(set_limited_api)
+ if (WIN32 AND NOT EXISTS "${PYTHON_LIMITED_LIBRARIES}")
+ message(FATAL_ERROR "The Limited API was enabled, but ${PYTHON_LIMITED_LIBRARIES} was not found!")
+ endif()
+ message(STATUS "******************************************************")
+ message(STATUS "** Limited API enabled ${PYTHON_LIMITED_LIBRARIES}")
+ message(STATUS "******************************************************")
+endmacro()
+
+macro(set_debug_build)
+ set(SHIBOKEN_BUILD_TYPE "Debug")
+
+ if(NOT Python_LIBRARIES)
+ message(WARNING "Python debug shared library not found; \
+ assuming python was built with shared library support disabled.")
+ endif()
+
+ if(NOT PYTHON_WITH_DEBUG)
+ message(WARNING "Compiling shiboken6 with debug enabled, \
+ but the python executable was not compiled with debug support.")
+ else()
+ set(SBK_PKG_CONFIG_PY_DEBUG_DEFINITION " -DPy_DEBUG")
+ endif()
+
+ if (PYTHON_WITH_COUNT_ALLOCS)
+ set(SBK_PKG_CONFIG_PY_DEBUG_DEFINITION "${SBK_PKG_CONFIG_PY_DEBUG_DEFINITION} -DCOUNT_ALLOCS")
+ endif()
+endmacro()
+
+macro(setup_sanitize_address)
+ # Currently this does not check that the clang / gcc version used supports Address sanitizer,
+ # so once again, use at your own risk.
+ add_compile_options("-fsanitize=address" "-g" "-fno-omit-frame-pointer")
+ # We need to add the sanitize address option to all linked executables / shared libraries
+ # so that proper sanitizer symbols are linked in.
+ #
+ # Note that when running tests, you may need to set an additional environment variable
+ # in set_tests_properties for shiboken6 / pyside tests, or exported in your shell. Address
+ # sanitizer will tell you what environment variable needs to be exported. For example:
+ # export DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Toolchains/
+ # ./XcodeDefault.xctoolchain/usr/lib/clang/8.1.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
+ set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_STANDARD_LIBRARIES} -fsanitize=address")
+endmacro()
+
+macro(set_cmake_cxx_flags)
+if(MSVC)
+ # Qt5: this flag has changed from /Zc:wchar_t- in Qt4.X
+ set(CMAKE_CXX_FLAGS "/Zc:wchar_t /GR /EHsc /DWIN32 /D_WINDOWS /D_SCL_SECURE_NO_WARNINGS")
+ #set(CMAKE_CXX_FLAGS "/Zc:wchar_t /GR /EHsc /DNOCOLOR /DWIN32 /D_WINDOWS /D_SCL_SECURE_NO_WARNINGS") # XXX
+else()
+ set (gcc_warnings_options "-Wall -Wextra -Wno-strict-aliasing")
+ # Clang has -Wno-bad-function-cast, but does not need it.
+ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
+ set (gcc_warnings_options "${gcc_warnings_options} -Wno-cast-function-type")
+ endif()
+ if(CMAKE_HOST_UNIX AND NOT CYGWIN)
+ add_definitions(-fPIC)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${gcc_warnings_options} -fvisibility=hidden")
+ endif()
+ set(CMAKE_CXX_FLAGS_DEBUG "-g")
+ option(ENABLE_GCC_OPTIMIZATION "Enable specific GCC flags to optimization library \
+ size and performance. Only available on Release Mode" 0)
+ if(ENABLE_GCC_OPTIMIZATION)
+ set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -Os -Wl,-O1")
+ if(NOT CMAKE_HOST_APPLE)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--hash-style=gnu")
+ endif()
+ endif()
+ if(CMAKE_HOST_APPLE)
+ # ALTERNATIVE_QT_INCLUDE_DIR is deprecated, because CMake takes care of finding the proper
+ # include folders using the qmake found in the environment. Only use it for now in case
+ # something goes wrong with the cmake process.
+ if(ALTERNATIVE_QT_INCLUDE_DIR AND NOT QT_INCLUDE_DIR)
+ set(QT_INCLUDE_DIR ${ALTERNATIVE_QT_INCLUDE_DIR})
+ endif()
+ endif()
+endif()
+
+endmacro()
+
+function(qfp_strip_library target)
+ # Strip unless macOS (/strip: error: symbols referenced by indirect symbol
+ # table entries that can't be stripped).
+ if (CMAKE_STRIP AND UNIX AND NOT APPLE AND NOT QFP_NO_STRIP
+ AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
+ set(post_command COMMAND ${CMAKE_STRIP} $<TARGET_FILE:${target}>)
+ add_custom_command(TARGET ${target} POST_BUILD ${post_command})
+ endif()
+
+endfunction()
+
+macro(shiboken_internal_set_python_site_packages)
+ # When cross-building, we can't run the target python executable to find out the information,
+ # so we allow an explicit variable assignment or use a default / sensible value.
+ if(SHIBOKEN_IS_CROSS_BUILD OR PYSIDE_IS_CROSS_BUILD OR QFP_FIND_NEW_PYTHON_PACKAGE)
+ # Allow manual assignment.
+ if(QFP_PYTHON_SITE_PACKAGES)
+ set(PYTHON_SITE_PACKAGES "${QFP_PYTHON_SITE_PACKAGES}")
+ else()
+ # Assumes POSIX.
+ # Convention can be checked in cpython's source code in
+ # Lib/sysconfig.py's _INSTALL_SCHEMES
+ set(__version_major_minor
+ "${Python_VERSION_MAJOR}.${Python_VERSION_MINOR}")
+
+ set(PYTHON_SITE_PACKAGES_WITHOUT_PREFIX
+ "lib/python${__version_major_minor}/site-packages")
+ set(PYTHON_SITE_PACKAGES
+ "${CMAKE_INSTALL_PREFIX}/${PYTHON_SITE_PACKAGES_WITHOUT_PREFIX}")
+ unset(__version_major_minor)
+ endif()
+ else()
+ execute_process(
+ COMMAND ${Python_EXECUTABLE} -c "if True:
+ import sysconfig
+ from os.path import sep
+
+ # /home/qt/dev/env/lib/python3.9/site-packages
+ lib_path = sysconfig.get_path('purelib')
+
+ # /home/qt/dev/env
+ data_path = sysconfig.get_path('data')
+
+ # /lib/python3.9/site-packages
+ rel_path = lib_path.replace(data_path, '')
+
+ print(f'${CMAKE_INSTALL_PREFIX}{rel_path}'.replace(sep, '/'))
+ "
+ OUTPUT_VARIABLE PYTHON_SITE_PACKAGES
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif()
+ if (NOT PYTHON_SITE_PACKAGES)
+ message(FATAL_ERROR "Could not detect Python module installation directory.")
+ elseif (APPLE)
+ message(STATUS "!!! The generated bindings will be installed on ${PYTHON_SITE_PACKAGES}, \
+ is it right!?")
+ endif()
+endmacro()
+
+macro(set_python_config_suffix)
+ if (PYTHON_LIMITED_API)
+ if(WIN32)
+ set(PYTHON_EXTENSION_SUFFIX "")
+ else()
+ set(PYTHON_EXTENSION_SUFFIX ".abi3")
+ endif()
+ set(PYTHON_CONFIG_SUFFIX ".abi3")
+ else()
+ set(PYTHON_CONFIG_SUFFIX "${PYTHON_EXTENSION_SUFFIX}")
+ endif()
+endmacro()
+
+macro(setup_clang)
+ # Find libclang using the environment variables LLVM_INSTALL_DIR,
+ # CLANG_INSTALL_DIR using standard cmake.
+ # Use CLANG_INCLUDE_DIRS and link to libclang.
+ if(DEFINED ENV{LLVM_INSTALL_DIR})
+ list(PREPEND CMAKE_PREFIX_PATH "$ENV{LLVM_INSTALL_DIR}")
+ list(PREPEND CMAKE_FIND_ROOT_PATH "$ENV{LLVM_INSTALL_DIR}")
+ elseif(DEFINED ENV{CLANG_INSTALL_DIR})
+ list(PREPEND CMAKE_PREFIX_PATH "$ENV{CLANG_INSTALL_DIR}")
+ list(PREPEND CMAKE_FIND_ROOT_PATH "$ENV{CLANG_INSTALL_DIR}")
+ endif()
+
+ find_package(Clang CONFIG REQUIRED)
+ # Need to explicitly handle the version check, because the Clang package doesn't.
+ if (LLVM_PACKAGE_VERSION AND LLVM_PACKAGE_VERSION VERSION_LESS "9.0")
+ message(FATAL_ERROR "You need LLVM version 9.0 or greater to build.")
+ endif()
+
+ # CLANG_LIBRARY is read out from the cmake cache to deploy libclang
+ get_target_property(CLANG_BUILD_TYPE libclang IMPORTED_CONFIGURATIONS)
+ get_target_property(CLANG_LIBRARY_NAME libclang IMPORTED_LOCATION_${CLANG_BUILD_TYPE})
+ set(CLANG_LIBRARY "${CLANG_LIBRARY_NAME}" CACHE FILEPATH "libclang")
+ message(STATUS "CLANG: ${Clang_DIR}, ${CLANG_LIBRARY} detected")
+endmacro()
+
+macro(set_quiet_build)
+ # Don't display "up-to-date / install" messages when installing, to reduce visual clutter.
+ set(CMAKE_INSTALL_MESSAGE NEVER)
+ # Override message not to display info messages when doing a quiet build.
+ function(message)
+ list(GET ARGV 0 MessageType)
+ if (MessageType STREQUAL FATAL_ERROR OR
+ MessageType STREQUAL SEND_ERROR OR
+ MessageType STREQUAL WARNING OR
+ MessageType STREQUAL AUTHOR_WARNING)
+ list(REMOVE_AT ARGV 0)
+ _message(${MessageType} "${ARGV}")
+ endif()
+ endfunction()
+endmacro()
+
+macro(get_python_extension_suffix)
+ # When cross-building, we can't run the target python executable to find out the information,
+ # so we rely on Python_SOABI being set by find_package(Python).
+ # Python_SOABI is only set by CMake 3.17+
+ # TODO: Lower this to CMake 3.16 if possible.
+ if(SHIBOKEN_IS_CROSS_BUILD)
+ if(NOT Python_SOABI)
+ message(FATAL_ERROR "Python_SOABI variable is empty.")
+ endif()
+ set(PYTHON_EXTENSION_SUFFIX ".${Python_SOABI}")
+ else()
+ # See PYSIDE-1841 / https://bugs.python.org/issue39825 for distutils vs sysconfig
+ execute_process(
+ COMMAND ${Python_EXECUTABLE} -c "if True:
+ import sys
+ if sys.version_info >= (3, 8, 2):
+ import sysconfig
+ suffix = sysconfig.get_config_var('EXT_SUFFIX')
+ else:
+ from distutils import sysconfig
+ suffix = sysconfig.get_config_var('EXT_SUFFIX')
+ pos = suffix.rfind('.')
+ if pos > 0:
+ print(suffix[:pos])
+ else:
+ print(f'Unable to determine PYTHON_EXTENSION_SUFFIX from EXT_SUFFIX: \"{suffix}\"',
+ file=sys.stderr)
+ "
+ OUTPUT_VARIABLE PYTHON_EXTENSION_SUFFIX
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif()
+ message(STATUS "PYTHON_EXTENSION_SUFFIX: " ${PYTHON_EXTENSION_SUFFIX})
+endmacro()
+
+macro(shiboken_parse_all_arguments prefix type flags options multiopts)
+ cmake_parse_arguments(${prefix} "${flags}" "${options}" "${multiopts}" ${ARGN})
+ if(DEFINED ${prefix}_UNPARSED_ARGUMENTS)
+ message(FATAL_ERROR "Unknown arguments were passed to ${type} (${${prefix}_UNPARSED_ARGUMENTS}).")
+ endif()
+endmacro()
+
+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 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:
+ 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')
+ break
+ "
+ OUTPUT_VARIABLE PYTHON_LIMITED_LIBRARIES
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ endif()
+
+ message(STATUS "PYTHON_LIMITED_LIBRARIES: " ${PYTHON_LIMITED_LIBRARIES})
+
+ if(FORCE_LIMITED_API OR SHIBOKEN_PYTHON_LIMITED_API)
+ set(PYTHON_LIMITED_API 1)
+ if(WIN32)
+ set(SHIBOKEN_PYTHON_LIBRARIES ${PYTHON_LIMITED_LIBRARIES})
+ endif()
+ endif()
+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.
+ #
+ # 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)
+ # 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
+ # a host platform. python-config can likely be ran though, because it's a shell script
+ # to be run on a host Linux.
+ set(_shiboken_backup_CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
+ "${CMAKE_FIND_ROOT_PATH_MODE_PROGRAM}")
+ set(_shiboken_backup_CMAKE_FIND_ROOT_PATH
+ "${CMAKE_FIND_ROOT_PATH}")
+ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
+ if(Python_ROOT_DIR)
+ list(PREPEND CMAKE_FIND_ROOT_PATH "${Python_ROOT_DIR}")
+ endif()
+
+ # We can't look for the Python interpreter because FindPython tries to execute it, which
+ # usually won't work on a host platform due to different architectures / platforms.
+ # Thus we only look for the Python include and lib directories which are part of the
+ # Development component.
+ find_package(
+ Python
+ ${_shiboken_find_python_version_args}
+ REQUIRED
+ COMPONENTS Development
+ )
+ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM
+ "${_shiboken_backup_CMAKE_FIND_ROOT_PATH_MODE_PROGRAM}")
+ set(CMAKE_FIND_ROOT_PATH
+ "${_shiboken_backup_CMAKE_FIND_ROOT_PATH}")
+
+ # 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}")
+endmacro()
+
+macro(shiboken_validate_python_version)
+ if(Python_VERSION_MAJOR EQUAL "3" AND Python_VERSION_MINOR LESS "7")
+ message(FATAL_ERROR
+ "Shiboken requires Python 3.7+.")
+ endif()
+endmacro()
+
+macro(shiboken_compute_python_includes)
+ shiboken_parse_all_arguments(
+ "SHIBOKEN_COMPUTE_INCLUDES" "shiboken_compute_python_includes"
+ "IS_CALLED_FROM_EXPORT" "" "" ${ARGN})
+
+
+ # If the installed shiboken config file is used,
+ # append the found Python include dirs as an interface property on the libshiboken target.
+ # This needs to be dynamic because the user of the library might have python installed
+ # in a different path than when shiboken was originally built.
+ # Otherwise if shiboken is currently being built itself (either as standalone, or super project
+ # build) append the include dirs as PUBLIC.
+ 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})
+ else()
+ target_include_directories(libshiboken
+ PUBLIC $<BUILD_INTERFACE:${Python_INCLUDE_DIRS}>)
+ endif()
+
+
+ set(SHIBOKEN_PYTHON_INCLUDE_DIRS "${Python_INCLUDE_DIRS}")
+
+ set_property(GLOBAL PROPERTY shiboken_python_include_dirs "${SHIBOKEN_PYTHON_INCLUDE_DIRS}")
+
+ message(STATUS
+ "SHIBOKEN_PYTHON_INCLUDE_DIRS computed to value: '${SHIBOKEN_PYTHON_INCLUDE_DIRS}'")
+endmacro()
+
+# Given a list of the following form:
+# optimized;C:/Python36/libs/python36.lib;debug;C:/Python36/libs/python36_d.lib
+# choose the corresponding library to use, based on the current configuration type.
+function(shiboken_get_library_for_current_config library_list current_config out_var)
+ list(FIND library_list "optimized" optimized_found)
+ list(FIND library_list "general" general_found)
+ list(FIND library_list "debug" debug_found)
+
+ if (optimized_found OR general_found OR debug_found)
+ # Iterate over library list to find the most appropriate library.
+ foreach(token ${library_list})
+ if(token STREQUAL "optimized" OR token STREQUAL "general")
+ set(is_debug 0)
+ set(token1 1)
+ set(lib "")
+ elseif(token STREQUAL "debug")
+ set(is_debug 1)
+ set(token1 1)
+ set(lib "")
+ elseif(EXISTS ${token})
+ set(lib ${token})
+ set(token2 1)
+ else()
+ set(token1 0)
+ set(token2 0)
+ set(lib "")
+ endif()
+
+ if(token1 AND token2)
+ if((is_debug AND lib AND current_config STREQUAL "Debug")
+ OR (NOT is_debug AND lib AND (NOT current_config STREQUAL "Debug")))
+ set(${out_var} ${lib} PARENT_SCOPE)
+ return()
+ endif()
+ endif()
+ endforeach()
+ else()
+ # No configuration specific libraries found, just set the original value.
+ set(${out_var} "${library_list}" PARENT_SCOPE)
+ endif()
+
+endfunction()
+
+macro(shiboken_compute_python_libraries)
+ shiboken_parse_all_arguments(
+ "SHIBOKEN_COMPUTE_LIBS" "shiboken_compute_python_libraries"
+ "IS_CALLED_FROM_EXPORT" "" "" ${ARGN})
+
+ if (NOT SHIBOKEN_PYTHON_LIBRARIES)
+ set(SHIBOKEN_PYTHON_LIBRARIES "")
+ endif()
+
+ if(WIN32 AND NOT SHIBOKEN_PYTHON_LIBRARIES)
+ set(SHIBOKEN_PYTHON_LIBRARIES ${Python_LIBRARIES})
+ endif()
+
+ # If the resulting variable
+ # contains a "debug;X;optimized;Y" list like described in shiboken_check_if_limited_api,
+ # make sure to pick just one, so that the final generator expressions are valid.
+ shiboken_get_library_for_current_config("${SHIBOKEN_PYTHON_LIBRARIES}" "${CMAKE_BUILD_TYPE}" "SHIBOKEN_PYTHON_LIBRARIES")
+
+ if(APPLE)
+ set(SHIBOKEN_PYTHON_LIBRARIES "-undefined dynamic_lookup")
+ endif()
+
+ # If the installed shiboken config file is used,
+ # append the computed Python libraries as an interface property on the libshiboken target.
+ # This needs to be dynamic because the user of the library might have python installed
+ # in a different path than when shiboken was originally built.
+ # Otherwise if shiboken is currently being built itself (either as standalone, or super project
+ # build) append the libraries as PUBLIC.
+ if (SHIBOKEN_COMPUTE_LIBS_IS_CALLED_FROM_EXPORT)
+ #TODO target_link_libraries works on imported targets only starting with v3.11.0.
+ set_property(TARGET Shiboken6::libshiboken
+ APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${SHIBOKEN_PYTHON_LIBRARIES})
+ else()
+ target_link_libraries(libshiboken
+ PUBLIC $<BUILD_INTERFACE:${SHIBOKEN_PYTHON_LIBRARIES}>)
+ endif()
+
+ set_property(GLOBAL PROPERTY shiboken_python_libraries "${SHIBOKEN_PYTHON_LIBRARIES}")
+
+ message(STATUS "SHIBOKEN_PYTHON_LIBRARIES computed to value: '${SHIBOKEN_PYTHON_LIBRARIES}'")
+endmacro()
+
+function(shiboken_check_if_built_and_target_python_are_compatible)
+ 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}'")
+ else()
+ if(NOT SHIBOKEN_PYTHON_LIMITED_API
+ 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}'")
+ endif()
+ endif()
+endfunction()
+
+function(shiboken_internal_disable_pkg_config)
+ # Disable pkg-config by setting an empty executable path. There's no documented way to
+ # mark the package as not found, but we can force all pkg_check_modules calls to do nothing
+ # by setting the variable to an empty value.
+ set(PKG_CONFIG_EXECUTABLE "" CACHE STRING "Disabled pkg-config usage." FORCE)
+endfunction()
+
+function(shiboken_internal_disable_pkg_config_if_needed)
+ if(SHIBOKEN_SKIP_PKG_CONFIG_ADJUSTMENT)
+ return()
+ endif()
+
+ # pkg-config should not be used by default on Darwin platforms.
+ if(APPLE)
+ set(pkg_config_enabled OFF)
+ else()
+ set(pkg_config_enabled ON)
+ endif()
+
+ if(NOT pkg_config_enabled)
+ shiboken_internal_disable_pkg_config()
+ endif()
+endfunction()
+
+function(shiboken_internal_detect_if_cross_building)
+ if(CMAKE_CROSSCOMPILING OR QFP_SHIBOKEN_HOST_PATH)
+ set(is_cross_build TRUE)
+ else()
+ set(is_cross_build FALSE)
+ endif()
+ set(SHIBOKEN_IS_CROSS_BUILD "${is_cross_build}" PARENT_SCOPE)
+ message(STATUS "SHIBOKEN_IS_CROSS_BUILD: ${is_cross_build}")
+endfunction()
+
+function(shiboken_internal_decide_parts_to_build)
+ set(build_libs_default ON)
+ option(SHIBOKEN_BUILD_LIBS "Build shiboken libraries" ${build_libs_default})
+ message(STATUS "SHIBOKEN_BUILD_LIBS: ${SHIBOKEN_BUILD_LIBS}")
+
+ if(SHIBOKEN_IS_CROSS_BUILD)
+ set(build_tools_default OFF)
+ else()
+ set(build_tools_default ON)
+ endif()
+ option(SHIBOKEN_BUILD_TOOLS "Build shiboken tools" ${build_tools_default})
+ message(STATUS "SHIBOKEN_BUILD_TOOLS: ${SHIBOKEN_BUILD_TOOLS}")
+
+ if(SHIBOKEN_IS_CROSS_BUILD)
+ set(_shiboken_build_tests_default OFF)
+ elseif(SHIBOKEN_BUILD_LIBS)
+ set(_shiboken_build_tests_default ON)
+ endif()
+ option(BUILD_TESTS "Build tests." ${_shiboken_build_tests_default})
+ message(STATUS "BUILD_TESTS: ${BUILD_TESTS}")
+endfunction()
+
+function(shiboken_internal_find_host_shiboken_tools)
+ if(SHIBOKEN_IS_CROSS_BUILD)
+ set(find_package_extra_args)
+ if(QFP_SHIBOKEN_HOST_PATH)
+ list(APPEND find_package_extra_args PATHS "${QFP_SHIBOKEN_HOST_PATH}/lib/cmake")
+ list(PREPEND CMAKE_FIND_ROOT_PATH "${QFP_SHIBOKEN_HOST_PATH}")
+ endif()
+ find_package(
+ Shiboken6Tools 6 CONFIG
+ ${find_package_extra_args}
+ )
+
+ if(NOT Shiboken6Tools_DIR)
+ message(FATAL_ERROR
+ "Shiboken6Tools package was not found. "
+ "Please set QFP_SHIBOKEN_HOST_PATH to the location where the Shiboken6Tools CMake "
+ "package is installed.")
+ endif()
+ endif()
+endfunction()
+
+function(shiboken_internal_set_up_extra_dependency_paths)
+ set(extra_root_path_vars
+ QFP_QT_TARGET_PATH
+ QFP_PYTHON_TARGET_PATH
+ )
+ foreach(root_path IN LISTS extra_root_path_vars)
+ set(new_root_path_value "${${root_path}}")
+ if(new_root_path_value)
+ set(new_prefix_path "${CMAKE_PREFIX_PATH}")
+ list(PREPEND new_prefix_path "${new_root_path_value}/lib/cmake")
+ set(CMAKE_PREFIX_PATH "${new_prefix_path}")
+ set(CMAKE_PREFIX_PATH "${new_prefix_path}" PARENT_SCOPE)
+
+ # Need to adjust the prefix and root paths so that find_package(Qt) and other 3rd
+ # party packages are found successfully when they are located outside of the
+ # default sysroot (whatever that maybe for the target platform).
+ if(SHIBOKEN_IS_CROSS_BUILD)
+ set(new_root_path "${CMAKE_FIND_ROOT_PATH}")
+ list(PREPEND new_root_path "${new_root_path_value}")
+ set(CMAKE_FIND_ROOT_PATH "${new_root_path}")
+ set(CMAKE_FIND_ROOT_PATH "${new_root_path}" PARENT_SCOPE)
+ endif()
+ endif()
+ endforeach()
+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}'")
+ endif()
+
+ if (PACKAGE_SETUP_PY_PACKAGE_VERSION)
+ set(PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT "__setup_py_package_version__ = '${PACKAGE_SETUP_PY_PACKAGE_VERSION}'")
+ set(FINAL_PACKAGE_VERSION ${PACKAGE_SETUP_PY_PACKAGE_VERSION})
+ else()
+ set(FINAL_PACKAGE_VERSION ${${full_version_var_name}})
+ endif()
+
+ if (PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP)
+ set(PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "__setup_py_package_timestamp__ = '${PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP}'")
+ else()
+ set(PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "")
+ endif()
+
+ find_package(Git)
+ if(GIT_FOUND)
+ # Check if current source folder is inside a git repo, so that commit information can be
+ # queried.
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir
+ OUTPUT_VARIABLE PACKAGE_SOURCE_IS_INSIDE_REPO
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(PACKAGE_SOURCE_IS_INSIDE_REPO)
+ # Force git dates to be UTC-based.
+ set(ENV{TZ} UTC)
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} --no-pager show --date=format-local:%Y-%m-%dT%H:%M:%S+00:00 -s --format=%cd HEAD
+ OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_DATE
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(PACKAGE_BUILD_COMMIT_DATE)
+ set(PACKAGE_BUILD_COMMIT_DATE "__build_commit_date__ = '${PACKAGE_BUILD_COMMIT_DATE}'")
+ endif()
+ unset(ENV{TZ})
+
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
+ OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_HASH
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(PACKAGE_BUILD_COMMIT_HASH)
+ set(PACKAGE_BUILD_COMMIT_HASH "__build_commit_hash__ = '${PACKAGE_BUILD_COMMIT_HASH}'")
+ endif()
+
+ execute_process(
+ COMMAND ${GIT_EXECUTABLE} describe HEAD
+ OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_HASH_DESCRIBED
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ if(PACKAGE_BUILD_COMMIT_HASH_DESCRIBED)
+ set(PACKAGE_BUILD_COMMIT_HASH_DESCRIBED "__build_commit_hash_described__ = '${PACKAGE_BUILD_COMMIT_HASH_DESCRIBED}'")
+ endif()
+
+ endif()
+ endif()
+
+endmacro()
+
+# Creates a new target called "${library_name}_generator" which
+# depends on the mjb_rejected_classes.log file generated by shiboken.
+# This target is added as a dependency to ${library_name} target.
+# This file's timestamp informs cmake when the last generation was
+# done, without force-updating the timestamps of the generated class
+# cpp files.
+# In practical terms this means that changing some injection code in
+# an xml file that modifies only one specific class cpp file, will
+# not force rebuilding all the cpp files, and thus allow for better
+# incremental builds.
+macro(create_generator_target library_name)
+ add_custom_target(${library_name}_generator DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log")
+ add_dependencies(${library_name} ${library_name}_generator)
+endmacro()
+
+# Generate a shell script wrapper that sets environment variables for executing a specific tool.
+#
+# tool_name should be a unique tool name, preferably without spaces.
+# Returns the wrapper path in path_out_var.
+#
+# 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)
+ # Generate the wrapper only once during the execution of CMake.
+ get_property(is_called GLOBAL PROPERTY "_shiboken_tool_wrapper_${tool_name}_created")
+
+ if(is_called)
+ get_property(wrapper_path GLOBAL PROPERTY "_shiboken_tool_wrapper_${tool_name}_path")
+ set(${path_out_var} "${wrapper_path}" PARENT_SCOPE)
+ return()
+ endif()
+
+ 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((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()
+
+ 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 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()
+ # find libclang
+ find_libclang()
+ endif()
+
+ if(libclang_lib_dir)
+ list(APPEND path_dirs "${libclang_lib_dir}")
+ endif()
+
+ # Convert the paths from unix-style to native Windows style.
+ foreach(path_dir IN LISTS path_dirs)
+ if(EXISTS "${path_dir}")
+ file(TO_NATIVE_PATH "${path_dir}" path_dir_native)
+ list(APPEND path_dirs_native "${path_dir_native}")
+ endif()
+ endforeach()
+
+ set(wrapper_dir "${CMAKE_BINARY_DIR}/.qfp/bin")
+ file(MAKE_DIRECTORY "${wrapper_dir}")
+ set(wrapper_path "${wrapper_dir}/${tool_name}_wrapper${wrapper_script_extension}")
+
+ 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
new file mode 100644
index 000000000..32823d9fa
--- /dev/null
+++ b/sources/shiboken6/cmake/ShibokenSetup.cmake
@@ -0,0 +1,192 @@
+# 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(DISABLE_DOCSTRINGS "Disable documentation extraction." FALSE)
+
+shiboken_internal_disable_pkg_config_if_needed()
+shiboken_internal_detect_if_cross_building()
+
+# Note: For cross building, we rely on FindPython shipped with CMake 3.17+ to
+# provide the value of Python_SOABI.
+
+shiboken_internal_decide_parts_to_build()
+shiboken_internal_find_host_shiboken_tools()
+shiboken_internal_set_up_extra_dependency_paths()
+
+set(QT_MAJOR_VERSION 6)
+message(STATUS "Using Qt ${QT_MAJOR_VERSION}")
+find_package(Qt6 REQUIRED COMPONENTS Core)
+
+if(QUIET_BUILD)
+ set_quiet_build()
+endif()
+
+if(USE_PYTHON_VERSION)
+ shiboken_find_required_python(${USE_PYTHON_VERSION})
+else()
+ shiboken_find_required_python()
+endif()
+
+if(SHIBOKEN_BUILD_TOOLS)
+ setup_clang()
+endif()
+
+set(shiboken6_VERSION "${shiboken_MAJOR_VERSION}.${shiboken_MINOR_VERSION}.${shiboken_MICRO_VERSION}")
+set(shiboken6_library_so_version "${shiboken_MAJOR_VERSION}.${shiboken_MINOR_VERSION}")
+
+compute_config_py_values(shiboken6_VERSION)
+
+## For debugging the PYTHON* variables
+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()
+endif()
+
+option(FORCE_LIMITED_API "Enable the limited API." "yes")
+set(PYTHON_LIMITED_API 0)
+
+shiboken_check_if_limited_api()
+
+if(PYTHON_LIMITED_API)
+ set_limited_api()
+endif()
+
+if(NOT PYTHON_CONFIG_SUFFIX)
+ set_python_config_suffix()
+endif()
+
+set(PYTHON_SHARED_LIBRARY_SUFFIX "${PYTHON_CONFIG_SUFFIX}")
+
+if(NOT PYTHON_CONFIG_SUFFIX)
+ message(FATAL_ERROR
+ "PYTHON_CONFIG_SUFFIX is empty. It should never be empty. Please file a bug report.")
+endif()
+
+message(STATUS "PYTHON_EXTENSION_SUFFIX: ${PYTHON_EXTENSION_SUFFIX}")
+message(STATUS "PYTHON_CONFIG_SUFFIX: ${PYTHON_CONFIG_SUFFIX}")
+message(STATUS "PYTHON_SHARED_LIBRARY_SUFFIX: ${PYTHON_SHARED_LIBRARY_SUFFIX}")
+
+
+if(NOT PYTHON_SITE_PACKAGES)
+ shiboken_internal_set_python_site_packages()
+endif()
+
+set_cmake_cxx_flags()
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D QT_NO_CAST_FROM_ASCII -D QT_NO_CAST_TO_ASCII")
+
+# Force usage of the C++17 standard
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
+set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install \
+ prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE)
+set(BIN_INSTALL_DIR "bin" CACHE PATH "The subdirectory relative to the install prefix where \
+ dlls will be installed (default is /bin)" FORCE)
+
+if(WIN32)
+ set(PATH_SEP "\;")
+else()
+ set(PATH_SEP ":")
+endif()
+
+if(CMAKE_HOST_APPLE)
+ set(OSX_USE_LIBCPP "OFF" CACHE BOOL "Explicitly link the libc++ standard library \
+ (useful for macOS deployment targets lower than 10.9.")
+ if(OSX_USE_LIBCPP)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
+ endif()
+endif()
+
+# Build with Address sanitizer enabled if requested.
+# This may break things, so use at your own risk.
+if(SANITIZE_ADDRESS AND NOT MSVC)
+ setup_sanitize_address()
+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:
+ import sys
+ import sysconfig
+ config_py_debug = sysconfig.get_config_var('Py_DEBUG')
+ print(bool(config_py_debug))
+ "
+ OUTPUT_VARIABLE PYTHON_WITH_DEBUG
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+# Detect if python interpeter was compiled with COUNT_ALLOCS define
+# Linux distros are inconsistent in setting the sysconfig.get_config_var('COUNT_ALLOCS') value
+# We can't detect it when cross-building, because we can't run the target python executable.
+# TODO: Is there another way to detect this and is it relevant for cross-built python interpreters?
+# At the very least, upstream CPython removed COUNT_ALLOCS support in Python 3.9.
+if(SHIBOKEN_IS_CROSS_BUILD)
+ set(PYTHON_WITH_COUNT_ALLOCS 0)
+else()
+ execute_process(
+ COMMAND ${Python_EXECUTABLE} -c "if True:
+ count_allocs = False
+ import sys
+ try:
+ if sys.getcounts:
+ count_allocs = True
+ except:
+ pass
+
+ print(bool(count_allocs))
+ "
+ OUTPUT_VARIABLE PYTHON_WITH_COUNT_ALLOCS
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+endif()
+
+
+set(SHIBOKEN_BUILD_TYPE "${CMAKE_BUILD_TYPE}")
+
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ set_debug_build()
+endif()
+
+######################################################################
+## Define the Python files involved in the build process.
+##
+## They are installed into the file system (see shibokenmodule)
+## and embedded into the libshiboken binary through a .zip file.
+######################################################################
+
+set(shiboken_python_files
+ "signature/lib/__init__.py"
+ "signature/lib/enum_sig.py"
+ "signature/lib/pyi_generator.py"
+ "signature/lib/tool.py"
+ "signature/__init__.py"
+ "signature/errorhandler.py"
+ "signature/importhandler.py"
+ "signature/layout.py"
+ "signature/loader.py"
+ "signature/mapping.py"
+ "signature/parser.py"
+ "__init__.py"
+ "feature.py"
+ )
+
+# uninstall target
+configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+ IMMEDIATE @ONLY)
+add_custom_target(uninstall "${CMAKE_COMMAND}"
+ -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
+
+set(generator_plugin_DIR ${LIB_INSTALL_DIR}/generatorrunner${generator_SUFFIX})
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
new file mode 100644
index 000000000..b3f994017
--- /dev/null
+++ b/sources/shiboken6/config.tests/target_python_info/CMakeLists.txt
@@ -0,0 +1,47 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
+project(proj LANGUAGES CXX)
+
+include("${CMAKE_CURRENT_LIST_DIR}/../../cmake/ShibokenHelpers.cmake")
+
+shiboken_internal_detect_if_cross_building()
+shiboken_find_required_python()
+shiboken_internal_set_python_site_packages()
+
+message(STATUS "qfp:python_info:interpreter_found: ${Python_Interpreter_FOUND}")
+message(STATUS "qfp:python_info:development_found: ${Python_Development_FOUND}")
+message(STATUS "qfp:python_info:version: ${Python_VERSION}")
+message(STATUS "qfp:python_info:version_major: ${Python_VERSION_MAJOR}")
+message(STATUS "qfp:python_info:version_minor: ${Python_VERSION_MINOR}")
+message(STATUS "qfp:python_info:version_patch: ${Python_VERSION_PATCH}")
+message(STATUS "qfp:python_info:executable: ${Python_EXECUTABLE}")
+message(STATUS "qfp:python_info:include_dirs: ${Python_INCLUDE_DIRS}")
+message(STATUS "qfp:python_info:libraries: ${Python_LIBRARIES}")
+message(STATUS "qfp:python_info:library_dirs: ${Python_LIBRARY_DIRS}")
+message(STATUS "qfp:python_info:runtime_library_dirs: ${Python_RUNTIME_LIBRARY_DIRS}")
+# Python_SOABI will be empty with CMake < 3.17
+message(STATUS "qfp:python_info:so_abi: ${Python_SOABI}")
+message(STATUS "qfp:python_info:site_packages_dir: ${PYTHON_SITE_PACKAGES_WITHOUT_PREFIX}")
+message(STATUS "qfp:python_info:site_packages_dir_with_prefix: ${PYTHON_SITE_PACKAGES}")
+
+message(STATUS
+ "The following values might be unstable because they depend on private FindPython API")
+# This is using internal FindPython API and is subject to break.
+set(_PYTHON_PREFIX Python)
+if(COMMAND _python_get_config_var)
+ if(_${_PYTHON_PREFIX}_CONFIG)
+ message(STATUS "qfp:python_info:config_executable: ${_${_PYTHON_PREFIX}_CONFIG}")
+ endif()
+
+ _python_get_config_var(_${_PYTHON_PREFIX}_PREFIX PREFIX)
+ if(_${_PYTHON_PREFIX}_PREFIX)
+ message(STATUS "qfp:python_info:prefix: ${_${_PYTHON_PREFIX}_PREFIX}")
+ endif()
+ _python_get_config_var(_${_PYTHON_PREFIX}_CONFIGDIR CONFIGDIR)
+ if(_${_PYTHON_PREFIX}_CONFIGDIR)
+ message(STATUS "qfp:python_info:config_dir: ${_${_PYTHON_PREFIX}_CONFIGDIR}")
+ endif()
+endif()
+
diff --git a/sources/shiboken6/config.tests/target_qt_info/CMakeLists.txt b/sources/shiboken6/config.tests/target_qt_info/CMakeLists.txt
new file mode 100644
index 000000000..7cc6b6ffc
--- /dev/null
+++ b/sources/shiboken6/config.tests/target_qt_info/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
+project(proj LANGUAGES CXX)
+
+include("${CMAKE_CURRENT_LIST_DIR}/../../cmake/ShibokenHelpers.cmake")
+
+shiboken_internal_detect_if_cross_building()
+shiboken_internal_set_up_extra_dependency_paths()
+find_package(Qt6 REQUIRED COMPONENTS Core)
+
+include(FeatureSummary)
+
+feature_summary(INCLUDE_QUIET_PACKAGES
+ WHAT PACKAGES_FOUND
+ REQUIRED_PACKAGES_NOT_FOUND
+ RECOMMENDED_PACKAGES_NOT_FOUND
+ OPTIONAL_PACKAGES_NOT_FOUND
+ RUNTIME_PACKAGES_NOT_FOUND
+ FATAL_ON_MISSING_REQUIRED_PACKAGES)
+
+message(STATUS "qfp:qt_info:QT_VERSION: ${Qt6_VERSION}")
+message(STATUS "qfp:qt_info:QT_INSTALL_PREFIX: ${QT6_INSTALL_PREFIX}")
+message(STATUS "qfp:qt_info:QT_INSTALL_ARCHDATA: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_ARCHDATA}")
+message(STATUS "qfp:qt_info:QT_INSTALL_BINS: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_BINS}")
+message(STATUS "qfp:qt_info:QT_INSTALL_CONFIGURATION: ${QT6_INSTALL_CONFIGURATION}")
+message(STATUS "qfp:qt_info:QT_INSTALL_DATA: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_DATA}")
+message(STATUS "qfp:qt_info:QT_INSTALL_DOCS: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_DOCS}")
+message(STATUS "qfp:qt_info:QT_INSTALL_EXAMPLES: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_EXAMPLES}")
+message(STATUS "qfp:qt_info:QT_INSTALL_HEADERS: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_HEADERS}")
+message(STATUS "qfp:qt_info:QT_INSTALL_LIBS: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_LIBS}")
+message(STATUS "qfp:qt_info:QT_INSTALL_LIBEXECS: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_LIBEXECS}")
+message(STATUS "qfp:qt_info:QT_INSTALL_PLUGINS: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_PLUGINS}")
+message(STATUS "qfp:qt_info:QT_INSTALL_QML: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_QML}")
+message(STATUS "qfp:qt_info:QT_INSTALL_TESTS: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_TESTS}")
+message(STATUS "qfp:qt_info:QT_INSTALL_TRANSLATIONS: ${QT6_INSTALL_PREFIX}/${QT6_INSTALL_TRANSLATIONS}")
+message(STATUS "qfp:qt_info:is_shared: ${QT6_IS_SHARED_LIBS_BUILD}")
+
diff --git a/sources/shiboken6/config.tests/target_qt_mkspec/CMakeLists.txt b/sources/shiboken6/config.tests/target_qt_mkspec/CMakeLists.txt
new file mode 100644
index 000000000..9f6513316
--- /dev/null
+++ b/sources/shiboken6/config.tests/target_qt_mkspec/CMakeLists.txt
@@ -0,0 +1,25 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
+project(dummy LANGUAGES CXX)
+
+include("${CMAKE_CURRENT_LIST_DIR}/../../cmake/ShibokenHelpers.cmake")
+
+shiboken_internal_detect_if_cross_building()
+shiboken_internal_set_up_extra_dependency_paths()
+find_package(Qt6 REQUIRED COMPONENTS Core)
+
+get_target_property(darwin_target Qt6::Core QT_DARWIN_MIN_DEPLOYMENT_TARGET)
+
+# Get macOS minimum deployment target
+message(STATUS "qfp:qt_info:QMAKE_MACOSX_DEPLOYMENT_TARGET: ${darwin_target}")
+
+# Get Qt build type
+if(QT_FEATURE_debug_and_release)
+ message(STATUS "qfp:qt_info:BUILD_TYPE: debug_and_release")
+elseif(QT_FEATURE_debug)
+ message(STATUS "qfp:qt_info:BUILD_TYPE: debug")
+else()
+ message(STATUS "qfp:qt_info:BUILD_TYPE: release")
+endif()
diff --git a/sources/shiboken6/data/CMakeLists.txt b/sources/shiboken6/data/CMakeLists.txt
index 46bd1bfa9..679eefe6a 100644
--- a/sources/shiboken6/data/CMakeLists.txt
+++ b/sources/shiboken6/data/CMakeLists.txt
@@ -1,13 +1,12 @@
+# 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()
set(LIBRARY_OUTPUT_SUFFIX ${CMAKE_RELEASE_POSTFIX})
endif()
-add_custom_target(data)
-add_dependencies(data shiboken6)
-get_target_property(SHIBOKEN_GENERATOR shiboken6 OUTPUT_NAME)
-
include(CMakePackageConfigHelpers)
# Build-tree / super project package config file.
@@ -33,7 +32,7 @@ endif()
configure_package_config_file(
"${CMAKE_CURRENT_SOURCE_DIR}/Shiboken6Config-spec.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/install/Shiboken6Config${PYTHON_CONFIG_SUFFIX}.cmake"
- INSTALL_DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6-${shiboken6_VERSION}"
+ INSTALL_DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6"
PATH_VARS SHIBOKEN_PYTHON_MODULE_DIR SHIBOKEN_SHARED_LIBRARY_DIR
)
@@ -45,16 +44,16 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/shiboken6.pc.in"
"${CMAKE_CURRENT_BINARY_DIR}/shiboken6${shiboken6_SUFFIX}.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Shiboken6Config.cmake"
- DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6-${shiboken6_VERSION}")
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/install/Shiboken6Config${PYTHON_CONFIG_SUFFIX}.cmake"
- DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6-${shiboken6_VERSION}")
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Shiboken6ConfigVersion.cmake"
- DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6-${shiboken6_VERSION}")
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6")
-install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/shiboken_helpers.cmake"
- DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6-${shiboken6_VERSION}")
+install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/ShibokenHelpers.cmake"
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/Shiboken6")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/shiboken6${shiboken6_SUFFIX}.pc"
DESTINATION "${LIB_INSTALL_DIR}/pkgconfig")
diff --git a/sources/shiboken6/data/Shiboken6Config-spec.cmake.in b/sources/shiboken6/data/Shiboken6Config-spec.cmake.in
index 06518d253..233404bc6 100644
--- a/sources/shiboken6/data/Shiboken6Config-spec.cmake.in
+++ b/sources/shiboken6/data/Shiboken6Config-spec.cmake.in
@@ -5,19 +5,19 @@
# 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
# file (so not during a regular shiboken build, or during a super project build).
-if (NOT TARGET Shiboken6::shiboken6)
+if (NOT TARGET Shiboken6::libshiboken)
include("${CMAKE_CURRENT_LIST_DIR}/Shiboken6Targets.cmake")
- include("${CMAKE_CURRENT_LIST_DIR}/shiboken_helpers.cmake")
+ 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
new file mode 100644
index 000000000..438b5c651
--- /dev/null
+++ b/sources/shiboken6/data/Shiboken6ToolsConfig.cmake.in
@@ -0,0 +1,7 @@
+@PACKAGE_INIT@
+
+cmake_minimum_required(VERSION 3.18)
+
+if(NOT TARGET Shiboken6::shiboken6)
+ include("${CMAKE_CURRENT_LIST_DIR}/Shiboken6ToolsTargets.cmake")
+endif()
diff --git a/sources/shiboken6/data/shiboken6.pc.in b/sources/shiboken6/data/shiboken6.pc.in
index 2ff841840..a82d23168 100644
--- a/sources/shiboken6/data/shiboken6.pc.in
+++ b/sources/shiboken6/data/shiboken6.pc.in
@@ -1,13 +1,12 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
-libdir=@LIB_INSTALL_DIR@
+libdir=@CMAKE_INSTALL_PREFIX@/@LIB_INSTALL_DIR@
includedir=@CMAKE_INSTALL_PREFIX@/include/shiboken6
-generator_location=@CMAKE_INSTALL_PREFIX@/bin/@SHIBOKEN_GENERATOR@
-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/data/shiboken_helpers.cmake b/sources/shiboken6/data/shiboken_helpers.cmake
deleted file mode 100644
index 7e772c7fd..000000000
--- a/sources/shiboken6/data/shiboken_helpers.cmake
+++ /dev/null
@@ -1,365 +0,0 @@
-include(CMakeParseArguments)
-
-macro(set_limited_api)
- if (WIN32 AND NOT EXISTS "${PYTHON_LIMITED_LIBRARIES}")
- message(FATAL_ERROR "The Limited API was enabled, but ${PYTHON_LIMITED_LIBRARIES} was not found!")
- endif()
- message(STATUS "******************************************************")
- message(STATUS "** Limited API enabled ${PYTHON_LIMITED_LIBRARIES}")
- message(STATUS "******************************************************")
-endmacro()
-
-macro(set_debug_build)
- set(SHIBOKEN_BUILD_TYPE "Debug")
-
- if(NOT PYTHON_DEBUG_LIBRARIES)
- message(WARNING "Python debug shared library not found; \
- assuming python was built with shared library support disabled.")
- endif()
-
- if(NOT PYTHON_WITH_DEBUG)
- message(WARNING "Compiling shiboken6 with debug enabled, \
- but the python executable was not compiled with debug support.")
- else()
- set(SBK_PKG_CONFIG_PY_DEBUG_DEFINITION " -DPy_DEBUG")
- endif()
-
- if (PYTHON_WITH_COUNT_ALLOCS)
- set(SBK_PKG_CONFIG_PY_DEBUG_DEFINITION "${SBK_PKG_CONFIG_PY_DEBUG_DEFINITION} -DCOUNT_ALLOCS")
- endif()
-endmacro()
-
-macro(setup_sanitize_address)
- # Currently this does not check that the clang / gcc version used supports Address sanitizer,
- # so once again, use at your own risk.
- add_compile_options("-fsanitize=address" "-g" "-fno-omit-frame-pointer")
- # We need to add the sanitize address option to all linked executables / shared libraries
- # so that proper sanitizer symbols are linked in.
- #
- # Note that when running tests, you may need to set an additional environment variable
- # in set_tests_properties for shiboken6 / pyside tests, or exported in your shell. Address
- # sanitizer will tell you what environment variable needs to be exported. For example:
- # export DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Toolchains/
- # ./XcodeDefault.xctoolchain/usr/lib/clang/8.1.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
- set(CMAKE_CXX_STANDARD_LIBRARIES "${CMAKE_STANDARD_LIBRARIES} -fsanitize=address")
-endmacro()
-
-macro(set_cmake_cxx_flags)
-if(MSVC)
- # Qt5: this flag has changed from /Zc:wchar_t- in Qt4.X
- set(CMAKE_CXX_FLAGS "/Zc:wchar_t /GR /EHsc /DWIN32 /D_WINDOWS /D_SCL_SECURE_NO_WARNINGS")
- #set(CMAKE_CXX_FLAGS "/Zc:wchar_t /GR /EHsc /DNOCOLOR /DWIN32 /D_WINDOWS /D_SCL_SECURE_NO_WARNINGS") # XXX
-else()
- if(CMAKE_HOST_UNIX AND NOT CYGWIN)
- add_definitions(-fPIC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fvisibility=hidden -Wno-strict-aliasing")
- endif()
- set(CMAKE_CXX_FLAGS_DEBUG "-g")
- option(ENABLE_GCC_OPTIMIZATION "Enable specific GCC flags to optimization library \
- size and performance. Only available on Release Mode" 0)
- if(ENABLE_GCC_OPTIMIZATION)
- set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -Os -Wl,-O1")
- if(NOT CMAKE_HOST_APPLE)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--hash-style=gnu")
- endif()
- endif()
- if(CMAKE_HOST_APPLE)
- # ALTERNATIVE_QT_INCLUDE_DIR is deprecated, because CMake takes care of finding the proper
- # include folders using the qmake found in the environment. Only use it for now in case
- # something goes wrong with the cmake process.
- if(ALTERNATIVE_QT_INCLUDE_DIR AND NOT QT_INCLUDE_DIR)
- set(QT_INCLUDE_DIR ${ALTERNATIVE_QT_INCLUDE_DIR})
- endif()
- endif()
-endif()
-
-endmacro()
-
-macro(set_python_site_packages)
- execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c "if True:
- from distutils import sysconfig
- from os.path import sep
- print(sysconfig.get_python_lib(1, 0, prefix='${CMAKE_INSTALL_PREFIX}').replace(sep, '/'))
- "
- OUTPUT_VARIABLE PYTHON_SITE_PACKAGES
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- if (NOT PYTHON_SITE_PACKAGES)
- message(FATAL_ERROR "Could not detect Python module installation directory.")
- elseif (APPLE)
- message(STATUS "!!! The generated bindings will be installed on ${PYTHON_SITE_PACKAGES}, \
- is it right!?")
- endif()
-endmacro()
-
-macro(set_python_config_suffix)
- if (PYTHON_LIMITED_API)
- if(WIN32)
- set(PYTHON_EXTENSION_SUFFIX "")
- else()
- set(PYTHON_EXTENSION_SUFFIX ".abi3")
- endif()
- set(PYTHON_CONFIG_SUFFIX ".abi3")
- else()
- set(PYTHON_CONFIG_SUFFIX "${PYTHON_EXTENSION_SUFFIX}")
- endif()
-endmacro()
-
-macro(setup_clang)
- # Find libclang using the environment variables LLVM_INSTALL_DIR,
- # CLANG_INSTALL_DIR using standard cmake.
- # Use CLANG_INCLUDE_DIRS and link to libclang.
- if(DEFINED ENV{LLVM_INSTALL_DIR})
- list(PREPEND CMAKE_PREFIX_PATH "$ENV{LLVM_INSTALL_DIR}")
- list(PREPEND CMAKE_FIND_ROOT_PATH "$ENV{LLVM_INSTALL_DIR}")
- elseif(DEFINED ENV{CLANG_INSTALL_DIR})
- list(PREPEND CMAKE_PREFIX_PATH "$ENV{CLANG_INSTALL_DIR}")
- list(PREPEND CMAKE_FIND_ROOT_PATH "$ENV{CLANG_INSTALL_DIR}")
- endif()
-
- find_package(Clang CONFIG REQUIRED)
- # CLANG_LIBRARY is read out from the cmake cache to deploy libclang
- get_target_property(CLANG_BUILD_TYPE libclang IMPORTED_CONFIGURATIONS)
- get_target_property(CLANG_LIBRARY_NAME libclang IMPORTED_LOCATION_${CLANG_BUILD_TYPE})
- set(CLANG_LIBRARY "${CLANG_LIBRARY_NAME}" CACHE FILEPATH "libclang")
- message(STATUS "CLANG: ${Clang_DIR}, ${CLANG_LIBRARY} detected")
-endmacro()
-
-macro(set_quiet_build)
- # Don't display "up-to-date / install" messages when installing, to reduce visual clutter.
- set(CMAKE_INSTALL_MESSAGE NEVER)
- # Override message not to display info messages when doing a quiet build.
- function(message)
- list(GET ARGV 0 MessageType)
- if (MessageType STREQUAL FATAL_ERROR OR
- MessageType STREQUAL SEND_ERROR OR
- MessageType STREQUAL WARNING OR
- MessageType STREQUAL AUTHOR_WARNING)
- list(REMOVE_AT ARGV 0)
- _message(${MessageType} "${ARGV}")
- endif()
- endfunction()
-endmacro()
-
-macro(get_python_extension_suffix)
- execute_process(
- COMMAND ${PYTHON_EXECUTABLE} -c "if True:
- import re
- import sysconfig
- suffix = sysconfig.get_config_var('EXT_SUFFIX')
- res = re.search(r'^(.+)\\.', suffix)
- if res:
- suffix = res.group(1)
- else:
- suffix = ''
- print(suffix)
- "
- OUTPUT_VARIABLE PYTHON_EXTENSION_SUFFIX
- OUTPUT_STRIP_TRAILING_WHITESPACE)
- message(STATUS "PYTHON_EXTENSION_SUFFIX: " ${PYTHON_EXTENSION_SUFFIX})
-endmacro()
-
-macro(shiboken_parse_all_arguments prefix type flags options multiopts)
- cmake_parse_arguments(${prefix} "${flags}" "${options}" "${multiopts}" ${ARGN})
- if(DEFINED ${prefix}_UNPARSED_ARGUMENTS)
- message(FATAL_ERROR "Unknown arguments were passed to ${type} (${${prefix}_UNPARSED_ARGUMENTS}).")
- endif()
-endmacro()
-
-macro(shiboken_check_if_limited_api)
- # 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)
- if py.startswith('python3'):
- print(prefix + '/python3.lib')
- break
- "
- OUTPUT_VARIABLE PYTHON_LIMITED_LIBRARIES
- OUTPUT_STRIP_TRAILING_WHITESPACE)
-
- if(FORCE_LIMITED_API STREQUAL "yes")
- if (${PYTHON_VERSION_MAJOR} EQUAL 3 AND ${PYTHON_VERSION_MINOR} GREATER 4)
- # GREATER_EQUAL is available only from cmake 3.7 on. We mean python 3.5 .
- set(PYTHON_LIMITED_API 1)
- endif()
- if(WIN32)
- if (${PYTHON_VERSION_MAJOR} EQUAL 3 AND ${PYTHON_VERSION_MINOR} GREATER 4)
- # PYSIDE-560: XXX maybe add an option to setup.py as override
- set(SHIBOKEN_PYTHON_LIBRARIES ${PYTHON_LIMITED_LIBRARIES})
- endif()
- endif()
- endif()
-endmacro()
-
-
-macro(shiboken_find_required_python)
- 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)
- endif()
- shiboken_validate_python_version()
-
- 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 "5")
- message(FATAL_ERROR
- "Shiboken requires Python 3.5+.")
- endif()
-endmacro()
-
-macro(shiboken_compute_python_includes)
- shiboken_parse_all_arguments(
- "SHIBOKEN_COMPUTE_INCLUDES" "shiboken_compute_python_includes"
- "IS_CALLED_FROM_EXPORT" "" "" ${ARGN})
-
-
- # If the installed shiboken config file is used,
- # append the found Python include dirs as an interface property on the libshiboken target.
- # This needs to be dynamic because the user of the library might have python installed
- # in a different path than when shiboken was originally built.
- # Otherwise if shiboken is currently being built itself (either as standalone, or super project
- # build) append the include dirs as PUBLIC.
- 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})
- else()
- target_include_directories(libshiboken
- PUBLIC $<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>)
- endif()
-
-
- set(SHIBOKEN_PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIRS}")
-
- set_property(GLOBAL PROPERTY shiboken_python_include_dirs "${SHIBOKEN_PYTHON_INCLUDE_DIRS}")
-
- message(STATUS
- "SHIBOKEN_PYTHON_INCLUDE_DIRS computed to value: '${SHIBOKEN_PYTHON_INCLUDE_DIRS}'")
-endmacro()
-
-# Given a list of the following form:
-# optimized;C:/Python36/libs/python36.lib;debug;C:/Python36/libs/python36_d.lib
-# choose the corresponding library to use, based on the current configuration type.
-function(shiboken_get_library_for_current_config library_list current_config out_var)
- list(FIND library_list "optimized" optimized_found)
- list(FIND library_list "general" general_found)
- list(FIND library_list "debug" debug_found)
-
- if (optimized_found OR general_found OR debug_found)
- # Iterate over library list to find the most appropriate library.
- foreach(token ${library_list})
- if(token STREQUAL "optimized" OR token STREQUAL "general")
- set(is_debug 0)
- set(token1 1)
- set(lib "")
- elseif(token STREQUAL "debug")
- set(is_debug 1)
- set(token1 1)
- set(lib "")
- elseif(EXISTS ${token})
- set(lib ${token})
- set(token2 1)
- else()
- set(token1 0)
- set(token2 0)
- set(lib "")
- endif()
-
- if(token1 AND token2)
- if((is_debug AND lib AND current_config STREQUAL "Debug")
- OR (NOT is_debug AND lib AND (NOT current_config STREQUAL "Debug")))
- set(${out_var} ${lib} PARENT_SCOPE)
- return()
- endif()
- endif()
- endforeach()
- else()
- # No configuration specific libraries found, just set the original value.
- set(${out_var} "${library_list}" PARENT_SCOPE)
- endif()
-
-endfunction()
-
-macro(shiboken_compute_python_libraries)
- shiboken_parse_all_arguments(
- "SHIBOKEN_COMPUTE_LIBS" "shiboken_compute_python_libraries"
- "IS_CALLED_FROM_EXPORT" "" "" ${ARGN})
-
- if (NOT SHIBOKEN_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()
- endif()
-
- # If the resulting variable
- # contains a "debug;X;optimized;Y" list like described in shiboken_check_if_limited_api,
- # make sure to pick just one, so that the final generator expressions are valid.
- shiboken_get_library_for_current_config("${SHIBOKEN_PYTHON_LIBRARIES}" "${CMAKE_BUILD_TYPE}" "SHIBOKEN_PYTHON_LIBRARIES")
-
- if(APPLE)
- set(SHIBOKEN_PYTHON_LIBRARIES "-undefined dynamic_lookup")
- endif()
-
- # If the installed shiboken config file is used,
- # append the computed Python libraries as an interface property on the libshiboken target.
- # This needs to be dynamic because the user of the library might have python installed
- # in a different path than when shiboken was originally built.
- # Otherwise if shiboken is currently being built itself (either as standalone, or super project
- # build) append the libraries as PUBLIC.
- if (SHIBOKEN_COMPUTE_LIBS_IS_CALLED_FROM_EXPORT)
- #TODO target_link_libraries works on imported targets only starting with v3.11.0.
- set_property(TARGET Shiboken6::libshiboken
- APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${SHIBOKEN_PYTHON_LIBRARIES})
- else()
- target_link_libraries(libshiboken
- PUBLIC $<BUILD_INTERFACE:${SHIBOKEN_PYTHON_LIBRARIES}>)
- endif()
-
- set_property(GLOBAL PROPERTY shiboken_python_libraries "${SHIBOKEN_PYTHON_LIBRARIES}")
-
- message(STATUS "SHIBOKEN_PYTHON_LIBRARIES computed to value: '${SHIBOKEN_PYTHON_LIBRARIES}'")
-endmacro()
-
-function(shiboken_check_if_built_and_target_python_are_compatible)
- 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}'")
- else()
- if(NOT SHIBOKEN_PYTHON_LIMITED_API
- 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}'")
- endif()
- endif()
-endfunction()
diff --git a/sources/shiboken6/doc/CMakeLists.txt b/sources/shiboken6/doc/CMakeLists.txt
index 8d78eb400..eaef4ff29 100644
--- a/sources/shiboken6/doc/CMakeLists.txt
+++ b/sources/shiboken6/doc/CMakeLists.txt
@@ -1,50 +1,61 @@
-cmake_minimum_required(VERSION 3.16)
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
if(FULLDOCSBUILD EQUAL 0)
project(shiboken6_doc)
endif()
-find_program(SPHINX sphinx-build DOC "Path to sphinx-build binary.")
-if (SPHINX)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../cmake")
+include(FindDocTools)
+
+# Generate html by default.
+if(NOT DOC_OUTPUT_FORMAT)
+ set(DOC_OUTPUT_FORMAT "html")
+endif()
+
+if(SPHINX_BUILD)
message(STATUS "sphinx-build - found")
configure_file(conf.py.in conf.py @ONLY)
# conditional tag for sphinx build
#string(JOIN "_" SPHINX_TAG ${DOC_OUTPUT_FORMAT} "format")
add_custom_target(doc
- COMMAND ${SPHINX} -b ${DOC_OUTPUT_FORMAT} -c . ${CMAKE_CURRENT_SOURCE_DIR} html
- COMMENT "Generating HTMLs..."
+ COMMAND ${SPHINX_BUILD} -b ${DOC_OUTPUT_FORMAT} -j auto -c . ${CMAKE_CURRENT_SOURCE_DIR} html
+ COMMENT "Generating shiboken documentation HTML files"
VERBATIM)
- # Python script that will be called to update the QHP
- set(py_cmd "
-import fileinput
-import re
-try:
-\tfor line in fileinput.input('html/Shiboken.qhp',inplace=True,backup='.bak'):
-\t\tline_copy=line.strip()
-\t\tif not line_copy: # check for empty line
-\t\t\tcontinue
-\t\tmatch=re.match('(^.*virtualFolder.)doc(.*$)',line)
-\t\tif match:
-\t\t\trepl=''.join([match.group(1),'shiboken6',match.group(2)])
-\t\t\tprint(line.replace(match.group(0),repl),end=' ')
-\t\telse:
-\t\t\tprint(line)
-except:
-\tpass\n")
- file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/py_script.py
- CONTENT ${py_cmd})
-
- # create a custom command to generate QCH
+
+ # Attach a POST_BUILD step to the 'doc' custom target to generate a QCH file.
if(DOC_OUTPUT_FORMAT STREQUAL "qthelp")
- file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/html/Shiboken.qhp QHP_FILE)
- add_custom_command(TARGET doc POST_BUILD
- COMMAND ${PYTHON_EXECUTABLE} py_script.py # ${CMAKE_CURRENT_BINARY_DIR}/html/Shiboken.qhp
- COMMAND qhelpgenerator ${QHP_FILE}
- COMMENT "Genereting QCH based on the QHP..."
- VERBATIM)
+ if(qhelpgenerator_binary)
+ message(STATUS "qhelpgenerator - found")
+
+ # Python script that will be called to update the QHP
+ set(PATCH_QHP_SCRIPT "${CMAKE_CURRENT_LIST_DIR}/../../shiboken6/doc/scripts/patch_qhp.py")
+ file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/html/Shiboken.qhp QHP_FILE)
+
+ if(SHIBOKEN_IS_CROSS_BUILD)
+ set(python_executable "${QFP_PYTHON_HOST_PATH}")
+ else()
+ 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.")
+ endif()
+
+ add_custom_command(TARGET doc POST_BUILD
+ COMMAND "${python_executable}" ${PATCH_QHP_SCRIPT} -v shiboken6 ${QHP_FILE}
+ COMMAND "${qhelpgenerator_binary}" ${QHP_FILE}
+ COMMENT "Generating shiboken documentation QCH files based on the QHP files"
+ VERBATIM)
+ else()
+ message(WARNING "qhelpgenerator - not found! qch generation disabled")
+ endif()
endif()
else()
- message(WARNING "sphinx-build - not found! doc target disabled")
+ if(NOT SPHINX_BUILD)
+ message(WARNING "sphinx-build - not found! doc target disabled")
+ endif()
if (WIN32)
# if jom is used and we have no sphinx, then jom will crash.
# so for windows, we always create a doc target (until jom gets fixed...)
diff --git a/sources/shiboken6/doc/_static/css/qt_font.css b/sources/shiboken6/doc/_static/css/qt_font.css
new file mode 100644
index 000000000..ce39943ef
--- /dev/null
+++ b/sources/shiboken6/doc/_static/css/qt_font.css
@@ -0,0 +1,15 @@
+@font-face {
+ font-family: 'Titillium Web';
+ font-style: normal;
+ 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("//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
new file mode 100644
index 000000000..08c4646c6
--- /dev/null
+++ b/sources/shiboken6/doc/_static/css/qt_style.css
@@ -0,0 +1,100 @@
+.text-center {
+ text-align: center !important;
+}
+
+.text-center img {
+ padding-top: 10px;
+ height: 70px !important;
+}
+
+.cover-img img {
+ object-fit: cover;
+ height: 50%;
+}
+
+/* Tables */
+.section .docutils.container td {
+ float:left;
+}
+
+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;
+}
+
+.sd-card-title code span {
+ font-size: +1rem;
+ color: var(--color-brand-primary);
+}
diff --git a/sources/shiboken6/doc/_themes/pysidedocs/static/pysidelogo.png b/sources/shiboken6/doc/_static/qtforpython.png
index 3a2f2bd17..3a2f2bd17 100644
--- a/sources/shiboken6/doc/_themes/pysidedocs/static/pysidelogo.png
+++ b/sources/shiboken6/doc/_static/qtforpython.png
Binary files differ
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/_templates/layout.html b/sources/shiboken6/doc/_templates/layout.html
index 630fb9533..8f16e1cdf 100644
--- a/sources/shiboken6/doc/_templates/layout.html
+++ b/sources/shiboken6/doc/_templates/layout.html
@@ -42,7 +42,7 @@
{%- block footer %}
<div class="footer">
- <a href="http://www.qt.io/"><img src="{{ pathto('_static/logo_qt.png', 1) }}" alt="Qt" border="0" /></a>
+ <a href="https://www.qt.io/"><img src="{{ pathto('_static/logo_qt.png', 1) }}" alt="Qt" border="0" /></a>
<a href="http://www.python.org"><img src="{{ pathto('_static/logo_python.jpg', 1) }}" alt="Python" border="0" /></a>
<p>{{ copyright }}</p>
</div>
diff --git a/sources/shiboken6/doc/_themes/pysidedocs/searchbox.html b/sources/shiboken6/doc/_themes/pysidedocs/searchbox.html
deleted file mode 100644
index 55a972156..000000000
--- a/sources/shiboken6/doc/_themes/pysidedocs/searchbox.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{%- if pagename != "search" %}
-<div id="searchbox" style="display: none">
- <h3>{{ _('Quick search') }}</h3>
- <form class="search" action="{{ pathto('search') }}" method="get">
- <input type="text" name="q" id="q" size="18" />
- <input type="submit" value="{{ _('Go') }}" id="search_button" />
- <input type="hidden" name="check_keywords" value="yes" />
- <input type="hidden" name="area" value="default" />
- </form>
-</div>
-<script type="text/javascript">$('#searchbox').show(0);</script>
-{%- endif %}
diff --git a/sources/shiboken6/doc/_themes/pysidedocs/static/bg_header.png b/sources/shiboken6/doc/_themes/pysidedocs/static/bg_header.png
deleted file mode 100644
index 843e7e2c5..000000000
--- a/sources/shiboken6/doc/_themes/pysidedocs/static/bg_header.png
+++ /dev/null
Binary files differ
diff --git a/sources/shiboken6/doc/_themes/pysidedocs/static/bg_topo.jpg b/sources/shiboken6/doc/_themes/pysidedocs/static/bg_topo.jpg
deleted file mode 100644
index 4229ae8db..000000000
--- a/sources/shiboken6/doc/_themes/pysidedocs/static/bg_topo.jpg
+++ /dev/null
Binary files differ
diff --git a/sources/shiboken6/doc/_themes/pysidedocs/static/fakebar.png b/sources/shiboken6/doc/_themes/pysidedocs/static/fakebar.png
deleted file mode 100644
index b45830e00..000000000
--- a/sources/shiboken6/doc/_themes/pysidedocs/static/fakebar.png
+++ /dev/null
Binary files differ
diff --git a/sources/shiboken6/doc/_themes/pysidedocs/static/logo_python.jpg b/sources/shiboken6/doc/_themes/pysidedocs/static/logo_python.jpg
deleted file mode 100644
index cd474efba..000000000
--- a/sources/shiboken6/doc/_themes/pysidedocs/static/logo_python.jpg
+++ /dev/null
Binary files differ
diff --git a/sources/shiboken6/doc/_themes/pysidedocs/static/logo_qt.png b/sources/shiboken6/doc/_themes/pysidedocs/static/logo_qt.png
deleted file mode 100644
index 39a4a26f3..000000000
--- a/sources/shiboken6/doc/_themes/pysidedocs/static/logo_qt.png
+++ /dev/null
Binary files differ
diff --git a/sources/shiboken6/doc/_themes/pysidedocs/static/pyside.css b/sources/shiboken6/doc/_themes/pysidedocs/static/pyside.css
deleted file mode 100644
index 9082e5caa..000000000
--- a/sources/shiboken6/doc/_themes/pysidedocs/static/pyside.css
+++ /dev/null
@@ -1,2197 +0,0 @@
-@import url('cookie-confirm.css') screen;
-
-/* -- admonitions -- */
-
-div.admonition {
- margin: 1.5em 0 1.5em;
- padding: 0;
-}
-
-div.admonition dt {
- font-weight: bold;
-}
-
-div.admonition dl {
- margin-bottom: 0;
-}
-
-p.admonition-title {
- margin: 0px 10px 5px 0px;
- font-weight: bold;
-}
-
-div.admonition code {
- font-family: inherit;
-}
-
-p.admonition-title + p {
- padding-left: 1em;
-}
-
-div.admonition a:after {
- content: ', ';
-}
-
-div.admonition a:last-child:after {
- content: '';
-}
-
-.body {
- width: 100%;
- background-color: #00FF00;
- clear: both;
- display:inline-block;
- background-color:#fff;
- padding: 25px 35px 20px 30px;
- -webkit-box-sizing:border-box;
- -moz-box-sizing:border-box;
- -ms-box-sizing:border-box;
- box-sizing:border-box;
-}
-.bodywrapper {
- position: relative;
- /*background-color: #0000ff;*/
-}
-.bodywrapper .admonition p.admonition-title {
- margin-bottom:5px
-}
-
-.bodywrapper .admonition p {
- margin:0
-}
-
-div.body p.centered {
- text-align: center;
- margin-top: 25px;
-}
-
-div.warning, div.seealso, div.note, div.important {
- padding: 6px 0px 6px 10px;
- border: none;
-}
-
-div.warning {
- background-color: #ffe4e4;
-}
-
-div.important {
- background-color: #fef9f3;
- border-left: 5px solid #feeec8;
-}
-
-div.seealso {
- background-color: #fff2d6;
-}
-
-div.note {
- background-color: #c5d3f4;
- border-left: 5px solid #7899f4;
-}
-
-table.docutils {
- margin-right: auto;
- margin-bottom: 10px;
- border: none;
- width: initial;
-}
-
-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;
-}
-h2 em {
- float: right;
- font-size: 10px;
- position: relative;
- top: -20px;
-}
-
-.document {
- padding-bottom: 20px;
-}
-
-.documentwrapper {
- margin-left: 255px;
- position: relative;
-}
-@media screen and (max-width: 700px) {
- .documentwrapper {
- clear: both;
- margin-left: 0px;
- position: relative;
- }
-}
-
-.body blockquote {
- border: none;
- padding-left: 0;
- margin-bottom: 1.5em;
-}
-
-.sphinxsidebar {
- float: left;
- width: 186px;
- padding: 15px;
- text-align: left;
- background-color: #fff;
- clear: both;
-}
-
-.sphinxsidebar ul {
- padding: 0px;
- margin: 0px;
- list-style-position: inside;
-}
-
-.sphinxsidebar > ul {
- padding: 0px;
- margin: 0px;
-}
-
-.sphinxsidebar ul li li {
- margin-left: 10px;
- padding: 0px;
- font-size: 0.95em;
-}
-
-.sphinxsidebar ul a,
-.sphinxsidebar p.topless a {
- word-break: break-word;
-}
-
-.sphinxsidebar h3, .sphinxsidebar h3 a {
- color: #333;
-}
-
-.sphinxsidebar p.topless {
- margin: 1em 0 1em;
-}
-
-.pysidetoc ul {
- list-style: none;
- padding: 0px;
- margin: 0px;
-}
-
-.pysidetoc em {
- font-style: normal;
-}
-
-.pysidetoc strong {
- display: block;
- padding: 5px;
- margin: 0 10px 10px 0;
- border: none;
- background-color: #e2e2e2;
-}
-
-.section .docutils.container td {
- float:left;
-}
-
-.hide {
- display: none;
-}
-
-/* copy-notice */
-.document + p {
- margin-left: 255px;
- width: 70%;
- font-size: 0.75em;
- margin: 0 35px 15px 280px;
-}
-
-#searchbox {
- border-top: 1px solid #989898;
- padding-top: 10px;
- margin-left: -10px;
- margin-right: -10px;
- padding-left: 10px;
- padding-right: 10px;
-}
-
-#search_button {
- border: 1px solid #3A393A;
- background-color: #3A393A;
- color: white;
- cursor: pointer;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- -khtml-border-radius: 5px;
-
-}
-
-form {
- margin: 0px;
- padding: 0px;
-}
-
-#searchbox h3 {
- padding: 10px 0 0 0;
- margin-bottom: 5px;
-}
-
-/* search field */
-form #q {
- width: 136px;
- /* height: 22px; */
- /* border: none; */
- margin: 0px;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- -khtml-border-radius: 5px;
- margin-top: 2px;
- padding: 4px;
- line-height: 22px;
-}
-
-#search-results h2 {
- display: none;
-}
-
-#search-results h2 {
- display: none;
-}
-
-#search-results ul.search {
- margin: 0px;
- padding: 0px;
-}
-
-ul.search div.context {
- padding-left: 40px;
-}
-
-#installation td {
- text-align: center;
- font-weight: bold;
-}
-
-em {
- color: inherit;
- font-style:italic;
-}
-
-/******** REL bar *********/
-
-.related {
- display: inline;
-}
-
-.related h3 {
- display: none;
-}
-
-.align-center {
- text-align: center;
-}
-
-.contentstable {
- width: 100%;
-}
-
-.contentstable td {
- padding-left: 30px;
- vertical-align: top;
-}
-
-p.biglink a {
- font-size: 20px;
-}
-
-dt:target, .highlight {
- background-color: #fbe54e;
-}
-
-p.highlight-link {
- margin-top: 10px;
- font-size: 0.8em;
-}
-
-#synopsis table, table.field-list {
- margin: 1em 0 1em 0;
-}
-
-table.field-list tr {
- text-align: left;
-}
-
-tt.descname {
- font-size: 120%;
- font-weight: bold;
-}
-
-#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul {
- margin: 0;
- padding: 6px;
- border: 1px solid #ddd;
- border-radius: 0;
- background-color: #e2e2e2;
-}
-
-#functions p, #virtual-functions p, #slots p, #signals p, #static-functions p {
- margin: 0;
- padding: 0;
-}
-
-#functions li, #virtual-functions li, #slots li, #signals li, #static-functions li {
- list-style: none;
- margin: 5px;
- padding: 0;
- font-size: 90%;
-}
-
-#synopsis span.pre {
- color: #009491;
- font-weight: bolder;
-}
-
-#detailed-description .class dt,
-#detailed-description .method dt,
-#detailed-description .staticmethod dt,
-#detailed-description .attribute dt {
- margin: 0px;
- margin-bottom: 10px;
- padding: 10px;
- font-weight: bold;
- background-color: #e2e2e2;
- border: none;
- border-radius: 0;
-}
-
-#detailed-description dd > blockquote,
-#detailed-description dd > .field-list {
- font-family: 'Droid Sans Mono', monospace;
- font-size: small;
- border-left: 10px solid #e2e2e2;
- padding-left: 10px;
- margin-bottom: 1.5em;
-}
-
-#detailed-description dd > blockquote blockquote {
- border: none;
- padding: 0;
-}
-
-#detailed-description .class .field-odd,
-#detailed-description .method .field-odd,
-#detailed-description .staticmethod .field-odd,
-#detailed-description .attribute .field-odd {
- margin: 0;
- padding: 1px 0 0 0;
- background-color: #ffffff;
-
-}
-
-#detailed-description .class .field-even,
-#detailed-description .method .field-even,
-#detailed-description .staticmethod .field-even,
-#detailed-description .attribute .field-even {
- margin: 0;
- padding: 1px 0 0 0;
- background-color: #ffffff;
-}
-
-#detailed-description .class .field-odd li,
-#detailed-description .method .field-odd li,
-#detailed-description .staticmethod .field-odd li,
-#detailed-description .attribute .field-odd li {
- list-style: none;
- margin: 0;
- padding: 0;
-
-}
-
-#detailed-description .class .field-even li,
-#detailed-description .method .field-even li,
-#detailed-description .staticmethod .field-even li,
-#detailed-description .attribute .field-even li {
- list-style: none;
- margin: 0;
- padding: 0;
-}
-
-#detailed-description .class .field-odd p,
-#detailed-description .method .field-odd p,
-#detailed-description .staticmethod .field-odd p,
-#detailed-description .attribute .field-odd p{
- margin: 0;
- margin-left: 20px;
-
-}
-
-#detailed-description .class .field-even p,
-#detailed-description .method .field-even p,
-#detailed-description .staticmethod .field-even p,
-#detailed-description .attribute .field-even p{
- margin: 0;
- margin-left: 20px;
-}
-
-#detailed-description .class .field-odd p:last-child,
-#detailed-description .method .field-odd p:last-child,
-#detailed-description .staticmethod .field-odd p:last-child,
-#detailed-description .attribute .field-odd p:last-child {
- margin-bottom: 10px;
-
-}
-
-#detailed-description .class .field-even p:last-child,
-#detailed-description .method .field-even p:last-child,
-#detailed-description .staticmethod .field-even p:last-child,
-#detailed-description .attribute .field-even p:last-child{
- margin-bottom: 10px;
-}
-
-.document dl.attribute,
-.document dl.class,
-.document dl.method,
-.document dl.staticmethod {
- margin-top: 2em;
-}
-
-.document dl.attribute dd,
-.document dl.class dd,
-.document dl.method dd,
-.document dl.staticmethod dd {
- padding-left: 1em;
-}
-
-#detailed-description .attribute td:nth-child(1) {
- font-family: 'Droid Sans Mono', monospace;
-}
-
-/* Qt theme */
-#navbar {
- position:fixed;
- top:0;
- left:0;
- z-index:100;
- background:#fff;
- width:100%
-}
-#navbar .container, .fixed .container {
- max-width:1280px;
- margin:0 auto;
- padding:0 3.9%; /* 0? */
- position:relative;
- overflow:visible
-}
-#navbar .navbar-header {
- position:relative
-}
-#menuextras li a:hover span {
- color: #41cd52;
-}
-/* new header */
-#mm-wrap, #mm-wrap #mm-helper,
-#mm-wrap #mm-helper li.mm-item,
-#mm-wrap #mm-helper a.mm-link {
- -moz-transition: none;
- -o-transition: none;
- -webkit-transition: none;
- transition: none;
- -webkit-border-radius: 0 0 0 0;
- -moz-border-radius: 0 0 0 0;
- -ms-border-radius: 0 0 0 0;
- -o-border-radius: 0 0 0 0;
- border-radius: 0 0 0 0;
- -webkit-box-shadow: none;
- -moz-box-shadow: none;
- -ms-box-shadow: none;
- -o-box-shadow: none;
- box-shadow: none;
- background: none;
- border: 0;
- bottom: auto;
- box-sizing: border-box;
- clip: auto;
- color: #090e21;
- display: block;
- float: none;
- font-family: inherit;
- font-size: 14px;
- height: auto;
- left: auto;
- line-height: 1.7;
- list-style-type: none;
- margin: 0;
- min-height: 0;
- opacity: 1;
- outline: none;
- overflow: visible;
- padding: 0;
- position: relative;
- right: auto;
- text-align: left;
- text-decoration: none;
- text-transform: none;
- top: auto;
- vertical-align: baseline;
- visibility: inherit;
- width: auto;
-}
-#mm-wrap #mm-helper {
- visibility:visible;
- text-align:right;
- padding:0 0px 0 0px
-}
-#navbar #mm-wrap #mm-helper li.mm-item {
- border-right:solid #f3f3f4 1px;
- padding-right:30px;
- padding-left:30px
-}
-#navbar #mm-wrap #mm-helper li.mm-item > a:hover {
- opacity: .5
-}
-#mm-wrap #mm-helper > li.mm-item {
- margin:0 0 0 0;
- display:inline-block;
- height:auto;
- vertical-align:middle
-}
-#navbar #mm-wrap #mm-helper li.mm-item:nth-child(3) {
- border-right:0
-}
-#mm-wrap #mm-helper a.mm-link {
- cursor: pointer
-}
-@media (max-width: 1279px) {
- #navbar {
- padding:0;
- position:relative;
- }
- #navbar .container {
- max-width:100%
- }
- .container {
- padding:0 2%
- }
- .sphinxsidebar {
- top: 16px !important;
- }
-}
-#navbar .navbar-oneQt {
- display:inline;
- float:left;
- width:31px;
- color:#41cd52
-}
-#navbar .navbar-oneQt:before {
- content:attr(data-icon);
- position:absolute;
- top:14px;
- left:0;
- color:#41cd52;
- font-family:'Qt Icons';
- line-height:1;
- font-size:40px;
- transition:all 0.3s ease-in-out;
-}
-#mm-wrap {
- clear:both;
- background:rgba(255, 255, 255, 0.1);
- -webkit-border-radius:0px 0px 0px 0px;
- -moz-border-radius:0px 0px 0px 0px;
- -ms-border-radius:0px 0px 0px 0px;
- -o-border-radius:0px 0px 0px 0px;
- border-radius:0px 0px 0px 0px
-}
-#mm-wrap #mm-helper li.mm-item:last-child a {
- background:transparent url("icon_avatar.png") 50% 50% no-repeat !important;
- background-size:24px !important;
- width:24px !important;
- height:24px !important;
-}
-#navbar #mm-wrap #mm-helper li.mm-item > a {
- opacity:1;
- -webkit-transition:all 0.3s ease-in-out;
- -moz-transition:all 0.3s ease-in-out;
- -ms-transition:all 0.3s ease-in-out;
- -o-transition:all 0.3s ease-in-out;
- transition:all 0.3s ease-in-out;
-}
-#mm-wrap #mm-helper > li.mm-item > a.mm-link {
- border-top:0px solid #fff;
- border-left:0px solid #fff;
- border-right:0px solid #fff;
- border-bottom:0px solid #fff;
- outline:none;
- text-decoration:none;
- padding:0 0 0 0;
- line-height:70px;
- font-weight:normal;
- height:70px;
- vertical-align:baseline;
- text-align:left;
- width:auto;
- display:block;
- color:#090e21;
- text-transform:none;
- text-decoration:none;
- background:rgba(0, 0, 0, 0);
- -webkit-border-radius:0px 0px 0px 0px;
- -moz-border-radius:0px 0px 0px 0px;
- -ms-border-radius:0px 0px 0px 0px;
- -o-border-radius:0px 0px 0px 0px;
- border-radius:0px 0px 0px 0px;
- font-family:inherit;
- font-size:14px;
-}
-/* end new header */
-@media (min-width: 1320px) {
- .body .flowListDiv dl.flowList {
- -webkit-column-count:3;
- -moz-column-count:3;
- column-count:3
- }
-}
-@media (min-width: 1120px) {
- #navbar.fixed {
- -moz-box-shadow:0px 0px 8px rgba(0,0,0,0.23);
- -webkit-box-shadow:0px 0px 8px rgba(0,0,0,0.23);
- box-shadow:0px 0px 8px rgba(0,0,0,0.23)
- }
- #navbar.fixed #mm-wrap #mm-helper > li.mm-item > a.mm-link {
- height:50px;
- line-height:50px
- }
- #navbar.fixed .navbar-oneQt:before {
- font-size:35px;
- top:7px
- }
-
- .flowListDiv dl.flowList {
- -webkit-column-count:2;
- -moz-column-count:2;
- column-count:2
- }
-}
-@media (max-width: 1120px) {
- #navbar {
- padding:0;
- position:relative
- }
- #navbar .navbar-oneQt:before {
- left:10px
- }
- #navbar .container {
- max-width:100%;
- padding:0
- }
- #footerbar .container {
- padding:0
- }
- body .main {
- margin-top:0px
- }
- #footerbar .footer-main .footer-nav {
- padding:3.9% 0 3.9% 3%;
- border-bottom:1px solid #413d3b;
- float:none;
- display:block;
- width:auto
- }
- #footerbar .footer-main .theqtcompany {
- clear:both;
- float:left;
- margin:30px 0 8px 3%
- }
- #footerbar .footer-main .footer-social {
- float:left;
- padding:50px 0px 0px 3%
- }
- #footerbar #menu-footer-submenu {
- clear:both;
- float:none;
- display:block;
- padding:0px 0px 3.9% 3%
- }
- ul#menu-footer-submenu {
- margin-left: 0
- }
-}
-.cookies_yum {
- background-color:#cecfd5;
- display:none;
- width:100%
-}
-.cookies_yum img {
- width:25px;
- top:6px;
- display:inline-block;
- position:absolute;
- left:13px
-}
-.cookies_yum div {
- margin:0 auto;
- max-width:1280px;
- min-height:30px;
- padding:6px 0px 6px 0px;
- position:relative
-}
-.cookies_yum p {
- color:#09102b;
- margin:0px;
- font-size:0.79em;
- display:inline-block;
- line-height:1.2;
- padding:0 30px 0 50px
-}
-.cookies_yum p a {
- white-space:nowrap
-}
-.cookies_yum a:hover {
- color:#46a2da
-}
-.cookies_yum .close {
- width:15px;
- height:15px;
- background-image:url("cookiebar-x.png");
- background-size:15px 30px;
- background-position:top left;
- cursor:pointer;
- top:13px;
- right:13px;
- position:absolute;
- transition:none
-}
-.cookies_yum .close:hover {
- background-position:bottom left
-}
-#sidebar-toggle,#toc-toggle {
- width:24px;
- height:14px;
- background-size:24px 28px;
- cursor:pointer;
- background-image:url("list_expand.png");
- float:right
-}
-#sidebar-toggle.collapsed,
-#toc-toggle.collapsed {
- background-position:bottom left
-}
-#sidebar-content > h2 {
- display:none
-}
-#footerbar {
- background:#222840;
- color:#fff;
- font-size: 0.9em;
-}
-#footerbar.fixed {
- bottom:0;
- left:0;
- width:100%
-}
-#footerbar .footer-nav {
- display:inline;
- float:left
-}
-#footerbar .footer-main .footer-nav li {
- float:left;
- margin-right:1em
-}
-#footerbar .footer-main .footer-nav li a {
- display:block;
- padding:30px 0 10px 0;
- line-height:20px;
- height:20px;
- color:#fff;
- font-weight: 600;
-}
-#footerbar .footer-main .footer-nav li a:hover,#footerbar .footer-main .footer-nav li.current-menu-item a {
- color:#eee
-}
-#footerbar .footer-main .footer-nav .sub-menu {
- margin-left:0;
- margin-bottom:0
-}
-#footerbar .footer-main .footer-nav .sub-menu li {
- float:none;
- width: 100%;
-}
-#footerbar .footer-main .footer-nav .sub-menu ul {
- padding:1px 1em;
- font-size:0.786em;
- line-height:8px;
- float:none;
- color:#5d5b59;
- margin-bottom:0
-}
-#footerbar .footer-main .footer-nav .sub-menu li a {
- padding:2px 0;
- font-size:1em;
- float:none;
- color:#cecfd5;
- font-weight: 400;
-}
-#footerbar .footer-main .footer-nav .sub-menu li a:hover,#footerbar .footer-main .footer-nav .sub-menu li.current-menu-item a {
- color:#eee
-}
-#footerbar .theqtcompany {
- background:url("theqtcompany.png") no-repeat;
- background-size:100%;
- width:215px;
- height:68px;
- display:inline;
- float:right;
- margin:29px 0 28px 30px
-}
-#footerbar .footer-social {
- display:inline;
- float:right;
- width:164px
-}
-#footerbar .footer-main .footer-social>div {
- margin-left:0.1em;
- margin-bottom:10px
-}
-#footerbar .disclaimer {
- font-size:0.786em;
- line-height:2.73;
- color:#868584;
- padding-top:20px;
- padding-bottom:0.5%
-}
-#footerbar .disclaimer a {
- color:#bdbebf
-}
-#footerbar .disclaimer a:hover {
- color:#d6d6d6
-}
-#footerbar .disclaimer ul li {
- float:left;
- vertical-align:middle;
- margin-left:1.18em
-}
-#footerbar .disclaimer ul li:first-child {
- margin-left:0
-}
-#footerbar .disclaimer ul.lang-selector a {
- color:#506a34;
- color:rgba(128,195,66,0.3)
-}
-#footerbar .disclaimer ul.lang-selector a:hover {
- color:#80c342;
- color:rgba(128,195,66,0.7)
-}
-#menu-footer-menu, #menu-footer-menu ul {
- margin-left:0;
- margin-bottom:0
-}
-@font-face {
- font-family: 'Titillium Web';
- font-style: normal;
- 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("//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 */
-}
-/* titillium-web-italic - latin_latin-ext */
-@font-face {
- font-family: 'Titillium Web';
- font-style: italic;
- font-weight: 400;
- src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot");
- /* IE9 Compat Modes */
- src: local("Titillium WebItalic"), local("TitilliumWeb-Italic"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.svg#TitilliumWeb") format("svg");
- /* Legacy iOS */
-}
-/* titillium-web-600 - latin_latin-ext */
-@font-face {
- font-family: 'Titillium Web';
- font-style: normal;
- font-weight: 600;
- src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot");
- /* IE9 Compat Modes */
- src: local("Titillium WebSemiBold"), local("TitilliumWeb-SemiBold"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.svg#TitilliumWeb") format("svg");
- /* Legacy iOS */
-}
-@font-face {
- font-family: 'Droid Sans Mono', monospace;
- font-style:normal;
- font-weight:400;
- src:local("Droid Sans Mono"),local("DroidSansMono"),url(//fonts.gstatic.com/s/droidsansmono/v7/ns-m2xQYezAtqh7ai59hJUYuTAAIFFn5GTWtryCmBQ4.woff) format("woff")
-}
-@font-face {
- font-family:'Qt Icons';
- src:url("../style/icomoon.eot?-tgjuoj");
- src:url("../style/icomoon.eot?#iefix-tgjuoj") format("embedded-opentype"),url("../style/icomoon.woff?-tgjuoj") format("woff"),url("../style/icomoon.ttf?-tgjuoj") format("truetype"),url("../style/icomoon.svg?-tgjuoj#icomoon") format("svg");
- font-weight:normal;
- font-style:normal
-}
-@font-face {
- font-family:'social-icons';
- src:url("../style/social-icons.eot?54625607");
- src:url("../style/social-icons.eot?54625607#iefix") format("embedded-opentype"),
- url("../style/social-icons.woff?54625607") format("woff");
- font-weight:normal;
- font-style:normal
-}
-.clearfix:before,.clearfix:after {
- content:" ";
- display:table
-}
-.clearfix:after {
- clear:both
-}
-.clearfix {
- *zoom:1
-}
-.clearfix .right {
- float:right
-}
-html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
- margin:0;
- padding:0;
- border:0;
- font-size:100%
- line-height: 1.4;
-}
-html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,caption,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video {
- vertical-align:baseline
-}
-h1,h2,h3,h4,h5,h6 {
- font-weight:300
-}
-.body h2,.body h3,.body h4,.body h5,.body h6 {
- margin:1.5em 0 0.75em
-}
-.body h1 {
- margin-bottom:0.75em;
- font-size:2.25em;
-}
-.body h3.fn,.body h3.flags {
- color:#26282a;
- font-size:1.46em;
- padding:15px 0 15px 0;
- border-bottom:2px #eee solid;
- word-wrap:break-word
-}
-.body .fngroup {
- border-bottom:2px #eee solid;
- padding-bottom:15px;
- margin-bottom:1.5em
-}
-.body .fngroup h3.fngroupitem {
- margin:0;
- padding-bottom:0;
- border:none
-}
-.body h3.fn .name,
-.body h3 span.type,
-.qmlname span.name {
- font-weight: 400
-}
-.qmlname {
- font-size:1.46em
-}
-.qmlproto table {
- border:none;
- border-bottom:2px #eee solid
-}
-.qmlproto table p {
- max-width:100%
-}
-.qmlproto table tr {
- background-color:#fff
-}
-.qmlname td, .qmlname th {
- border:none;
- text-align:left;
- padding:5px 0 0 0
-}
-.qmlreadonly,.qmldefault {
- padding:0 5px 0 5px;
- font-size:0.75em;
- background-color:#eee;
- float:right
-}
-.qmlreadonly {
- color:#414141
-}
-.qmldefault {
- color:#D14141
-}
-.rightAlign {
- padding:3px 5px 3px 10px;
- text-align:right
-}
-.centerAlign.functionIndex {
- text-align:center;
- font-size:150%;
- margin-bottom: 1em
-}
-article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section {
- display:block
-}
-body {
- line-height:1;
- font-family:'Titillium Web', Arial, Helvetica, sans-serif;
- font-weight:400;
- transition-duration:1s;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- font-size: 16px;
- background-color:#f3f3f4;
- color:#404244;
-}
-ol,ul {
- list-style-type: square;
- color: #17a81a;
-}
-.body ol,.body ul {
- margin-top:0.75em;
- margin-left:20px
-}
-.bodywrapper ol>li {
- list-style-type:decimal;
- margin-left:15px
-}
-.bodywrapper ol.a >li {
- list-style-type:lower-alpha;
-}
-.bodywrapper ol.A >li {
- list-style-type:upper-alpha;
-}
-.bodywrapper ol.i >li {
- list-style-type:lower-roman;
-}
-.bodywrapper ol.I >li {
- list-style-type:upper-roman;
-}
-.body li p {
- margin-top:1em
-}
-blockquote,q {
- quotes:none;
- border-left:10px solid #ddd;
- padding-left:10px
-}
-blockquote:before,blockquote:after,q:before,q:after {
- content:'';
- content:none;
- width:100%
-}
-table {
- border-collapse:collapse;
- border-spacing:0;
- margin-bottom:5px;
- width:100%
-}
-a {
- color:#17a81a;
- text-decoration:none;
- transition-duration:0.3s
-}
-a:hover {
- color:#17a81a
-}
-.main,#footerbar>div {
- max-width:1280px;
- width:95%;
- margin:0 auto
-}
-.main {
- margin-top:80px
-}
-@media (max-width: 1120px) {
- .main,.navbar-header,#footerbar>div {
- width: 100%;
- margin: 0;
- }
- .main .main-rounded {
- padding: 0 15px;
- }
-}
-.main_index {
- background-color:#fff
-}
-.sectionlist {
- margin-bottom:2em
-}
-[class*="col-"] {
- letter-spacing:normal
-}
-.landing,.main_index .row {
- letter-spacing:-0.31em
-}
-.main_index .row>div {
- letter-spacing:normal
-}
-.col-1 {
- clear: both;
- display:inline-block;
- background-color:#fff;
- padding: 25px 35px 20px 30px;
- -webkit-box-sizing:border-box;
- -moz-box-sizing:border-box;
- -ms-box-sizing:border-box;
- box-sizing:border-box;
-}
-.col-1 h2 {
- font-size:1.8em;
- font-weight:300;
- line-height:1.1;
- margin-bottom:0.83em;
- margin-top:1em
-}
-.icons1of3 img {
- display:inline-block;
- float:left;
- margin-right:0.75em;
- margin-top:-5px;
- width:2.75em
-}
-div.multi-column {
- position:relative
-}
-div.multi-column div {
- display:-moz-inline-box;
- display:inline-block;
- vertical-align:top;
- margin-top:1em;
- margin-right:2em;
- width:16em
-}
-.sidebar {
- display:block;
- position:relative;
- position:sticky;
- float:left;
- -webkit-box-sizing:border-box;
- -moz-box-sizing:border-box;
- -ms-box-sizing:border-box;
- box-sizing:border-box;
- width:20%;
- padding-right:20px
-}
-.sidebar li {
- text-overflow:ellipsis;
- overflow:hidden
-}
-.toc,.sectionlist {
- padding:25px;
- background-color:#fff;
- margin-bottom:1.25em
-}
-.sidebar .sectionlist p {
- margin-bottom:0
-}
-.sectionlist.promo {
- padding:0;
- background-color:#f3f3f4
-}
-.sidebar-content:empty {
- display:none;
- visibility:hidden
-}
-.col-2 h2,.toc h3,.sidebar-content h2,
-.sidebar-content h3,.sectionlist h2,
-.sphinxsidebar {
- position: -webkit-sticky;
- position: sticky;
- top: 0px;
- width: 200px;
- overflow: scroll;
- overflow-x: hidden;
- overflow-y: hidden;
-}
-.sphinxsidebar h3 {
- font-weight: bold;
- margin-bottom:1em;
-}
-
-/* On screens that are less than 700px wide, make the sidebar into a topbar */
-@media screen and (max-width: 700px) {
- .sphinxsidebar {
- top: 64px;
- /*overflow-x: hidden;
- overflow-y: hidden;*/
- width: 100%;
- height: auto;
- position: relative;
- }
- /*.sidebar a {float: left;}*/
- div.content {margin-left: 0;}
-}
-
-/* On screens that are less than 400px, display the bar vertically, instead of horizontally
-@media screen and (max-width: 400px) {
- .sphinxsidebar a {
- text-align: center;
- float: none;
- }
-}
-*/
-
-.toc h3 a {
- color:#404244
-}
-.title {
- font-size:2.25em;
- font-weight:300;
- letter-spacing:-1px;
- line-height:1.15em;
- margin-bottom:0.5em;
- word-wrap:break-word
-}
-.navigationbar,col-1 h2 {
- font-size:0.85em
-}
-.navigationbar h1 {
- font-size:2.5em;
- margin-bottom:0.85em;
- margin-top:0.85em
-}
-.navigationbar li {
- display:inline-block;
- margin-right:5px;
- position:relative;
- padding-right:10px;
- color:#585a5c
-}
-.navigationbar ul:last-of-type li a {
- color:#404244
-}
-.sectionlist li, .sphinxsidebar li {
- padding-bottom: 10px;
- line-height: 1.75em;
-}
-.col-1 ul {
- margin-bottom:1.56em
-}
-.bodywrapper li {
- margin-top:0.5em;
- line-height:1.25em
-}
-.bodywrapper li.level2 {
- margin-left:10px;
- margin-top:0.4em;
- font-size:0.9375em;
-}
-.bodywrapper p,
-.bodywrapper dd {
- line-height:1.25em;
- margin:1em 0 1em;
- color:#404244
-}
-.bodywrapper b {
- font-weight:600
-}
-.body ul,.body ol {
- /* margin-bottom:1.5em */
-}
-.bodywrapper ul ul {
- margin-top:0.5em
-}
-.bodywrapper .naviNextPrevious {
- margin-top:25px;
- max-width:100%;
- position: relative;
-}
-.naviNextPrevious.headerNavi,
-p.naviNextPrevious + p {
- display:none
-}
-.nextPage {
- float:right
-}
-.prevPage:before {
- content:"< "
-}
-.nextPage:after {
- content:" >"
-}
-.navigationbar li a {
- color:#404244
-}
-.navigationbar li:after {
- color:#404244;
- content:"›";
- display:inline-block;
- font-size:1.5em;
- line-height:1;
- position:absolute;
- right:-2px;
- top:-4px
-}
-.sub-navigation {
- margin-top:10px
-}
-.navigationbar li:last-child:after,.sub-navigation li:after {
- content:none
-}
-.navigationbar {
- margin-bottom:10px;
- line-height:1em
-}
-#buildversion {
- margin-bottom:10px;
- font-style:italic;
- font-size:small;
- float:right
-}
-.copy-notice {
- width:75%;
- font-size:0.75em;
- margin:20px 35px 0 10px;
- line-height:1.75em;
- float:right;
- color:#585a5c
-}
-.copy-notice.index {
- margin-top:10px;
- float:none
-}
-li a.active {
- color:#585a5c
-}
-.flowList {
- padding:25px
-}
-.flowListDiv dl {
- -webkit-column-count:1;
- -moz-column-count:1;
- column-count:1
-}
-.flowList dd {
- display:inline-block;
- margin-left:10px;
- width:90%;
- line-height:1.15em;
- overflow-x:hidden;
- text-overflow:ellipsis
-}
-.alphaChar {
- font-size:2em;
- position:absolute
-}
-.flowList.odd {
- background-color:#f9f9f9
-}
-.body ul>li,.doc-column ul>li {
- list-style-image:url("list_arrow.png");
- margin-left:15px;
- color:#404244;
- margin-top:0.65em;
- line-height:1em
-}
-.bodywrapper table p {
- margin:0px;
- padding:0px
-}
-.bodywrapper table p {
- margin:0px;
- padding:0px;
- min-height:1.25em
-}
-.bodywrapper .qmldoc {
- margin-top:0.75em;
-}
-.body h2 {
- margin-top: 1.5em;
- font-size:1.75em
-}
-.body h3 {
- font-size:1.35em
-}
-.body h4 {
- font-size:1.15em
-}
-.body p img {
- margin-top:0.75em;
- max-width:100%
-}
-.body .border img {
- box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5)
-}
-.body .border .player {
- box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5)
-}
-.body p.figCaption {
- transform:translateY(-30px);
- color:#606366;
- font-size:95%;
- margin-left:3px;
- font-style:italic
-}
-.body table {
- width:initial;
- vertical-align:initial
-}
-table .odd {
- background-color:#f9f9f9
-}
-table thead {
- text-align:left;
- padding-left:20px
-}
-table,table td,table th {
- border:1px solid #eee
-}
-table td,table th {
- padding:5px 20px;
- line-height:1.3
-}
-.body .fixed table td {
- min-width:50%;
- width:50%
-}
-table.alignedsummary,table.propsummary {
- width:initial
-}
-table.valuelist td.tblval {
- font-size:0.75em
-}
-div.main_index .row {
- border-bottom:10px solid #f3f3f4
-}
-div.main_index .row {
- position:relative
-}
-div.main_index .row>div {
- display:inline-block;
- width:50%;
- vertical-align:top;
- padding:2em 3em;
- -webkit-box-sizing:border-box;
- -moz-box-sizing:border-box;
- -ms-box-sizing:border-box;
- box-sizing:border-box
-}
-div.main_index h2 {
- font-size:2.1875em;
- margin-bottom:1em
-}
-#search_bar {
- width:40%;
- float:right
-}
-div.main_index .row:after {
- content:"";
- position:absolute;
- top:0;
- right:50%;
- height:100%;
- width:10px;
- background-color:#f3f3f4
-}
-div.table {
- overflow-x:auto
-}
-.body tr > td > pre {
- font-size:0.75em
-}
-p.qt_commercial {
- border:3px solid #5caa15;
- margin:0 auto;
- padding:15px;
- width:28%;
- text-align:center;
- clear:both
-}
-h1.qt_commercial {
- padding:20px;
- background-color:#5caa15;
- display:inline;
- float:right;
- font-size:1.25em;
- line-height:1.25em;
- height:1.25em;
- color:#fff
-}
-div.qt_commercial {
- border-top:5px solid #5caa15;
- margin-bottom:50px
-}
-div.pre {
- position:relative;
- height:auto
-}
-pre, .LegaleseLeft {
- background-color:#222840;
- color:#fff;
- display:block;
- font-family: 'Droid Sans Mono', monospace;
- line-height:1.5;
- overflow-x:auto;
- margin-bottom:25px;
- padding:25px;
- margin-top:0.75em;
- font-size: .8em;
-}
-.bodywrapper .LegaleseLeft p {
- color:#fff;
- white-space: pre-wrap;
-}
-pre .str,code .str {
- color:#aaaaaa
-}
-pre .kwd,code .kwd {
- color:#ffff55
-}
-pre .com,code .com {
- color:#55ffff
-}
-pre .typ,code .typ {
- color:#4f9d08
-}
-pre a .typ,code a .typ {
- color:#21be2b
-}
-pre .lit,code .lit {
- color:#ff55ff
-}
-pre .pun,code .pun {
- color:#fff
-}
-pre .pln,code .pln {
- color:#fff
-}
-@media print {
- pre {
- background-color:#eee !important
- }
- pre .str,code .str {
- color:#060
- }
- pre .kwd,code .kwd{
- color:#006;
- font-weight:bold
- }
- pre .com,code .com {
- color:#600
- }
- pre .typ,code .typ {
- color:#404;
- font-weight:bold
- }
- pre .lit,code .lit {
- color:#044
- }
- pre .pun,code .pun {
- color:#440
- }
- pre .pln,code .pln {
- color:#000
- }
-}
-pre.wrap {
- white-space:pre-wrap
-}
-pre span.wrap {
- display:none;
- background:url("wrap.png") no-repeat;
- right:0;
- top:2px;
- position:absolute;
- width:20px;
- height:14px;
- margin:4px;
- opacity:0.65
-}
-
-span.pre {
- color: black;
- font-family: monospace;
- font-weight: normal;
- background-color: #eaeaea;
- padding: 2px 4px;
- color: black;
- border-radius: 2px;
-}
-
-span.wrap:hover {
- opacity:1
-}
-span.wrap:active {
- opacity:0.75
-}
-.copy_text {
- background-color:#46a2da;
- color:#fff;
- border:2px solid #46a2da;
- padding:10px 16px;
- margin-left:-10px;
- margin-top:-50px;
- position:absolute;
- opacity:0;
- cursor:pointer;
- float:right
-}
-.copy_text:hover {
- background-color:#fff;
- color:#46a2da
-}
-code,.codelike {
- font-family: 'Droid Sans Mono', monospace;
-}
-#detailed-description .function dt > code,
-#detailed-description .function dt > em {
- font-weight:bold
-}
-h3.fn code {
- font-size:0.75em;
- float:right;
- background-color:#eee;
- padding:3px;
- margin: 3px 0 0 20px
-}
-pre:hover>.copy_text {
- display:inline-block;
- opacity:1;
- transition:0.5s ease
-}
-#main_title_bar {
- background:url("pyside-logo.png") no-repeat;
- background-size:100%;
- width:366px;
- height:86px;
- margin:15px 0 15px 0
-}
-#main_title_bar h1 {
- visibility:hidden
-}
-#main_title_bar .search_bar {
- letter-spacing:normal;
- width:50%;
- display:inline-block;
- -webkit-box-sizing:border-box;
- -moz-box-sizing:border-box;
- -ms-box-sizing:border-box;
- box-sizing:border-box;
- vertical-align:middle
-}
-#main_title_bar h1 {
- letter-spacing:normal;
- display:inline-block;
- -webkit-box-sizing:border-box;
- -moz-box-sizing:border-box;
- -ms-box-sizing:border-box;
- box-sizing:border-box;
- vertical-align:middle
-}
-#main_title_bar .search_bar * {
- letter-spacing:normal;
- padding:0;
- margin:0;
- border:none
-}
-#sidebar-toggle,#toc-toggle {
- display:none
-}
-@media (max-width: 980px) {
- body {
- font-size:calc-em(14px)
- }
- #main_title_bar>h1,#main_title_bar .search_bar {
- width:100%
- }
- #main_title_bar .search_bar {
- margin-bottom:15px
- }
- .main {
- margin-top:0px
- }
- .main_index .row {
- border:none !important
- }
- .title {
- font-size:1.5em;
- font-weight:400;
- word-wrap:break-word
- }
- .col-1,.body,.naviNextPrevious,.sidebar {
- padding:10px
- }
- .sidebar {
- position:relative;
- padding-top:0
- }
- .search .sidebar {
- display:none;
- visibility:hidden
- }
- .col-2 h2,.toc h3,.sidebar-content h2,.sidebar-content h3,.sectionlist h2 {
- text-align:center;
- margin-bottom:5px
- }
- div.main_index .row:after {
- content:none
- }
- div.main_index .row>div {
- display:block !important;
- width:100%;
- padding:15px;
- margin:0
- }
- .body,.sidebar,.col-1 {
- width:100%
- }
- .sidebar-content,.col-2,.toc {
- background-color:#fff;
- margin-bottom:1em;
- padding:20px
- }
- #sidebar-toggle,#toc-toggle {
- display:block
- }
- #sidebar-toggle.collapsed + h2 {
- display:block
- }
- .bodywrapper p {
- margin-bottom:1em;
- max-width:100%
- }
- table td,table th {
- padding:5px 5px
- }
- .sectionlist {
- padding:0
- }
- .sidebar > .sectionlist {
- padding:20px
- }
- .sectionlist.promo {
- max-width:46%;
- margin:0 auto 1em auto;
- float:left;
- padding:0 2%
- }
- .sidebar .sidebar-content {
- clear:both
- }
- .copy-notice {
- float:none;
- width:initial
- }
-}
-[id]:target > *:first-child,
-dt[id]:target {
- -webkit-animation:highlighter 3s;
- animation:highlighter 3s
-}
-@-webkit-keyframes highlighter {
- 25% {
- background-color:#d1e8f6;
- color:#444
- }
- 75% {
- background-color:#d1e8f6;
- color:#444
- }
-}
-@keyframes highlighter {
- 25% {
- background-color:#d1e8f6;
- color:#444
- }
- 75% {
- background-color:#d1e8f6;
- color:#444
- }
-}
-@-webkit-keyframes copypaste {
- 25% {
- opacity:1
- }
- 100% {
- border-radius:10px;
- margin-top:-50px;
- opacity:1
- }
-}
-@keyframes copypaste {
- 25% {
- opacity:1
- }
- 100% {
- border-radius:10px;
- margin-top:-50px;
- opacity:1
- }
-}
-#footer {
- clear:both
-}
-.footer-social i {
- font-family: "social-icons";
- font-style: normal;
- font-size:150%;
- margin: .55em;
- color: #cecfd5
-}
-.footer-social i:hover {
- color: #eee
-}
-.footer-social .icon-twitter:before {
- content: '\f099'
-}
-.footer-social .icon-facebook:before {
- content: '\f09a'
-}
-.footer-social .icon-youtube:before {
- content: '\f16a'
-}
-.menuextraslanguages {
- display:none;
- visibility:hidden
-}
-form.gsc-search-box {
- font-size: 25px !important;
- margin-top: 0 !important;
- margin-right: 0 !important;
- margin-bottom: 4px !important;
- margin-left: 0 !important;
- width: 102.5% !important;
-}
-table.gsc-search-box {
- border-style: none !important;
- border-width: 0 !important;
- border-spacing: 0 0 !important;
- width: 100% !important;
- margin-bottom: 2px !important;
-}
-
-table.gsc-search-box td {
- vertical-align: middle !important;
-}
-
-table.gsc-search-box td.gsc-input {
- padding-right: 0px !important;
-}
-table.gsc-search-box td.gsc-input input {
- background-position: 10px center !important;
-}
-
-td.gsc-search-button {
- width: 1% !important;
-}
-
-td.gsc-clear-button {
- width: 14px !important;
- visibility:hidden !important;
- display:none !important;
-}
-table.gsc-branding td,
-table.gsc-branding {
- margin: 0 0 0 0 !important;
- padding: 0 0 0 0 !important;
- border: none !important;
-}
-
-table.gsc-branding {
- border-style: none !important;
- border-width: 0 !important;
- border-spacing: 0 0 !important;
- width: 100% !important;
-}
-
-.gsc-branding-text {
- color: #676767 !important;
-}
-
-td.gsc-branding-text {
- vertical-align: top !important;
-}
-td.gsc-branding-text div.gsc-branding-text {
- padding-bottom: 2px !important;
- text-align: right !important;
- font-size: 11px !important;
- margin-right: 2px !important;
-}
-
-td.gsc-branding-img {
- width: 65px !important;
- vertical-align: bottom !important;
-}
-
-img.gsc-branding-img {
- padding-top: 1px !important;
- margin: 0 0 0 0 !important;
- padding-right: 0 !important;
- padding-left: 0 !important;
- padding-bottom: 0 !important;
- border: none !important;
- display: inline !important;
-}
-
-input.gsc-search-button {
- background-color: white !important;
- height: 35px !important;
- width: 25px !important;
- color: transparent !important;
- background-image: url("doc_search.png") !important;
- background-size: 25px auto;
- background-position: 0px 5px;
- background-repeat: no-repeat;
- margin-left: -43px !important;
- overflow: hidden;
- min-width: 20px !important;
-}
-
-input.gsc-search-button:hover {
- cursor: pointer;
-}
-
-input.gsc-search-button:focus {
- outline: none;
- box-shadow: none;
-}
-
-.gsc-search-box-tools .gsc-clear-button {
- display: none !important;
- visibility: none !important;
-}
-
-.gsc-overflow-hidden {
- overflow: hidden !important;
-}
-
-input.gsc-input {
- background-color: #fff !important;
- border: 1px solid #d6d6d6 !important;
- box-sizing: border-box !important;
- -moz-box-sizing: border-box !important;
- color: #868482 !important;
- outline: 0 none !important;
- padding: 9px 10px 10px !important;
- transition: color 0.5s ease 0s, box-shadow 0.5s ease 0s, background-color 0.5s ease 0s !important;
-}
-
-input {
- font-family: 'Titillium Web', Arial, Helvetica, sans-serif !important;
- line-height: 1.5 !important;
- font-weight: 300 !important;
- vertical-align:middle
-}
-
-input:focus {
- border-color: #46a2da;
- box-shadow: 0 0 5px #46a2da;
- color: #000;
-}
-
-.animation {
- width: 100%;
- border-style: none;
- border-width: 0
-}
-
-.player {
- width: auto;
- position: relative;
- display: table;
- margin-bottom:1.5em;
-}
-
-.playcontrol {
- display: none;
- background: url("play_icon.svg") no-repeat center,
- linear-gradient(
- rgba(0,0,0,0.15), rgba(0,0,0,0.15)
- );
- background-size: 25%;
- width: 100%;
- height: 100%;
- position: absolute;
- left: 0%;
- right: 0%;
- top: 0%;
- bottom: 0%;
- margin: auto
-}
-
-/* expand/collapse code sections */
-pre input {
- display:none;
- visibility:hidden
-}
-pre label {
- display:block;
- margin:-3px 3px 0 -16px;
- text-align:center;
- color:#21be2b;
- float:left;
-}
-pre label:hover {
- color:#fff
-}
-pre label::before {
- font-weight:600;
- font-size:16px;
- content:"+";
- display:inline-block;
- width:16px;
- height:16px
-}
-#ec_expand {
- height:16px;
- overflow:hidden;
- transition:height 0.35s;
-}
-#ec_expand::before {
- content:"...*/";
- color:#aaa;
- background-color:#3a4055;
- z-index:99 !important;
- right:25px;
- position:absolute
-}
-#ec_toggle:checked ~ #ec_expand {
- height:initial
-}
-#ec_toggle:checked ~ #ec_expand::before {
- content:""
-}
-#ec_toggle:checked ~ label::before {
- content:"-"
-}
-
-/* permalinks */
-h1:hover > .headerlink,
-h2:hover > .plink,
-h2:hover > .headerlink,
-h3:hover > .plink,
-h3:hover > .headerlink,
-h4:hover > .plink,
-h4:hover > .headerlink,
-h5:hover > .plink,
-h5:hover > .headerlink {
- opacity:1
-}
-a.plink, a.headerlink {
- opacity: 0;
- padding-left: 8px;
- font-size: 0.8em;
- font-weight: 600;
- transition: opacity 180ms ease-in-out
-}
-a.plink::before {
- content:'\00B6'
-}
-
-table.special {
- border: 3px;
- padding: 0px;
- border-collapse: separate;
- border-spacing: 20px;
- line-height: 1.5em;
- table-layout: fixed;
- width: 80%;
-}
-
-.special p {
- text-align: center;
- color: #3a4055;
-}
-
-.special a {
- display: block;
- border-bottom: 0;
- text-decoration: none;
-}
-
-.special a:hover {
- border-bottom: 0;
- text-decoration: none;
-}
-
-.special strong {
- color: #17a81a;
- font-size: 110%;
- font-weight: normal;
-}
-
-table.special th,
-table.special td {
- border: 1px solid #888;
- padding-top: 14px;
- padding-bottom: 14px;
- padding-left: 6px;
- padding-right: 5px;
- border-radius: 5px;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
- -khtml-border-radius: 5px;
- overflow: hidden;
-}
-
-.special td:hover {
- padding-top: 14px;
- padding-bottom: 10px;
- border-bottom: 4px solid #41cd52;
- overflow: hidden;
-}
-
-.command {
- font-family: monospace;
- font-weight: normal;
- background-color: #9cd1a6;
- padding: 2px 4px;
- color: black;
- border-radius: 2px;
-}
-
-div.leftside {
- width: 50%;
- padding: 0px 50px 0px 0px;
- float: left;
-}
-
-div.rightside {
- margin-left: 50%;
-}
-
-.btn-qt:hover,
-.btn-qt:active,
-.btn-qt:focus,
-.btn-qt.active {
- background: #41cd52;
- color: #fff !important;
- border-color: #fff;
-}
-
-.btn-link {
- color: #41cd52 !important;
-}
-
-.btn-link:hover {
- color: #222840 !important;
- text-decoration: underline;
-}
-
-/* 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;
-}
-.card-img-top-main {
- padding-top: 10px;
- height: 70px !important;
-}
-
-.card-img-top {
- object-fit: contain;
- height: 120px;
- padding-top: 10px;
-}
diff --git a/sources/shiboken6/doc/_themes/pysidedocs/static/relbar_bg.png b/sources/shiboken6/doc/_themes/pysidedocs/static/relbar_bg.png
deleted file mode 100644
index 4036733a7..000000000
--- a/sources/shiboken6/doc/_themes/pysidedocs/static/relbar_bg.png
+++ /dev/null
Binary files differ
diff --git a/sources/shiboken6/doc/_themes/pysidedocs/theme.conf b/sources/shiboken6/doc/_themes/pysidedocs/theme.conf
deleted file mode 100644
index 01a4dd4a1..000000000
--- a/sources/shiboken6/doc/_themes/pysidedocs/theme.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-[theme]
-inherit = default
-stylesheet = pyside.css
-pygments_style = none
-
-[options]
-nosidebar = false
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 a54fa7ef2..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.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 <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation License version 1.3</a> 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
@@ -92,6 +117,7 @@ add_function_parentheses = True
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
+pygments_dark_style = "monokai"
# A list of ignored prefixes for module index sorting.
#modindex_common_prefix = []
@@ -101,27 +127,40 @@ pygments_style = 'sphinx'
# The theme to use for HTML and HTML Help pages. Major themes that come with
# Sphinx are currently 'default' and 'sphinxdoc'.
-html_theme = 'pysidedocs'
+html_theme = 'furo'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
-#html_theme_options = {
-#}
+html_theme_options = {
+ "dark_css_variables": {
+ "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": "#27138b",
+ "color-brand-content": "#27138b",
+ "color-admonition-title--important": "#27138b",
+ "font-stack": "'Titillium Web', sans-serif",
+ },
+}
# Add any paths that contain custom themes here, relative to this directory.
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 = None
+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
@@ -131,8 +170,12 @@ html_theme_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_themes']
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
-#html_static_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_static']
+html_static_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_static']
+html_css_files = [
+ 'css/qt_font.css',
+ 'css/qt_style.css',
+]
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
diff --git a/sources/shiboken6/doc/considerations.rst b/sources/shiboken6/doc/considerations.rst
index abab2c28d..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
@@ -181,4 +193,4 @@ What is 'inject code'?
That's how we call customized code that will be *injected* into the
generated at specific locations. They are specified inside the typesystem.
-.. _`Mailing list`: http://lists.qt-project.org/mailman/listinfo/pyside
+.. _`Mailing list`: https://lists.qt-project.org/mailman/listinfo/pyside
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 6ab337680..cad49086d 100644
--- a/sources/shiboken6/doc/gettingstarted.rst
+++ b/sources/shiboken6/doc/gettingstarted.rst
@@ -11,13 +11,13 @@ need to continue if you already have a built PySide.
General Requirements
^^^^^^^^^^^^^^^^^^^^
- * **Python**: 3.6+
- * **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: http://download.qt.io/development_releases/prebuilt/libclang/
+.. _downloaded here: https://download.qt.io/development_releases/prebuilt/libclang/
Simple build
^^^^^^^^^^^^
@@ -25,13 +25,13 @@ Simple build
If you need only Shiboken Generator, a simple build run would look like this::
# For the required libraries (this will also build the shiboken6 python module)
- python setup.py install --qmake=/path/to/qmake \
+ python setup.py install --qtpaths=/path/to/qtpaths \
--build-tests \
--verbose-build \
--internal-build-type=shiboken6
# For the executable
- python setup.py install --qmake=/path/to/qmake \
+ python setup.py install --qtpaths=/path/to/qtpaths \
--build-tests \
--verbose-build \
--internal-build-type=shiboken6-generator
@@ -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.
@@ -54,7 +54,7 @@ You can get the ``shiboken6_generator`` wheels from Qt servers, and you can stil
via ``pip``::
pip install \
- --index-url=http://download.qt.io/official_releases/QtForPython/ \
+ --index-url=https://download.qt.io/official_releases/QtForPython/ \
--trusted-host download.qt.io \
shiboken6 pyside6 shiboken6_generator
@@ -62,11 +62,13 @@ via ``pip``::
The ``whl`` package cannot automatically discover in your system the location for:
* Clang installation,
-* ``qmake`` location with the same version as the one described in the wheel,
+* Qt location (indicated by the path of the ``qtpaths`` tool) with the same
+ version/build as the one described in the wheel,
* Qt libraries with the same package version.
So using this process requires you to manually modify the variables:
* ``CLANG_INSTALL_DIR`` must be set to where the libraries are,
-* ``PATH`` must include the location for a ``qmake`` with the same Qt version as the package,
+* ``PATH`` must include the location for the ``qtpaths`` tool with the same Qt
+ version as the package,
* ``LD_LIBRARY_PATH`` including the Qt libraries and Clang libraries paths.
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,iVBORw0KGgoAAAANSUhEUgAAAc8AAAFUCAAAAABnsuh3AAAAAmJLR0QA/4ePzL8AAAc6SURBVHic7d1dbltVFIbhtfZxxBQS0fyXizR1UjVMjJKmtI1AgFpC+gc3iBvmUP8wBwbAbJyzNxfHTtskTuzjiO796X0uKxVFerXO52MKdVtAVa8MDqL7Iv8M3J4Y/gwL/PZQrwwPanLmZIGeIa4MH55Vlm7vp8Gi2vcMcbn/8KyTjPvMSOueVVwefE3O3HRa/r5QLw8PziojZ15a3meIK8ODs44ncualXc8QVwYHo04iZ25a9azicu/gbIntzE+b/Qz1l8MHbGeWWtynx9XhgxHbmaX57zPE1cH+iIdtnua+zyquDcmZrXl7hvpOf2/UYTszNefz1uOd4f5oydjOTM13nyE120nOXM3Vs4qrgwdsZ87med6GenXIduZtjvv0uDbcGy3x3pmz2XuGdKe3x3ZmbuaeVVxjO/M3636Gem3YZTuzN+N9hrg+7LKd+ZutZ4hbf3fZzgLM1LOKW/1dtrMEs+xnqLcG99jOIszQM8StwT2+sy3DzT3HOXnYFuHG/aziNjnLcVPPqt7usZ3luOF5G+rtwQ7bWY7r7zPErwY7vHcW5NqeVdzu7bCdJbmuZ6jvDnbYzqJcs58h3u2znYWZ3jPErfc8bEsz9XnLd7ZFmtazqjf7uyP+c93STOkZ6s3B7mjJyVmYq3uGuN3f5b2zQFf2rOLm+/tsZ4mu+nxb1ZsDtrNMV9wn21mwy/cZ4iYvKsW6dJ9V3OyzncW62LOqN3r32c5iXegZ6o1+l+0s16f7GeJ6r8vDtmCf3GcVN/p75CzZxz2rerO/x3YW7aOeod7osZ2F+7CfIa73uvxP3Ap3fp/NdvKwLdzkPqt6o98lZ/HG98l7p4jmPtlOFcHMrIpr79lOCR0zq+q1/j45JYRmO/fZTg0dC3G9z3aqCFXkRUVIqPkopCSss51KOgO2U0no8neQKQk1OZWEwH+uqyTwUUjKIn/fMvJDTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTy301EJPLfTUQk8t9NRCTx3JLNFTRvJoS/RUkTxW9i89RSSP7ie/dz73z4FbkTwGO3nK5yEN5zk9fe4fBYtLHt1fHVmI3KeAZjuPzKOxn+WbPGw98X2CgPPtTEbP8iWPbidPzaOZGZ+HCjf5KDQOyX6WLXkM9iEnz9uyTXKGyWOWniVLHt1eHVmIk19hPwt2YTvNuM+SJY/BTz7JyX2W63w740e/yH2W6vJ2mtGzWMmj++nR+GuEc7x/lil5DHb65NJecp9FmuQMFz/+8HmoRMmj+5vDC9tpxn0WKXl0f314cTvNuM8SJY/B3hxe2Y77LM4k56XtNKNneZJHt9OrttOM521xmu18PCUnPQsz/ZNtg+dtUZLH4K+n56RnUZJHtzdTH7ZGz6Jc8945wX6WI3l0f/fomuvkPgsyS056FiN5dH97Q06et6WY6Tq5z1I0H4VuzEnPMiSPwV9d96IyxvO2BDd9K/QB91mA5NFueO+c4M8PZS/Z+Cv4WZ6l3GfuknkM/vLx1f++8yJ6Zi6Zx2Avns+wnWb0zJ9Ht5fHs2ynGfuZufF1Hs/8HsJ95qzJ+fPsOemZsybnT9/P8S0BPXPm0e3HH+b50ofvh7I1ftjOc53cZ75a5aRnrlpspxnvK/nyurLjF/MOIvuZpeY6n7+cuw/3maMm57Nf5j839jNDTc7jFjm5zyx5XbW6TvYzQ811Pj1p1Yb7zE2T87tf250a+5mZZF63z0nP7Hhd2bO2OdnPvDQP2yenrbuwnzlpcn77tv2Z8bzNSLOdi+TkPrPidWWP3i0ygp3Z/pgR/g9eV3a4UE4+D2Xmm98WS9L559Z+FCwqffHXHwte2H8K+gdgTcZwAgAAAABJRU5ErkJggg=="
+ 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,iVBORw0KGgoAAAANSUhEUgAAAc0AAAHNCAAAAABZLn/BAAAAAmJLR0QA/4ePzL8AAA53SURBVHic7d1djty4FQXgc6mqmayhPch7duFxP2UNhm0EWVhgd7wMj72JZAHBuNcw45J480CKXd31px+qdMk630OAmUEaRh9TIo8oCiAiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiWocs8UOd//Vff/3DLfGj6ZwF0hTx9x9f6SJ/T+isJv+PdP7+46u20fw/mS7IP4Kcv//4arfl2FxB9t85w1xR7l96091/umOYK8n8W2+6Nw937YZhriPvr73p3jzcdQ3DXEnW37vzbx7uOscs15Jzie/8/cNd54Rrk7XkG0ci/v7TXeeE19nV5Bub4u8/3rUNGOZ6sv3qnf/1gevMleX65Tv/+uEXhrmyTFfaxt9/Zpiry/PrZ2lgQ5bfP0sDI3IEwNLAigz3TZYGZsweUCwNDJk9NlkaGDI3Az6ctmRmCgzTlHkxcKeBLbNyYGlgzJwgmu71Z5YGlszYT+v8m3/fdW6Z7fI0xfQVSl8aZPzD0ExTw2BpYNHUscnSwKKJYXCdadK0OBimTZPyYGlg1JRAWBpYNSER7jQwa3wkcacBSwODRq9QWBoYNjIVEf/6M0sDq0aOTfG/Pty1DcO0aVyazt8//LLbKG+aNo2KhaWBcWOCYWlg3YhkWBqYNzwalgb2Dc6GpUEBhs5pWRqUYFg83GlQhmFjM+40YJjGDUozrDNZGpg3JB+WBqUYkFDTvf7M0qAIl6+0Tffm813LMEtwMSOWBgW5FBJLg5JcuNKyNCjK2ZxYGhTm3NgUlgaFOZsmS4PCnAmKpUFxTkfFnQblOZkVdxoU6FRYLA1KdCItFzZBc/5TluNzWudfszQo0LHAWBqU6sjYZGlQrGNpsjQo1WFiLA3KdZAZS4OCvQyNpUHJXqTG0qBoz2PjToOyPZvTcqdB4faSY2lQvKexydKgfE/J8ZOL5Utj0/l7hlm6PjyWBjWI6bE0qEKIj6VBHQRgaVANB5YG9RCWBhVxLA0q4rjToCIC7jSoh/v7p1e7LT85XQf579/ajQK8bdZAfNt0G4GKMtDiiReFdo1TUQ7Q0omHQIHdFgLmWTjxEhYn+ufP6qAQrlXKJQoVBQDx7Tbkyc8wliokCRWooEUTxyfjLJL0S00VhaATgHkWS56Kg5CnB7RhnmWS/Rqoz1N1wzxLJM9LvZindNiAK9DiyGFFqxB492PjlCvQwhymGZecKj+2YKNQliNjs7/eQttGmGdJjqYZ8oRAOwcJlfyV/1w0xYk0kQZo69RxOlSI02dgCiCqunEerYgCfKRt3tkTTQGI6lagrYhCGahxp6+0UVh1aiiIeMG17WKaqVBQdaJgoJZdTrPPU6G+EXDBYtiQ74iF+ZCION1BOSOya8jYBNL4lK77iYWfWUPTRCrhW3EsiIwaniZShduGgoh5mjMqTaQtCk65RcGgsWnubTnhFgVzxqeJWMJ7eGlYyJsyJc2+kPfSbiTcSxmpCcO+Qv6CqEChThrsRMAVqBWTxibC1TY0RN1GuWIxYmqaQFqBqncAH2lbMOlKG0nMsEEHr7zcrm9OmgBEVFSlkQ4db5+rm5lmrOQFW6gyz7XNuW/24pYwr8KCaF050nzKU7zj9HZFedLE3haFfnwy0evLlmZ6BKrQho9A15ExzactJ143ygXoCrKm2RfyKq04CPf4XVvmNAFo2Ii724Bbwq4tf5qpwu2ccovCdS2QJtBXuD7kyTCvZaE0gXDOiYrnMcbXs1nsJ4fLLYO8pkXHZrhncmhezYJpxsKPs6Drmf0M5Rw59l1sWs6iY5OubNGxSVfGNGvCNGvCNGvCNGvCNGvCNGuycpoK5SlE+azdHqjwGKJ8lnuGMkh/2ibYzeewcppA3HrCMHNY+b4pKlCFV+H9M4O1Z0GicCLgO0lZWBibAgH4TlIGa89pn97pDcds8hCFOdZPc29iq+B3HmYxMKeNr4CqAOIlrkCZ5xQWxibSDiJAOT5nMJIm8PROEjyPZZzIUJpIMyKfDshY+w9UGFvPUPoFi/PhkBM2CuPYSrM/plobUXjhCnQkW1daAE8zov5/ecEdzGCaQHyrN3xOO7xByECHMHal7YVDpSCKLrwOygvuEEbTTPMhEbT8zsNQRq+0QCr8wjGb3KIwhOE0994xiwtQxnmB6TSB/pgwVeEE9zKr981EIBCFA1Q975/nWXiGckmc4AKq6viA5QzzV9ogFLiAgsdsnlFImn2fIBqWK9yicFQxaT4digGVsHBhni+VcN8MBBBFvwSNRS7zfKacsRn0x6aKOh5ec6C0NOMxfnGU8vb5nPn15gEBABUR8UgTXQJQ4tgE9r6kHQo/DtConFnQvjAjEnUaTsPlfCgoc2wC6TsPfYPL4YkS75u9UOCGA4353aug3DQBiIqoSHjHjNfakq+0wf58iHGWOQt6EudDxf+tzKOG30KcAXFoVpEm+uL25lWSJgEofE5LLzDNmjDNmjDNmjDNmjDNmjDNmtxEmgq9jWP8bqM9ULmNtugm0kyHhdX+mOUmrrQA4PUGtoTdRJqiIgKP6t8xu4k0VVRFHFS9VH1zuYk04ylEcHF3X7Xz24r/oj63944Zqv3I682kmQ7F6L8KUOMMt/R9QcPFgxgBgY8n2FS3++R2xmYUBqWK1njM5s2lCY3HU2v/+kNFed5emvt7cNXVNTxvMc29Y6pR1/z2NtPc/86D6/+5gkBvNc10SFg89a2OSv4muqCjBBBJx47Xcczm7Y5N4KlR6Fwdh2Lc7tgE0qk12gCqqsX/1b7tNENDBFFxVWxMKP6vYw7pXOPSE72dnvYMqWXZybFZk1u/b9aFadaEadaEadaEadaEadaEadaEadaEadaEaQ6nsP4WKNMcTsw/0mbrPlzaG2a2nOfYHCm+zWKT2T+YRfGbrnY3+HFsDhfHpFexOh9imsNJfEkbnYjNt+6Z5hgqquog2tmc3/K+OZLG7wzCGXwFlGmO1a9TvLP3JW2uN8fqvwvgxANia/3JsTlFHJ+iYYs8YOScMI7NKfrxCefVwc4rDxybU/WToE7C20kWMM05whW3bXxjI05eaecIV1w7v0OOzbksLTuZZgZm4mSaNWFPWxOmWROmWROmWROmWROmWROmuazr7iDienNhes0tfhyby9JwsvGVBijTXJz3V9sSxjQX55xXqMgVvtxh52lOnUQFEGkdICpL7yHi2FyYqEJ041r030lacHxyTnsF4RFo1/hm4YehTPMqVFTg1aksuiWMaV5H3LOp4t2Cw5P3zeuIH6ZzELRxubLAOOLYvJ54DK6Xdov4ObPMmOY1xe88wOtGZYHPdjDNK4tfjmzFLfBOEtO8tv4dlk7CO0k582QXdG0SPxfZoAPUZX3HjGNzHf2KBXDQbCfKM821hDw7UcmXJ9NcT8zTdU2u+S3bg/WERqERwS6sXWaPLI7NdfUfXu4aefpO+mRMc23xkBN4J7OfsPBKuzZRURWBkxY6s8Ll2DQgXWJ/bOOXtCcOUI5NA8J0CKo/oVMvwNQZEcemHSoq6NTBTS38mKYhfaGAqXnySmtIXIA6QNtJO3A5No1JBa7fjB+fTNOc/ljGDhvFuBUo0zSofwT6o2l01CNQpmlSynMjY7YoME2jYqOgnRuRJ9M0S+OX0b2IuvAe6KX/C9O0LOzxQyc6bE8115uWCSBQbZzvF6DnBx/TtE0gENWtg+5EFOcbBV5pCxCee3rxmwsnNDLNIoRH2grfyLktYUyzDH1BpN1GTg9QplmK9L3I3U+xIDrcRMQ0y9EXRL7dqsOxHWFMsyRhOgRpdaPHHoEyzdKEEbpzcuSRNtMsz+ktCkyzRCFPD2jzLE+mWaaYp3TY7BXyTLNQYZUCL7uNC5+lU2Ga5YpLTi9//izxH5lmyfpGYbftv+y69p+I5ogvIvmuEY7NCsTXVrRtug3TrEDYotBu/sM0q6CQ3fbxnzxhpg6y237/8IU7SWqgMUxeacungnbz/cMXxzlt+VTUN4/vvzhV3jdLl8L0PGevAuqbx3e/OQ/upy2eim8e3/3WeIBplk6lbR7f/dZ0AJhm4VR2m8f3fZhMs2gqu+33919cDJOzoJKp7Lbf3311vv8XHJvFUki7/f7hq3uqDNgelGqvNEj/jlfaQu2XBgnTLNVeaZDwvlmmZ6VBwjSL9Lw0SJhmiV6UBgnTLNDL0iBhmuXpdxr4g//CNEsTS4Mv7khTwPagMMdKg4TrzbKoqG9+f/ftyGUWHJulUfjm8e2JMHnfLEsoDb41x8NkmkU5URokTLMgp0qDhGmW42RpkDDNYpwuDRKmWYhzpUHCFUoZzpYGCduDIhzdaXCIaZbh2E6DQ7xvluD4ToNDTLMAl0qDhFda+1R228e33y6HybFpXygNvp0pDRKmad2A0iDhetO2dKbBkDCZpm3DSoOEsyDLBpYGCdM0bVhpkHAWZNjQ0iBhmnYNLg0SpmnWxZ0Gh5imVZd3GhximkaNKQ0SrjdNUkG7+f3913FhMk2Twjrz7beBpUHC9aZBsTQ4taP9NKZp0cjSIOEsyJ7RpUHCNM0ZXxokTNOaCaVBwjSNmVIaJEzTlkmlQcL1piUKGbHT4BDTNGTkToNDXG/aMXanwSGmacjU0iDhLMgMFd88vp1SGiRM04pQGgzZ0X4a0zRiTmmQME0bZpUGCdM0YV5pkHC9acDc0iBhmuubXRokXG+ubn5pkHBsrm92aZBwFrQ2xdSdBoeY5spm7DQ4xDTXlaU0SHjfXJXKbnvyJOjxODbX1B9QkSlMrlBWlD65mCtMXmnXk680SDg215KxNEg4NleTrzRIOAtaSc7SIGGa68haGiRMcxV5S4OEaa4hz06DQ0xzBZl2GhyS7D+RLsq00+DID+YK5fpUvn/IWRok8kf2H0kX+L/87x8Z6zwiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIgP+DzpdwlLjG1tvAAAAAElFTkSuQmCC"
+ 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,iVBORw0KGgoAAAANSUhEUgAAAc8AAAFUCAIAAADNuyD8AAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nOy9eZwk11Xne869EZF77VW9t1rd6lZrtWRLtqzNLdkG2WC8YI/BZowHMzDAmAczvIGHPSB/BmMYYJ4Z5mOYZ8wYsMHyAhbGYMsWEpZkua1dLUsttdRbVVd1dW1ZWblGxL3n/XEjo7Krq7eqvFmZWeer/rSqqrPiRkbe+MW5554FoaO4m+4+9YNTU89PzW5SfgokEhJqJATEtT43hmGYZSEgICHX+jQugrvpbgDIjGROBPNFGQoAgUCAApC1lmGY9gbFWp/BhWKkFgBePHZiVlUEggAiQEQipDU9NYZhmPPTGbbte774HgDIjGRePHpiYiovBC1KLSEAG7cMw7Q52AFqa6zaqeenJvz8VLGMUiEQUV1qkaWWYZj2p+3VNvbVjgf5fJhHKQkI6lKLCCy0DMN0Au3tt419tQePjc2oKsgkASEhYCS4a3p2DMMwF0H72raLvtpjx09Mz0kEJECoyywisF3LMEzH0K6ehEVfbTA7tTAjhIMEgASIQIQILLUMw3QU7am2BABw1chVJ9XcPBSBPIiiDhCAAJC3xRiG6TTaT22NVfsgPCjGMmFNqcAx+roYf8BKyzBM59Fmamt8tVeNXCVGs858LvD1otQiAhI7EBiG6UzaSW0b4moLQRFDHS4mMGDkQ1jrc2QYhlkZ7aO2dV/tRG1+LqhooQHNf5HictkZhmE6mfZQ29hXS0fT1QKAQ4iIhBQX92KpZRims2kDtY19tXQ0RVMeSoy9B0icK8YwTHew1mob+2rH/XylqIUQRmoBgaWWYZguYm3VNvbVBvOzYQmFEI1SC7wrxjBM17B2ahv7avF4JigKEGBEFhGBgOvNMAzTXayR2sa+WjyeoXyCNBAQAhISRNEHrLUMw3QTa6G2sa92Mljwi0gaCHQUgxDlirHUMgzTZbRcbeN6tSfDQkHVNGojtZH3gFMYGIbpTtBp5WhxvdqXjo3ldRkQNWmTu1APQWCpZRimO2mdbRvXqz10bGxyapaATJXahhYMLLUMw3QrrfIkxL7ak8H8THFBI9TLzcQ1vVhqGYbpYlqitou+2mB+PqxojIonAlBUDIFhGKbLse+3bfTVLkotIdXb3TAMw6wH7Nq2sa/2pWOjk1NzoYjyxMx/HFbLMMy6waZxaaQWAMLd7rwqK0RBCAD12l4c7MUwzLqAgICELdvWOBDKU+XikCp5vgYUJn/BBCCwWcswzPrCzi5ZvC02Ec6XXF/DYhFFaohCYBiGWTdYUNtFX+3xsclK0SSJEdSllmMQGIZZjzRbbRd7iwX5meK8iIK8jJuWEDkMgWGY9UlT1bbBgZCf00VEocnYtVCPq2WpZRhmfYKiWUdqiKsdnVNFAVI3+GnZfcAwzDqnObbt6TUQ5iDulGtsW5ZahmHWO83woi7G1e5xC0FVm3bkLLUMwzAA0Kx42ziutjASFlJV0ALrbcW43AzDMEyd1e2SNW6LFVJVEThxCwbToZyllmEYBgBWpbaxr/bF48dnigUgGcXVRsFerLMMwzAxK9XE2FcbXO7MQlGETiSy9b+bd4oMwzCdzcr9to2+2oXYgQCNcbUMwzBMIxfvSYh9teNqrlFqTbtcllqGYZjluEi1jX21B0ePn6rmRViX2noVRTtnyTAM0+lcjN+2wVfrzsLCoq+WpZZhGObsXJzfNvbVLgyrYsJHJevdbgCA3bUMwzDn5sI8CY31aotJHzTGYV4IaDy2ds+TYRims7kAtW2Iqx2dKS9oAgFxWi7Xq2UYhrkQzmeTNvpq87pMGsVpcbXA2WIMwzDn5vx+20Vf7UhYSFVRSRH7ajm0lmEY5iI4uyfhNF+t2RaDKPYAwTRhYKllGIa5QM6itsv4ahf7khtfLUstwzDMhbOcaDbWq52juq+WO+YyDMOsiOX9tqfF1SZ9qG+LGQ8tSy3DMMyKON2TsHxcLdVrIBB3zGUYhlkZDWq76Ks9drqvtl4gnKWWYRhmpdQFNPbV+rudabXggtvQWYxrIHQDS3zuZ4mVJlrmR+ysZ5hVsei3XaxXOxzm3YqLblSv1tyRLLadQ6yMJlBPgBDmbxQShUABgABkXqlBE5D5o0FrIAICMInY5nej3xIg4si/WKNZhRnmYkDHSO3IVSMT4XyNAle5S/sv8A3VZiwrc/VdTAQARUqR1qAUaUVKgyYiDYQAnvBSIumg40pXgjDyCgAuugAUUBhQGFLo6yCkMKAgJCUARV1zBQoJwkFHoDBjxUc47xkyzDrHOfWDUyNXjbx4fHReV0ydGS6i2J4Q1csAIQKApsgy1USxiUpEDsp+p2/IGxhw+wfdgUG3NydzaZlKiWRKJl10E8KTKB10RMPn66BDQCEpRUqRCqO/w4quzocLBVUohAuFsFgIF2aCuZP+qdkgX89wMYYwIqIAEZ8h1S1oll2GMThTz0+Nh/k8lYka4mpZatsG84kIQESpQQcUBDoEIE8kPOG66GRE+tLU9p2pS3aktm9LbO53exMi4aLjoesKV66urXIjIYWhVgEFNe0XVXm8NjHuT47XTo5WTxyuHC+pkk+Br/2QQonSRddBBxF0/THAssusc5y5zWElrLjoRjUQEHhbrB2ILVkppCZd0bWqrqVEctgd7Hd7Nic27U1ftiO1fWdq+yZvwzmEjCjyxhIQncstZP7lNLeAeX1cVNNBx5FOEhI5gCEY2JHaGr8y1OGR6vEXy6+8VH7lSOX4XJCfCeZmgjkASMpkAj1CMg4N1lxm3YJ3PvkuTaf3yiXiYK81oVGMzGdR035ZVXqc7GXpS3eldlye3nV5+rLL0jsSInHm70ZfnNPTfoEJgaanp3nxWV6wOMqZR5v2Zw6VD79QfvmVylGjvwJFWqQkytjPyw91Zv1gYhJw3+PvjMO8+AZYK+qWLACg2eAKSUkQV2X33tT7mmsye7clt4x4Q/HrQwrrQQLLfF5Wc6yjqbKcClM9qiF2XyhSx6snXqkcfWLh2Ufzj0/4kx66AoVEaeYbW7vMeiBS2zsef1dcbsaYM2t9YusLI1sCBQL65IdaJWVixB3a13/znQO3bUlszMi0eaUiTaQRhdmSMr/YPp9XfD5U37XTRK5wzL8q0nPB3IHiwW/OPvBM8fliWFSkkjIpQLCHgel66rbtE++sp+dyYm6rMSojQVZ1raZrGxMjV2b2vGXwztf33uAJL36NBh07T9tNZJclrmEEABoIgBo368aqE1+f+daj808cqRyraT8r0wCoSLX5m2KYFVO3bZ94J4fUrhUIGJIqq/Ilya37+m/e13/L1dm95p+WXap3nB41yq4hfgslVf7WzL8+MPfI4wvPEOm0TGkOGmO6lFht37XWZ7K+iNVEk67q2ubExh8b+uE7Bm65JLkVABSpRm9sd1S5XKK2xlo31m5ZVR4rPPWVU19/vPCMg9IRDvtzme6D1bbV1CNnhSLlU9Dn9Lxt6IfeNfIjZvsrJIUAJkGgi7Wm0b0bkjKO3Zr2H87v/9zJL79cPkIASZHoVmcuERkfvb0huvXSdTSsti0ldtEWVSklk/v6b/7gpvduT26Fumc21tn10PAt1lyTEWfsXF8H90ze+9WpfxqvTaZkEgE16a5RjfgtBzrwKbD3EXvCddBhwW0rWG1bRBx1oEmXdeXa7JU/ueGddw7cCg1L7O62Z8/GEq+uefvjtZOfnbjnn6fvR0QX3W4SXAAgohFveFtykyJt513hserYTDArUFg5PLMiWG1bQZwSVtO1pEi8b+OPv2fkbTknq0g3BnJBB+6ANYtG34IC7aAEgPtmHvz/Tvz1WG0iI9Pd5MYNKXzvyDt+cesHS6psQxAF4B8d/7N/mrk/Kbzl81KYtcCorbPWp9HNGCcdAVV1dU961y9v+9nrc9cAQEihBLk+7dkziWqJEQGAg1KREiB+aHDflZnL/9fYZ74z92hCJCQK1S1GridcRMzItKW340Q3NS7Jw2bWHFZbWxipVaQCCn906M0f3vrvs07aRP4btxpLbSOx5kqURKRIb01u+sSuj/zVxBf/+uSXa7qWEInuiMnVoAFAgRbU5PeCp6+WmHaD1dYKRmpDCh10fmHrB9+74e0AoEkjoEDRERkKa0Js7wuKnDA/vfm9O1LbPjn66ZP+qYxId4Hgmv0xMxOaeNiGQvJMm8Jq22TiPTFfBxkn/Zs7/q/b+24yJq3RWTZpz01jvpyJ1nhD/80bvOGPH/3ky+UjGZnhCCemQ+GNy2ZiZEKirGl/xBv8/V0fvb3vJkUKAIzUIiLLxHkxVykOTw4p3JvZ/fFdv3l5endJlQVPWqYz4YnbZIzUbvCGf2fXb7wqd5XZ8+ENsRUQXzQJUpHantzye5d99JrsFSVVNr7dtT7BFWI7mLpTr8s6gNW2aRhfrU/+sDf48V2/cUVmT8hSuzoaLVxNemNi+Hd2/caV2T1FVepowbVK16fGdC6sts3BSG1AYVZm7r701/ZmdoekTOgoS+1qiN24Jj1kxBv67Ut/7dLU9rKusOAynQWrbROIg708dD9y6a9em7tSkXLqWsBSu0piZ7cpmbY9ueXXL/nwgNPvUxAHeDBM+8Nqu1qi9FOgkMIPb/vQLb03KtICOMyrydR9uEKRui531a9u/zkXHQJeNzAdA6vtqogTc6u69t4N73j78F1EJOpNyFkImsgSH+4bB257/8YfL6uKOEvbHoZpN1htVwsCVnT1xtx1/2HLB8C07eJtMTsshuICAsAHN733jv5bFnjHjOkQWG1XjpHUgIIRd+g/X/ILrnAVqTiudq3PbikU9Tqn8wJn6RzRDsSLBk1aoPilrT+zI7m9pmssuEz7w2q7KhCQCP7jtg9tT25RpM09v+ZS2yiamrQipUgpUCGFoQ4VKN0QlBnvQWnQ5jWBDhUoRUqTbkP9bdwx25rc9Itbf9qLnnPsUmDaGlbbFUJEDjoLYfGtQ29808BtALBWDsRYDRusUyKgOIdNopQoHXRc4bjCddCRKGKR9XUQ6BAR669xXeE46EiUAgUiatCK9BKjOBpxjULpG3fM3tB/812Dd9bIh7q7nGHaE66TsBJMqaqKruxK7fjgpvcCgFnYttKwbYx5MMKH8e5cPb6dSB+vjk/7s7Ph3GyQz4f5kipXda2m/Zr2AYCAAgoR0EMnIRIOOkmR7Hd7B5y+Abdv2BvantwSt1iP0aSJACPTfg1CLxqK1wgA+NDm9z9eeHa8dtIV3LOAaV9YbS8acz+bruPv3fj2TYkNptZXi6U2Kr9NCgBlQ6uruSD/XPHFH5QOvlI5OhXMllW5oqo1qlW1X9O1kEIiEIgIwvxC3JLSWMRA4AkvKRIJ4aVkKivT/U7/juTWKzK7r8tdvSmxAQBM8SpNWlNDg5/Wam4suJr0gNv3oc0/+bEjf2Q6SLbsHBjmomC1vWjqIV/V1+Re9WNDP0xEEmTLRiciI6zGUWA6ehXD0rh/8vHCMw/nv3+4ctSnwLhozQsQhQB0UHoyWxflSJJiZcL4L9NGEKiqa2VVmYQpoqNPLjzrTjuucLclNr+m59qbem/Ymdze5/aa81mr4ujRiIAA8OaBNzyU3/+t2X/NykwXVGVkuhJW25WgSKVE6t9t/gmTTtoCH0LsEcbTO4S/Ujn21MKzD849+vTCcyGFLroi0lbHlW70u3VRNXWsz3Gqjf8kUAgULrjmCETka/+l8uEXSof+auJLV2T23NJ74/W5a67PXW3s+vg6xOdp61qcgRn6fRvf+b3CE6EOOQKPaU9YbS8Ok6Tra/+u4Tuvz11jvm2N1BoRqW8QyRdKL31t+r79808erY4lhZcUyQR4jevos7XzOsepnvlPcRNGY9ELFB64CPBy+cgzxef6nb4be667s//WOwduNZobH6c1eoeI5h1r0ldk9vzI4Js+f/IrfU6vQmV7aIa5WFhtLw5EVKSGvMEPbPo35ictkNrYRWvs2ePVE/9n/AuPLTw15c8khDfg9hFpvZy2rv7Ezqa/nnCTckCR+pfZh78//9RXTn39pza9+7a+10G0h0Yta1Fh0kk0aQD4seEfeij/vVP+jCe6rVnvhcM1wNoWjgC7CIyLtqTKbx++a3NiQwvivRalFrREWVW1vzn5d7948Nfvm31gPljIyayLriKlSEOrFu9RFASQ8Qv3OjkCeq508KOvfOIjL3/icOWYcUHEzlPbV8lcH4kypHBnasedA7dq0MD1E5j2g9X2QjH2Wo1q25Jb3tR/OwBom7d07DQw0V0OykPlI//p0G/9z9E/L6pSUiQ94WjQuoU6uwQzaEgKEZMiIUA8kH/kwy/+5ldOfd2Y4S0TXIPZq3z3yNtGvKGAwhaMyDAXBavthYKIArCqam8auO2S1FZFyqQz2FC6RkctIgoUX5u+79cO3f3kwoGczJiu6bo9aozFzwNETItkUZX/8Ninfuvwf58N5iTK+GFgVXAbo8E2eMP7+m42xn57ppbxSn/dwmp7QZhIo6qubUtuvmvwTvNDRCs3Tiy1sefxL8a/8AfHPjUbzOVkJiS1OHp7EJ+JIu2gzMj0/bMP/epLv/1y+YiImudSiwQXEADePfKjWZnhsASm3WC1vSBMBVsCurn3xp2pS0IKo5IIduyUuOoKEf3RsT/7i/HPOygTwgvbO5LUnLYGnZWZQ5XDv/by3U8UnhUodEsEN2ZLctNdg3eUdSWuMsww7QCr7YWiSGVl9h3Db4G6i9CeYRvr+P8a+4svnro3IRIIoDphkz0OB06L1JQ/e/eRP3hy4YBsiYVrLo7xIbxp4PaUSHKtcaatYLW9UBTpV+Wu2JXeEatG0w3bxpApRPybk3/3xcl7MzJtvLSdIhx11VMpkZwL8r91+PcPFF8wLgXzAnvJtca3DgCXpy+7uffGhbAo15952yHTZD3Cant+jLBq0u8c/pHFn9iZ1CaeFxG/PfudPx//vIOO1eHsYd5IUiTngvn/duR/jNcmTd5dnI9gAyOsIYWecF/fd4MnXKtxI+3Kenu/HQOr7fkRKHwdXJG57OrMXnujGEk1sVNj1fFPjX020EHb1ia/EMzbSYnkWHXi40c+WVEVgULb9CeYMpICBADc3HvjZelLK7qKbdZKBxv+ZtYVrLbnR4Co6Mpdg3dmnYwJaWr6vRIHMJkw1T8e/fOJ2smESHS659EUS0vJ5JMLz/7pib8EgKg8pLXwLBMWHVI46PZfl706Pg0bYzHMRcFqex4QMKBgc2Ljq3PXQj1P1EYoQqw+X5r82sP5/RmZ0aDbyihbGUQEQEmR+NrUfd+Ze1SgUKDtDWcMZ2Pe3tF/S4/MhhRCu8beMusKVttzYe7bkipfn7v60tR2860towxIoBitjv/N5N95wj1bTZmOAxE1kUTpk/8XE387G+QdlLZtduM9eFXuqi3JTa1Ma2aYc8Bqey7MQjghvOuyVzfm/jcXI9+mRPfnT355yp9xsauKqhgHblqkny++dO/UN6CuhpaCE4z31ny9r+8W8wXbtsyaw2p7VkwoQk3XtiQ23dhzHQAIFNRsK6nRgH1m4QffmHkgKRJdWQ9bgUrL1N9NfX3Sn4reneXgBAC4ve8mT7jdsUpgOh1W27MSR8vvTu/cmtysSCEgWDCRYivvcye/HFLYaJp1DZE7FcVMMHfP5L1Q94DbMjnr129TYuTqzOWm95qVgS4atB2P0CbvkzkTVttzoUmnZPL1vTeYb5uug3GLM4Hi8cIzB4ovmAq2XYm5dA7KB+cemfZnGhs9NH8siGqPecK7re/1VV1dq47IDBPDansuFOi0SN2QexUAWNofi4/5j9PfmgvnXXSbPkRb4aAzE8x9Y+YBAFCgrObyaiAAuDq7NyezCrrHD850KKy254JIb09u2ZAYNkZo029XY9hKlM8XX3pi4ZmkSFA9HLUrMUEdNe0/PP/9mvYbm+s0nfjT2ugN783srumaWPUie/Vn2/V638Wzd/Ww2p4F0+0K6Kbe10Q/aPY0iuqFAwLA/sKT47VJT3idns5wbszTJS1TB0uHHsnvB5vmbZxv3e/2XZnZXVFVXIXvorG4u2ntvqI/ZDrJg8UNQtOPTptK8y3+08pKb50I9yU7CwgISEA39Fxna4R6WcUpf+aBuUfSImluxbbZz7ECETnoFNTC9wpP3jlwmwRpL4sXABQpAWJPeldGplcTVIdgtkjJE54EQSu1UkNSLjpg08h10U3JVFIkWqx6BORT0E2Ri02H1fashBTuSG7bmthkvm36HIpvhoOlQwdLh3qcXFcGfi3BmLdZmXms8PTx6tj25FbzyLExFhEhCADYk965JbnpRHXCrB5WciwECWJeLXz00l9948Bt82Ehqrp58bjCBZsdHP7D1p/+0Ob3t3IaEZCLzmw4/58O/dZEbXLFV6brYbVdBtNVsKTLr85dk5WZ6IcWrE6BAogezH/XEY69OoTthibtonu8OvZC6dD25FawWeRMAGrSl6Yu2ZLYeKRyPAGJ1VxnAsrINAD0Oj2rOSsb7zdewidFIikSzT34hdBDKqoiwpwF9tsug9kQC3V4Xe4qgSJK/Wyq1MaGbT4sfG/+CQ/d7vbYNmLM26RIPjD33ZCUJcMW6p+jkYC96d0uOrS6Eg0IqEgBQEghrQIbzs14I3c1J7YyzBX2KfB10N1+sFXCars8oQ6HvMEtic0AYKldtrnbvl94eiEsrrc5SkAeuo8Xnj7lT0c/sVkSDACuy12Vk9m4q9sqwUjJVwhYcEzFB1zVma3w/URN77nV8blhtV0GAeiTvyO5bdgdhHpSf3OHQESjtw/lv7cOK14bQ6yqa48XnrE7EkaLkr3p3WmZMlbY+nHatBIiColt23PBarsUIkIQNe1vT24Z8ga0CdJq6hQyQbUCRUmVXyy/AkDtVvHaNvHT5dH5x6CexWtlIEBE1KRzTnZjYsToLCuCDQgo0OF6sxsuClbbpRirEwG3J7cAgPHTNV1uNWgAeKLw7HxYcNBZP07bRhDgpfIrJVUyWbz2nAkm4OrK9OWss/YgoBDYk3AuWG2XIaBwwO27NLUdLNRGgHrJVwB4rvRCISx0cW2EcyNRFlXpycIBqGfZWqEusVdkdkO9foKtsdYfsVtGgw5N5SbmLLDang4BAoYUDroDO5LbAaDp1UyMG8FU1H6lckyBXm9uhBiJciEsPVV8DgDIWh2D+P6/IrPb9Fpfh8sIi9RnbqBD8/X6nMwXAqvt6WCktgNu39bkJk0aodm2LYHZFjtcPn6iOpHALs/WPRtEhIAhhEcqx8Ba0Z9G+pze7cktqklhCcwSAgrMc20dTuYLhNV2KQSEIDYnNgKAtmBwIaKJ+jxeGztRW0V2U4eDiATkoTfpTx+vjgkUtivyeMLbm9kd6PapddtVBDpY61Nod1htl6JJe8LbkdwGdmK/qF6JZrQ6XlRlaS22v/0xGZ+T/tSx6hjYebYtjkUkUexMXhJSuG5dN1bhYNvzsn5v9bNhAu+3JbfAYrBmMw8OABJlqMNjlVFXOGSrO1dn4AhnLswfqYyab+2JoLnK25NbNFjwDjEAPtu254PVdikayBXupXXb1oLcEgDkw8LR6qiHngZat+taIgIiB5yjleOKlIO2qnYgolHxQbe/V/YoYNdt8wkoWK8T+UJhtV0KkU6LpPHbNp3YpCqohcOVY6aTuY2BOgLjunWFe6I2kQ8LUA/YaPpARGSue4+T25zcwK5bG7An4byw2i6FALYmN5t4+6avN2MpmfSnFlRR2t+Ib3OM32a0NjEfFsxPbKzx41z+Hie3ydvACaY24F2y88Jqeya0M3lJ9JUFKTT3+eHKcYmy6f3SOw4CcFCe8qdm/Dnzrb3HjybKyPRGb8TnjTIL+MRqex5YbZdhW3KzvYMjIhEdi9R2vd/wRvIQ8Gh1FABW3zrsHGhSALApsYFImwIK9sZah4QUAKDNHkAdD6vtUghgY2LE6hABhUeqoxJYbSPXrYPOseqY1SYrdV8CjLiDWZnhutdNh2MSzgur7SLxXspGz7baBqPV8fUcadsIAUgU47WJwOZSNA5z7nf7ck5WkWLLtrlY/fi6A77hFzHFYnIym5PZ+Cc2BjrlT9d0jTdqDAQkUY7VJgJtcVMbEU1Jmj63NyszitQ6aDfeUkxMwnpfrJ0TVttFEFCBGvGGPOFaHWi0Os4+hEYkilP+dEmVrY5ixLXf6c3IjFpdyxzmTDgm4byw2p6GIjXiDXloRW0JoryxE7UJq1mqHQhq0uP+SbtjABJRn9OXlWlFisMSmktAIU/oc8NquwgCKtIbvCFXeFYGqN/aJ2oTfJ8vgQAmanbVFgAUKYGYc7Jml4wfeE2E/bbnhdV2EQRQpIbdQYlWkg7ie3vCP2WxeHanQqf8GasDxNd/yB0w/TKsDrfesOp27w5sZaZ3JqhB97t9ENVdtJVINhvMmuPzDR9DAJP+VP3r5l98MNcfEQCGvcEV50ybdvcBhXqlz2OBQlrIVDQH1KTVGgS3kYtujfyWj9thsNpGEBEKUKR7ZQ9Yu+EFiqquVpQJSCAbycEdC03Wu50D2YkXQDDFaQacPgediw/vRQ3U6+QAICkSqzkRG5+7yZoRKMQaRRaK6OoyZ4XVNsJMVg/drJOOftJ02xYIAaf9OZ8CMzVZamMI4FQwbb4QFlvmIAD0Oj0OytpFNtHSoFMi+dmJezbNbAhWWmlBgb6177V39N+iSTdXFo2C/6B48N6pb1qyFc46NIAAfLb0vGutilt3wFdnEQU652SSImm+tTRlZ8M5X/vIqQ11zHVGwIqqBDpwhWvP5I8rgTnoVKF2ESdJRECucPbPPxlSaJ7NFzt23ITpjv5bmm4Gmss4Whu/d/obkc+ktTuxSZFwhMPLtXPAahuBgIpUj5OrLxIt+A1NZdugEFBotSBAZ2Eeaeb6z4b5Dd6w7RF7nZxzkUUqjIIQUUomV/MMDkklLUW8AACAi05OZlts2xo0aJbac8Nqu4ginZORbYvWlo00O28AACAASURBVPkFtcAV/84EEQNS+aCwwRu2JxZR3UXZI9EhWkkd9zhoemVoUCveXrsQCIhVr23h9WwEAmhQGZlJylVtgJyN+C6dDwsBhXwzLMGssufCvO2BiKjP7Ylt24tyCPCndm74+pwbVtsY1ERpmUqgtdQGAgAohAvcO+BMTLBzIVyAusvFyigYRd1lZJrqP7E0FsMsgdV2EQ06ITxXGO+KjcbmBABFVTZtX5t7/E4HARXokq5YHSW2ZHudHH8ATIthtY0w4a9JkXDRBQt7ZERREGlFVzQQ3+pLQERNqqLsqm1MSqS5BhjTYlhtY1ADJTAhUVoqYmDCSH0dBdu2OECn/dGky6oCNqv2xX6DtExZG4RhlofVdhECnZAeWPMbGu+Br/3IjcAewwaMJ6Ec2bar2vc//1CstsxawGoLAABEiKCJkpgAAEslYwSKQAc+BbwzsyyadFmXARZ3FO2RFin+DJgWw2oLAJGZSUCeSICdtq/miIqUusiE0XWCKXe56EmwdoXMgdMyaWsAhjkLrLYRRCBQJKI8HxvB4QQACjT3HzyT+uONTJds8+izSlqk7Q6wRvBWQDvDahtDEkS9rIatqv6KlAbNtu0SzLPNJO9CS2Jg0zLFMQlMi2G1jaCo8KiMvrdzJ2qKbVu2Qs4AITRqa18HEzaLFTDMsrDaxpAA4aAEUyTBzg2vQCvuSHYWFm1b+2rrcG1ApuWw2kYY2za6Ca3d7Jo0sd/2LCBgSCrQrYjZcNHlJx7TYlhtY0hCgyfBDpq0SSRjP8IZkLFtAwrB/vWp52czTOtgtY04zba1hgLTNortqmVAAAUqJNNM0K7euujwh8C0GFbbCNPTybFu2yoCzbf52SCi1kTImWoYDNNKWG0XMf1aoi8tDYGCDdtlIQBAJKDW9H53Bast02pYbZdgVwodlBfbo2VdQdAi29b2IoZhzoTVdhG0XyjGASlBWGrg3engqvvQXDiWslcY5hyw2jZiXQMlSnsVHTsf1K3y27bGX7EGdOnb6g5YbU/Ddly9RCmiNSxbt8tgmhi2YqAufeARsOC2L6y2LcVB6aBgv+05acVziD8CpvWw2rYIYzVLdATvkp0dBBQtSWvmj4BpPay2rYOIHJQSeDf8bFBDEJ7lkVhtmZbDaruIBm2qothzfQkUkj0JZwexFSVpAICrVTCth9U2AhE16TBSWyuY/R8XXbNF060bNSuGWuhJUC3Zi2OYRlhtF9FAyqraEgFAUiZMYRquu3gmCIgtmZOBDniBwbQYVtsIBGPbhgBWHAmxtmZE2iQ4MI0gABAZT0sLhgui2jcM0zpYbRfRpOzZtkRk5DYrsw467Lo9EwKQIOv1Yuwa/iGrLdNyWG0jEFADGb8tWXCqYn2zPeukuVTCciABOShNazjbTpaAQv4AmBbDahuBAIri4qqWnKoIxrYVDm+RnQkBSZSucFtwcdi2ZVoPq20EIoakatoHAACyccMb/c7JDNu2y2JsW2hJMGygWW2ZVsNqC1D3GxBQTdfAcrWErMxI9tueTvRsI5AtU1sKbA+xJiBwBY72hdUWAAARCUAA+hSAtdgsjDwJxm/LLGKuDAGZTkUtUNuKqnZn+RYOK2xjWG3rECCir32wbNvmnKyL7Lc9HQQAQMSUTAIAkfVg5IquWD3+WoFd+QjpFlhtF0EQNZtqaw476A546JnuZKy5MQQkQWZEGgAQLV4Zc9yy6k61ZT9CO8NqG0MCsEa+ImXPsNKk0zKVEAkNBICcThZDQBJFRqZbM1xZV7ryQcfzqZ1htY0w4lfVVbN/YuNWNN5hABhw+xGQN8qWIFDW1dbqc4igm21bpn1htV1EgCirShwE1vTjx+lkI95gaypddRBEJCGybVtwacqq0pW7ZMTzqo1htY0hiaK0qLbNJ7bXhl1W26UYT0LasichdgdXdNXqQGsFz6p2htU2goxtq8sm5NYqw95ga+oKdhAEIFH2yizYjAmJH3hFVepCy5Zpb1htFxEoyqpS1T6YUgkWVppGR4xtywEJjZhg2z631+4oROYjKKlyVz7ueM3UzrDaRhCQQFFSsW1rcRNrxBviu2IJROSg0+f0gmXJQMRCuBBS2J0fQTe+p66B1XYRAaKkyn7db2tvW3zIHZDI3ckiKGrLTRKlUVvbY82HCyGp7lRbpo1htV0EEWvaL+qy+dbeSj8lU0PegOZmLQDQkLbroZuSyRY4WCLbthtd5/wIaWdYbSOICAgE4mwwB5ZnrUSxNbFJsXnVAAIYpy3ZXFUYIZ8PC91r2/JmQPvCahuBiCZ5dDqYBctq66CzNbFJcdvX08BBtx8ALCc0EwDMq7X121oVxK58hHQJrLanIVDMBnNWk3eNlGxObNKgu9S8WgkIsNEbjr62c/HjosWFoKBIrdW1Z61dt7DaLmIC7Gf8OastAs1GzdbE5pAUF6ZpZKSutpZARKN1U8GsT4HozsnPetu+dOWEWzkC5EwwG+io1HTTo8Biq23IG0iJpAbqyr2aFYCIG70Rq0NQ3bidCqYDHfDCgmkxrLaLGNt2Ophd7E7W7BsytmQzMrXBG+raqM+LIW7csNGybQsApn16ISwKFNCNC4v1PpnaG1bb0xAoZsN8uV5q2s7diACQEekRb8g4E9Y5iEhEjnAG3QGrA5kElnxYKKqSBEG8sGBaC6vtIqZGlyI9Xpu0NERcSTAj0xu9kZBCNkcAQIMedAcSItGCsfLB/EJYFF2bXcLTqX1htV3E1J9FgNHqCasDKVKucLclt/jaF7jeCyYgoCK1PbHFE669UcgEVAPMBnNFVZIoOTSVaTGstsswVpuwd3AT2AsAWxKbEiKhab2vZxEwJLUjtS1hU23jyz4Xzi+okkTRlVqL3AayjWG1PRM8YVNt4zJUm7yRYW8wWN8bZeZqBBRektwKgNpeO7LItIUZY9tCt3oSgJ0JbQur7VIQYKxqUW2hHuqwMTEy7A6GFFgdq82JUvhQbEtuBgCyWTvCxCFM+JNEBDYbTa4hCMAekraF1XYpCFhQC/NhwdICHxERUJMe8YaG3IFAh+u51i0CBhRsSWwaiNJ2rXQkM5fX1C8er530hEvr3oHDtB5W26Ugoq+Dw5XjAEBAlsrcmiIJW5ObBSKs41Ak40bYltgS11q09OCJay2O1yZddLq6Bec6nUvtD6vtUgQIX/uHK0fB3KIW7kpENJ1yrkjvzslcSKr5Y3QCxmlb07Xtyc29Ts58a+PBE3c7LoQLJ2oTrnC7Vm3X62O7I2C1XYpAUdO1Q+UjAGApAD7eKLsquzfnZBQp6Ma8pvNirq0AsT25FQAU2HrqxN2Op4KZ+bDQxVtkrLXtDKvtUhBQgTZhCQKEDRGMXbebExuG3SFTDGx9OhMCCoa8gUtT28Ca09ZgHm/HKqMSJBkXUXeyHmdRp8BquxTTjjAfFqb8aYHCkus2lpWrs5cLc/+vM4yB71Ow0Ru5NLkdAKzuFiKiInW0NuqgJKDuXnGvu8nUIbDangk5KPPh/Gh1Aqy5bmNnwvW5a3BdppMZAz/U4SZvZMgbNJ0srBr4vg6eL73kdLHTli3b9obVdikE4KAzG8wdr40BgKVcr0XbNrM3JzNdfP+fAw06KZNXZi4Hay5yaCibORXMjFXHnbWtkEDr0UHPGFhtl0GAqOrakcpxADB1DOypYa/Tc33umvWWUWYUJyTVI7Ov7b0erLnIARbX1QeKL9jLVbtACCCwmc9iMjiY9oQ/mzMg0//VO1I5Ph8uSOPms6QDRIh4c++Nprj1+rF6jBmrSQ97g3vSu+zFfkFDhYQDxefbYA1B9c4gVs7ERQcB2XPbnrDangECASWE90rl2KR/CqwtcmMVuDq7d8QbstoMrT1BgNf1vBps99mtu8hfKB1acxmiRbVtOggAnvDW1xzqKFhtl4GAXHRP+pNxwQQbVmesApsTG27qfY0plbJ+zFsAECjuGLgVbPbZNV4gRDxWGZsN82vesoEAfG3Fk2BENiES3R1u0dGw2i6DuUUlyIPlQwAgUYKFHmXm/ghJOejc0PMqB531000AAQMdXJ29Ymdye/QTy26E50svVlTF5DWs1UU2JWOs+m09dNfVBkBnwWq7DOYW9YR3oHiwrKKuOU2fxMZTKQAB4NW5a/dmLivrilgH3lsiEiAqunrXwD5XuFZ3ruIdzudKB4uqvNabSEgEgR3b1pAUCQTs8gnUsbDaLg8BecJ9sfzyXJiPfmLNmRDqcMQbui57tSYN3Z5URkQChU/+tuSW63JXm5/Ziv0iMvF8ZVV5pXwMLCdQXNApWfTbAgDkZJZ3ydoWVtvlMTpY1bUnCgfsjYKIiGgMrrcM3jnkDvjk2xuuHUBEAaKsym8eeMO25BZN2p4CIqIpmHuw9PJYbTwpEgR6rR9mFH/ENt51WqY84bLWtiestssTVbkG8fD8/vgnNgYysq5J78nsuj53jSaL5bTXnKjoF9W2JDa/sf9WqMd7WCr9E7sRXiy/fNI/5eLayxABBDoEm2EYOZll27Y9YbU9F4h4sHRoNsib5FpLFWqg7hR+z8jbXHShe+uBmTcb6OCm3ldfnrkspNBiUgMAADjoVHXt2dILpu1jO1xYs0tmKQwDAXNOth3eJnMmrLbnQoIsqfJjhScBQNsPGLg2d+Xt/a+vqIpAuxq0hoQUjnjDP7nhnQAgQFgs+oWogQBgrDrxdOFAWqTUmroRzAeKgCGFRCDs3HqIOOj2t0ESB7MMrLbnwvRW2V94CqIEd4vmrfEh/MSGd6Rl2qyvu0xw67XD/XcNv/WS1DZN2jxUbLpoAAAOll86FUw76Kzt9YwWMYghqYqu2GsItNEbISCOA2tDWG3PSt0YgVfKR+fDQlSpzw6mIBYRXZHZ/Z6RHzOZDt0kuCYUoab9KzN73r3hbVAPD7BaiUagCHTwr3OPpkRSr/3+GEDdtjVhhZam07bEZhNU1zWTp2tgtT0rZqMsKZJjtYnvF54GAHt3rNEdc/v9xMZ3XJu9sqTLlhabrcdIrSbtofsLW386I9PRZqA99avrzFht4omFZ11slyqLkdrqio2Dm/e4O72TgHDtkjiYs9El97MliEiizIeFxwtPQ71OlSVngpGkkFSf0/NLW3+m1+kJKewC8zY2YGtU++Dm997Yc72J+jLmvKVB40fXP8/c72u/bS4jCURfBwthEZodN4CI5vE17A2OeEPrttldO8Nqey4QUYPOyvTjhWeOVcYECqt7ZUTkoFSkrs9d/XObf8ok1LeNUqwQo6plVX5T/+3/duN74h/ae1PmiWgcFw/l9xsNagdDjwAQRE37+XC+/oPmHbzup+5xctdkr6hpv2vWRl0Dfx7nwVRfPFYdPVB6AeqBO/b2yow1rUm/c+StH9r8vrKqGDOwEwU33oWv6OqVmct/ZfvPIWIrNscQNWgA+Ne5R0/506Z8eJtcQAHok58PCwBATT0rcz0V6aRIXJ+9uqprojOnTRfDanseiEiDTojEfTMPVlXVaqJ9LEBmif2hLe9774a3F1VJAHZcTJhRPQGiqquXJrd/bOf/PeD2K1JWpTYe2nzxwNzDJVV20IH2sG0h6ujsz4cFAABqcns0xChn96rs3q3JTb4O1rouBHMa/GGcB2OOJUXiiYVnXyofbsFwkXVGGgB+dfvPf2Dje0qqEpuEtk+gKZi3IEGUVHl3etfvXfaRrcnNipREaVVqzcEVaInyscLTTy08Z7J12+e6CUBf+3PBPBhdbOqJmXI/mvQVmd2vzl1b1hXbySPMRcFqe34QwWzyfmXq6/Wf2F2jGbejGeKXtv3Mf9z2IUAIdNABgksAdUOyoIq397/+Dy/77W3JLUZqbQ9uPhcJAgDun/3OdDDjomups9wKICIA1EAzwSwACDsl6k1Ox12Dd/TIXEBBh7qhuhJW2wsBAUCifLzw9PHqWGx+2hqs7sCN04Xfv/FdH7v0vwx5AyVVjrfy2+0WMqdaz80NFamf2/Jv/9vO/zLkDcRWbQt8CCYx5PnSS9+ee6jHySloo44YJlLCRWcunK+oqkTZ9LAE87BRpF/fe8Od/bdUdQ0B2YHbJshLf/6KtT6HzkCgKKsyAby+9wYFdv2PplBLfHwNdGlq2619r5sOZo9WR0MKXXQFIjXEV60t5jQcdAIKAgq2J7f++o4Pv2P4LRJlLLVg2XlqhjCeyr+a+OJTCweSIqGpLZIaYhBAg06J1C19r805WROm1swzrPd3Q8RX91x7pHLs5cpRidLU34C2mTDrEmS1vSDM0l6RngvnX9f76gG3TxlHqs0UyVhwEYCAep2eNw7cNuD2j9UmTvqnNFBCeLDW90+ss5p0QS0MugPvGH7rRy79lT3pnZqIgCKpRev7VHFq7Ivll/949M9d0Z69MMz50K19rxv2BjXo5ra/jDP0NOmE8G7uvXFBlY5Ujy+ookDpCcdUrz/HpEXAJX8EIIJo/FYAChDRHxQShfGQAEv5uWC1vTDMHHLRnQpmep2e1/Rca+4TaMlmd+MQezO739B/c1qkC2phrDqOgK44LVGqBav1xuMbW3I+LGSdzJsH3/DL2372R4ffnBAJTYQA8QrAatp+tEzGqIzh7x/9k6PV47Z35FaMg868Ktza97rtya0aSDY7bCDOlNGkEzJxa99rd6cvRcB8OH/SPxXokEDHNnXsYSAgDZoANGgFSpEKSYUUhhQGFPo68Mn3ya+RX9W1qq5VdK2qqxVdKetqUZU1aE+4tp1sHQ46a30GHQMREVJCeN+Y+ZcfHrxje3KLIi0txzPFPlyo3xuK1JA78O+3vP/Hhn7o4fn9/zB138HyIRcdgVKCECjiNKrmnlh8tKiRIpAirUmHFPY4uQ9s+jd39N9yTfYKAAhJSRAirlHZklvPVHtxUN4/+9BjhafNwrkNb3sCEogVVTtePQEAwlqxiHijlYBu7r3x5t4bD5UPv1I5+lL5lWPVE6f86UK4UFQlV7gOSg3aRddcNBcdVzie8Bx0Eug56HjC9dCV6HjCddHx0HWE66KbEK6D0kE3K9NPLhy4f/Zhe204ugNW2wslWp1hYrQ6fu/UNz687UMt6yHWqLkm90GD3pAY/vGRH33TwBsOlQ//y9xD380/Nh8uVFSVgFzhuuhIYbylRPUM+ou4sQkIIydJtIREJCBj6ShSCeElROKS5JY39t9+e/9NmxMbAUCTJiCnJRtii2daXzg7KEth+QuTXw0oSIpku3lsDQioiTzhHq4cC3ToCsfGtWrcaAWKnn+70zt3p3feNXhnRVVr2jd2axyQK0xXDfMFoECx+DcIgaf98MwRkyLxwNwjVlvMdQGsthcBIipQWSdz79Q33jJ452XpS1u51RvfQgIFUhSQ2+vkbuh51Q09r5rfUngk/9j+wpPHq2OzQX46mK2oiitcBx0XHQelQAEIREtKT8VfY8P/0EisJlKkAgpDCnwKJYh+t3ezu3FjYuSazBW39d10WXpHfCBFynjxWrAh1kgUuQEAAF+Z+sfnigczMm1yydoTAvLQPVw5VlTFftFnb6B4lWOef4oUAEiUKZlMyeSqDl2/4Mb/4KAj0RGAiis9nhNW24vDiF1FVz47cc/v7PoNaHB+tUZf4lGidWJd7nudnrcOvfGtQ2+s6drzpZdeKh8erZ445c9MBdOn/Jl8mC+pigAUKI2dYrY74lwms+SMavgCadCKVEIkep2eEWdogzc84g1t8jbsTF9yZWbPBm+48YKYL1oT47UEMzoBSRTPF1/828m/TwjPvIs2NGwNZvFxuHJsQRX73T67G62AgIurosYJA6eXaVjZGRjLFwAyMi1QtEedtfaF1fbiMPaCh97D+f33z37njQO3N0Y4tfQ06lUIzO1aV0lKiMT1uWuuz10DAL72Z4L8bDC3oIpFVZoL5ueCfFGVfAqqulrVtbgNmiMcD11PeGmRTIlUWqaH3P4eJ5eVmV4nN+gO5JxsPLqxkhqLnqzJ9kgckmzq2H5q7LNzwXxWZhS1UYztmRCRRFlUpZfKh7cnt7bAGFzMCD/9sjRlYDMPMzItQLRJWcu2hdV2JZhs989O3HN97poBt78F22VnsqSoAhAgoIOCiDRoTYQInvA2JUY2JUYaf9G8QJHWDSmtpqaBQCHP0r1Gk1akEaPon0jucTGWqPVSG50YkAT865NferJ4oP2lFuqdgD3hfm/+iTcN3N7puV5mAkS2LXNO+AKtBAJKisSh8uG/nvgS1AuDre1tYxIizNcChCscCZKINGlFUUCPJm3OU6L0hJsUCePCS8lkUiQ84ToYNYwwvxWSUqQ0aVOR1kHpoIzjQ23HdV3IWw5JSRRPLzz3hZP3eui2SYOG80IAEuWTC89WdW2tz6U5ZGSKbdvzwmq7Eox5mJKpf5i+7+H8fpPm0CYWSiy75guBQoCQKCWIOOX33EDdH+egFFDfm2447Nq+QYirz5ByUE7Wpv7g2KfKutx6f85qQBD5sPB88SXzbQed+bJkZFogstieG1bblRC5C0HUdO2Pj396ojYZ5ZW15aqwUXwvCjjdZG4T4pAvidLX/h8c/9ThyrG2Dfk6GwIx0MEj89+HegemNpw5FwpRUiRFs8s+dB+stisEo0qMybHaxP84/r/r2TttKrhdQ+yxMXb6p8c/90j++20e8rUsCKhAG2eC8fms9RmtEKzHNqREstndf7oNVtuVYxazaZl6dP6xz4z/DbSHA7eLifchTb+if5z+1t+e/PuUTJrtvg4ybE0ASQK90er4I/nvA4LqEI/zmcQTPSvTa3kenQCr7WohIAfdz5388temvmniw1hwbRBfVUVKovjO3KP/7/H/bfoydJbUQt2346CcDwvfm38CbHZgahkZmengs28JrLarwtz/EgUBfXL00407Ziy4TSS+ntr0ZZh/6uNHPxlS2LalZ84LEWmglEg+U/zB0cqoRNnp3lu2bc8Lq+1qMQ5cF92Agt87+ifPLrzAgttclkjtgYXnP3bkjyq65qLbWTtjjZhlUEIkjlSOP5zfD/ViiWt9XisnIzPstz03rLZNwDhwXXTnw8JHD3/iqYUDphc6C+7qia4hgJHaF0qH7j7yR/NhwUO3/RMZzk09jjD5ten7ZoLZTs8OyLBtez46+wNuH4yF6wlvLsj/5su/++j84/J0C5c1dwUsWrWkJcqnFg78Py9//JQ/5Qmv06UW4jmD3tHq6L1T3wCI6vN26GzJyHTnnXRrYbVtGhgVzE8Udfnuw3/47ZmHTFKAqUXARu5FERe4MVdPovhOfv9vvvK7s8GcJ7zOdSAsARE16LRIfWHy3gPFFwRi/NY6brYYv203fCrWYLVtJsalkECvoqu/e/STfznxRQAQKOIQJRP6s9an2e5QvaaaImWeWP849a27D//3sqp0k9TGmJZ3fzL6mYqqCBSx2d5ZgsuehPPCnXKaDNYrW2vQjxeeGa2deFX2ynQ9/N5UpesysWgu5rGE9V4MoQ4/feJzf3riLxHAdD/ryqvnojtWmzhRm3hD/82mdaZx43bKm0XE8drkv8w95NTbTTJnwH3JLID1MoAOOs+XXnqs8PQlya1bkpuMEMf1tqFz7qVWErtcJIopf+YTR//nV6f+2ROu1SbHa4upppYQ3sHyy4WwcHPfjaar2OJUaai11p4g4qlg+pszDzjcfOussNraIXYaJEViMjj1cP6xGtWuyuyNOqMARb1nTi9ayECDG+GxwlMfO/yHTyw8m5UZUxK7K6UW4gcMgifc50ovTtambuq9wRHSlF7DerWXdn77iDgfLvzD9DddVtuz0uFBJ+2MWQ4rUmmRrurqZ8b/9pdf/MgThWcQo85OpiZ3p0dZ2sDIysP57z9XerHP6VGkulhqDfXHMyRF4mvT9/3XVz4x5c+cNk/afpc1I9PmqdDm57mGsG1rl7halYvOhH/q/tmHJv1T25Jb+txegULVnbmxQbfW59sWmGpqmxMbn1x4djbIu8KhddDMNbZwE8J7uXL04fn9GxMjl6S2CRQKFLTrPIlrxfna//Kpr5ldzbU+qfaEPQn2ie8iByUBPFd68dtz35kPCgNu35A3YLaDxBJnwjp2L9Trzuh+tw9RPDr/uINOd3sSYuKp4gp3Plx4cO67U/7MBm94yBs066TGWVF/cUsvyrIJOyZMuKwqX5u+rwvioK3BatsS4vmHiJ5wAx1+v/DUd+cfmwnmtiU39zq5uIwsnR6xuA4nbhSTAIiIl6d3PVc6eKwy6gp3nTx94tgvKaRAfHLhwPcKT8yHhU2JDb1OT8M8obh9ZCx/NmbLmfJqQhjjoeNTAoCvT3+7pCti/U3aC4PVtuWY6ZsWqZIuPb3wg+/OP3aocqTX6dngDccTV4FGgHgnbV1pbvyWFWmJcmti84P57wYUrsOLAIhpmSqGxaeKzz2S33+0Otbr9Ay5A3ErDZMcUY/gboLyNmpr1IMZSNeVfXHUBpElopIuH6uO7S88+fjCM77219UndTEg3vHEu9b6JNYjJkQMAGraB6CESFyVufwdw2+5Lnf1gNtnXhNGrW1xHQYwxIlkAsWfjn32rya+lJapbg22PQcN86SGgJ7wtiY27+u/+Yae6zYnNvQ5PRJl/GJFynT/RECoN68/94QxSh1tbkUDAgBIlGeaqIEOy7pcUdWCWhitnjhWPXG8Ona0MjoZTAU6bNzNW28f03khICDBartmxEtmgqjrok/B7tTOW/tfe3Vm7+7Uzg2JYfNKRcrcPEvunC6e2Y0hyYVw4Rdf/I2jldFENyaSnZcl80SDDnRIQLtSO67NXrEnvWtrcvNGb2TIHUjJ5LJHMNnPBERmwVRfNp173IWwOB8uzIeFglqYC+Yn/MkTtZPj1YkT/sQpfwYAJAisN2lGwEa3xnr7jM4Lq23bIUD4FBRVKS2Se9K7rsxc/pqea67NXDnoDTS+LF7oxfaLoQUTnYBMLly8XLU3Yvw2BYoH5777X1/5fU+46oTWYwAAEBNJREFUcaEfGyO2M43v2iimT0FV1wId9Lm9WxKbht3BQbd/ozcy4g32u32D7kCPzKVlKiPTCeEtOZomHVLo6yCgsKRK8+FCQS3MhwsL4cJ8uJAP5/NhYT4s5MOC+boYFgUKFx2n/qduC8OSTPT1+emcF1bb9sIImUAhUBDpiq76Ouh3ewec/o2Jkb3py67NXXlt9sqszJz5u4pUfXvt9PUjAhKuOHwqTmSKlpoQu/MAAARgFJNk078RtSBD+N0jf/zVqX/udXrCdebDPZPY2hWAJqbF10FIYUCBg05KJJMikRRJV7h1fZSIKEAIQAXa9L8gIEVagw4prGnfp8DXfkBBTfshhQKEg45EKVE6KCUKqjf4iaYBq+rFwGrbpph5bNy1AYUBhZq0KxwHnR6Zuzy9a0965+7MrkuSW3Mym5appEgsexAFmkjH+yWnBQ+dRRwp/qtBYAkoXjAueX2cXWrPvDWRTxLl0crofz5091Qw3dFFxJtLfOXNQj7yNoDWpDVpXd/mIqLYFIWGcIL4F0Wk3cKIMprGPQ3PV2B5XR2stm1N440EAASkiQi0sUcUqYTwtie2XpLautEb2ZQYGXIH+5yePqcnIzMZmU7LVNNPqaTKhXDBLDDnwvm96csuTW23Krix4yKk0EHnC5Nf/ZPRz5y5LmYMp3sb6n9dyC+eUZeOtbW5GLXlpOY2JZ7rsR0nEAGkRBlbMcdrY69UjoYUBhS66PS7fQNOX87JZGUmIzM5mcnIdMOfTEK4LnpJkfCEK0AAYEK4ApAAAgoV6YACs66sqEpFV8u6UlaVfFgohAtFVSqqUj6Ynwvn8+H8KX/67cN3/d5lHzWZx5YcuOZtEpHpAf6ekbc9nN//9MJznvBYDs6k8YI0LlNWeSimWbBt25EspgCYLWZEIggpDElpUIq0Jh2CMlUKXXRddFzhShQSpEQp0awWQaI0d5Vx55lFqCJtFNz87WtfEzkoBQoHpUTpoitQVHT1Izt+5a7BOxQpARbLAzaq+XPFg7/84keM0caCy3QKbNt2MI0JRQBAOqoJ66GL4Nb3yhZfo0n72q+HVcbhVY2+PIh+CxedgBKlg05GpOB0R54GDQRE9PmTX7khd+2QN2iqVdl7s1F8AtHV2b3v2fC2z07c0yNzIYSWRmQYG3AuWTewZAkZKyxhJMdGiwWiQCFRmL1ms93sRJvOkc0rzasa0jHrhzrNu6dJJ4Q7Vpvw0Lux97plz6S5bxAxCq7Ylbrk8cLTk8HU+gy/ZToWrrjYvZxNhmI5Xu7P8q6+Mw+FiAp01sn8/dQ/vVh6GeuFoOxV2zN+g5DCAbf/pza+20VHg7Y6IsM0F1ZbZoWYSNiyrvzZib+KfxL/3XwQkFCC1KR/aHDf7X2vr6jqheREMUybwGrLrBAjcwl0n1w48LWp+xBRgcVqeyY+IT7+z25+/7A3YEpJMExHwGrLrBxTMyWk8AuTfz/lzzjoKLK4usd6wzdN+pLU1p/c8C5f+9z8gukEEECz2jIrBxE1UFqkDlWOfHHyH6De+MdurQaK6rq+a+RHrstdXdHVxsaaDNNe1NPxkHfJmFVCRApUVmT+burrB4ovCIzyEeyZt0bKNemE8H528/uTIqltGtQMs3IIjAMMkFAQqy2zKuK8g4qu/p/xL4QUCvuPcJPZoUm/pufatw/9cFlXli3jwDBrSYPUAqHWrLbMqjFlv1Miub/wxNenvw31No62o8HM0d+38Z170rsqusoOXKaNaJBaIlNGjz0JTDMwqQcC5OdPfuWUP202smxvl0kUIalhb+gDG98tUXKmA9Mu1KXWlDsFoL5sdsemDay2TNPwhDtWHf/LiS+CSaBYrj9rszBHdlBq0m8e3HdL72t94vgEpg04XWoJqC+b3TwyuGPzRlZbpjkYmfOE9+3Zf32s8LREqUC3YFwTn/DzWz7Q6/SY9tosuMxaQY3bYoRIlM9O50dOjvT3AddJYJqFkTkXnYIqzgQzdwzc4gnPVL+1OqL5us/tRcBH5h9LioReaa8KhlkVBNiwLUZA+dz0ieHDzw88DQA7YAerLdM0zHZZUiQOV49vSmzYm9nd+E+WRoyr1VyW2nGg+MKx6lhKJNiHy7QYqktt9B9QXzYLI1UjtUfh6IP4IKst00yM9jkoD5YO7Ru4NedkwH6zSIEiJJUQ3oDb/935x0JSgju/Mq2kwao1UpvPTsNIdV//LQBwFI6acqSstkyTISKJcl4tVFT11r7XaSBRrxBmZTwEIBCAGvT25NbJ2qkDpYOucK2V22WY06AzHQjZ6RMjh5/vfxoA9sG+B/FB80pWW6bJRH19QBytju5J79qe3KJI2etddlpPQ8Q96V0Pz+8vqGILkiwYZomvFojyuekTI4en+k9A3YEQv5ZnJNN8iMhBp6TKf33ySzVdi4NhW1CtZtgb/OCmnwh1yNFgjG3o9GwxIOrNZfuGk0ZqAZb24WTblmk+xnubEN5o9USv03N1dq8GbbUWbeQaBkTEnalLXi4feblyNMHbZYw1jNRGWY11qd0yPHjVwB5o8NU2wrYtYwUiIiBHuPec+upo9YREafId7I0YV6uRKD+05X39bm9AIZcHY6xAgCai1jzlieZy0/nhk8MDfQCwD/Ytu23Ati1jhTj8diaY8ym4re91sY1p1cIFAA007A36FOyffzIhPN4uY5rMGSkMc6fH1d6Ndy/7e6y2jC1M+K0nvEOlw1dm9mxNbiIge9tlsNjznBBxT3rn0wvPnfBPeugSLfWgMczKWCauNpeF4dPias/2u+xJYCxSNzb1p8c/V9O1WGptb5eFpDIy/YFN70mKREiKpZZpDgTmaW7+A4pqIOwbuGUf7AM4z0Od1ZaxjivcF0qHvjD5VQBQYLeTWGO1mlv7XvfG/tu4GCPTFKIVEkU98mJframBcDZfbSPsSWDsUo/NotHaiRty1w15A/bCb8m0JEEkIg0kULym59rv5h+bC+clh98yqwMRtJm0RBoxn70gX20jPAUZu8TFE8aqE387+fcAIFE2V2oXG/NQ9C0AOCgB4KmF5xIiAUTsS2BWDkV/C0TjuO3PZnpHUlMDJwDgQXjwQqQWAByLp8gwAABgmp/nnOw3Zx54Q//rb+u7yRih0Iz4hNgRrEkDoMkSVqS+NfOdf56+/4XyoWJYSsqE5rIJzMpocCCYydabzWwZHryufxeC/yA8eOG7Aqy2TCuIe9t8ZvxvXpO7Ni3Tq3ekxgayIg1AEiUAFFXpO3OPfvnUPx6pHK/qWkJ4KZnkHAdmhTRILRAA4Fx2ioaL1/XvgtNrIFwIrLZMKzD+hITwXiofvmfy3n+3+SdXEw1mfsscUwMZp8FEbfK7+ce+MvX1Y9VRAcJBJyNTGoilllkhp0stAeazp04MH366/wSAvw/2XaADIQbveOJdds6UYZZBkcrKzJ/s+d2d6UtMrfELFFxjCzdGjxm9BoBj1bFvzTx4/9wjL5Vfycq0g07kp2iwfxnm4ohSGAAQgQABerKZ/Mjkg/33RS+4+GnFMQlMS5EoF8JSXhXuHLjVaOKFVL+NX2B+RaAwtu3zpZf+fPzzfzl+z7/kHy6rck5mY+ea+UWWWmYlxPas2RYD6s1mt4wMXtW/G85SA+FCYE8C0zqICBCSMvFQ/nvfnn3oTQO3haQckuf5lbojQoN20AGAkMIDxRfuOXnv08XnCqoo4P9v72564iqjOID/z3MHpszcYRhhWMCmRt1aExZduGlc+RFc+kn8AH4ANy5cuMCVYoza2giYtot2IfUlGo0pGwaBGeYOr2lh7j0unmcu00ppCsPcl/5/JISXWUBC/nk495zzSNUbjxB1tWtTeEi/D+XSSQFBbENh1S/P1Cfrvb7al6rV9mPa0vD0bib3nuiT+Y0v5ypv10aqZ9xdFvcbdDUsiGdgDsLDh3u/f9X87sHuSqTqiRkzVwCECFk0oAFQwPXVQlQAqfql2V7UAnjZWm0/pi0NlYiEGpbM2K/7f37d/P7DmQ/iQS9XK3h6tNdmcQHeQXj4Y/vOYvvO/d0VI1I0RfvfXHyVOqOWLsqdatXYZRtA1S/N1Kfqtar9/kWiFkxbGj4RCRH5XumLzYV3J66/VXq9P2HtB/ETMIHsdPe+ad1aat/76/Cfroa+V9anOw2YszQAJ5u9YC+8sbXaQUUtmLaUCDvOuxfuf7r++cdvfmT/xntFg64Hz0bt2uN/v92+fbv909ZR6zg6LnslQCJELBrQgCkgGimMvcEZCPwWpl1fLQYRtWDaUiLsvvtRGX2ws3Jze/H9yfe62hWIQOxzsD8O/r65vXhre2k/PPDEK0hh1BuJoKoRiwY0YK5W29vvBan6pWh6f7n2A3B8jr7a52HaUjJU1RNzGD2e31i4Pj5XG3H/r93f+XkxuLvYvrsb7pXMWNEU7ddD5ixdBrcW3K6bAUQn/PJMfeqd2hvA0TKWz92B8H/st6Vk2EHeoow2jjaKZnRu/NpScO+Ttc/mNxZW9n4bMSNXTDFunlWwdECXQgERtzhOBFXfn61P2iWKV3F1gFELzpJRgmySdjWcKIyPe5XNo6Y9zxakwI4uunzaW6AIu722VinP1qcG0ux1KlYSKDHx5u/d7l77uFMQr+L5HFKgIVC4ixjczTeALSBcXtSCaUvJiu+2GRUDgP0GNAQuYd3IOBRmYnAjDGfgNnFKi3htQtI/COWa2lsY4u1emHAjDJcbtWDaUuJOhhR4WSNdNrWDCzBuXy0C394tNrARhjOwkkBErwQFICoqkagoANO3r3aQfbXPw7QloleA6z8QFTUqCpnwS5gee1hzd4sNttnrVExbIso/7e1PhEqkqFVKM9MnIwzDKWKxbktEOed6D1RUFaKdSjOob9pa7Q3cGNrzAp5tiSjP4g1zIoIIgd9cn179pdaQc90tdhGcJSOinFJbp3VvIhr4rbWpR83XGu4Fw+2C4dmWiHLHLqMXuKCFwCAotxr1R81aMlELpi0R5VIcs6ISQXf8hKMWfEpGRHnTV0BQVVGkIWrBsy0R5YlCTwoIKgDaleZ6CqIWTFsiyg2NdyD0ojbwm43pVEQtmLZElA92s1ekYkQVgNHEH4s9g3VbIso8hdqeWiOqKohM2qIWPNsSUR6oRIDpDTEE/lZjKl1RC55tiSjD1F1zo719nYrI1WoTGmE4A8+2RJRVdq9XJGJUIVBgp2ILCOvuFamJWvBsS0QZpVB7r5iBzVrp+K1GfTWdUQuebYkoowQSKVzUQgJ/K22PxZ7BtCWi7LGPw4y4Gxk65WbKoxZMWyLKGlV1tzXbzzt+s1FfTXnUgnVbIsoWhYit14oI4lpt2qMWTFsiyhCFu4DBLlUMKikazH0hpi0RZYJdOAMVCFQMAj8Dtdp+TFsiSj+3RREqUIGmcTD3hZi2RJRqajtrxb1X1fQ3e52KaUtEqdbbC+7ucuxNi2UsasEOMCJKO1FRQFQhnUrGarX9eLYlolTTSNzTMdVOpZXRqAXwHyPPnEkObic1AAAAAElFTkSuQmCC"
+ 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,iVBORw0KGgoAAAANSUhEUgAAAc0AAAHNCAIAAADzJ7dKAAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nOy9W9Nl13UdNub3dTfQaBIEqJCynIoT56IokitluxzHFeeBceUh5aekyvwRec8P4L9JlV/ymKokDyo/JFUp2bFkUbZoXUnKAEgAJNA3oLu/s/Kw5hhzzLX2+bpJgSJAniUKfXqfvfaalzHHnGvuvU8Dl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl3EZl/FFH/HzFuDnNr41vgXgvXc/eu+9jxBj8HjozwPbjHaKjagPMdYvXz7rvCMO5gb/m0LH4VxOjFuufvuiOTkQA5tOx3MHZduNcH7u4KzgrAiM7QKmZvB/0waD15RlVrF4LPzYWS3Oi9rnLt9NkWNfyi8XK9CO5FjnBtqsgZCpb53lK6QRop8wlnObWGPk3yOirDzWU9eFTVbZ4gBCcTwl/2wLHU05nLVOWJBxNIumPAixW9c6EO0WMF2d/+oXdwx8Y3zj2/g2gMePnwJIJM0/wv7k2BxJZqi/JCXtJx3N0mkRndHPB09E/RcSlnHAo/30+g8iihdK1MMRTZd2Mj8ch3SfkgJtuWRVNtXoykQJ63of2FbGvwIGDv2WQXuGyw4/lKgHpm0K1pemgTllVcKN0Owj661wwTrL8IZzENrNvnjEzBqxz3I9yk+m5jkonMHM9tdlStPUZduj7NwslPWiienAd7Er1uEm2ky3rKUr9cssGDlS8JdrfGN847fx29/Ct/7i+x/86MOPT7ga6ZCBMWN1VgxlchUdrIyGuxbAyPpiRjT/uHXWAFinRFTRgWU6bO4q1EBEYIx2FZ2OAMYsDStW+B1rrzEOMDBUgMSmJoVfiSvyWy0RFCTsWykXNUvymaADGQBjuKQVorxErWgL1TW03OKRqWNtCbIA94ngCSvxjbqgGyEwslwdY5bmFcGmxDD3ulMahGjtZlifNc/cIBRH+BluBHQI8TqriXg49xhm+hkcYyQWD5Bg8o+eABqolnLVjLAAvha2ktrwYyevswZiblUHA47LG1x2COnUMucw+zSXm1Kj4qVH/5kt5y/y+Nb41rfx7d/Cb/3+e/8W771+g1Mw0Itt0+RBqAFlYgVeHuiBKhgtwB2dWIX1dtCJz9AkVM0Y1c5T3EQEj2hrTxDk5cYYCvuV+KKzCQzuO9tqA7hUxJLWds8e21qoZKxZk00j1L8JKjAnUamA6WG2hbKMs213U8W8XOkcJ5MOO+g0BPEiaHeurgCjcMoOJbiZRjoUhAQGh1DnowahJalEc8pZCG186qm5qZmcPeGTfQp+GzN9T3Xl1hU/OEKLg0onnEkqnkKEn5aNzHRg9RDRLp7oiBnkvAbjXddV7IjKXw4hy1XNcca2NfeXi2dnTxbA97//4Y8/fHyDk2w+imWDTk60xMa2t/AmCmQgjgUjz6piHFj3sGLMW4pcSDUC7Jopl6JA5WGhdZCjOl+I+Fp00VZLMeJ/3WvbDX+KgQ56SUT7tGgZWRDmZ7Eta6lhcV1Zo9vHOruhdT2TeWB7qLhG/HYx+F7bDpIjnGskXO00rLylfGOmFXZsw22i5I01PSwQapuGnnJaJ7hroYUq/6GtHmgK+58ovqryPeWKRnzowCjb7gcPneIpxPLQrRAy4eGRohJkMHcGDyn/YdBRtyRsUXltHSikIOR9qswR1/ilGd/8p98E8ODrD77//Q/f//DxGKeIEayREGFJL8MseFAGj2wBhoE+ovNpIOZxT9I8OP8+2ElMBAcXkLTzmjYl+UJtoJHXzFCRCE2PrNkiayhExIjBHI/537lQhRxFqmCg8BUqKDVbqCjsg2qCmqKpGZxSYk52msEwhdadGM6nJmi1rYKQXpBHaP2UIVh+RrTAptSrRpAdLKg8rxQRMLomkgBWTSkKOwmyeAoTAcT81rkvun0om68Yqt0MQg110RFiPqKZc6H0SJlZ+6qg9bjgGBGzGSXjRoQOMqHfDqEO8hVCnNIgZEF0K4TqhGEahYINE1YZVwzAjAEz55hTWjOKSaIwIFubj1S7FITou1+CMUkWwL3feOvTcboZJ7qS+YcYSXfQ48xxKrDa9hzAUmJYqACNmxQqS2HieTI/WCred1WVPBUqPCGA3Op58ibbYgJ+6LyqsQSgrRvKsXQSqBT2g3tt0vu2TWByUylnunFr4bVtTjLxt06CHCG6M9MVDcmSVvct4nltQvOVW2U09IV6wWgtgnWnod3EK3cSYLG9tbAEoZ+mGeUe0YqHnQRCDFUmkvwDGGz2/vybUessUzOr7/JI7WLpgdKKBVCUheWmpbeDc82oXwqeFcne/Opr4627yTYkOpkguC/CTGXiq2RbwPqIMAqruR3fXit5kEfF9sLRLVTItvBQ0djYFgQZoaDbFIZqajvL26IrwL+vGw4/xU7QKOmAbWWinh68y9nYtiRFkRaQ5RO551zf1kMFRhnlt60Pk75wx51jWydxTfQuUE35aToJBQazNgi6YwiZkCUGOOsnaUY58XWazpkj8o9KG0yDQ39WGd/hYRqFLVQHD5tRezPa3Hq2k9A/l0eoG3UPu9M6aJ+wm2ly8kF6WygeC4R+8fsGsyf75IdPbn713njrHhiZtX0ChN3A3B7MhuzcYyMszLidDcQI8kPM/VRtNHxHw4l1V7fYVtS2fTX/F7zaEBkF94NWPaUqI0+gRiwWI5f3Umj+3+CXUqNChuLNEbZQBcMSD9giJBpZl+SLERgeYVdAEhm31sM6CSQobvlIte4MBuFUqdS0UFEiDDGUbVSJFFq+6yiDVMtFpVaQwqRLldbZSYiheVRCJMu+SChWDULN1GEk6xAaBSHVYkETV6XpTTLPjhYUoPWq38IEHSDqs5sgx0T6I01n/QReUwsdN6MEAzSB57WPm1Eo+wyHEE23hph4Pdse8x4MsgE9O4qpqXyY0HLSCCuMvG8mjQax9ws9dOPr3/6r7z8ZN8Cp7632LYZqrpmqk3SBicqQG+aXmOkcKnE9V5PnarnYcnKYDGvFt3USClietEtaCxV4/hiCC0ReyOUt21uxThtUctbVRg8Vij3FiOXD0k/wMBP5yA5IQ5URRifupZMgtkV2pPMrLlnFIRdqlrdS2qlqcRNgYoN+gQnGwtDdBJ9LukctxJxGk1OSFBnWFCkNVK/R6a1QjY4fauQQkkj6qtV62gmJJtxE7pGyDy+gvxdBSytrMiy3y25pRp35qsHPIWRFvSCk3HA2xMpEI+tZZK+tl7LE3/wUpr3QO47sQ5srjn7xxsA38I2v4Wu/hd/63vff/+DDh7PzPWicGPPGixjNQ6huT9n+CMDI20hZMw2g2DbTYJIzuXllW6FH6W4m5AVYNcvjAeW8/SsYZXioKI5UcfMmQDQ2aY8kMeOI/jwbLdx0yKrLh4XCDkFvU1pCWijDex41KwvW1g4hES97+TyodKVNA6tU9K+kJkza2p14wO/2wWafnJLJj/HLRkjvJ9A+zCPeptjbwdr3LGKbweGkIAgd2keUgfK1KsrGaMQurZ99g/n/eYtPm+/adGwJe4HQzrY9tzUIgbu9JcR6H8/38h5K0iAUqPMC6RGyLarLNmhWN7hH3wqhX8yhlxEmybIsWPpuhR73yl67wWvb0f09re5sa//Z+QJwBnO2gkL0KFTkOQzzKCiq2HYLFfSFqjzKxAOWTiCuaB5mfKsbm+lMrvO1iT4vO0STrYEevOwRmxhND6vKxZBq0RoRe1B7aYn2eQkVWS9cPCPNagppluwjCLkiWCkDFK6U0PX6aw7L82wtA3bZ6LBaSHVuww/42XrlL4GQLdSqyDKd2BZ+57hCLLE0+QtUqCXdhpOtAXWObT0TVIens20LMdPOYTDdECXezIfeZ1aY2MOGti+LUrasFzCpfqGGXkb4vXe/c/rB3VH+a50BMPDMOq1lLhri+cPckMEP9hPkWTs4ULwlfy9hDC4Ex+5SjYaJ6qQJy9hLX8KrGKGK1wHbseAFE9WJSGKHkerPq7barWcjMACGAkZ22Vn4MFpQbgJK4LYtcLatoI72msOgpKF3sBrhNhiUN43fF7bdM4r7hRohzkBoY1v9FcoUQqX1RYpwezOhHCoNfNOAxl/FNfI4dXEWuCVhi0wk/ErTS1GMjrZBCMz4CR08X9tSeHCJYwihz6VhXbYDCHlt6+mnZnHLkRqZRwbrEjWeYR7h6hgFY1PpF2aoJ/vd773//ocfX0cM45CljDdgeaiApt9zIL8jmKAdUyIxmmcQr/Cagy/aqkWv/tBZaWm9KWItf/CKTQvXDhlaTWixba8bfwZPJtDgfrcnv/QUotRSoG/m2voJUFwHAKs82Kj25xYMBrq4EVPz21iZqLxJjbQrRye+5jKp1qst6bE93ILUhnlkfTKBENJCZR8jmiWrtdpCIi1su4m3QMhr2/JI900lw+TYIIQGXdX7trT2ZwghTw/aIDqhW1Dzs3uEYQ5miiE11A7JTE8eoOkiMH7RnjfQywjf+977H37wKK7AG9VimYKR4BJpU/kg40EHVdRYqERkVKnK4A1H0m/Upqn+Ey0Ph3pe4r6ozhTgjFd8GkuhwWsGLFSiFYOJxUWjKR5FmB/9dQ3kVvzgNQcZIdjpA6lgXq6CQRq5p/zgskkcLlD5JTVlOzUFqT0v73VnL5O0xFmo+pCS1pSKyWjmqFBR+MmS4mj5qJhQlGHAc7+nXK6meiM0YgSdsbBthHdE9GQCOn50UNZbClXWZDQRElcNQmjqpJqWQuQvM7MMokAYee18zcHKEeR9/WFoU847gJCTo4vHDzAIKVIqcDqEfF8fC/C82g27QLZqmRSGPFKxnj40XPm244s/9Jzs3d/4ypPx3JPgqD8rCffa1jrgZWvk3/beP+q7LJVmxoPuMhE2ucMoti1R2kJV24LIXoF7dlarTaqxYTsp87SyfvUuyJJplWAnoQw0z7r1NQcyaXTrAVabLF3ahX+PahPfzpfljdbNw/VHstOUFDBPRCwb1jIHbUuNlpJzcdPSARANAc0UlbZ90yqjodQMehay6s/uBxMWCBkSSnds9bucUoBoRoi+BSk1yUlWhbfnVamQOwY1bun+O4Ri84ts675jHM0PraBZZpkpGJKttgVLrdUjMEJA1+WLPexlhHvjrXuncUIMYx2PFrFtBRIK9DK3ZyQYsHBbqCRg9x9M0H2Og05CbE4Vb6JxU0sGolG52ENFNY6IT2qqNjGNdFnKNVJQ69vadyNbVU7FIj6neCFsb70t9ciZ2vZW0B9wEyM6J9lnsS0dQhd64+eAbUUiErWzrdwk9ZZdtrRuEFoyvatpSjnbwp9AWNi2Jw442+qUnW03CMkIQYLGwra08rlOgs4XaixXbZ2E6oFubPvZdhIsYD0TyK1nmlFrJ4FqViOSIbn/YALREfGL0jdYXkY44ZRNxwjY3laQlntY6COKOtPu+hacGOlR7RxrvywWikmt7TUHkG2De7zaMXM7tGwhWzxwlxqCHFfXDbGhWdKBm8dQGHOrqKth2QnadpiCUg+gmk+5cx18ctvSh3hLWcECz8s6M0FTSn4ZUrMc2e1DpdKh3CkX903gz2BI25OTppjcs476iltx8lSa0yAkjZZgLppuW07KYwTq4T01CVsIhlXCgK6lyEspOJ9qC+gi/D0LNPHUwy3bLqKqtugQ4kIGIeOsxI+SSsdqNNrVPnvWtnSAwizFz7jIWFFnzvnUIaRxCCF30NaMchdET3tFuAoxRnoFWz62FkEHZzTnringyP9iD934+s6/+v7TcTNJViWSbyr9vpNALKoqM1VI1I5DFYGBtcrl3oLgBfkuAwB7rjb4msOgKGFbP3T2UdVZjndFJGHfqLZCwBMyZVv2g01Nq3fCOv6s0GERrBYVcHTbxqvRJq25RpLDI+ToqzaX2FX9UihXCI0mA/u2qE5CFYfzK/7LDmtlaI7wTnqH0Fh85CcTGG7zZYtKa29z+6Y4AQRqFDpdWySWvSzT6SeuNkqjtqhXfGO1qttBl/IW9kEJr8xnGrmPkHGA7TUH2pVfsQs0mo1ub0Y5C9uRxeBQhUQe8NhfgKe9GpQ5aDs9eDu2MJfpvrhjexlhLG3FhsSyVweKttUqWKJbv9ViFl2aSCh07s4LJlrmdZNvC4vppXKMsW0DPZwy2lewaFnbfMZNcI3Eth1Yh2xLcg1eNhPErK+yXdJvkmO5G9AzwQHbok6ASpUlirb8UR+jEXTlDxrN0qc9TR+wFOesareZdBwFg0OucbZtX1GSElVcI2/2MPYGy8FOedQcPclWT1WAPHz0mgO0d3G+kF92CEnT80FxAKGtNyKnH5kuz87AHfQYtxYDsMcVej/hsJOgg+e+MrZtweI12R5iXrTZ6rzsmLVrkD76iyf4Ig+9jPDd7//www8fDcDuCBSV0HBQ+YP2uYUKKj7L6OjA4tWKyMb6VYEyPyQ2h65b8YDGJ0HKZcQvvOno8WiEhWgrNFDIlthViTt0uJCHSi2UahbR2gXTysQVhlk/QaYdKxl/qU/LCo0W0a2zhcoC+j6ljOCx7be/2F8rfwx+GttdmWH2Mbb1HKaIOihvjTTVUYFRxgGEFsId5WsAfrdI7xtLiVb10uIj1hfEG/s7aDuEljhyjl6+aibajFD2Qf9qclWn1Aq+4IJRX71keyQYGB4KQmieWuKo5Nwh1BdyJoGFOZQzomn9BRx6GeF33/3D8YN7J5ySwshUOLIOAMfQHNWcm193GHkwi3ktwKpk66fluu7Ro9ccFA/pvto7DW0RHfTQEXPe3uucQpS0C+FSTQfWAdui0cpBmIWTVSTVQhcCGaA/mYBbOwkUb7hd9k5CLwlFQ+iyOQluoaK8QEkpYrZzSnwKm/f/OgyOfGQAMb8RMCuEKGFLgcJP+aypOWqKtWvps1p0Ck5MUYOWFaJXIZJHq7Ox0iDkopY3XU7paNFUHtGK3knozajUNDNFsS0PvsJrDods6+sa9a+dIvOR1BexmHJNR/hLZWAX+As51JP98+/+8IcfPIqrE1D4mcQH7dINCj2ZA2kdgQlGTF5fLDTEy50B1ryAgbLRYiI4+57QpiMXKrat4iMEueZgKVWB7Ysa0bQ0g9KulfAL20rUo4ubfRTk/prDskv/eb7m4OlB3LT55ZYfYOzJYnvNYRxpJAgdYM+D2W3rbEsjlJycUizgCTu64J/hDzCamgf9zd4bQWdbZRhdp/K6rVsrivicaykpdyG8tv0E/22Pgi2fD7dH8qbbtniz7ujA09tGsq3M8k3VF/J5A72MkCQbpyCgpsmhzmCaYvb78qAHmIDCtsA86LWJTkPkFZxt85rMjU7QsPiPWEOF7c7Zx8x3AyrM5p1lklj9xzaPkQeqrTyvEAxpiMKixeRUc3CKIB4eKo7LYfaBaYpMDGUz3rh3RSZLTa/wZ3jSkyUJzSW/tAhZ4gF2wlZfYJSbwvbp7m4TT6HSJQVg+4kU1n9cnHvEaR+FXBAkwtXipqBG8NDVREGLkRxKb173icqJK7M7BQ/iSteba8T2moNcIAhVc+tWCAk/ZtikmB4pCSFqtBrBvVkLs6Gc98KC7znkl9NAUav27ZEDw8LTF4qFbQvSxZuhIkeRggJk2UdEQQy3WZ4AvhhDz8le//qXH50+vYrr3GgUX2YpiHkUk8/SK24dyz8HtS0qVF6ltl2Kx1YjeCXYtyp0TBatdZcJ1vzIoDC2dYGXA7YQLK8uldToGgmUpTs2NT3bw6otFmwRVtvaP0omI/rutv1gAkXCEipp2a311nOAFx0HBeNiH4tt7GDIWdtPgsXeSehsi80+ezOqu+lAVBNP8b+kHBxC6PCuKeD98tRChGsH/TUH+6NsG3Zz4hyESk2UVZfgqrpv86zOL8S2olh3BrxpkP5gJ2FxDGqcg9B+cN8embWHTcE5CPks0+gLNUSyL75298Wb17hiJUh86vGCUdsl3npSfiy2RTlxzspDa6jwVGtzV0lYaNDcM2y7horNQgJLeYE78EZcIHcdveZwyLZo0d5im3l44SOolqFsPgUdW8tngNVHkFmhv6QQP4dOwhHoayfY247nOwmUcX/NYXkfSzDQxUEFDxO2+bH8IrGjFFmKsqNmFEHVzPXT/2CCbFKfozLrckPykG21TlFNF+9MM4ps2y47CCH01xzSXoQQxfxZQqgAz0h3LcqVX7y+gV5GeP61u3jrHgJ8EIpcO/WLxJL2WcFdTtD7+X1VT1VMcWusUAl2BjS0DbQFGy7b3J7Myw2RB8NOnhuSaiGE4iE3fMGf20/nsmIUlJcdTS6qb4Vg29YN0wja/nDzmDCL9TqqccJCsQyMTAbsFUAdNNufh7/moEpLsvGr8ssUt+0Eyyulu/ORNrlw4amRXBBODTkxGyIsxOlMzp+6Bfyp29oOFwyiJrdq2iR024pfakldsCsFt09BiCqXEVLJMADVc2DzKJgvZrz0B2/dPg4hMA0cQmjGkWQrCNGEJaqlkOnikBFa7AQtMMCHviJEcx77AX9NyBZaIaSDtC36XxXmgqUHhbygoGgVrkXTF2Toxte/+d3vPb55hqtAzAcMyt2+e2AtqxwtShoZQ5h+Vt4b5mPVpGLM9nmpuRif+4auykzbaDS2ta/6QmPCibJXeaBKdlCUsIrKi6C2r18WRV9033haJk+siw+FIYhQea5px7BkhT5nV2choNv9Xpvo+to9dNPlWHaCUaZrVNuPLAYHylYLl0mRKqEGJ4VtoMRYAl5sxWFstl0g1E3n+2UXLy92VDetEIrNPgUAmXzAZbf+B255zaFvouvDAiGQbRsSCkLiO1rBpDXQtokL8FKauW3NKKFInMfC+yf4pxy6eA1Csi0srlFYkrIrhPyEz/GwlxH+/Lvv//CDhxFjxEkeCYsluG1Df9o+I5pnSL2iA7CMamxr+DjkGofIDix3DzqJYCFimwjjqZHIhX6bHohqPlM67yfsvCn7tHgAYCFaXW7FgBmhxfxOCmPldxVZ9QBVpFpsSVdPujxEN6lkPme6g22gDp77yrjJ7VMhQQ/WV9BlrU1I3SqZVom4/U6N22dj2xUGji4ZXFmHs1p6WEyEqrP22wYIxMK26dz2Ri+21xx2CKVDe2FYhkWLozLv4Q0AVNwVhAxgxWvtK9VWhZ+iVGEzGD+v8poDg+IYQiLNLcSWKQu6PvdDLyPw6YIx4uSvuZFwclg9lRkvxLZWT0Fsm64Whe1N2EKq+xvCGreKTkMdWOtcBtjKtvxqZWrW27UTspRa1Vt0tt3YJDqw8voCrpEaKSMPuhHarK3DuLKthwr1nFoYrc9c0W77lfG4ULOP3+vYaxPBwPBwECqeJ6iR1oIbYWHbYRcQmOStrHa1rTpiW6MMX8jZVmK7hE5hoEaayxqj24dTtPdiyuHWAkidxL+0wvpPOYBMjTRIsw8lXPY60qFB6JBtbVc3AP+Ls62sR28Sg2Jbs69UDDHtnHQ7hBbC7cfdtuv+w+Ko2PbzzrN6GeFfvvOHL969F3EaUf9XxrXSQD6AYlJsK6eqLhERsqWeSdLYVrYTqow9sRGToH8wt/tgfu0+axOXhQD9YALLwSInyAa8C5XIMa5EFUAV0lD40WiD1/J0zbpTGjdRIeJLOVvbwU0x166bRqkE41Q7j6gL6z4nzBq1U95DBfyrYGB4qGhZCLetubpJ6kdbaL1zJI5NtlVQwwvFl0NoYduiWgO5zCu2Kr7Wictu14to5TK6I4OCli02AryTQP61EIsNQkuSoA6eBrBAqBN0SxKQrUv4oEZdzYx0Ee88yTMH2Tad0vePW3lLwfLDLc0oi6OI5hRJ+3kd6sn+2Xd/8P4HH0VcMReJYMqeBrvKllsvrCoo/uCD2pxBqA4c1bYAsNaD4ELLxk3RIkZbwrgmGuiX1ttaD64xmUjfn0zAIMn0H0xYFlpBT+ulDEsh33fc8MBGXc3Z1qPLNdJa1eFgnJtTaWN7OME2giQ+X9ShvATMLbWte9MDxuNfC4mbRH/UjemB5nG2nQdFVPZAW7OP9wS07iH2ind7e1eB3RtZxxAS9loK+Wlec1hxyyVuh1Cr+KT+1ow6hFAFddhyPVeBfRF6Qk9+ZvxPdbH0bXfMeMK+pU/lTvHOyZTt8/u8gV5GmCSLCLGXjCAsemoNNnrEvQG1qwKhtFx9qkBo6zoXCjZyyMDphiXAuFD+ra8+xRPbSjaP2xReqbKuxctrou1wIxfD8poDaiEeFOdPUVR6UDbfbIKShFVOEm/+fWiWLCBrK1Rcze6jEF+EQoUihLbblULVFEp3cRdrdrCQU/R64Wm2Lbb1g5IHxJdainQ3eEIaXgHPrJySgI9RiPc43x4VsU34vIhRSfMI8R5G8YX+URoNNFEPIdRIgdiDQbe2DfNTuZmXzOBYX3NwHpRtTYM0qYBXKZbWFoTkVkeI+2gJCoW5u8mbUdwc8RWHZlw9rpBoLggtSdor2VsgxCkJIZct8Lkc9jLClx6dno0I8Ee7rUALc1ulEzGEpU1VW4pJ5kZmMstBKpzylwthGPQaQWyLXg0hrQwygm8uSlqTEx48HYt5eZUMfbdLNVPkeUspuJiVUirNTWDKGS55X0gq3DJLopZHjhZqhQktKZUB2IO3w0MFMjwVeNUfTNgWUoiF/rvvBM0I6C0XmMAGoR0ManySpXDmNXJn0fAAACAASURBVAfVtg5arWgLQTRKgxeENNEh1CeWqFszCkVMa2tI7Vrhn3ML3+s/5YC+KEpy502PG2kEVMoB6anp2CHUeheLm1Y16R+WI0c/mPDKrzl4wtZBrXseQp+zIZJ99rU7pzfvnK5G77B6/HuShAITm54o/ym1GrZ0V6CAoO4mE3pU39YSVGx8UVAQGvMKKzftbLuAXkDZuWll29FErj12LrR0pGgpSWv4hlFGGJqFYMpSApxj2/JIj5a225WCQjtKj7kmY25O+fm/5lCxLewtG50mKQDrFuiRW5HWBqFxpJEgNOijZRPd2Haj6WXKmWZU/vXlnQQY22LtJLQqwTsJnTqPm1Ee1LniT9GMoke2TkJqWn0DKNepfM9K+LNrRn3+3lPQywjPvnbn2Zt3YCQbVJ52AzD/4ls8BbnyUivjGbO6CkvlQT6aT5vXT3TP7WztL2JibW7YiaF9B8RSLNRJsGRQMUP5RVsKXRdbutUm1642tc4d3Ny48hntvGRAnYRA6HHctvWTfaz2ge2PfGdaeyv/ysQOVM9EBi9RQdV45oCsF1xocKOqOCXpcoPB1xwqXuUFr8e1EMAIOdwJbn/VhcuJ4l7zQnChTmQTN+d+MCF1y1rQnRHVuonzEFIfZukspXiaOBomNUXXLHDRdGku9vhLcGt+ZAaZj4KJZPWaA/rDCdKItB70UXp6kVZBTXjXrK6OsLc1oyAr15aXaY9xEHqSDcm2FttDiaQq3Njx47BReHohz3T+eRr2MsKfP755Ma5O8ukwHlVy8szfa4pBuFU9RcBA4FkmsmU+oHw2Y3ouxD1GK3tVQh6taMUFWo3QZIbxWhWJy96qT8mLdI1Uc4F5KXMsgwKD9Sw7Jkmbftt1lFka2/YKqGAEY1uKvde2pQhpqEowL9K1Ymk0gJK3HqiKKFExb/z11giRfdBPONdJ8A/LZtCuedCMQol9xqHLDyb4rTBp9MqvOfQKt2Bw5CZhxuti0UFp1BeCTpCvU7Z68FYs7CLPy5GcGoTcREsKlMHLsB1CjrolxGAXWUPMaG61D9S7rW2UKURcJYTySmW025tRO4Q+NzxrLyP82fd+8P77H2VqHDivJ5xtmaKjh7Fvew+ANcoK8lyaPZm9XnMwArKvBvOWEcNZKPRQycWGLpuWoLZAoKk8Z7jPHGGKu3AoDLaZOVsvAWTHJCmqbXicNynwsNozBPplnkWsG6EEM3oq+5gHV5IC6kY+tQi5J3XvjWjfpGOzzx4q1LcFyf6VZ8HdPqjAQ/+q7LD2PFI+LiTSYotH5zuEVFvQ2mIrb8Is2yA3fu1OjG3HBrxiaio1ako1E1JwvgMbFIX2CWtWl4mafQxCa6e4x1GZQl/1XsfKtkIbWvQVurhwPRw8whYKymAs1F6c2yCE5JNYiPjzwrN6GeHPvvfe+x88HBjcywuJAwRxtHheYjXt6MkQ3THUeW//u3sEDdVRxKjuCBR/hQVcA+65xCu7WzxU6cHjrejolFFTbKH67Gq2cnDqVNUHvxy8CP8jblq4jyZaEx7WUMmvrHvQOAh0pduHfiiPmBONcIcRHz0mtjUo+P7xAEIizXPlrT77TnCHkDt0hVCvpDIfWA0rASkMUI+KlJ8EctdlM/hCNEVDKMeNWig57sA+tlDNFWUkuzYl2msO5ZTsgKbS48A+rwIhkWPJHGaBwxBTmBhWXSMcsC0pVTozSlK/nNnK96mL78lai/Zz1DeolxHe/TfP37tCvYYwzKMSt+0EddCSDGRHhZkOrqBvFLAwGmNS/1wAeS+7UZmxwcgHi0Sl6HmRYpNIsFq5lRpVqMBoyLZvh7JVGQhj5IGiIU20TgJrHyUNBHE2JRAbL7K169N2bXfZYzK2WRTHQkUTjZgcweg0LTxYqHj3Ro6h5626LeKz/CHYHNcm+rB0EpYU2K9QuuOI+1y77H2ScGN/MmGN670zoMR8zLZmPY9/1zQMe7J0dKx6wV75YxQVAXj11xx8Wxbd4A1CVMo9rkhRevOgQE+iFWK8DmS0JRtFbv7Clq8Kd+5Y82q7VzaqNY0+BzxrLyO89/4HH48QzR6EOgBFCD8fh+USA/KQcVOj5oXBc6UCVjp1sJw9+gHG6fwxaQvqhlJsdPfDGIShAv71bFEsO/QusOdqObsWtVm0Z0bhX/I1h2q9gU6JsmFss9CNoJg/Av1KssMW4hJWb1ivvNeNqWSYbOXrLhu4UCPcpfXmnYROPU4NTspy67q15xXbkwkgnpYfTNAmfEe7Lg4qaGVEmtrT1Uad0qh580DUVc1urqWD01lwEON5N63IzW1Sn7vBl5x9sGHdULeIN7p25aY9Ulo+YBZjoExPQGzr/UwJvKHl5zq++U+/+bXf/NrXf+vrO8mqnnUzAe47pfGmp1OYp0FUGsTOtgoVrDQttjVg0e90Q9JTPSGSW1ssfdsdtT1UmpoeKl6buEddTSkofYmtg1DJb5ObjJLm+UGy7WxLQx1Wc1iCtoeK2xybEWIJFfeIo9Y0EttmgPSssbPtIHOEs+0hhCjVSkO03sJNxbZlWHPoFtuNwtyhRaPOtvy0bMJ3tO+r+04ZBnhDO25l262hSeNEW6i3RO2J2u0HE9jXWTsi3r5Y7ROmZg+KtmE904yS+ocQavaJTU35Z5BpGSAQ21L/teajIkLCz2noOdmrX3/w+PR8BFBPjfTXwfumGEYlXgke7hc62woNL61tYRZ3tgUdz65n/VhCcdCEaPPF9oMJW20L2Iob2/rBW9gW3dnBWdi4gCcPhjHqvQwTmb3pEMRabC8aONueC5UeFZUYelKshkldxVa8hW3tJkyxLW57zeEYQhTvuHt7jm3dyB1C7u7o3HTAtlNSdLatDStwjm2xkuDqt6UM10STGQv2lpuTt7ItkdBq272TMA+urzkYrVNpgsHVPCpBNL1CzHtuTghdI0jfnW11tjEterMk6VeO6WWBG+rnMUSyn3zt6sWbV7i6mnoSYImwjvqlyV1w79x0tpMAc8MS24bFxkfLTvDVOgk4YFuire8jbgf9somuEn5pyflEzx/8dgGWR6OFSprg6J9yAAOd8jpv9p7yypsow8Koc+kkHHiEbmp8ITVNIynY2Zbfh7NIkdPBS2XnmlFcK/bPh31bnrbSkJ1WXnXPFtFU7obXtgBrEJHWxrZipVuaUQSeTMdPfZdtXPNqEKKDasor/GCCfmvkL9eMkpAWhcTeT9aMMn0NG3ZrBj1xZ7Ax2o86CT+f9xT0MsInX58kG9QyEnxq3limsDvKEYgoftS5wcKhlX7SmUFb8yLxFwoYw/2cFX0ipiF5FTZs+EMJQ885K/azHLRbNFN2asvz8rKjxEsdKZJDIUZZoM4HEIm/Cl0UTJMIZDqUxab5ltccUDroGfXIsjf07ojZh9WHBJJhQ7inzUVtaSPpMC8rTT2iqC/kWZRSzAWorDDxU4ZH8LcgtGiUNOVW0bo4V2HpUCm2VZHrbRM6EeYyikk7mAuK+ybtZDqIfPJfEZJHqNsSIcanIdtSnQYDpH8RXU2UbZX9z0FI2SjouwqxkCEGTGRdT5ploQIEb3l7uRPEgyQJghxmTK7TIaTFTEeoUyT7K9J7ULias47iQ7cEF8NsXimjvF58YjIs6f/Khm58/cHv/dlDfIoTf+sBYL6gntY4PH/LUiXeHF6MrBXuWF3Y81WltbXC9dpEi8IWFaUNbbOZYkf1aOmzWmPp3jaKt+ICqhF6leFzFzpbjCBS2DWCMVpyn70OB/0C5WA9aw/khm39pvyD4nnXMrayrtWMy6bBjitJHHhkV9N3G9rAVYUOf81BRmi3/cS2HAebpNv7tmYHHVw13SDk9mllI6vCtrVAmBr9q0EqdtOhW15UIkbupoNPlGOtJIxFi6Xz1hcanEIHpLfMFQah/Z9yKAUOtqSK5dJx2HLoEKJ5mV/L2iFfe1Esd9pludCMA2yvOfCq+kp3av4Kh72M8Cfffe8HH3wcGKifVMXyQLBp6o8R+/syZ/kC+df6CpUDsWyxYbG9eNRpYicFOYZfgW4YvK5Yd+Z0AmhwocopEOhhUOBCIbpB+VvxPzYs5tV8t8urqdqtjeQw+9DuicBBqBBYYaLUv/1ldHxgH+Mm/wpWW61tvp5ywjRqobLYZ6cM1IvFmRvqPqb2eMgQF4KiZDiAUE8ktZSq3SMiPoCQHMqcKs9WXikiWJ+mZynY6xH0CJGJ9hW5aSjg7aR/RNOyHg5DrOzesZfRt6aMDPneT1DGyzxipkNHl/msQwglXokqCPn5DiHfjmhTpU2bzFm20C5QdshNU274Znj9lfKsXkZIko1TtF+HSbS3MizNTXMYEaPK27V2y3Pbh8z28goppto9KJy1ZIge27zs8G8pq4DlbKtXryzW6IGgW8kQuXn0GsEkbGzbi6AKBuskQAe1DTQiDqcS2ccXAj1DtuU5YXlCbJuUS0+uvFnm3Ws3rGyLUVxDOzFWu0bnatvUvlibgrEcJ4TmXN72EyctmyTHz17b6vPSvUVjmdZSXADmPHVon7TwwM62ytOsZls9QsndreVpAn7vdTYacpreWOwAQjvhel/OMlgx4XKvjHpUHlESddPBDlL+sh4PehyFDF4iUk2x7c7Fbr2GVb+DPMC9N6dEW+hnPvQywr94518/e/dOxImij0xuYXoWxpk5mAbR2daxNFZ9/EjFPMqUDnqPFlC2/HCmdVsTfffB688FUffAGCmbQmyGJiE3T/fbl43oLf4P2FbkJgz1FALLH+gaSeVaq3KzzOjP/6f9pwRJKXJKibKqULblVTwmZcZaeZSaS3pzWq8qxlccVCUUFYxkrs28wgwjd5jpXtJJiFWjxrYwwl0cqrrepsCw2qw4Ki/M3EZCedlrDsstrPJmlXsSbM1kzp605/CJWwrpEFo3/hgOIZQ2UjMINVRRtUDIGTxcnmV1T/OwbA16k2o2WvCIdY/sbMtIZwopFYEG+J/lUE/2T7777g8++DHvGYFNgz1/goZY+gkip8N9khZsO1YD1tltIIp60qBuX4eI44+zlDyd5jSrKF4bVnte1RL44H0t7dINCj0mwYU8f4Ag8/rCMbREV17MpsDSxrpoqVmOsE2tB7cFi9uWNqlMZuhv+1YjGo9kdCOU/D1UStTOGtKubL8/0rbu0j8vP8Ao7G1+ueUHGGHJpLfSHUJdIxAPpIptaxVmdoltPooFP5xSHqSPLE6tdJ1fer+c+F47IrU9XL3cILTnAMopI2idAwraLt5CTCqXEZQNSV1/FTyrlxH+9Hvvvff+xxEnw6U3SQ/cabcCGtuCoWy7jyXpcRJA44KQajS0s21HQ9ti7J0ECUyNWm9ri23GdL1ULT/z/WKmDjGwk/5ypxgtVNrq2ya6Y4Bzz7NtxUBXsGgIVRMGReH9fuskNFRuoCcGvKzDFiqI1Zu+22ihsiSVbUMg/uLV8lArX2nT9TUHXuo2CKGvu98uO6xtz0NILnC2LVozJpD5+SGZwEpzBlJ9yyVugRDtvHjE7EQmpB1Wbuo3aZeFnG2t6KDocgqXOX7NoRMrbodQx3aKATOsUZCzLboRvFpvappvPDx/ZqNeRvjPHzw+vbjBjfXdwtyAxTq9MMFS25KOuKmrgwdsa+QyzDplXB482HJ22SrMdNDZ1ibCgFWGtoX8/kuUKI1tD/q2MslRbSvVjkPlsLbtue0c22IJFcieyT2s1udfKtyZMVa2XXkTt4Lh3CyLlsa2DqHo3oRR+SgYpM2cbYe+G2VPrD+YUP3KpTlLDCj+j9n2aJaw2uzDhRam6Gy7/AAjiap1Eo7ZFqbxXtu6m25hW4wm7Zo7jyHU2FbeIIRS59S01d63veZQmewVE3ZvRq2R0tG1sK3OR29hFRv8bHm2Xkb41asXb13hZH2lleOwMJqITxJzygqn2tIhn5cUW23NhO4mwMDUzKRJRfFdgKBj9PmIbQtDqVLlD4Zo9dno71ACWfq2L2dbQcr7tlo3Clj1rYG+JZW+I1tDRV+UmsoLyVe8wvaaw862bqK+pyundFgvTTRxGU1IrXELhNadQbbXihZVsGOpbfGZ/GAC/eLYeEknQa50QlRX91wnAeSn1ghBRtj5l8rONqPQc4Mpu5bwjTrPs20HlcXR9rxXCeRp/Azb0ik7hAaVKgA725pnK/Yl6kuaUQU8ueln+Z6CXkZ4+qtXz966ipPMNoxDI1Tf5f+Cx0eRESKK2hDQQ9ki1mmV+sCfsfcUHuKrKAEEkbI7YzK4JU+SomzVDeCHEO0651JsfZYL53Gqi3zkP1IxhZ8/jp7L5nlVfRd1holKqYapMzVqRBAFrLB41vVTPQZzRldQTZjpIkk2pYiy4PRDeNzORNhZd8pWyA4aapQU4OqpprypUHEIKWB6zaiQk/W4kAh5PkFfP85LrAZYz863UTCMiU02FbmC0FRSPiq2JRrD76GZRgkhBQvoUyJt35LXvwvJpwnT9lGmr1c4FCFLiBEGQlqVRKMkRA+lVNQ08nQekmGxDyxS4EYoQwTfEKi2M0XOcJ9KWKMHMu9yjzFMVLfqAiGnIFMz7cOIlh3KI+JxO/izGbrx9e3f+9OP8OyKlayTrMBnEQ47Lve0Co4WZG6sNo0/K6zsxxS3bZisvgPKEG4Rlb2tX7YIwOM5z+pBj5bSNHRWFYxWc1U1qBZJf82hSqpAvd5XfGFXq7rA2rulUViJweky9EHtf3R9GBy50EwcqXGI1dR5y0WzzLJn1KvKWKQyR5bpBk9o9ZfXkguEdvktAEZfKGzt9MkgNlUFDupLVUC6ThmW++BEyG19260eXG4eOISOnXIAPFXf3vIEUI+nDhJku83Ud2+tL2lqjkUGTaR4Q76AGbmjqxZC86xNqdp2SppfWv8DFubFtkkUB9F3DCGRACsnMbIi3TdJ5TIu1C6uvPhZj/Yywrs/+ODHMlHr5TVgrT2a3kksh+kr92hSRm9MkUvc6NVS6GyLjU08C7X9IAo6S5djnuNiL2y15hVj6qFqkQw612gP3rIVnQyWf5Ge9PTShEUj3GXvryKFYbYCq6Dfoyu6as0+XCgq902eEnd6I5cFIzrbGhiWNmLDiQG6QQj0pmY5hPz8BiGjRW2qBl9z4LVY4zrbDoFrKpOFLQ5MV4x5SKlmw3NsuwaLn7Dbh7dbk5zUNPAUtzyZsL3mkAxllKq018Lk0La9FBCiEm8LhLhQ2cfsACDK5OlXE0SJvPoies0BLcR66WaeYuRVJohhgi0c7SG2FC4eYq7yZzQGfhO/+Qf4g2/hW5Nkh8zOeqanAld1yRKu6jyvHKYaYWG05c0MYyHI7rniwYO3Y0OPbKpwrT1Ut/WwmM8rzOML9/Gyw0/oPB7I+FABW7TOkor+JvLVv1rYlpI3oDjQacyl9FjrC83tvqhQkYkWpvaqT2bhHO0+aed2Y7lRhiIcZlvYwc5BPTihoRirqnCF0BEXwzajUZieQmsLAmNbWWa1T19ooZLW99yJ2J2y2EfKmltb2LOv0yg1F9LWL0JfLTf1PbMKQrbQvjNYIwVGYRuEhjxrgQ9OUU3DjNIKdOKnyvQpx3DN0GxbYStfo3JtA2GPo9ICW4j1Ap+X6Knlsxl64+tfvPMHz969OoUnNKD2iBk2VSQ0opHOcK3klV3VLVSUodiUBQmK557/wQSmvGbxZRN9wLb8MPqUKnuFPz8fuWLrH0ExKbaVUzk7/zI3qrlGMtVoRmtlpreKukblEc01UWUVdL/Uxey0YupiqaF6lhHVXnMYKZxRjVxQoqwqNBqyUMHy2c93j5B2LRbXhYYtBBbdtaK95tD7gnCIofNjg5B5n8aiiSJnxXLQt8CjRQrc7ObZzraKC5MUnW0lPhgk7Po51++5TQxbMJZ4MrWJ527yunhNKp0ZmHr5bI6uV1u7Xts2DVpWuI2CUJTi1TrQwqS8aefLlWBd+NkNe+MrSfYKcrKTRWkorDsHdTdU3utUKFbCwrYgSxqk5uQk2nkBw1LEYp6DTbEW8oPLThAL6aOmeCYoTaE/umvR2bYmDudetTkTP0Eq2NgWLcbKSmPTCO4mCxsxYql2CCxUpqmJa0wOElMVgkEvWrOz2Dad0tOAoiXosoJTFBjajttnLRTcm1Hlze3iukL2D8S2YQYt3DW2hYhP6ziE0Dn3ltrWv10gJE23duqe6UtSfa6PW4TUd5XACrEGod1NhXYhYemrmHh4OYTyr0bo7ckEgBHQNqpbR8Qh5BugM4WqkJAwkBi09lkIfWY8q5cRZrvgFG2Nc6An3D2VQfirk/qepVvHGc1pbp4ttkV/zcEbU9zsrYS7LCo5myRHbAuzuO9S4QcX/NETDiwPOZJatV86o/NxXGvpioGPb3b1UFlX39l2sW3rZtSUsv1C0xYqSG5ytgV5dbpr0KF2n2MH/bykQd8NvsR2y53L/vEchDrboucqZ1skI6makrfkrmpBa6Fzueos2yJZbOiDnSabNPu0ZlSnsAaJatamchm2aybJQDK0O5W4Urub1sQAJoZercs7rcusINqw6mxbhRRr9JblrE2NcO2N4lEClJrdTUvRGj3Mdwh9Rjyr52Tx6288PH06ojL2wuiHvHkuVF6NbTW9VItNz1S+UlmYS5yCD17hRctmvmlNNsPLQS9rSOB1K7dMXOzDhQxYJJyCm5iVbMtTF7Z1jcq2ujjOhIp3meXQLfMfsi2WUIHUFNumTEkKFfE/zWsOg9d/VQhZqOA824KaNrYFfVBZo+F+4PifctBZYu2zbHtLJ+EM8HBLbXsbGHrjc2qSKc/F32rbsD/jqEQ1Cl4bNca27XPPNDRlSzmrmiI0//kHsa2sPE85w7YwCEWXDZbmeZUDCB3o+BnwbL2M8PWrF1++Ol2dWlbJlUpiW/6WUIHhY9nwLncwhaHgt7Vi7xyhs23r26L2SThkW++mEU/YgHXYnQn7rCnlmGH2MeP4QhVmL2FbIH8XgZEYxVRu+1xhbB5ZNJKot7OtvClpO9u2UFnYdljUR3GLyFUYilbq0Ne3s60Yz2fJkl1U3NKMiu5N5g9p19m29W1LoaMfTBCQjptRNF2Z0WatFHyukyCnWHAZhDa2LUkBtdtgESLSWt7H4kLRNRKE3Ecr2o2kij3dm44foOzTGz6ttoUS9hm23TU4tyc7w7boCftsM+ov+55C/csIX4sXX70+4TS0CU+6mk8Yt/COFFpbhpgySdYAoik2Z85zdFNvziq+iERbMC50ZBhD5ePNfJFBnQR9W3xp/YRJVfNwimrb4T7JrGzqDAnGKSltFHpqz8uFVk2pJnJitmxHmibCfqI7+CB31d3Qea3BH7omKgakZnkg3FC0LY8rdGV/xZh4Lf8H4+sZDGzIpj9D8TDtYDYqJwpHtM84gJAKakEIdrGy6gKh6B5haJWODD9Ir3wADIO4n8soSgOhwNZrDhJOuAqnTv0XJFw/gRrFMosWlr5ySkWfBSAYKanp8pqD8Fhq9heE9NYQIVS2DbOtahEpTQmbeBZNjskg2zosK4lKTZmCz3TOD8F3GTJZREhq2KNuAd3OoW11880NTtlWaZ2CHEJC4E8z9DLC7//LP3304tNxNUboPuYIFlkj1DxU6QJjE6AVnkszMT8g479N7LcFK5jRSLDVjEtHbOkkTA/YGvpq3SdZNQQRTbFLKoWtWFCJ1Pq2sNN6mbbWJryIlDWlxoDSAYL20k1ZXxb2msOQxXoF54WDVx8umCqUYbrULQ6f4t6k02FwNICo76SXMhClOZhHULfL3D6dbR0/9dHqqQYh94gVkgXaHUKwFd2M05YheRvu2/Zc7zyIB4WfHiY4vA9GyYqOdUQVRo8yGaFSINbo05Z6fS5dIK9XBbYfYNwgNHyhHikVJl6W2jleF4vgzkJoabaUX9qDt2Jb+DjzmkMcme5wgzsIgHlc3hx9nVcf9jLCH/35O+/+8KOrOOFK5pjmSbvxJcxpufZ8z2AO51Vv4U30r4rCOvTLkZolhzmG8rwi3OX+qgqP/EpbD9toRPc3VApZ0Q0Fj0Fkp9ShuaNb4GihCn6LJQM9i8Jk3eLlEf4VQs1PWWthW9YXLo/TlgJ+ntpoIo7ELp9Vii0T8YTkWgYF182tkf0LHObeHfTD7IN109AWXQKJYseiEaHl9jEIrXtbsedATgi5x14Ih/a1XkriyD7D7XNEqdgI13cCcWQfUcAeYpYzenh0irr9NQfZJwo42qJ5pSVEyZ6Ibnz62/MHAWLQ6iYSFGflt7ItX98P7u/o5ca2glCZyqPPGD9hYHFESvyJh72M8Efffee9Dz6KMQYLowzc9oBI4izbV2meA+xSmoVrqhSSTalqhbTNaqlM8WAxVjsDhwKIje3xgwDOfXUIepFIFWFKvBaTjoNyjHHW+pXRVrOPlNVE0ZG95jCqGKFV0jO5xtKyLJLweOBaDu6KCh5fGlhOGW4fLcTzWmuSle3k2GHRFRSbribqJGVb1GnIo0WBrQhZQNgptYgY3T6m78oXebLOzZxBD06Wbbf9BHfOfRmEOvYqontZt+45ehy1ufvmkplPP3aEard54z/4JpBFyJKwLXLHAiE5y8QDbV7GJ4pC1HZoH7p4NULuszNrwNnW0oeesBgOfYeQ2+eQgsT7ZvafZOhlhH/+zrc/efd6kqzFB0u+tAd7o3076BslmKF1tAtdRyhxM595saJFFKbzUSzg1pHnnG1Dh3s/QQedbV0w+qns6xpBUNBBc1sJ3ElhbX24NURe3QgprP+ANRJhHuQMmPaTYCvbClWOmCMfrR3S87I5d69h1u916AfPB01nSQPlwKE0XrzloF+QVraVfSwmi8jGCqGyjyC0awRLPMXU/TWHQblyrXqFNye1VznKBQsMXkK4tGd9XlJg/bG6KajUuuJBu40Bwqyn7nMLjt77iq0aXdlW4sF0tDAHPeXRBOwQWsMcAlAFRYW5CHd5ng3d7OL6YwhRKURB6JWHHxqQEwAAIABJREFUXkb45+98+5N3B8ZVFX1tS6eUAbphcP+n3UfQjWGZKqJLSdOE2VGWJVV0tlUK7ZCSI71DWmbMv1SE0NLpfAb2nBulx5JDOxXCuOnsThC2qFQ2oHgkrxA02C31AmwhFeZVk2Q9yPiohmLWtmtT0llSkHLHgcjbaVoXQlOzdaKp0dreiZo7KCbYl5oUHBRFt0DEtjsYCkJhi8rUS9tk6X7QsGZCo6Gyl0OodW8Jg7qPr4fb5ELdH0f/AUYo0+z44UKNcJ1t/WA/02xr9lHBiAJeKafwsGKdQis8OlFtj4INvzi1k67upoN8sGjECx9AqH131DNERbf3DcS2km/tiLhNGKHFttRheHPmlYZeRvij7/679z74EONKpYXjofRsD4goaOw3pxQq/kpKWtxTaxnXeZOqHodKnbS2gUJzUcCKTnML28Jfc9BWiagP84Gs1XKDs8mSVA6LIAM9IUu5HO42Cy0AGtsqUKtWM7SgOEk9HqIlzqO2h0qpiZVti0NkW6lm5UAjPs+dG9vCuMnZFpTYIFQ7pwK9m8skbEF7K4TWipiow6KmMyyMB0s8CV16ONuyVGFPri+ErUWDbaFXYlvnL0eLhN87CR1ssPdnjG356dXYlpNZokad9apse474jthWCxktVmutOgll8QHYlsT2NCXtYh+GbfPOS4aekx2/fv+j0zOMk+726p2eo1ABWN42UNc+jzVhirlUgsW2OAL9PGChAmeivS2wE591EmrFzrZAAWTglToJkrdVQ6bLWbZdSLPLBj/o4LOJWCi+xzahwD6VMTqZtbGtmKpM4sS3cFa8Qqg4KewlvIUKGoQsHiiH9n6zmUBgpcjVEbGckfKc3zvH3ow6N6tYpiC0o66xieUPVGFl5YZaOmJbHL/mQKcdQYhG3+8chOFhZVuH0C3bo5eyLRghrZPQI8R/5wRm0mKGMl2RlYknGBQ/DLuIJna3Hte2vVqHRXpjW1kZwPbgbdhCbrRc9FV5ViT75Gt4/iaG2q5RskxlN7atwPZ/TzSFNoMEqm/LmJQbAptBbaHjUFlo2vUXcSxsS6Fvr22XB13ylA1Lx7XtoGUI+jp4prbd6250ti37mBFoW060WYYt3RUoRhcnDU6OxWigkZ1QuNCupnuzFX0GvvQmBatsBIvq3nSDTqYJWm2LYlt+7mx7ezPqFdi2Zi0eoZv2hHTAtnUFFR7UuFcZhz+YIAsXVG9vJnhtO8p1jXDPQ6jY1gJwBV7fxfYfTOj3kRe2VYramlEFIWyJgRbWwYNMfw5CzrYowm1sa/3nsvsZtm3U5xB6pfcU9DICSRbcV9b9CFonipfqU92LSYTyAZ0pPf9gh3AUdflrDlRgGtQXCs9IFMIPzpkzscjWwWZKWoffCjqtQqmyLyKwv+YQErl+9ZK5w9gnJ1ncTkyIZGu/09WZaKh5Jm270WFRHX1iKsKrBJWPiJFO4VO1dQG+AEGLzL+FuHuAhyxXoakpkqrcKRnIYulE2d9jDMUCboJioUiSjQj+EwgVZkGPBII3BaUzgAMwCD8qgty8CeHBWYKZPCLZPH+gNEoYwCZmLkjOZDTY7RNtNbQoGqdGNw4YFKG0Ef2za7RAyC7sTqGYBiEUDCo8/UWgsAowJFewUWjPgUWUbeWRaAYMSwYCUhjCYXDyFNLmWvTpshViMgUjNjj0AhZdVUpQ4FiyjiP/ZaNeRvjdP/n45mlVsrzC8rxIlMK1RmWJVK7KPrFZKK/TnZaYVKSsG/y51t4/8hVp0bFM9HTdzeEVQa1oC2Up1Jri1dzxZ1r2F3kHCk+Vci0wYDl5jDJgzVUOWGxrTBG2kJtIRrAUmLrpgdtBf9TGPGmr1qgyhX8wTzYYQDWC8oemeYUi42/tHUnrKaSZSIycN2JznwTdjhmsZ7mxmjO96YL+mIFDaDedN3kKQmhCErW9REDZoV2kb8xVeqvAqAeq9FTC/DYJumxQCi0Q6gsN90X3SyPcRdMeR0CJvUQfF+qdBGdbEWG0kpFhY642nOQ6lfhLkdZZxgYhJAjbdsTcBJ87OLcW6jfKpk5Wz6I3Rcoy0ZxyOPxlhO++894HH2HczKcYFWhLQe5su8QDPQGLGb3ozRpWmwm1qgZJZLnV5849Av0ws0q8hTRto+GhAmrUzkkgWKhwoRADeQFLD9TjCgvbbgieV64yzUw3ohZdQgWqKA2LZYElCS32kfvLR/trDjOBEEDTGShTirJFNAds0kOFrm68VqCfV1tiCenQur6FSkGr2JaEGkP/t7Lt5N9IctZCK7C1E5OpoqFruaniRnDZlq+WSPG+rUKHoQBtCT0J2b+YTGyK/LY+VbOnQwjFBcuWvFHYHmKwKy8hpszKa/VeW1o5FPAQ266dBHg5JeW0adDup3+10DTNlZHlZHVgn84MAp6aOcEv2msOUjQXtXtSkB0OxvYywiRZlitByByEyqKe6eMIQBFOstFQAVLdEf5nNq9ojEo4Yigpsxixo6f1kZ2mlzyxxUPDlu8OivhGo1SaW2w0/CsVvD0etFhwIXhOjoJRi1WfZY6g6XpRIyyKMmxF0taA3wsbvAClHzSlaEB2Vg4/YFvLc86PLYqsrjwEvRP0sX0KeEnG2UmoWiaomdg2KTe9aruWspRDyImYEq6bKkvYaWHlBnR0LfsYmkgLlWA0PCE057bQF76IO0OXx8JOqQ4DneyzTLaxeA3tam49o2l7zUFvXwlUXvYuuz8CNTrUZfBW0vlXOKBpuDv2EHPKEiFYTQNUAduud/trDmd5Vi8j/M473/703evTuIHyfkLAgbVvuAZMf/O3fOBsO+j2AFQIlk7cwLLGpVLSU7SIsriDPuw0Onr1X2NbAsvrX1cNwtYSKrbvGY4o0q4OHrKthh8pRdKjR0kblu3Q1BREyl4+0YPHbFodBEjAtA5Xl2d4irMtWkjDbcuF0iMSD2bb0W27eXaYRmuY9XsdB685oAqN/JKipPjacFC2JYzBhRqEvBo1faXRgZpn2NZXZChAuEctpJgRNQky7QmqVrv1pHsb4e5lb993R7+CywaLIwqkuko3KCNU4VK3ZNs0VyPc5tbyZo8UZ1vZ1tMA7enp3JkKKhbD5tp1GtsW/VaYi3DrebZjntXLCL/zzref/rtADG640s7RnKcFl7aj60miqoMtVMxhtHNaXCsNthDkhhkils3z3M7BDcFErK3r+yNDSdl3i7GQxTVxj0lUbsbCtuCOowOJq/ZALesYsPpaMp3z5rDTWmx3anby0jkikaD1aithlYwl8CzUg8GBnqIagwgGujhqrbMQkqZnIFTeXAO7pmeTJ4FTLzIERUm0BcS2Oxgab3KhQsKtELI0xvyHo0jpWmgh8Zc659p32NrLVrxg19i2ywaarhGus60f3MDmWC29VgjtflmeTKCM+2sOnjUcQl0jGB4ahGxWzZXYFhJhlocrSC2cXM1c7eEE65d7xC6jv4zw8Rg3IMnaI4otVCjTHirYtpClp5cDHUxUdXnNwZRCociDooy+s+0CelnfWmwN9+5R29YtFbGAVWxLN1BN2zXltxHE0t5JkBbrjsZDhdZuobKQJjOBxzaMm9wCtSiNUGhr28AB1FPTMmV7zaGzrRNT4RJmH5TYIOib7g6hI9DvbNuI74BtmSDYi5YobMRN+/A/dIGTS+HFEvC6iXZG6PkDtEldameEbrE107NGR2YNqLYtvEUaHsVht0KIrlnuAQjV7eDOthuExFYiwdavK+iql2lNTVJWtTy9SN/Ytq1OhMvOi0dQdmpNFSm7tiCiJvpC5hQTfGfblWftZYTXPjp9MpJe5yVra2KBXUaOg1Apj/ZOQtkIZX3NclUBEbxHD8ox1eOJsq8VaL5Fwq1s68CqRIejWcZuYYy2h4qzLRkn3TDn6OAB29pCvkWSaqLggy0nM4HX3fCDzrY2sZI8yho9VBho6pEUDQW82UDqcmLaa1t00HuoOH7at3KKXWdptlQN1ZvvYltSFKzXTFQB0J1AJ/u+kFII5JeFSs7NMkVuaUY1b9I1q0e406vydUR9h/6agxomFEnYWJtXt7BtF8P5dMdqWd6wWiFmullY+EdOCtTuz7Catu1BcQChnW010WCPTl8vg1BjW3njoLZtPGsvI5yev3k64Zrh6DTxUomdbQufbtyePw+6nNLlXCcBGchBJgZZSql7XZSmXxaqUMFPwLZ5wFuEYjQRH/3REtL2mkOestboDfVeUKOzrR9c+m6keHMQpzjbHoGebNs920OltqmcMn1hhToO+rY4ZNtGDuvOoHLnT9JJUPC3O2z6ohZKCfcfTBhMZbH/YMItzajBg7d2EhyfWJpRC4R2tjVaz5Nhdra+rXCjrOINLGfbMNko65lOAoxt9fmIbYv7eFpb9JBti0adbT08aJ7D2rZrVGrubGuiAnWwStSfAEIUoBzaX3Oo9xTsZYTx/M3TDa4RI4pkJxRCFKYACGYAaRKWtYoVTTE7Pxhd08ex2YheDASNBD6gE5rIJ4kx/5LZIaJM0/Z0A00c02iKVxMdJVJ55CypKXfqaqGYN6XBgslfcwDBFCSpRiMR5jMu2iHSsyUnIbWYJoKB3vEnTZ3RcgPlTpER9EE3v3kqX3MAD6XoafvIaCmjoUFI9JTnGE5AnNTNyUPbdgjJJQJO0BQFrjQBltcc6KpE0WjwJiKjspH8EgYhLTTQ7AmHkFJOJNQbIEVhRoWwibYQy78o+PoGtIEurUdp3DISe6n1LCjAmK2l/KsooK6aKkhGDzHiIf/NpQC3qXRmhYde4dBXUUA1hLuvFRQi2W66AraipubR4AU1jxRQTQIyUYpcJnLMa+llhH/1u3/88OaTGww9JwvAb9VYPQUJ2cvbKkwsD7QoVT5HL8htG8tKotitohBordlUiR1BeyApOXiiSfWOSzKvuvePlGx7Tg6TEL6/Hk072prAInpbaam+LVptOypipiStwp1mqUXNF862rcKlDIsRdDz/1FeuOxfyi0hTkxI4fM2BPVo6I5WXtbF0P2j5MrLhpDTyuQ4/MLDNPkYm7fruJlfB6mK/UZYQYmqZFFYnDDSp6NdmooIQVaicZ/fxBaE0uHtkt49jr/BAD3DHxz1U+EKzEw0q505ZIeRsS31hpovlK37b5ipYOoSOep2yQ+1iK5VMufydS6C1FGAmEvJlH5gFljCXm4x2YV+5bGWfjlU3grNzexnhL9774EendMWMD6OvooxKAgb34nipykTtobJCjbzWkCrM9VKrQ42JQH2nChXKaE9IuBuqO7kshE0qVkNUMa3mVcbwWWaExiax2UdB3jsJ2gwJP9Or0bF02LfVaERcCxEKnnIMJeWjBYKHoWJXtv1U3SGWofNpezI5F2JV4sRX6O7ARceJICQtxpGaLjajy4njYL8cnM0HxcHKPeqCM2mwYPR/k4mx3TZznTq1AVIMrm2+vaYRhPx8TlkzffHj9ppDihzga8jz+KBx5wP3hVXaxxc6YFuvdg+/svzRHGonNJoDfU3LtkfTK8WFWVjB01qcCQMncTO4sy0WX7jlKU/z5mGIUTUtNL+O+M2hlxFIsvPSrE0GrRFRq3pMukCH+UEylSDFQYF2QVevJDYSFEFXJZFb0/qpcXZoAbtl46XtyrbGUyvoUdUExG5+r6OXvWLbhbY8IR1nI8OSvFkJPPi6jBExgIUyyh32YU28nW3h9kepLL9I5eNQWUAm3GAS7FzI6FrlFhN5/s1M10SVGMuKHiowpjZJnW0Hr1ZENtavKEouVJRb5kBVuM4nAZW8BxAy/EBxsVmvQUgesZRTEPKCgwt5fVALpZpFtCG3KJxZwx88Z6g9WXH3y9gWNfEc2w6sBOdTWhzJ1377y39l0e+V6av1JXcLExq224c2O6QvxoVDSEFxAKHeggCpZuBb+NbvvPP7n76L01jeNEbtzZFFbj1oZULY8gehQuhIpmU32kIFrVTEEQkO09BrW1jHBwxw+juzOKQT3bbSUJdNeFo2NcsG3DEnxEfvQsi1t7OtrNOasmTY+dWKJcNKGcrY9iBUHPQ5xypcC/K1Ej+aRTgVsOoFVwUJmZAuy+w410imMjFa3HaNBhWRqIYEemSXVlKihb2fdrBuf9SlbzmICMMV1WgQKlBVCLZeZ4HcSw2YRwxCO+okm1+/VhypMWmakUxwcFcxOOXoJ8Hwsk6CNJJd9k5Cb7W5moGyhrB6AIZheaGxFNkWQL3C6+zcAnwPc1iY14oOGM0dtLEmOva2hRKu3/r77/z+g3cRYyDbOTHo4qw6qHJxe7/XJxLp1slvlv2gpwgmAbkBFY6NhnQ5HWxsi/I6akvnHqNuGKhoGAoZ1YOtvN0QLFOWMwxYDfc9mN0IglQt1+hBq7Td0sK2f6kfYOyyadE14W1sW6QA/dEQXHrZ6ixc1/5Zhv70SFqG8DvcP9ahFq5aCIvu7C3wDPNmd2stBOLQuU9alMi8fT/FjmLb0OPFYfjBgVKc3/etS2x7DhibR+im8h3tMI4uXvah0Hym2+HrfaxiW2wGbxBCW7R99oM0r3d49JVDqGK3Yw8+C1723fIDjD6lJbBWgtB0sRR8Nivt09sC4eItZTin4M7f/aM/e/AQMYY9hzoMsIQVEMyDGFHIqhvkqZiEHmU1WB6DMOf13aAt5so8uG+pKkIYDGXEPLl+2I9v8CrnjTFUSo3ZVBrOtuSpZqNR2SIlF8maTYfZIaRmytFy+OjfgkbIUKk9YBWrI31hyKQHUhXVUp3WR61BTNhBxT/sg7hJssFkkxAeKoJdgdm2nHmBVIQ8FCx3Ff4xRrZ/qLxZewljSbjudXi5YRSzZDIRU+icefDIrZ3BZfNEEIKVdTS2ZZLMxUpaiVSHsEYQrVeEq6CwaK8QW9h8MFX0ikEpMDmWYT7jxHc5UqRIue7uG9sqii36mqf2IndkpIiCywgeKWYEg5DszCgYJulS5A5GCHo94mhXNFlQSAwBb6AnBpdapoAOrektIXTn33v6/PlgLhZ1RoEIxbZk6yDWojcVLGNzbZfYEdMYE02mirygV1xizh3dXpWInG1LI7GtLtVDRbEt3u+yCcFFYRaWvo0qCpui2qwlVZZ9zoeKIkGloG+Y/CDBZ2wLcwoJBSjLQ/eIvNzu3JQn0IMzbMpEzn0GO8ciEZzSjczXodqWP4wntqXfpqQDIyrqvAy3OPWFnLxNVGOukLVR/hLbeqgMqqwUUsFNjYwR9W2K4sG98mZnW52wJmxjmUWjJY4ahOgs0XoRXzFmmswf9QzinnXJYMBmHNVewSim7QyigmIlWe8kxBo7jQdsbhCrrD+4aNb+nhdIss62AdXt8E6C7OPV9DB3oBaCrEfAhCZOf0lTJoMGoTs/ePedt95+886duzc3N41tTeWYJQbNZc+zSOog3MIkK0vNUOl2LONaqKCzrRKdaFSFiUAZ59kWw7NaodTZFgOjIsnYVtf3YnwHfVPAJCEmKlTsbkCVpluoDAKr8ZfYFqURuD3Kg2NkaqdwZzNZX9RrGYHrMBPUXDkUJXNJy4VaWCpUMjoImDFg4RcCcC5EZShPbXF6fA43o9WqS6ZZ2RbtYFGYaVRhdsC2UAekasKqzwfKuvaU2BGE3OAW7Och5GhnyIjUXM2KHWfbYknCzRmJuG8cRmJgIlgLurW2XToJFMfdLY3a9mjnPkWZAzJM03BJafuapbodTPEjd+UE9gohQcTdxOBd2NbdlNRtbAtg3PnRhz969PDRgy89+MrbX7l319nW9gtJeKHCdxRdKSOSr0LR2gA0mtUadRrKMzjNpopheUVgLdx7qDgjGNum70ZxjqrcfA5BuuWXg1Yg1y9s61BYQgUYBJZIX4loJT4LFXQTpfoFBattSbLTERM30xfpkaS/3L22gtrYFh5yIqBoKSGGOZRzrYazr6xyBzbgOqzJtiPRwNI8Pa5SS6a01i4XQnQIHTajiLRDCC15ziGEbp9hV1AiZNqY+Zz7vHlJ9Q4VUH4DcyT4grF6CCGQcRxC87+xyAPZ1Dzi5ytMwi6eC1VOcTcE2x++P0/zjAO2Ne5uO4Mi3J1t9a2pKbMXhKhRdBeQqUwRZ1sQQpxPoTOZtKrEYbD5GuSlQakEjDlLTFUJRr2agbgzxvj000+fPXv28OOHDx48eOurb927d5exKu5xFi3Xm82Grk16H/wHaCoCpQxNKT6tstRpyEICKHPXXFNptdEgDcsiyacYTM9DVKyW4NCiIn4SjlUZ4qC0qaXxls14mfpTEnJWq015qgNLygoKWXCPUcwzihmUQ3m1LfF3y5OO4WPdhBJ2bWPLKeFflX+aL1aHaqI9OTyoWJCY21sDiqYh89Mj1LCFCkxsatSynWcyyx9CWk1xb0ZLG0mU4L4IwT3cTBB53aAo8+jIoB11nP5tbOuL2gZckJITRLK+BUF3VmNb2+Z73af0BmrkC/HB27a30kLRo2/ZJBX7wHShRiFiWloKHs6mbGVZxSRIao1t4VmgfpJmLL8qYoRrBZxsJUoFzCNmOsKgxAvjrgDGnZgt5DFePH/x0UcfPXz48I0vPfjqV9+6d/fu1dXVmPfHrH9mH0+zBTpizI/axQbsB8FHnBQ4zd9LzKtzVDHpZZT8bdXEYLVVoSLW9inAiWX2tDdmkZFpYMSJICLdD9R7Gqd8FH0Y9EqAMOh08u4Inrqf6Ji+yxBuPCHJqcNiQzWXStRlqyT+9rJXpUiYCworMMNShml/2NJy1rLFHkdfKXMoVFY2MdoNa4Ukk6oIV1ZDPfx5wqh/+dwB7WyC1bbTI4pw5zV3n0/0CO98VF9JwnRptaIgkh20YCSLMIyQ+b3AoIgAYuAUBJWHvafGZZZ5JGQ6gdZLsGGE6x4BZv06Tiw8gieOU1mFmEPy2jiNWKIvTWe9jipanVJPOEVqFyil+LGxbTr0RIdannFanLFLSzMeMvp0cwPwspeLWf2CcTJdKLYk868GQRIBnFobZACIv/G//u25NFDOj8CDB196+6tv37135/r6OtlW3w1JGEjIC1TVLyy4sf3CtBMWk4B5eqxfEZbpP0gZegtmayWitBHWeBCRlY3AHdzWUNBVxhWuOPtgHB992Vk/xaxXm9JOl0qvMNzBdVD28RrSfRRGqaCF59zFoRYqioecQVBm6A5/nh5qRk3hKssMxhqXn6FSwnRKGjJGFQ1tz94gFH2uQUh2aLtL576eAcaaGBkpUyLprI1INxGDpySEx8Kyv5aRlxCD0Xe3z8q2HmJp7zVnZCxre6vOiIwXBaSyj5nutr6tPjgpu203CGGxz84nlRhmjshllKvys3bv6Gwrvyk0vOnkRGxWrUgBcEe5NBDu6kcPHz56+PDBl7/0la985bXX7925cwfA6XSaFxSLhipX5K4iTVLbCi8aQg8gCSvDRKRXJF9hyGuNsLaAEBPlsMqBRx4qvzLpVU2g3FsBjng2np3KxLfx1ss47ez3t048+PIno+m45fyIxFjFRiAirq5xpf0wCrjZMJ17Atq5HDpsVfrLSyfbxZEHvZMFMN8xvEcDAZ+uBzd6zfHHZd22ojN+HXgVCI2my+CiwycWVmWiBPowcrI9GDPKyNO1mRD38TRb1DwC1LXoGcJXvOn2URHDald+83AbOmkaZkZ8fhgqLVN8EkwGkF2iKJ5VeWHECZcnWApqbMtLHzlULtsaYswoolR/zkXttuAGY27t63Vw0OwSnlDrENrYVuLllDucZtpmm+IKwKOHjx49fPTgwYMvv/ml+/fv33vt3hjjdDpVqlUKQ7+lrz0KmERUMPL3ZBlmnJKXFNxJdc2giupCTGfAtUGxz/VQCWo/26+16YuYOeFmnH713tdfu7p3wql8eoa4fjL6+8kmrqe82lo6t3ZIPk5j3Iybm3E64eZmnG5wOo2bm3Hz6enZx6dPTmNcxdV1XF/j6jquruP6Tty5jquRIT0UyUyZcwyT8KBvK4cq0RakBVOVC4RY1HsbIC8xzAEVuJ34hupBg4HKAihUKNkMVGFjCu8EnaBy4rNk33ffPC4yIq9UKZ7trGDHh8VKEZefJu5LUizbGiPnLNuti3pgkT8shSgoaGnRk8qLjGt74nNiYJZnlYsCKh3z26FFmQl4sUwJ8korcg+bDK69Qaj6CUYj1XUUqIAoAmXFOiWGOJYFOhWvH1MwM9aKHdy+YtPoDraRO5kxAri6ugLw+PHjx48f379//8tvfumNN9547fXXkm3hpWuln4hgstC7DdyB5EPey3NgQnAlhwkRCr5unVqcFbA8VCYWZW4PpGCLSnFYMR/W1rnG9cc3j/6XX/uf/4s3fv3J6UnE1W6uw/EyEhzLKUL5q195vcRPNW7GzfPx4sXpxQu8eD5uXpxevBgvno8XT26efHzz8NGLJ49vnjw+PX188/jJzdOHN48+ePbhhzePr+P6Xty5c3X3bty5jusx5jZnZJVpDmIeTUbw4LcGVjCntiK3PBvDsrh2dCECnubQDgvchQ928FFoKWEYriIviSFuag1Nmd870ao3gmFW3NQnqsqoB2/LUv4txenPgZnpijqd4kGltBeUmsZH6EaA7b69b9t8JDWTyJJsx6pRNXfHGIh6cjVI68ouifcwCjDrxUKye5PBc2chwPoSqNQdpmbZp+5X1GMUNqv/loKfJutZwZcmsmwNIj+PHfAscVEXn2z79OnTp0+fvv7662986cGXvvTg/hv3T3wIDNpVRLmmHqWieYV/Zrxq4TqCGWAgew4LRTdfZTbVF1ZoOLAUGMtCYZ6LBqxAYETE8/HiP7n/H/2N+//+OUP9wo8nN08f3Tx+fPPk4c2jD5796IfP33/v2Q/fffaDdz/94TvP3vvw+Y/uXd17/eq1e3EXESecsmoJx2I1QJfGWQ8GkBB958hqix2ozNcIuzEgfq8bAkPNw8qjDqEWKmAo9m/xChDy4IfYFhbYfcuZLbf1NYdQiTIwDtjWeBO9Mn/FAAAgAElEQVRW3oZIkJIoZa+bjNH4aGlJO0Er34vj9k2xHUvCoyXD+ggjqt+QHpZggwK3LOhs67ZF/7asUxScvGk74JVtBQaUaxAi2Z1tqebOtmGgtc7S3knIy9wpgByNnW0/+eSTTz755NHHj+4/eP0rX3nz/hv3TzeneZ/MHxWudxu41WjcV25gi3SYoaiGAHpgnY4hQX8csS3PWEMFbavVaoQKC8Snp2cAnp9eXB3uvX9RhhlTW5S4xvUb1/ffuL7vZ57G6ccvPvrxi49//PzjHzx//ztP/vgPHn/nj5786Yvx4vWr1+5e3b2K6xNOxKLaiGEuyDAL1jWw2uRMqOTHfNOv2LYFZ/aPGwi8GQXthBQqOsgPuZLXSqr+jBULQqS31rel1k4ZUaawZ9l4j0NBkzf6q6Nbt56kS2gtcd/e0NSKvpOzbaJ2vpSLhDvYM6FfnEoa24pj89tRrrQ2HP1VVOOZNYH3U7CtbUlrXVlbwOkQGjrf2RYQC5ly7CmMMfQQGFr3VmDBEdumre44ybJ9tNLuzrbPnn367NmnTx49uX//9a+89ZX7b9z3ZxKCT2SDFEqUoBpUyO1fRjRIvLx9rPicmtiRPW4VIc62ZYUzaRzscMGA1cJsnjvp9Tqurl65b/BFH1khjgHgNE4gZUz43onrr959+6t338Z9APjv3v6HP3r+4/eff/idJ3/8u4++/XuP/vXHLx7eu7p7J+5khSPy1t/bFi+52KL6JaEy5n9mr2DepBlGsuDNVrU9J8Qyq1OcVsEVhCz4td3xZpQajpN6hMxqRplG6I0pVfcEbb6nwZ/kmNUhn6VgKQhA/85DdWbQAc/EsLCttyzRZ6128FhgrGWtc2gfkYS/BdRec8g0x3X7O7AexWynlmwOg3N9Wx2005QIK88ahJge6iIgJ4h65k5pZVuIpcbwx8L4EMlBM8oXujNq60zR2eh6Kds+f/78xYsXTx4/ee3119/6lbfeuG9VzxjpKm0YtMUgLHXvGCVsxWR7Rp0ieF7zwkQGjRVGZVnzwfANncKmSKBN0cFfojF9nf8VoPnC4nymGgT3a1f3/tprX/9rr339b33pN/6HX/lHj2+efPvRH/4fP/rtf/nw9xX5V3HFvFpsa5WRbl5VzNsG3CLanCIvTubJWqNyO9gUHU44xhCMlqqGwkIF5n27HFTf5VyxrZpRqmUWCGkiZ5G2jE9ao20qU2SgPJLb+d0+KAkDrgChbsqnIUTTFke6B1idNLEtrPBkn5T20et90zkW5ukXjLwVJQ4jDTj3ynSziWQLtb4tdN3SqAwgQkC1/ottEww1gRWYbNT7ttyBAGEsJMLVSzYHFAQg+FzXfD6LBW8+yv9qbHtzOj158uTp06evvf7aV99++/6D+xERV8ECV5VRBHDKpsKpbkpGFiWzDhnaF05v1a9vwa1W+CE4jmrbIERjvqqgr8It2wuTLcwGyn+/1MPJd5rkKq6cdq/iajYZvvHV/+a/ffu/fufT9/6vH/2zf/aj/+eHzz54MV4AcTeuB1+g4KPmJwbtsmVRXvS9WLFPtMBIUCa0+YRn7vMiwt58mNcd1k/Q9XtnSVk8Vxxtr3MAIXSAzRM8l/Su17Jf9kclyQjz76cY9iWCpVFGR3QZmlSTjo3WYfwePkvVX+BkvvC6b4m+lQQVYgrbegaEYZ6GDLpVHFa31YqhFvvYQnCSXQh36Sec69vCSqtRfpGy/PUDpcJ6g2CKqB+g07ZpphB7UNcgdP32P/nrwacW4iqqDzSpR79yfJ5t5xhjvHjx4uHDR0+ePL6+vr6+c+cqruYbZZoyyKWlvZ6+BZE2gRARwZvH+VEiqAUG8mO1mcI2ZeahIeeVpZge6YZK4zwzruPqyc2T/+nr//hr935l2C2Jy5hOB5GwdFQi4iquvnLny3/ny3/rH//Kf/+f3f+bP37x8ccvHj4+PQ3Enbimt5RC00H0XZBwixTkFKMMIDmXuOFGfF4gsojSzq5KaTYZpgIx6poNQkZJEyfRq5UDCDlTewnW0RUW/w68TBCRARCqbQMxKioDFhts0IXZB7bQoInKdDRDVqOc1czOyiNgIQY7f7EPjw4RWD6gNjvooyQMMam4A8XlFublFFbWVTl129a85StLciLZApgZQb7ICwU7CTFJNq/KqpYP3yXQokBoP0VXLHSHWbLeqkmMMGXO819a24qDPv3k2Tt/8e69e/fefvut+w/u3713NyLmvTJUMmXCVMGaEllfRehTlq8doMwkxq10pMTreoYqeB7xA5oLS9oXTn3FIcKtcqNoEPeu7v6Dt/7eP3jr7/2/H/9//9sP/vfvPPnjH7348RtX96/j+mbchACaLhMY6nYZAC9qFofOI4UbVR+6S5Yuz2ZaxTG7mjw4V68aRDDoRV/sEGJdPMRrYgfxF4wUBqM6CrQqHoOkwZqwod4I1BskqR7NTyW1MzAFyuA9KFY1R/miPGIN3722pTMUgMF8an0PDJaWrI70wyIo+7S0B95xWajYW7fdhhDVHvVt5YE2ReSkSktcqB9MmFSrBtqc5D/AmJ1cqBWa1r2j8KimgeWUwRDIPHuebcHompz7/MXzd999795r9958680H99947fXXI3A6nSoCExhSaiB0vxVMJ9qIFOp5w8O7t2UpZ8yexxIcdB56qIBOHJ7MRwvmy3jJqJrCEnDeTMP4+2/+nb//5t/57R/93//nB7/97cd/+OjmyZfuPLgZN1tvCyLckZ4th271mjb1IKkl6DGvRrCwdzjPEwqqxq3HWYt8rMyE5qgllSRiNSBEXp2G6mq8jsNKq25diJBV7SVkmoH1LBjcQ5dR8Y+q5pp9GDUuiYtX2aLvFFXxjVFTnNahFAWyWKAe+p88VgvxztlAbcHTuJMQ1oBtGi2E6+WtA3LpJMy6WCbe+9Tma2izwnwxxYuln1Cz/OCo/dj1W9/8tWwaJDS5IUFwN5J7eHjftoxpWrGqVff2dHN6/Ojx0ydPn7+4icC9e/dm37bO14akMsa8DriXmAjNU+kGj4q0EYMNtjuDcBCsICopFnS00NqCuIrrJzdP/sdL3+CnGm6uQJwwBk7/8f3/8B+9/Q+/evft959/8Befvvva1b2ruDqNEzdEYZuVdIqcRcobolrUprW4DwVMgiWTdPgOsKqqooJA8nJVcwuELJe3FUGARYeQw5KnMcaLlHWCuhAMUNkS7cvQrRctqsqX8hrmYTljmBbwKkTJgASkWVWX9DiSbKUmSF6x9hMiwF7OTG8p9GAVF+nX+jFG3dbRQmsnwTPSYT8BuXTrJFifF9R3GDnYp4Y9N+7aTwCfsU012RGZ3Hr91jd/DVqQYAj2TVe2nZ0jBKL28ucCrNj2dHry5MknT58++/Q5gNfu3Yvrq51tMauOcsPcUnY9PVQkkKG2QEvLNutUEvNQKcJVqM9QmTx76c/+ZYay71VcBeIGN1e4+k/f+Jt/98v/5Qmn7zz5kxfj+b2rewMjG1DVHh3lS8uRYRQWR6ESPM0nEiyYRUO2P5MmR3DbU6sqtzM4N6JZIVRl8HqkalHLHwvbapPZ4h8L2yoFBLkWUZfzisj+w0VFmi1YKK1SS2UyibrlD8WRMk3zCBOh2NYJN4NbHmNVFWW9zra9heEBe8C2uLW8PWRbU0ps6ymHEOp+IV9N3cznleGSCgdw/dY/+bXKGWTbYlDSbhTfQgUvznQSChT8MNn26dOnnzz95Oknn2Dgtddeu+psy00eq4xKepkq2OJI4VleuxAVYLLsuVAx3FdtsoTK1eU+2Gc01EC4jmsAL8bNV+6++V+9+bf/g9f/+p88/fMfPv/g3tVdsEhj2RXe2PHYXth2nmAkaBH9/7P3bqHWZdl52DfW2ud+zn+pW3dVV1Wr2t3qq9Qtyw6SETYJjglOHHDAIQ9OCHEIGEIgRHkMIclLCBhjyIOwX2wCSUQeFCeQmAQcmSALhGJ1q9XqVl+qum5//ffruZ+z18jDGN83xtrn71Kr6/ytl1pVVJ2z9p5rzjnmGN/4xjfn3mfOTRrgGUrALe4WA+253cpPPgRt0dC24UUF1gq3RYvklRn1jjTlzuuyqszvFsiTwwJoM94ED1mgTQQNN2Ufn9tWAyC4PBVt0eKo0BZtRWweYg3j8pamkmg72yeimJQfKjN90YDcoZUvmoR+XUVbm7/af2hDWkFbjbw5cqurKilydDBulDUAhNmiqzIofmg0E7GvAyunoZt09KfrCSAojuO4XC73n+wfHR49evh478rulat7ZkPTbfuJbXl1ZXagn0V3vk8fqJl9ubim1UqnvNdCBfOkzX7ypVk+/Pj6KFevctZssfTlaONfuv4XvrD9uX/4wa//0wf/75qttWCqmoNr4Mqj6amlEhactMoZs4huN90c4KeUrGmfHdDyg02Z2vnNNZHFSxZA2wvqwe/VHdpNuaVhBrsa+awo5pu9uWWhYpqTMZlBw+cbAH1Ow7qYm+/qumS3L9qrDVMutsIKRUWtRUkTmIcYgbtXmZn+WGLHmEVihcSIDw84Rc/IIbSItxmUqt4INTqN7T+UfwpuWiUxp1+1ZcSHSBQ3dlMyrrfJLQp+wYweixMUtnhtQ1s5MKDjCjnQTAer1C8MGb2aWSoJx8cPHz7au3Ll2pU9G/NgkM545C/lbFDpF8OJ1/ShsqS18kwrD25ppKZKd3Q6VvNgeEPYj6H2Mq9ObOPg7Sc2XvzPPv23X9546X+8+RsjhjiTC+AC2hbpW2F/yoj9zaJRzthGER9kwtZb6v+l285APPeRubdRaCsfE1DOwAsMTsVDb9t54Uqml+N2Es1pissYMS8ZkmKA+YM4ZNx7hz7ElPNvYyM+zEAHmJmOoVmZQCbBSogRKZ4SYux6hrbxXNLYfB6rC9D2xm0/YlLnejP7rI6WLxUEd89sXFvMHagF7W+Q0VtrztkEssbEACwySwRsDXni3BpZNDS0NRrAE3kHDK5fnBtoXTiVuzU6w9rGT45PTk/uPXrw8Mq1q1ev7o3jaMOAPPlOahHFRH6NfiDrpGFjUn1BOu3ZEaivMSZThGWu65m8diEVcbNF+Pi6vKt7AhyTTwsb/72X/+3n1577tff+4dKXCxvjKzPynazmtEAGTPMCtq2dVrMX+MWkYghEgfhfBtTMCZJB2ZR+BHd+3ImEqSGmz0UD9xINe2lVQBN8vDASNs1gK4cAWPsoRwdxF2yFP5cQUngCMFZaMYqJxyczFss+fT9jtVPCovKBSZ8R7dWkvCUem9uH68XoXkXbuCVtJJfPzVJSaMoSZylmV1otrSd7lp2bdTQwu/BS5YYierOEXdoLRQafOR6dPB6wyM9LO7lrvEoFi+6GtH6aM0C1RNEBA7/CG11PuKgkPBVtz8/P79+99/D+g2vXr165cmVcjPqTOaWRNR/y9C5+7z7yb+jUgeeW3J3oC0bYLF02VyCTtbZCfewfX5d5idgGgTWzf/2Fv3x97drffefX9peH67ZY+qSF6ISxIyF5i3Bztnadm2BGA2e7KMWn3AGePHBSQ090EJJzQyBdhqMqpktgQmOy3sK1Mj2Ia17zKufseOH5x12KyBstEM/Lv72UEZfaCKvciR+Ry2qQYYpiMbSP88kGV1B4mgvIvxkzY8Gd9uYT+Tur7PxPA+5KSA1taWBzAJM+BsfXXTYGcckzQdIIyaU4bG9rAbnBCtrGH87pMi7J/yyTtcyHC7JV2ad5aZX1Q/prYmcIucbjhu6W+AVX3smWpLAJuoZolU8oIJ6nnmwrsAcEuJP7vbv333n7nft37x8fHbv7MA5paedXPCQdt/Awp0epQ0SJFzFiEvb5iUUYg1PYurrqqFdrhT6+nsWlRGv82oS/cPXP/Zdv/Opza9dPprOFjXDvwBqNuHwG/ttg1xvXE7AWtFlrK1ghifN0YX0S3GAk3Ug/DxDLoEgX8mI0aN4VcC3J1UsudEJY7mDVAIgCdFQVsE4gqH/bSxA4ehEQ46kKEogoEeCZQtL28awSQK1FBMDwyUmJyYYMAaW61qqAlfddTJYoshJiemxYjEBvCZQJJBqyM21lmJs5TyWwEJ7bx8VSmeESUsVkne8Rws4F3HgpH4iEXbmQG/+VEZRsou1gSBru5vR2Qm3MQGhrgsYUtwSpOf2Euvwn0bbddG8jJ9rmWNzNMQyDO+7de/D+u+/fuX33YP9wOU3jOIr7UDHncJjWeIu9uRkxOek3yjBe9Uu5Al2kSNLHNPanc7W9Lyx9+ZXdL/znr//t3cXO8XQ62kjPrTIwGqHoj5hsoE8yNmvuToqRHXKNi6EwusLbG24me0yFNjEsEzm5CZHKUgu+GJwat9H3CN6lHhjmoCkYInpqRuqiUE4MtIICenQKChGRLDczUsxKe5by1yYPdgESUhkqcVOTqlRTsJuj6DNqAejzjtAfwI6gFXGYIp+fwQqul7EtxpUYQT4rfGwuVMEtqBXa6t+noi0SeaotCVxzIa6L2uZfGAzyl15v3paAgGm5BMnh5RFQQ2S+Ad8YTedir3aqLgZbAjEwjoMDDx88vPH+B3du3Xn06PFyOS3GRUfbMKRChVuRibYhn0syRtwkKktg6Nah03frfExkf0qXoHbAsPTl1/a+8p+8+rc2xrVTP82vqrkQKoLbVoBnyYKKE6+SpupEb4iQ2fpHhYonSCGR1hjbQTmCm8QrrehTjw34lMPFvvuMSCurroJ+8MJoELaquhfazu3gbMVppgSSBuNWSgw5dzjIghQ0EKxnoBM3Qd7dclVx1WaBFGoZX7BaJm9NnOOsaaIe3tgit2KI614GCi6XN2lb8fVVg8Nbp11P6Nh6EW295s5RPt2F0FwIyO+fhTJWFkmBjAFpkOyftX7QXDc0+YHAmiRcHDachbIEiOb92wpW4i37MBvHEcDjR4/3n+zv7Gxv72zvXNldX1tfnp83tM1lTB8lVqe3qifPMiR+ZP0BTYsOWovdFv7j66dxFdT6sPTlX7z+y4+WT37tvX905mcLW0xc1CgXFSrpmQDqB1+RC/Uqm4gw5ipTClNDoLQ5cdrcIID2eKOoE2d1SJWDZ2gI6zXafPqMuGHWkR5XsKVwBedbaO7FyDpeoM/IRKsrhOMHEHqs4igxVTUGvI1fQ7oINCCNFUNvSbGpAVwRNu9JRU1qmr1q4c+1E8RP63piVownSReHn8vhzKxpW68Bp21RE+lTnt3RTWuVCr0l0lJ/SNLuhUzPZUiwSkEA3GW1XJcCtTSkbhbaKmxYFcjBOAKfQfAfi7ZPnuwfHBw+frK/s7199dqVtbW1Jb+YJksIUwRW1KiSIfENg6P5mtErvXkwHf/j66d7CWrNh8mnv/bCX3l49uh/vvW/Ln3JvbIioaKocvHywXy1mBEKeqRydp131rCpkw4yIDEEV+qGEfz0afcIiuyRMNlBUP1iPrxGDGZoq2kKW3MWfH9BQ3uW0kaD/oqxCi/OqCFivcpncHf/Im6uoC3IV9iREoyttOrT7hR+JalgBusFfIWYWQH3r3AhdibuWsFAosQq2s7HhnlHBbIraEtzdbSlB/BpfJsZfEGZnAaL9xnbBD2Vf/cMinJ60XiaxsAEE/R2hrYOqQdEc86tYe5FtD0+ODo5Ot5/sr+9s339+tW1tbX8gzlyDFLcZOJyFFA0YJgZzZXCG3KICjCm3I/x9qd6BdQOZpM7gH/35b/x3aM3f+fRvxhssHI0lbFo3iw8Nb66KtEKcFvdqgg3bWJ0tO1h6WJ2FlxBx6OKc3V6F6UgxSp1JGyyDp3sHa0jdQ2iT7UFLaApZxjwBa/45zD5tAIpuPg5cpSl8GWTjK+IY0Y2J9tAsIsGHM6M1gmhkts2Iyi7OGcEzne2mq0jzkg2s1o5YOVgbSoJQgnhqlp0bcSY+bzh+8xL2029pGk2gl8LusijUUZHjTVoRJVUMEvtHJ/WE9wuRsKX3s2VY/wUsSSCSVKQES8w3I62wzgAODk5OT093X+yv727fe36lY31zRRb3ckhYjg8PaG7aB4FuXBlV3DDTFIX6r8fXz+li1A7TD4NNvzHn/oP/tPDt+6fP1zYojytEBPlK1zKhrCwilUIZMWPUGvshK4KFcyxD8UJk4Fkewm4CBHRSbUAHmaNkCjMawyuiQAztJVBNF/6rXeWag2phbze2rb494bXViAuAO0syiEoyk4TV/rHHGbZqIEjTdQSobJFa6Ul62hb8y6QSOkTBZCtx5bplF6oNHM1E6kkMc7C3hr4ubfM9DTBp9all+FNye1mLxcazMwwmFucPECqBkBuX3ViHkian2nIusmHwTjcOF0gcCvbW2UGZs7oa8CQvqaTCZkzZymkFzP8kznnjx8+fu/tGzc/uHV6chIpWG9zDSdEHzPApjQ7vM5BOKbyL0n07Es04ePrp3p1qP3Exov/4af+JjX2RBZtVTldHKnumbaeWojSxWoHJtpO2rKwtnkFoMU/qBsGcK82zG0KAJYIlJ+gmZLR8DxYRMZETlWYKGyKHEBaatpXMcAwdTAlpEMzRbZNLsxhxytTA0HlJ5aB0TD5TdaXsqjD4Rx+vJRDIeRWbjBORCxPa5QvTbSvRl4/Ftl3vTRxRfiSgJjoWftOnnWAuQOT5243d6YcExOjS2XP4cGnidm2s9Euf9MnSkyIfydM0hN0X/7TXAiLzIqZUWxIGE9+mhQTOhgCWTO125z9UNy1MjqU0/kY5spslf8ogQphi9u2PC0NNhDV3adpevL4yf6TJ9vbO9efu76+sT6Og8N9ItjCqKTlSJwfLYHPPuagAxUZHNLZPr7+VC5DQC2Af+X6r/ze49//J/d/c3PYiG9QFHo27iZ9QMSwuA9RoJAXJFmOqbHjjhQFaq2jDEIyXE8Oi0RaltDJDylzmpFhwJF/GEbsqgPABW7blEHhFw3UaHjDrE6KNWwvNvcU05EXJxEi0YHggkcjIcUEPMem2lVj0KjErqoEaePvJbm4aq68Zq28WHNutLfX9bOsk+Jrqh9UDOITpYxwKp2k6RNRApitOET/rba/OqTmxxxARJaeUKULsDAmAWgbopJOThUi3HnaK51NRZzpjGotcqItOCmh7VN0Ww3RZnw2Cb+xYzQjCHYBAAcHBwcHB9vbO1evX9nc3FgsFkB9rXg8z/Q/ziRDJUDVm4uYwuwZXhRcIiv+6VzzPDLbCuin6P40BqY61c3sb73yN//g4I9und7htx9QdJ9Vat742gwcW+mnnyvIWxOhMDqTmqOt9XJSSAfyWgaA9pYrtwNoH91NJta4xIf0KIZoJKHJPSCnnSF1EcbOztAGfKEAJ6xHIJLmEDvZVhkji91EDcbqDDfb8MRM27zBjprV+mqi7T41IO7LtLqavaNiWOYwQquXahFoIBSON9ZyzpQNDmrWEbobdNfVS/phUY9zfujK6DKimOkCPDABgi0qOUDkME+3mh7B83mamCiucYVLB+c24Qxt+01dOcOGBYeHBwf7+9u721ev7m1ubq1vrAfnXdGryLblWILf5Lgm2z5LhFFeGzE+w27+5JfDl770CQMP62moP81hCOjhuLZ25d9/5d/5r9/8O7vjzjnOS8WiSxtFA6C5/CxUCD4VBhDjmJE3tvVqK9QoLY/RJWSABlUP8BnpQkUX40b4YWjwFMPoZSwKGmbasThRb6KU09v6fEbGjoIaJR+soABadDbhkeiwovAZj4Mw7LMLpiWNU7Saz+JSEADK1Jjx4rKPaC9KtwXHS1OWUTO4E55YcChfpqshYBa5MGWgetpFFwLdYCX19pfi10W7KW9oW16SvQFmBJP1mYCMDqJNTPSNACu0zdTRSUhMUwxXybGPHk9TEkS7OBozMxvt8ODw4OBge2t7b293a2d7c3ODaOtcak85V45L2ayxoOYez+aKMZ/7+XcPf3Dn9P7CRv9J+vtjsO9DXjbYYOPCxtHGhS22x82dcXt72N4ddxZ54A8Azv3cJww2DH8agCu+9It7P/8Lez/3+/vf2hw2lj7lDDJwGVBPKYrBUOk3K9o7+Wpo24McQmrL+4LNxkbybR3rg0SRH1gxXBfWAQG9DG4QVgTcHZjQ4nwVbWM87H3GzY1EMsdRM8q3deCz2YxQEYYs6BPesgmjOieyoiTY3NpeZkoYglJUi/eOWaAyC2aCjrYi+KZpMrNK4WlxTKJYQoeXlGmEYI5/Vh4hO63yQjDdtB35w+ymwxdKH0pvQrMUYVX8S+/vy7yKtiS0wsKGtkrLDYJny5XDanqClrvQFkV3ZwmJV2yUHR0dHR4ebm5t7exs7+7tbG5twlNJMCU19toJLUzL0ZfoWV1Hy+Nfv/mP/58Hv7Uzbi8xfcg7fzS2fRjqrb5m/UcbbVzY2sLGhS12xq3dcWd33Nkbd59fe+7ljZc+uf7iaxuvfGLjpWi19KU7RgwAehnx7C5R2smn3XHnr7/4V7/+5FuGIWss1WAN9ebYJO5TtM4voG2P3oZNszAjIvgFbFJCNjK4tC07Mu0DFCXIHomNINry4zxFXS6gbQNKW4H1jk1oiYF4J1yopNIZWiNlZZ9aCjD2SXa8o20+t9fKM7RdwU2OFsQelznFZzVNnxmhgI9N6lWtCDvqMzIyqMBJno6inF6cK9eoo/KPFKMumK5BCt3AkN/z3WhizLRuetY6M7R1gAWEXMeItml4uleirdar67a0XcUB0fXixxycCymENhRotisPgQ0DgJPj45Pj4/39/e2t7b2ru9tbW+6YfMqlLLTIEbQDIl7DesZQC1mtyNRTrjLhj3zlKS+utmo9OPxsOjvFGeAOv33qky+XmJa+nOB7485zi2svrD33qc2XP7f1xs/vfunzO58FMPk0uQ9Z9Wh5ntmVydoBfG3vy79y9c//5sPfvrLYW/o5QMGNVIZoxGJqHhhzga9LliDrIVxknCukV9CWzlhom9W6ntYIjjujKqXCJBpmrjXpuwXR0Y9EW/4sWkHuANgAACAASURBVNezC8oW7Waudo2tT7OAtUMGG3oHFMYtKuSpPXMoJt22zSwXcgU3OQBXjkydhetis1YzKiR1pQTHAmj5vHXgax3NS9eUZiqplPjhFKN+pG6rKVgznTJcpZ2FyhVmAeKZ8ZRXLnhHW2HC/OO3tMbqxxwy6cTunyyQpNn6mmm4mZWYN6XbQkJK2aMmlrFVjhBoe3pyenpyenBwsLm5eeX6ld3tnclnf3m3wEjD4CePf6Ja/k98hRO33z4MuT705R/5YmcuQlszG4D4mouFwbAO+uUSy3vnD26e3vn6/rf2FrsvrF3/9Oarv3Ltl/7yc39xzRbuLvHUubx/khn/uFeA7GDD0pc74/Zfef5f/t0n31j6OcMd8qo8ipeqVUHHCg2Zo20Ovr1kigEVtlYGgyK/vyQ8JV67WBNbZRe52wp9oCa/WoRP43F29RE0h+Vg2yuzhpgKeIhQC2uUVBqRLLRFTRN6W3s+2EovWT7WqNtKBUF9ur5O4JPL5IummRm5XmHfnAn29apWLYliLo/UvJkU9RKkXF9EW2FsirDScWdoK1Ko8OrprTsV+kT0w0L6hIAvbaAOKokV2s4MwC3UcDOrX/hP2ycV2lI0yPMheWRX6c5mY+1fmNBFAyGkRAbJYRfR9uzs7Ozs7PDocGNz49r1azs723JGb0OrFPahYHeJV9hjqpJTWX0W/1bUw6b54Do3ERfoul5MaOrP6PFpRI2CAQOwZmvr4xpgS1/eOLn13vEH39z/zv9y63/7N174V//6S3/VSGygsHtGUJsOaAB+8crP/dLVX/y/7v3mtcXVc19yHjKTa9mZL3swQGgrC9dPhVClY15QEtSfoV7yrtbN8aIwVjVTMiCLzY+IFpO8FrDKQpeU2nPvqWrxpmAoSXc0qY7SNgCVX4Jsxpkgvr+/EbiinwoXC4W24pAeVr6QIVhNnMTMTHxJRu4kgNbrNi/zEgT1c61IzTmb1IKsKMXSbbk2TCGZthON07CGautyLpFqhadzbJpXIdjgZoYhbDZ4YmfIsko/SVrpmXyiU8IYzOMLFqMtvSFIq4PyeTl6fHuCOeCDRVLMrwSLLwgD3Jl3FEXmqAPTSbbjQn3wYOVjDkJbAMMwxJ86Pzw4uvn+zXfffm9/f3/yKd6W3hHGnO2w/vQuJW1PdS+8YfZ11yxjk2sTGjJVpi3pneCJerm9OeLEfDI/L1ji1/xlRLu7w5c+TZjMbGPY2Bq3jqaTHx6/+/ff/x/+o2//6m89/J1u4Toe8Cws4z7YcDadbwwbv7j385vD5oQp3EbMesrz+PmBAXobo5u2tWR27nBg5Yw6mtyZYdtQJtdlAhwTiu6ZIMzbE9hRrE78WfV4aYJ4C0yoFVGiLwPzdPeYEMwnAmFhYhtDkThPGJVLxOyE9SZua+VCM5rZ7IOkAbOX1Cohz8lvQi105xymxJL6mEMCR1Fm1RCcUTmtbI7sMRjaStFgnN00H5t5ayX7cEbZYw8xRwRFLEJK5RbOlR9zcH2WI0MEgE/cVCnDynRC2yFc0Q0W35FoNriZJ5i5mQ9JYQttQdjTcd9E20RAM/dBoNkcPaWA0HxJN9zM4wSREW3j9ECmq57fU/4hpBJmo1DMZQZLmKeirZkNZu5+cnxy88at995+//HjJ8vlErGBRrDwRPqfFqcNoz4tVOgUE7O0PzVUGjrDK1QQjksPtjwAzUV388kBt/j8UkZDLp27T6T2GfijDevD+gS8dfTOf/XW3/l77/6Dw+WR8YODzw5qYwVHGwB8be/nfnb7M4fLowGDOzN0nkDwaUp/40s1pI62pCFxRahkVNvsJbYtgyfATWQbJIlGLqOSoQd5rhoXCPwkovsMyQttU6N1TLEUmSSnQMAsA0WqCPGW+CKIEdrmUOUJDWXShaYZohWEtfwh3zOriRDXqpo0gZXDka6Vh+Odn+xzUBFMC2tUEXQTZyS0VaIq/GpoC9Ra+Mr0vexTaMuHzEKMjC2JB6lNoK2GA+Fc5pv8UNnTXciBhdE2nriXAweLlVRDSUkzWKGMTCWBxwfqww6BsOB72UEqITFMkLRT6CXvpc7Guipd3Inw9EM+ICuXkoiymNDaz5iXyq/T09NbN26ub25cvXZ1Z3t7bX3NhiE3ynqc/VQuerNcrcocNM8GEVkVEBgeuSokGlb3XXGFaFtGZkdUBWMV2ueXnGQ3PAOD2WALAL9x+//8/uFbv/r63/701mthtGcnIASynPv5yxsvfWnn839w8B3M2TQ9TA6ec+1Kgtgu8UJGXskPXWSAF4wWlpHxmXwkHK5H15xEY2VBURwzA8FBCQ1JUbIjI0tOrpOrGX7RcHqG6c1zYgrxCDRPEJJqzHIhSAyZG8E5zaqUm7+pnjSwekqsy7YVlTkUEvSkUKSeSiE0I9p6ycMlSJqWbO7ngmM02adoslZktce8ZeQZRD+BW72efgfBD43cyDWGoMFkkPGc4DOWLykJJXN0rmqsMKuJAEqkvGRsF9TYDQms6ZwpGAVkJ3jGe1PAZb6wxFS4QCHpbS5OTn7GcI0Z9UcpCZDrmA3jeHZ6dvvm7fffu/Hg3oPjo2NDfmfNsyuEL1wZw/zF21LBy/NWZAFGVkastzDLdwBdxXO5KWoZKlhjmUiPjXpeQYE8J37bGbe+sf+H/8Vb/90fHXx/sOGZstoqXoBfuvZnX974xMl0YpXWnR6WVVE6WylZTsMlksnYVrZVvZyEqFXKQGNDzHMmJkuiKj6VhJHDd/aVwd+ECKhMTkhFJQ1OKAVRT20nmRHpkBAfdAlvHeViN6qF5kKQCwmmrd6P8gtyQ9FGJLp1qijfYe9tu4xiWA9VJ0d1ETgaWdkih6PEpmc9JQbYkEbwRudFivs0jctjbUbMDOaCfjdBIO09CyPROWdwaLQweH6NC5OTkamSMls4R1oMUbRnv7UgSlQ8bOZ6WKiC1D0iUlwLQtykc3Bilr5FJcFKSRDagqSVg7ZVtKWSMEPbCrAZGxrH8fz8/M6duzfev3H3zr2DgwMzW4wjovJRuDwT5HV5vMbXUnd6nqcfu6+GitMdwdxeKyMfYqgYmitA5WEktzAwn577NGlz40+eK+U49+WVxe47R+//Nz/8u985+J6g9hkZyt0HDEuf/uzez7+x+fpZHu2KHCFBS9jqLT97R1vkohfzFaNp9TKEtsxMCYheCwSyJ+cAeoma6Y0/KIlqUSqhemsIhkA6QAKOgNlSxDEq6lw4zMG988G5niCXuOhCatKCu5KBzV2IMMN+6av0kuiIBWxpIpmSVFs6EdGdHqwFrRtNa24KifpS7z0QRLqZxuatWhJF5yISJSoUkAzUkwMyFPLp1CyTmFC9pbUHgZ1rLsnjLaMPVogJ6HFOVqn5gbqDXok4tcRNoi242SXeY6ZWIKI3mOVioNAWtDqzmCqShrZFeSkmZEnWeMYFtF0up/v37t+6cfvWzduPHz+xAWvjGppfPDuo5bA+HG2fLsJ65f8PCRU6+4eECjN2E7q4Vs5yxrPuMcPZdL672Hn3+MZ/+/Z//8HJrYDaZ6EbgJQ20t5X9760PW7FB8NaqGSYUZll8g7OB/pfvppG7mg7ryQSD5DWrkpcZAoteyVnSJjOdRH5EkBrZecddQmyFMZ4PEfghIpUxMFd4VgurpvWFw2bZgm7JZXuBh2bVl0IzYXwtLYraKssRl9FaiJehjRFlbOOcgJbG3AbW8yoct7Koqy04rBngsOctayibS9EukJtDdDC9mYQ2gavbLDGupOvDzQV87xVdjdxHa2KEfwoRWTooWdPYzISbDNx0cOTohbE0Tz1MAJmLoFhjra0q19E28y63AezwlsU2jYlQTHsCR+BtstHDx/dunX75vu3bj6+DWC0kWNF/+GjX/TjIk0kJkxf5SU91VeoyON7Ndd8UakXYmc2D2yGd0PbAFQTxTKOiZ7hYV6cTWd7i923jt75e+/+g+Plsf5O+LOjtAC+uvuVq4srQWkvhAo0i+C2xKJ0fLHdpiTQxLOYrEzWKomZksDewezYeGdbFFq7A/RMQ7TWsHHkkiCy6AsaniKCZQeROgqH89aKC4mGr6AtLohR1EaUKlZdCLPROlpbMUGmkNmiCJtSBYmfcg2YRltBRHCtiTRumx5+oQQpCJZvMKUVkndu3tHWuCJaHGOP3leEAw0viqkQvG0Fbc19iKo+ltHlRMh0RaWXiJkOFBR1JoGmgaUJsJYHZ9gEgewzCQcoryXeIxFXg7AM6K7bBnxb3kwnJwTS8QNb+UYYa5imJLBFpi/VA4G20zTtPzp4++E733vwg/f2348TTkIQZ3FwKYDiTMLikWiuTB7hipYVYtKM3KhQthUWPwVtUYgAOlOy/uw0ppc4lbxKKmEA8Nl0tjtu//aj/+9/uvUbYNL66DZ5ymUw2NKnL+x89upib/JlI/jCJhGcaEKAMmFrTkBKAnc4yECItiJuK7aVFOP1kkIzQXMmSdbYsq2AWMyfDaEu+NgMPSORtcSlqMITg5N/sAo3cinXhia9bIXWEWhmYhTv1Bs0X6/RzsQob23nTHD2UikJwdESRGIOeZMZI8afzFdKgtzbZ8Fic93Wxayd0H+Rwvds4dUqkddbj3y+E+KFttwcM+EBnMhJRLNFUkp48W+QCVBQMQGXOEI4cK5/VkV6oyGdwfJdWUk6GUN6vggHfbqCIrfh0Prx5L+R161SNJB51NpLAtFM/A7BR6Vctk7ZgYufj3Q3wzgOS0yPTp/cOrpz6/DuS1svfHLnpbVhTe/pDPcj1svOKoHh13N4AofWWOUbp+De0IG4ifZOxbm4hrWMDTbJ5RQfYVRA9hOjIRVzGJZYbo0bv377H//KtV/63PYbsc4fxRpPvZg7JwBf3P7cm0dvuy/NBpexIOsBFZBRlob7SKLlI2OWhga18WsiAi1fjRS9pD/KbQkHVovVYS7egAa1CW1WyySQMi6BMwSYX5PjhbPmqFnEckUqJlmuakDMuHMXisero3IhZh2yIM6UmYVPLfuYsjXqfXoaOyq6SRCooRCA0pScGduipVK7wK8EYyB/wmyE8t52t2IBrS7U8tVqyg7lb2as2J2YZLk8HPRAQWAI/Blo4ai73NyG6MEKqKC0Go44GJ8c6msy5CHNxkxEbiyVLHHTeKrTDXnwlu8ryIdf1G2RRBVm+ohF9JWkBCKtWZAYBa3oMD+fkZJupFqptwXzsIWNDhydH73z5L2v3/nmDx+9c7I8ifc07QP9h5/gykowOUinEhMXVUS1QkVJm7SuUwkoOZcmUDedqR7E7qqU6aaEdcuC1fN/CEnQJ8oM7gDOprO///4/kvWemXRgAH7xylc3h40pDpE3oQyQv2fmFywCLK/DhwH3iRyk4r9VLAgM6KRJ3Bb8On2U6ZS9EzdUw4rATgD4UQXJAt4W1Ak0xAJD/H2GjGCSuBlv7hw4I3wipSZdShKHonXdhdLfJhpMLuTlD6a2hDEHMLXSigkjmk8dmm3WMA51E1Ei+rn5E58F8SnH5gkNntQXJJPtyaiKbeKiWy8L0FyipTHrIcbJdl48C7GWLzELsZhz2lq7QSApxwJ5OkT00TKpQZtgBGWjiVlzZMMM4qFlbk9oBjBwrz/9wkQvKBrILZUE3QfBcgF6jKZOqDXRIB86JE9XpBDZSXF5ujYhFd73bYLhJmNqCZk2RSiPp8uz9w8+uHl0+8XN51/e+eTWYlOY8pNzW00/y52Ytk1mQj2RAp/RJQ3PlHUnUhq0xKtsL+9RWwYPSAQ6OgOMSRrS6RyWBDxCzQzuC1t8ff8P/9nD3/5L1375oxP8H3XF0nxt9ytbw+bh8mi0McsAxkbRlPxZRQwztjw63udTIyjhlz1xEvSsg5RyiD4FbexYtFektdojsSlJU9m2Bqw3q5Y39iSqTqC0eruAMJwg1mdCyywg7TU0jiY0KW674kIEJmVNE+mTz0zNhboRgKnBuoYLYhk7tcLbwvZA2+RxGYaTsyyrbfEALXjZZ2J5VymW42kVLaFWb5BBZB8tJYEbrXZUKy5ezrx6iFEtTFWG1HVBpyWzgtUaMVBjezCqK7BkT0EgNqGItPlEySsmitrQNiHRwXKNNEKu1s4P8C2lQnj13akHusiwoiRE1RXarRAFHW1RN2U2QepyWn5weOvm0Z2Xtp7/5PZL24vtcciNsp8EbXNhRcOJX1Qy2qTk3OUK9DBTTDYCgpVQcSZng8svpXlh7kasglwspqFtFC4E+VgMwLH8jdv/x1+69stSZi4XbeNpk087i+03tl6/f/4wbUZVRE7vbfqt+qYTryoJJa6lW0fbtB1BjFFA4yaPJppzxnyJYykAFKTOX6Vt845y58paGLFP8W8Ag4jVZAalXAizZxOVhbZigoXveIoLdQBSOJf/8I5pvisA3dGW+QOCLQVZjjzLUjOui+Uqg1II1HP2xNH2os3mnZZWOEdbzr2LP5UYBMRN0qmR87EyhQ6zZAluyD+DaFk9i+/lzpipXsy6Q8dqA3mjrYoYdpbbTpYbJazYU+kjMIS7Gh0w4kI7E/mGEhmMOKR8Kf9L+moObnVIZLCmJITVE0pidK5TYNou00tORhP8GCh9IeSCwQYDbh7c/vqdb33/0Zv3j++fLc9yowwukP0xaud06QwXCTuh0CAjiRXQDFuVzBWxaZr0sICbhNEqOct1ZpmYjzW2ykdLi6ATux4f8cQTOzmDHxz+8Hcffz1qhT9u7j/JJRn9izs/O2DwisQ2ZE5W9aNyjGrzfFyzmQ5KMF8aDyeAK+miADKgVZkvrPZW+9uKwY29CveF1x3phPnsiZQE4HuyzM6OWHEmDljeYP3MnU3TcoG1iYwWHckfxGrDK7qy5MQjJRinCxmbgF5nzYXKucgMalESCDLkIoozImNVQj9gqDqfKEhVJmimKq7gfI83D2eIZW5gFmarzmT7slp3oVwdI9WIuEg3c/09hUQ8r6QSB1B9NYF7L0KKEuQrSGwQSy19lDQRSSLLAcVTE067nsA0A/bJdJWIYmLYljqGMW7Sq1NJ4E1nqUHMTSHDkxb7bHzOJbL+9q4vAEFjbx/evX1097mN517YvH5989r6uA5g8il8JIbchYhV4Aiv1ZEXBl4NOt9n3F+UKxhju2fynCHZiOLceiD56ttWSA3fWx11FkGbIFdHrUYbD5aH//ud//vPXfnahOlZ/FUenWf4mc3XBxsm9yFH1eEJnF0RDdSS6tV8pANUbMv3XCVTRoFumrpp1i6aBiIIQ1cJR4EKvR8ztKIXz7gtKDLkRPgEV2BzUjQCq2xTXmCVRm8HxHhzWKUkGIfKn9NJnqosaTwXXUhgpDt6VSHKvvSeQuqEJYVtjE2yQQ45A8Q1lJn1TM5ANtrs0KKAzmErrZoLreRLMWIwOrRMvSN32CJxxLNby/FIBU20RUuWSCwNM7iWlGx1ZhwZJsfpARYA5miLDq3lo/AyAMjGaSfy3Hyb7EVptk+KEDsLJdomodZFWIm2Zgwkyy0vr3F3wjsOo8HuHd+7f/Lg2tGV5zavP795fXOxCaEt99cuFtFKra5Mkz6EpLY9u6QyQpGRUeGaSrnCSuFJM1f8VKjQdQTBTwkVMADm8a9QySGa2RLTm8dv3zu7//zac/reAzyD689s/4yTZWAGNOnlXjOq+lFoizZN0ERM3f1AjEILZBiYo616L4hn+AmYdLO/jZ3WMCQ+rORI+XKFd698wbc1D1CYFdpaL2vBk3lOb7A+nhnwWXumzaZpzRlieEVRn4a28NlDCm29yGMZjTHjWQhn8QqrbKuoBgFY2U8zM9PDqAk0660krRWMLiWqr0hr0sSotpotf2Bg/64YYikY2JJ2M54kyJnyEGxU9W50vmgbecH6g3mmIBGM+1nC5gr6ylvZhTyZgoDluUFVE4IKabURaTo0ieTCebaQWbD5J8Gb/Sehh4o1To+QkSteWpHD14bFaMODk4dvPX77Ow++98PH7xyeHQ02JFlGusZFJaFFsKfsmWcizQNWA2JFpvkyi0f5t1NvsvLS5kzdjVQosYzy+U0wjTthqZBandJTXQnQgXVbe3D28J8//F0g/5Yzns31ifUXdscdEPrLf9MsIiymov6iktCwGCAKeHkMlyOvUhJ0LAGFoIU+vcTmv1Up026z6O1jU6tWd1tH6hb8XYKYKQkSH9H0WL5PQZAR1ZQE+RVats4R0IWyKG4ygmbUM01FtmdDa0V3b+h91Tok6JlGjgELrSrUNGdUB0+iM1QMVDZSpHTpwzid5iEgp65oak1WXQjz0bbsmPg6GPK4tilWBECG3HxKjHNSdmN+SCjM+UnqyFUDEUETS+wS2kJ7KQbxMxfaas2M+kukYMquIpwZRFVyOPFR8m6hbcB0mzNYhhAnyHAZe/EoS3btIreZc0SD44jQYlgMNjw53X9v/8a3H3z3+w/fPDg7TN2WYfJU0VYmCucxgI9OmybDSmPHGbWYes+9TsT0lpkJB3TijrYtUKGGpDDJa7QyXBT5ovpSRxhtfHj++F88+Sbn+pTJXsq1sMXPbL42MW4VtI2kgHeEUwqVCjwCSuWVChXmZ2n/TbfNUjv2DcoKoryzRem2LZNiZjqhbdc0Y9WUBbECCpgvCiGy0DZvmrw8KFPyJub2iuR0MZ9ZNeO5ZTKnYedJpRC/AbR3F/KaZmJcowiJtr0hWwlRwIpOlM3hK7qt5S0uvDWH76kXaSgjsjnnpbRXLtSxpjCtrUWLo1mILWo7W2mo6na9Rg7nxRFU9EPJX9sRFLQA7mHRiwwglzUQ1uMJFCWgmtygeowbXYRAVnXcFgbfp5dM1QbrJJDmonSHYpLGR5KViYXlo3IY+X7P6XD6INX0tEbotofnh0fnR/dPHl5Z33t15+Xd9d2MiqdBz4wINGJkTM5cORgP8bjqQmeqNsWe+CbpeOGINZSJIC8aq/AALdXaMh/JcNACcPUzhdkHJzfvnz14bu36M5UOPrP16d978k3YQFaYhmm1LeSlqPnWNGQ4oi1nXPaRYyF2aelPaPsGzNj0KslmBFa0MhNM3t104glJEeasHIQGTUcTcdJk48Lkz873zyJQA82VnrlxhChDJCOZzgZ7igvV1EDclzlAwcE+1IX0htaRmBZ6jilTJEwEfcpw1D6+tpSKKuTL1jrqPiwwkIjkbXjeOC9hkrkNLcTAnLQSYgtWoE1RViznvowx5EMuyHHGfIiWA0RDk1eyzWD0r37wlgSVyIrktvGjMftadBUGzgmn35Vv52GIeGmAUnRMgThBNhmE1OGIv5vq7hafyCeM+kVMsARbPoxenGHQ300KHxaMb0U4XZ7eO7r/4Pjh1fW9V3df2VvfeyroaGHkymFQHgVM2aDWNVElwh/0Omu0KF1BTt8cVz9UYE8N6HsHs4SqsbUwsx7YBsDXbXH//OEPjn743Np1h+ffIXsG12e2XhcSOSYGTyfySs0Cto5xRRdaQ9jqe3IBUD/ElQtA39fJBGM0odaoElggO8c3C12gEBadUjWAdtQCRctKD/NaxFpDqBVmnDsBK8c0iWhJIRNYY2bBmYmUj9M2LV3JmGqbNgr+wuPHBfegczppppXTZlKcCAnGlKQdENhEouZMLW6OievQ9rlNmU8Oz6mlv+jMcpmuJQlOWWMzywPVsxBbINEyfGVo+/dEQhNmgcGWgUeeFTMxrY5cD9oHsyhzY/jGTisP5DoQkaFhKd15A9tGCugdAbAIoSBNicaL2U9QENHE+HhFPtYak/SW00kTmE8jrSBTQT6OcDQQasF/DIMNACafHpw8un/yiGi7GwoDowvqVqHSqAXkO0Aed/GJdQx5vbH0ihlOtY5ykbSDt5dWuO2HnlEX2gp5Y2wZ2AqVxbC4d3r/zaN3/vyVX5jcx6eklY96BYx9cv0lEqaJneiMegsVB8wmZZynX6uj/JOMOjYPZo6f5MHKxlU0zkC2M1wJBTPCKEInkCXi5EM8GWS+h7DeG4KeOtFZkdvcoSSwTIp4b59A+0nsceGtNv+FuysWg++okkmT9qmPgTSKEJahPRNJq6rkE0JagNAW4Rwkfgn4lSTEuDPetS7tEyJahm7tOfQCQEUfgAUSE1SfMl3nSna0RYKOCZtBGk60NeRuDQE6YSETh9MauaKWSCtKhaT3gNYf+TsdLhNv8f80Zsv75BNGjOK+RVqCJJ4tHT0Lt7SiexbDt5ade4ldTgvUu6QnpBcQOR+fPvnmvW9f3dh7ffdVHzCYDUMuuIaftLiqJ+aa2rAQmIOx2o4kQSFD6JuRoLKUYr6jrZez4UPRtqbZqRZgC4wPp8fvHr/HwT2r3bDn157LwGJ6s1kKYagYJvfRfkzAt6f89MdcHl/SmBVjOT4DJ8qutG5HT0Ws6o+4zwBJawugpfqVnqC2utneXAlbK7iifDi5BbhSk0+jjYqfp9nhxzWMPf03X/pEti/cXKHhNF65KFZMp7Zke/1Mpp7NIEf+xwnCSZfac1A0gihGW0k+JgWx3opLNgsxGtwXzHF00abPFBsmKIJqaqojhNlklcTbBGQW1AQ9q5tVbKt76VpN+aXmSCpfwFU0NZyjH551hpeRNbSBUEowzktTzqXVKKrWyiQRPyS9R39kLim5TIxidniMZ9mYoRY2Pj7d//b9P3LDvUcPTk/Ptre2Bx+maRIhqm2WhDN5n+s4PfMdMxrjzgVudAHIqVkZNcdCcyyBu14qKAdxVENihHulnGziCxvvnz08Wh5vjZuTTxWyl3rtLXYXtgbyBSi9ad55Zzj105/f/dK/dPUXBhvRV/fHuz5k9DHf33n89X/x5JsLG73sFA5faAsk2tqsueCmEtUKlNABegIoJZEALRTW3BlKkHv0ZVKtEwhRhGNh47/54r/20toLZ35G6PhjjPDhV2Mtw6mf/uaDf/728XsjRlRueIoLkUBIBVJdTw+/IJgk2uajJN2wrRUZIZ9y7lGZFIDnEAAAIABJREFUl3sn1Zy7UHcqhVKGSV8dn68IgAWJLLj8VqMkmXQUmYwBlF7gQjYuZM6FwF9ARNB0Yik5SC4ya1mxXKJLEyV7ysoFiX5nWkDRXYEmYDOLZ7uqxBUMrGdkaZObmkhsR1vq0TNWQK4uQ7UsEbl1gC2GtQenD9+7c+Pmk1t+fbmxvbm5uQWfpokHhkpIUdZNai0jpjiRNqa/pE3DnRjXLCcaPoJhWUVZWy0l52Zvuhq9bXZTKWeCjxgfnD++f/bgU+PLP244/vgXPX204bm16w/OHg4FX0ohxvdmJO+M2//Wi391eDZi8csbn/yth79zdXFliSVJidcYGtq6tz1aQKSgZ7JslK/KlysLdmsThtIw4Lo0euty485w2VEvioczP/vc1mf+xif+WpyZu/Tr3Jf/5N4/FWwpB1At0WTI4ph7WIfVTeGpzaA5q6uieY1jqEY3Mp/Ifi2Eje5dOk8ba/HfOdqWjN6yWl4Lox7cgKk0UCSEgOoGCZbGWKDYynRQhC0Ak8s4uW9YolEqSRbJxZAqq5IadW5J3+IAzarIowPZjMQQgbYWdy3wH7M0z1Kd5E/sNz3USs0S2sIL2kqaI9IWH0+foOqb4OzwwYbFMJ4en9y5dXdtc31nZ2tnd297e9PdSW0VmjRPy7daO8I+kMFcuk2hbaRNJnyhLd0aT0VbdrTCMqDM2fzPG9pitMWD80f3zh98Ci8rQi79GjE+v3b93tn9AaP6sNVQsQnTxrD+u0++/v7Jzdc2Xzmbzi5Rx3DH2rB4deOVvcWuSjVVE6TOSuxxk56f5SAuqLG6yvJeHWr0WrKOtivYlEjdWJQisthIvGU0O5lOvrjzuTVbm3yatDl6SaZa2OJ7hz94+/j9vXF78slLOuhJZYWbN4AhtPW3deCbzwiFtjRSf26iBdNf8FbV2gK2p6EtbJ7eumFXWgFYlJaaOANySjpGYlsaglopIQsANZ2mW4hHSBYA59mQp8lYVRczs5qOENiKPMuTTCJpZL3RjB7lM+1pFW3pzbOZZiqRequlin9XH6SFKt7pAFo/pSQ0mg0vgAoEdLNhHMeT49Pjo+P9J4db25t7V/e2t7cRaFvh5dz442BJWzr0JW/PnOQlYbhKk6oqehKWbiuJakY5yDJaMIOIoOqv0HZh48OzR/fO7iMxQpXXJVzG0Y42PL+4PvkEWzh3eBqI0OndFjY+OHt44+Tma5uvLGwBruhHvJy88Mpi94vbn/v9/W+vD2uOyWbukGPiOcSkVRSAUF74tExGi7PRPJIjCDva6iFsq1f9AjaJEtLDDWd+/rntz2wM66nSXhLOyg2/dfDdhY0TqCEqFAheXcW6gLarSUXOqVgwddjRFox91pVlR5rfvTHmOdo26aZkt4Q/qJkTMG2l1aDAqIMdSG0gYi3dJNAnPyWVZ+kt38GCPEFeRVuwOCN6elcbTdQycFcuY07imBtmgEfCce2hIQAkT51l+FLlJ2NM48fB2yA1HLrXTSNueM9kHYLSAfPIRNR6gd/MhjClGZPxskNLYFQ8BDTrEl90xzDYOI6np6ePHj6+eePW++9/sL9/aIMNzMjhrPn/mTuSpHPluPEXx7UNdWLbyap5vjtFgFxvhmjOj9q/iKr2vkwN2buLP4aTjTbuLw8en+/ncJ8Nox1tfH7t+pRZwTgA1iW5vBHQ09qw9o39b3EHBpfLsnfHna/sfuHUTwcFgeX2V9CGANZgsoLg3JTJlwDdBlCGrUVvN+OOk96o5qgFRb2qdYlXa0H5zFhcO5vOP7H+4isbn0QHm8u7lr78xv63Bhu7m7ViyAX6hNFwSyWbnjY0IzXsKuqKoUDNDXnQIcMjX8xbhGDnohCTTANuWQ00o7GESvPKnuGEC9RhIea6VBvzyRYDSgw0aZ0KnCqSgoC28pFJ2XhiLYKWVTRTUZ4uJjrXWColBe727qXMpB/xJUgBJSKDaKtfAljl7XU7y4YZUnOKOWZjycdpgxlF1KCNRmcZmtAK2dzUKB0IBgzDAOD8bHl+tn98cLSxsX7t+tXt3R0mT0Jt7tRJdeb0WImKZKcyVLygzdMzK+eWLFNi83Lxo+5YK2UdLcg1jNAdbDieTg6XR+z0x4jCP/k1YLi6tjf5MozcNg+7h+adNVv8/pM/PJ1OtsYtdNN/hCsQdPJpsOGLO58/93OjUuyQd+jDY9DKNSYLZSHqCcVNvZY15yJk5OV0v4Se5GFNGuIboGXw6tQr05udTKdf2f3Ci+vPI1nTJUPt0XT87YPvjajjjIoOlI+lC3HuQlsT2fd6v2bEibSMa5VLkgSE8UhrU9OLOlAncGlBt1oRfbhKHRnxlM1y0TWjWpQF6lMUQ/IjknmBoDgti+EEEIa48+AtR2bUUAttdVCbSgKJZ06g7C1eJt9MBGkHb1dEAh/axya4oSc/TbRV1+X9+XXiZEA52MRK4Za6yr3JoSowY64UX3WHDQk4Dqobyn+DcgCjpcN5GgCWJ71smqajo+Pj45ON9fUrz13d3dkZBisNAJlBoGyX1ICu0BYh0T1WbtJZYyDdjQlLJyMqE4Ayh9KDtx+0QFWH0d0mwA+Xh4jv0fBuz0u7zGxjWG+4MWVEuDFqK5kubPFHh99/vNwPnL0sEDGuwifXX/zUxiuPz5+MNkwzFgmBahOwhK3Ieik/47hy1ARyMaGtwtlI03yOJq0At3ZfjXumFA10Mzvxkze2Xn9+7bqOBF7Kpcl+5+B7J9NJfJtl2oGD6nOxnCMFjYQwlzXI2OihYOQCQsCybpkO1ZDOTxKREOL8cKX2vRMFo60zACsivC+JkkGzuQ9mwEDak3UOK17STykL7pWbkTQ3fCSY5RA1taWXsK1TP4x9rSiDo9IO7dkqMAYYTKU9t7yMICrd1cqJDQMA5B+vQRRqbkQMVtQklOLbMQrABziG3PTqeoIyEqWTmCFMkgDViMQlg5kNMUy+NThh2IRqydAlA8EBWLlYcdYckx+fnNz+4Pa7b7/3+NHj8+U54MMwWPkVurTEfE4cNJ4YNLhNKczAfbLUcqivs0zx+LCHCnD+4RxvcS4PjpSezNe5KHGuZLRhfzoEEH+k9hlda7aeBjRVnJPTZ6Hq0t2BJZZ/sP8diLRcxiVIur529Qvbnz3x00as6ICVswygd1uJBdMk2mtSu8Le/cNbTaVx5F/BcbE8a2gCYJ4a0w7xh3O8kcQEJjN3X7f1n9l8HcASS8pel3DpOV9/8i2kY+coV8SoKYftLHGdfx9IQ6VKxuwiMfSCfSaaor+kVgmUqY8yBuAU1CYPrTDkUmeQxQ89xMhJoqOJi85YAAbyZCfEJ47lYYgk2Il4JnorjpukLsmdF9wbGtpSZHL5GoyNc1Zi5Yk+BD3KuqShIXZJsUnZSxCWQJ8TcLFlObtj3jE1CGUIahQMDOSDmYti9IGGM9D1xEs+TS/FuHI0ibYabz4ebNQ8iixA7n52dnbr5p13337vwYNHJycnAIb8hAPA1JznU2hnS9NlLDG2UqJNVQq588dCiuQYZLwVk/JgOVZ05CS/HfsxYDhaHp1N55dbe65c67amXT+xEfJCZNpNXuCG8fee/MGzGIa7X1nsfX7ns8fL4yGdV4nnKWhL3RZzJhuyYCMsRXsLbVF1sTf1trTOOdqiYZPxnQEKLrQ12Kmfvrr5yqsbLwMM0cszTvzwjf0/ICMQ6YkRJtqiZeuVEopakHe0JVzP0BbJjRLHiddqWEzf00YmtE06qL4iMnTsmQtC2NWirNB/56I7YIukxQnPCbUMslwSDllHg4AUS9k2Ka/IayK2RAYASuMigDyimjCI2VEGgLIEWX1axkBpBV1J8HQ6ToCQIqDtmm8pCVmhWVJeON1XNMiYrYz8l7KuynLOPhqGY3AfGeqUj6B+C4hRJzGOLNc/J2jUvJWWzGw6X965defh2trVa1e3d7Y2NzeGYZiWEyjDOg3FWp32Tr2Yo2tKnhTu5EXpWjJEJq1cFzl7Q5C8wTKNTmpnfr7Ecg2LP3ls/rjXmq1FnOW6WB6ABnOLtDGYDTZ8ff9b575c2KV9AXms9YTliPGNrdc2x43Jp1YUd4VUjjVHiDp+KIxUFMRNZ6iavFMSZDXSiNpNLl8G2lw0ALM0BhtOptNXNz75+tangIqOS7TS7ZO7N09v19gi4C+4kABLkut8RikLqDYFo8mb3TCvXOmZbu09jRkkJKjvoCs5QNfjjc91dpbF4Hy0GlveWjgDOIFPy84FMMKKYCJgoTSI7DbbSFgBjxIAK2jLtxcLgyyFdtSgjzf5LB9HLE2WkoiEkBRQfDlgltiCXFEqp0JPgrDX0dhkd5xRLQMqhNPr24yITKiDU0R8ZQMBGtIycsSWESkHgcICp+xuZuM4TtN0987dtYdre1d2tna2t7e3h2Hw5aQoFbNttaHs4jJRTie9OJNsrdlFoappUgzjBFY6sUbrZlj6cooPpEKTu+RrfVjzWbJAhWXOrUJlgN0+vfve8Qc/s/XqpY4iF+iT6y99ZuvTbx+9F6OSb4tYYU6m0qngLbzCswBZHqXbiu9AmbuhLRgxFWy1Uom26QGF8wpRX/rytc1Xdsedcz8fcZknusIlvr7/rXOfGIDOPFiUir7q3V2dd+Yz6m8ToummgZZvuY0kCGJQ0M2GyDRdo0XI2EV1xJtagXbyqRkWADzERPeWROrAAGE6a2Bn4QvJCgntmW6cgSoqlvpCngMj3Uv8p+wsWIYwLQ99gsdiStxMzSJVmay9mAVd5ukfOzMW8tRecjiNmJF0KjeErFk0s/gmGvtsSgJxPrqKhWIpouKwFAAzWpdBiOg3lBfO17IOdiG2ODGAQNv7dx/c+uD2rZu3nzx6sjQfx0HO48gqX6wq/R4FP7k0xNY88uIpKoTVS4Ka1cIq3ChbFX3Lrgy2jLPu0Cwv8wo7rA1rYjIUQuCzucWSOT3df2//9/sTLuUqnN389InnVg9onK6QEmGL59J0oJ6VukFiFOpwmOhtUwdW9AQQpb2rFljFevWbyeDcl1cXV0KchTD8UixDTviN/T84nU5BV46jhblcCXdGVaGPmaxr7nuYOZ4RZGe2jeAW2yCvn7VVBT9XbwkMrFqjNXlbam6pb8bjTCtbA451ie/5tlW0DVR2xmZQVlJJYpDPN8qSIYV/cyXNGJghrLqZgJxMEKyUyTkIbCRlESvRvWV1HfDrJTN4oS3r8pRozaWRGrS4CVzSeJyuxXmwJGnI6enHUloTgFmOWPoMbzI0asW8XhUmF4lVikmRlBCf8jyZT+O2AMbFYlpOjx8+vn3rzq0btx48fOTwYZTDJAcvhswYi7TMdc8HhjyVhNtJouj/BO/EZU/ocjloTILaHwx27udLLC8rYp96rdsah+YMGiYLJ6dlCjNgieXvPflmWvKS0CSec+7LrXHzja3Xl74EuYaVNYS2CmYlhbyS0ZiwtXTbQNcgvHPdlkOo30y6rRfJbcjcemTE25mffWL9hc9sfRqAZZK4nMu5WfKDwx8u+U0XwXG95XY5IKEQaMBHpzWmENK8Qsx+czWT0exFb02vFNqaFx54e7lJflCNChPaZoJMNcRV7AecAIvc8E92mMhG6pLHAFiWGF+MXRMukfMZrSaXcJyks/PXpvtxNFZ1d1MjKfWFkkCJUHooOFonc5WCnIZkp13ejce4yCvIOXNUpRpXGZEMNN3X2YrPozcoO6EJswFyrAmZsyRiwzLNoJs80oqX8NAUiETfpyoJ+4/3jw6Pnzx6srO7c/Xa3jiO05KqrfwkywqjVNfYkDEUU9epncvIsaSMKvPCQRPBjcgrdgZgwjRdXsQ+9VpgzHyNXpVEEs0fmUQdZj7hu4dvRml8iRKkjPfpzVdfWHvudDpj3UbqkgZXNkILckeZjtZlguAKCTSsZUZLQudOLoFyOYKsGjYshlROuA82nExnL6w//9ntNyafBpVbH/kK0WCw4TsH33+83OfJE54gzGFH/nGNODTM9HpmCPqqTPr0abLS6hTVaOf8WeuCBC3aMX+mgpZGk35Gmwe3dTIVI5ur2HamSXPE4aPAxEAsJ23jIR+OrpXAXUlgi1RJW6mS4ygSbKJFfLQKZGV1Y/7iLk2OBjqyQO4egBr0OASBLB1IVClRIMaboMWiQ0pCptX05XxUp33h18FBE4uKw5Iwk2mj3qgxy/lzrqCakY8tjyS31X9LSeCQpSSA/6ygrU/T0eHR/bv333vn/Xt3708+xd8n66c2fIVCpWtyCWDKztnQs2RCEnnPLCtCm6CbjpK8HQAwYhwurwJ96nWGc82l0o+R2iQLId1wDLDD5eEfHnyXueRy0oC7B4i8tvmpT228cpIfDPNOMwmsUDB75oZiUqtAnGhrOhATNQblBTTYzRJHyCzixsDM8JT7xcDNzDGtD4tPb7wKYJk6z+VcEg2+uf/tw+XRyC/xqUhORko8oLch6ykCYM4IjXIqWGuaYH1AJaELXGKp/WY6LasxZTL0IoAkGlISoqJl9RkkNiE4iJ2nbufhcg4zG4SdCV4iqEbRwQkcWdESsng7UCiq3IxqA/KYTbJOSrPUABxE6sQmr645RBoeGFTY66kmqBqsfCmlH0taSXocgCFEAOUEDNQfPLRsE5MV7aRDZqNszd4ZAmZmNkCoa6rCjWirl/SvQCjlODCvxLA72rILyg3MdEU/3cyGYXD3k+PTB/cevvPWu/fu3j8/X2a+S1KcEUjyKi+2ckdLtI3E6D6lwA3WEJlhU4B3FNo6GCSYRhufxZ8WT4uZATidTsk+MlQ4o0bSveDfMJxOZ3G66xKlg1iRyafXNl95dfPlkxAiAaQyiNJdUNUuTZkvTQkExTyQTCwIXyppRuVm4hZj0xOQeFSFl80hwx0+sdPwsxBnP7/zZxDk6/JSY7oQ8IcH3zlcHsVfGHEWx2RjLOMcDpuinkvCKMEqfVN5S/UzJyX5W+/JZfcE3BnaOgWcuX26C4mCFNqqrWrKpKQZpJm4DbxrAHwB1vAAbCB9TZxJxM06vKFjMpdY1fhQVQ6qWgwUGZigmbsSngoAMVMhkCCOrFTRzkE5YIPleRMXYXWLoZvl562c60KOSFZAxAWVCHNwAkaMi8XFQLQlW+UkQWCxnJUzzpgLWaXkijtnApZ1zchsUMsWc+aASYVj9cJsbj7EZ8tarVJ6gpP5ui+Xywf3Hjy6//DK1St71/bW1taGYYBLQ8reaCKuMlg0qVLKyU0s9kiPodGm6ZE+Fn/LyBfDQArzrFjtqZ8lnGjYyXqs2DrtFKt5PJ1848m38HIA3uVAbdj/fDofbPj05mvrtjblyueIxB+lJNDxJWYBDH7Vy+JWKLRlynQDJh5CwJzYgjPL9+fUi50B8Akwx2DDuZ9fXVz54s7PxkQuyyaBnAtbPDx7dOv0rhGpkjyBnFtGAQvT/E6gZAQgdiZ7KxDkytMh25/24BjoBrSkUDjRaKq1sMZ50RK2okMBEn/mIQt3YY2H6+efyCm4WQBt1rEqak/OkxiXXTkoHmRpX6JB5hahLWM0AKBt5ogoZ9GArCEyvXqBeyCPQzoOCtWzhOJszWTLoN1pA+EcYbwYI5y9pcldmEMWkhhY/2RsOEGW+UFKN2VLYT1MkZXWYVCRjw/JbBPCTA6m3rvVuYuXiEswXkVbmFZgcn/w4OGjR4/3ruztXdld31hfjGOkXi0cZ94ZEO8SpbIYkOszUWZYywPoJxMwYIzve31WKAucTmcKIdSwcyCMkFg0Vwq7dXrnwdnD62vXJtfNS7hisp/deuOl9Rfunz+Ms71O+Q8VzMoEaOyphUMOPi4tseKtMaBUPlKijQbG5M+buapaVgFNoMPSp+fXnvvE+ouXe6ILzCXfOfz+g/NH47BwKNDTZ7hKHKinRawhVUyPKQBkXaoGlKuqblD/HVXBx6m2cbqtQHYlHaJcSA0zelUQNDBIlFOHMZSBhTycMJP4QBnTKWNGUa8KiD8lLiK1g5QAnEDM0p5tTTU/s5U2nlgNseyHNJfScV35LcqIIJoOVR0sr/IlUHvWQS+JA9F1gizxWsS1MCOvQlwW7QFzXJXQIPjGtH2W4UaoSt0hdbbmCwGzaY1U3qKUyvRacZY2ZKSu6gkFxF5eHmICgEcPH73/7o07t+/u7x+cT+fDOCR1oPBNJaG8k4OkbgSqstYK2F7mBlYkkZ/WbC2+hPDZXad+ytVKtKUA0kMlppDpeLTxYHn4zf3vxCAvayRJKoCf3X7jxfXnTqcz3Uyjxdug9KZ8gFbzVrVLEUZeUHwKBFmTqzc9gQLuTLftLFDYEVrHxrDxhe3PxnsuEWQt/yYbvn3wvQdnDxe28DbT8psMDrCKT7YuqwkVPA+S1IxWuG3ECjNZWLuQxHWDthU7ZhMJEcabxrQkaI6ov6BCkM8mb82NFXf3QU+3XDpjnkjJMv9R9CP1OJbtYlrJYkUPYzwpFIPSUUIgXIcNiMhEIqN11Q91RWRSSNpWC6WWMXdnnhfaFmGvmitsZZIogquVySx1GQIrrYNcyewz3p2cklkl35G2N2SqLbQVAg8FZMhyP3EzExfzGetCQKQVRjO07bJKZtZkeT5gGAYze/LoyY33bt65defRo0fn58thHM0wYSIlpSdnh0UqTPilEJgJucYYz/dN7tvj1mjjdKlbKyvX2ZT7YCaPz//OQkWABfjCxsfn+9/c/zai8L4kZAn7n0/n19eufXL9Ex4mzfIi6yOirXgm6wnUDUGtaBqnAOYPgDpephCxG+OWjDMKskb3ThJjTWPaS0w749ZXdr8AYEjGeDmXuwfB/+HxuyfT6YABXmiFFsRkgDJGMBHSn/BmLzpmWb9JdE2CzEeBPKb4sdAWZd5q2MiCAFoE1poL5b/G8dvKoiRBZGnuBrOFyR6CAJAEO5mqSf2K2jLfS3qeyMpShyVLKgNANlW8luAa4RzQKnwutwGsmBnzN9HN22uux7Fspn8nsGbla2RtUM0FzSUxNbHDmq+RwRpFFPIIkJWEgR3yeZBDcazxgqPZTnzW2I2XOpIFjNNrTJZ2mjrRX3q1EpCxqQQjOp02ygDsPzrYf3ywvbO9vb29e2VnY319OU3uEzsmo8p8Ps8HSuz0d2M2UO1msAnLnXELwAQfi75f8nXmZ6T7OUtGF5jK6aksUAzDqZ+8efQ24rvmLhVq44fPbX/mtx79zuSTKX5mlUkbbwVtXL26N0mNIlaYvZrd+qpLJ9uFAtGYA9MLKPaYTb7cGjZ/bucLPTF/9Cty72jDD4/evXN6d31YD+8QCHZJtHsXQNfN+Se+so1XdqEdwwPFbQXcHW1V3wiLkcPQ23zFhZikoUqCFFiwXin8ghABYhUWznyXCc+Ei03GTGJbRuIKxdDY2DhcoW0yTMJ67EqbQj6hrcCJGxW0jQm92FpUlaW508CFttmSSQLUHXkzVquhbaIC11qkucQAlBAh/Zaor24FjHIGoJZWPIJ4CLDia1cCfXKaRFSuDRppYYLMoTHvUDSQpzbzc2pE23EAcLh/eHhweLC/v7W9eeXq1fWN9WnKTW+rPTmCNt107pqFthq/pesM28M2F/uPDcyf5Jp8Ol4ex7PTSVGj7aFCtp6vLmxx9+zeW0fvvLH1+uQTU8VHvdw9vkDuizs/e2Xcu3d2f83W5niqYGaGLqUvcNQY58nH0QK764zd5ZEPLBwTdyrRQNEGOhm5wmubn9ocN5e+vMTDIWa29OWA4c2jt2+e3F7Lj5PQFpVyvN1rP0GELydHypRnKoQAFCEzqn4U2jYXrFzlM59pJTnmhi5rr6RDoS3EkTUjYy4dWEU7lUpWGoAJmCOMnLudLE9TSTCKB8wtmZ0IdAGoyXgTDDB7Cl2NYODgLykLMK+VbpvFbSkJwVSZBKOtZKtUArK2ztGUbuupJKRMms5eUZcmM/JKShFZByLHlOgWCJOYSw2jQDXHh0GrXtHNbWE+nUoCqEg4RYVkC+AxHuNTsjZoSkICMZUEDTWVhHEYhuHo8PjB/UcfvPfB7Zu3z87Oh2GAIc9yySOoFSuuIxjS/khHinWC+eTTpm1sj1uc5TMB2gnTw/PHZhZFemW1DIwoA6vQRvIRX7PFvbMHf3T4/XjIJfLZATb59OWdz+8tds99aaBoSu6jUYWSQG5VIjIa4XWRP0q0VBJi5aXbgncYiCa01c7Hqm4LwN3XhrWv7n4ZhfiXc0l/eOvonfvnj9byRBeIpx3d6EJdDkyeGNpboWiCkDMIcnqICKaTJvdkRzJdgqZEVcvlmBlw3kQuVElayAu+2lB4piRERwMR0CTwJDcFlR7CRSOqKbcGAnLXJkUWY+Hq4pEctgsxAz3y0GWSWjpFzocGTYUzAUS6bdIsZQCGVq6Y01rUMT2jzvKAp0mascR41yDiFYlUlq6QAJcTLxy2FHq0GaVO42ektTraikfM0Ee+lIvlKWkTba3Q1mUvo+M6NZMSNLpuy0vOCNBWwDAOZnZyevro4eP3333/5o3bJ6enNgxpsmDGmb6ymqlRM1RYxoQFsfTl7rh9ZdwFM/VlBXC/lj7dO7uv77e1ih90SshIhvjIwhYPzh9+9/AHYfhLFCXNbMI02vD65qujjc6MT/Q3UtGI0uBWRnwUyQVJuhif8f0ruq3YVoZ3425CW+toy/wMpKQzfnX3S7jUXBgpfWGLg+XhuyfvjckNCuZQZUdxSY58hrYRTEnkKJYWbwox2joNI8kF44TEE2SBrGyk2ybg5tib+S+6ENU0F4ZoXYS2NH0m9aECGfBhSMC2IqsQZ8oQ9sQgSgORwcXbuFVOkS/PFIho5dPF9JKGOskbbKgnCxcNaGiLVJESb5Ke5Uv8yVuhXmxPdJoqx5Dm5DhcuDI03s+oDWMQN0mNkzO65t0BV/BmboPlkoqlMzSRQJ0emk3BeYkwEm1zZWzIl5ijM91RzJijrRsMA790mwnRCm2HwczOz86fPHly450vsKBjAAAgAElEQVQbH7z/wfHxCXmXGybpfUEwjMHAyktoAvB7SZ5buw4lncu7hNpLX949exArjjaeLpl1lpGhQlh99/jG0fJ4bVhzXB7U0uG+uvulzWFjya8ra9VoH1UMe1JMEjqd/LcYn9CWM51EmjqDm3MuAJmSI3zM4M6/pexw+O64/bPbfybfeHm8Pgbz7vH7bx+/vz6sO6bwZMKc0W20ZBGvmnuiLWl+UI+EmfS/0MQCbSeH25TpLJMJ+ZIqAxmZWJ0r5lO9YcZwO/S35au6gTCdo13xvVj0BeaigfO/ILGdmZ4bLpYlt0RNA/gxB4hSx1/CoaLqlOyceB3GGpAlALLyDBzi37UwZ7Zuuzu5QgFG7u78wzmS4JLbRRUrkM2Bxnq58Jcfc4BcjyoI/9gERFOTulLCcY4H1IsS6qo+B8G6LBNWB0sCMRf3IQIhua1Ys6X6Cu7uwWGD9jwGAmDOed4qNRmHF/4Olh9zELFlqObHyaZpOtg/PNg/3Nreuv7ctY3NjRATME2UtsmJJHYwPGJG5768ulY4+xPE6odcqnAnTPfOHgwYBGSM21ASMrRIMRjSZg5ft/UPTm6/efT2l3c/79Q6P/rl8JBov7r75Y1h4/j8dLDBk3OYBu+ro4JjoowgX5RVXQoD2bogdSILNt7hynBRSeAMVQRxg8Tx5Z0v2KVuBoJ8FsC7JzfePbmxM2xPmAhbnHmDuYIYFnnew4avKvZdUSw8i6dNzhMe6dj5epRxOUNn/DUoAQD9FfU+Hl2ZF9lEyTJH2IcdSylXXHD4GTStprUKWKcfWOVVwg7pcfqPMUeTz0JZKp7AufKwstE+xv0bYglrTZu3TZ4LiQaZITJdoxuo0DapZS5tVvBZqJuSSW3W9sMvacFG7tOiVsvOOl+klEsJpQpxxzpCwfWDOC4Ng6xHLLNBdhRZEc6VoPVyQFkucPZdSfDMAw490Di9CE241oreCIcfHR4dHhxubm9ev35tc3NzsbYA4NMkzHDNKycTwxjOcX5tceW5tWt4Bpe457kvH5zHwcwkIIqZHrqKbpEjB9aH9RunN988fvvLu593dxsuB2UsGeP0M1uvXV1ceXj+GEzcwk36aZWojdbJh2cwRHiy3mpOCfk7C9s52uZNeThDwb+29xVZ9VKgNtYittR+ePTu6XS6N+4spyBdyfXELjlTb3xEdCpNpIkI4JLIG6lcFc+5TcMoz8GQDHCTuUxnLHrQC4iGnq6XrI0ESU7ElDUw06JoLoviqzVQMJzhdWYIEAwlQKFFJFIAmvmCUZ5GMFVVDIx0ssPc0GYDbixSmHHCdv1CAG3QztMH6ecJS4U8bBlLTZyyhBnWVTQmBbX0goLcRE6dTXNx8NYjkijMU6/Nk14MXjEVpTmV2UpShH1pBfFCJSJXquIi0ZPSkJEl6NKmwwlC/xydzMvloYnM7OTo5MbBB9tbW1euXdnc3lxfXwfg0wSVpq6yJPWfpS+vr13bGbdj0/lDA/Mnvx6fPznz84UtSAs6FUp3nIcKVPEtbLx/dvDW0Ttplks93RUh8pXdL7x3ckNP7kjBsEQfsLhqQ9tZ2PPOrNUcqWuarcdC22zKqQ6wn9/90qXMui6Hwwcb7p3d/8HRDzeGDR1S9hqJkoephNdNopW1GkU+btKmknYwShgYIihEWwYhmHLFIbsmazP7GzsqM66kQKGtzYfacCSent/zHbVyUioxWQA8QGVSFZy6rZEAeuGV8SCJkgwJa2rW1GSd4y6/UEoiH+ChOc/HSulNeVCu4pREERGus005ilhFT3kz+SQE17I3FUxWnU5zBB7Go7RoUkgtt/5kQTTh2jhcJFhT+GD7mXMa8TT78pmmA9k6wTJGnWJFctwoLSwkci4HwCxiOZKEUcnVwtYY2vxkQmzq2jiOxycnH3xw6+YHtx7ce3ByfGLjYMMQymYGeR7awIRpwzY+tfEygDhDehnh+5Tr7tn9OLnBlNUFzVLQSFucvMkNNrlvDhtvH7135/RebFhdlkTrPDvztd0vL2zITqUFUTfIu23AqECNWBVddb6nGq60MoY6jZAllbdWK7rt5NMrG5/8xMYL8euli7N3T+9/7/DNzWHDMYmDNW4Y/4YI60RbYVK839mKccgFRbVKZ43KzUH6k06QERB7OcGFjJ0y9xg7goroFRdKgpmWVLlKZl1YnKHZ09vCSo2swqYyDzNHOrJIwlxJIN/Kt1H3yQU18mCnFiiyj8RJZvVCueKryGLDZ30VP/MmMFiuMsDcZSzDWSRFdoALqrJf5nnLhMp9sjSw1cNj/tkz7RazpXgg1slZls0I4g5+MVJz7ZJvoPSauRnW5l+rIU3A6JotmYj9M3kWtResgnjbkpOvku60jZvZYhxPj07vHN7d3NzY3tne2d3Z2t4CME1TkhMAGM78/Pn1629svQbAbLhc7U/GAnDz5BbZ3CxUDOpPRbTsL6iaNob1t47fef/k5ovrzwcFu6yxxRJ/be/Lg41LP4PWVcWZeNVsbCDXM41cbIREr3gfSlaWpymplE3kpdlBQoktffkLez936V+opjTz7smN22f3Xli7fu5L8lOGANfiwtjil9k0rannc8qZ91q1ntbi/g7tnaVzPYBR1WtCp7XBpanBgPiL6r0b2S/MKJHagCG385PwJcMjKU/hMn6BX+Bbllv+c77FWUApWad92NZNxxJE6MuQ1CCJcE6VOwAkrWfaQAUL5cra0Rc4tTrxYXkCxMgWfFaxGIlelSZgooIK9+i1s1cjD9dzmXJmrypxWlXmtXaZ3PIdmn+w/SgJcuhmsnX4rAFtGZgCoiSwNJYZc10X856Ktv0omLgtB+g22DiOJyen9+89uHXz9q0Pbh8eHA6N2xp86efXF9c+vfEa4qTwJWNsXW8dv0MO8v+z9ua/kmVbetBa+8R4p7yZWZk1z3O9V6/fe24b220juy2sZjDITC1AGAkQ4n/gd4TEbyAhCyRj6BaNaCP/gDHQ3eAeaLrb/YaasiqrsrIya8iqyvHevFPcGxHnLH7Y6/vWOpFZr7tdN169qrgR55y99xq+9a1vn4ggN8mp4oYFyxDrc5NhGXx58vXnxzdwwunwWUEZOD8898z4KRDZypcNyRI0CqQJy0DLSdIEDu4rBQr7uSDFvsxMtYAFmS2aAQoXtvz+xndOq7rUBzhEmXfzy4dXhjrsLE9DEiRJqiWZ2zoZz4IJnxD71Ffa4+yZ3vqIFOIIJPWRsypczxHDNZpsC4xRDMTpacJ6AZn2fwaqATIAf+yKxc1BqV0mZ6qsjJUBsEvC5zjnCAi9QHgVdtCxEGCeAqR84upn+DWCvBpbEAmKqkmnylln6ODNr+KhKALdNkQbPgNHU2/5xSE4Fi7g56SzgM0kFaUbKXzpPrGMQGml1WSZuWLI3ihx/wdrL+4xMLQS8HtPtxXgMroDoq2boQfB4uldObWzrfrh3cV8uTjZOzo6Go/HW1ubG1sb9eiTbn52eObZ6VMuzqbEOsWHiVydfYqiKdh5UICR9GkdtBb63imRXZ1db61ttEECnsJceZ0fbHz3yuFVgTbjARFVi3ghTO8HmRQIr3HhCjgm+jDu+0pC5DzxQkRUpRObNJMX156X0y4w9ZaU+8v99w8/GpVhlwi7pTWiYAiSFogRHAetf4CawD7gU2EfTcdUyFZx7EE7K1DTBBCQs0p848UlMNhQ+iNyDngirF4gTYG21YlFwJHqnS5Yq6k4pU6VKNr9ym3dqAJB0s/Cp8RQsz1hXdoV73UFXM0/mVDvg3cFxUDtBLIDxgpeXM/gUOpYZLwBFoIh5IzQZhV33SrwWQidVWsE9xTBgUry6d7xYkAWK15qcIr4cnwGFnPv89s0EOwsxhoXZuNE/A5Ir3jm1LeamwqIR4u53uJnKXRbAx+KRsSNbTCzBr3FekPMdSnTpBQtTWmX7eHB4a2bt7/47IuDvYNOurVm+vr6yyKSf7TmFJMZF+w+mX0q0ZA4Z01wk5toRxw2MKbaWTctk4+Ort6a34kwP7XpmYj8YPO7rXRSR0ejoi5e4W5ugYMAK+CziLrIbaBlYqmgTqkxA4SRxrFTJVVc2OK1tZc3Bxt1tqe1cLRasrvY/ejok7EOTbpa+Sh9ipDz0GUhaBq4LcDLcIqiToRDiW5BWKPQ0j7YmEgMNvFnZypAMr8tHzvjXqc5PfhIMr7zH8t+Q9kYiKvENXWLCmU8cgIhO8WuGJgfEWCFb2H3vkfn2Geb4o6DxMvqIit/ZyPL6lcLG2QUnxsgGDqNeSVA2THiCFBL4U11lDLBjbdefFBieSsYWZ7XBkssgnwPtNL696YJmn/3qnGpFupB0F/Kb2gloPQCbUVwKldpeMsvZgYeK+hiNHzqWVjvFvbp1shJDLfOhasB1Lp7FJYyf4UorNp13ezoeH582+7Yixef++HGmyLSaFPjwcJPp4ZlX89vHbZHvk7TDk1Hwla8GeQCrhM1kU5sWEYfHl29vbj3+PhRpP1pPl5df2lapq20cJhb2wkEdmXhUXRUMRMy3Op5aBACZ0jXp3UCPCX1i7P8XZOiMu/m39t4fa1MBK9+e79QNBCRy0efLG1JAAAghsSB9AoIyxRVIs8CW6XXmjhGS1DO+rejOdUuJDOAqAonqeOuX3iePcKOm002so5EdZXbis9WyW0xNynhZ/JCsJ+guarFJ+YlhugQ1Ao0TUq9s5+c08XQ5Gyu1GuKS4dSnFu7cmsFqOrl3SmaGCbpcBpiMYRF1jEejvMxG+imfvWiDqPZCu40da4hoqpFlLBrBSqaqoqW+iWHiksVwW0J9XuuAdVudgSNO8TpfOWmxUHfWGJVWDYNgFgnoKu2dqpUTQYZwn2P9YlYKcnV4SdjiQH+e6PT121FtQTDNahJ9TMOs+Pj2c6xzezT/c/n7RyqfnWGV95vw2157tXZp77l5bBk3uW4lUylQ74xh4NGqZiZNdrsLfevzz4Tkfpj4KeCtsSsSZm8ufH60pasfV2lsh26RqSzmIh0fvOGIb7BbaE/BoKwXUVeCiLEE66rNgkOjCKkqqoLW35n/dWi/JTLKRQ/XuSkO3nn8NKoDOt3R6BOGBVYi+csEj2KiuWscNvOQOSJdABZgmCUFhPtQKVB/417S5WYVkiN1sK0I+01UelcqzRlCGGg4LYW004DYehiYGwei0idGhM+IXE4c1Lu5SBarB7aSvBvxxyLPSuQr+BbTm/F+W+lccBIYwdbocvP9RNBddWnW2GaQymAxStRpbferQl4BdFWweY0oRGiB86rPQgafwfYOr6vvBD4KkD72VoxGpioIPR+Tn3my4XzUq8Dg2JqKKG1pjgCSrjBMC0KyfWq4Se/Jpbj9gq0lVTY3Lz1XDPYzCfgYoYA6sTGzei7514bleG1+5+9defd6/ufHy6OOqJtxbgKct9OSbg2+8y/2bYWQ0MPFMpIzgeD3SI5RaR+y/Wlww9n7bGSS53eY1SG39/87qJb1nYGChfys7IG36o1b2hqvRBgMMtkH20TpIpFYvfQ9kEVoi5+2S2fGD/6+PhRP/eUOgw69Kg9fvfgg/odXdHJJFYuAZ0Prii4fEZb0kmemNA2M02irQsOEjWmj7bp2sFdcW2KB47B3gVGwZYUXdoLqp6AI2L1vi6yl0qtnTirS5cUDRyFwfpFnGYDnUTZ9ogFIMQTCZ0ADX39U1EsDPNw0PZ8j0tK0rcUy6qVoJ7lmK9CG0NvRT9QCwg5onqYOVAoB0edJQuFrUIS4SCYpy+OwITjDAQ1miKBGI7ujzduMXIcpdOGGtBcFGoMOjIsuR4XQ8Jz6pXTG1fXfQyeC9EgRIZAaUG9g6Ww2xYyAjdNW+u2hht/8/G/dtyeDMug67ov9m98dfj1xemFC2vnNwbrTWmk3lQrLnUwEP6UD1Wtp394eKXrukEZRGFwkO1NCnqQgG5EVlT3j8vo3cMP9tr9aTOx+puep/SoXP7Njde7+ntX4Q/n9ciOqIWUnNwu1gscIJDHDPErvSjkd6ssyvFIGykzO35j7ZUzg00RJs6prVpEbpx8dXN+e7PZaK11pIOuV1GpLoTslZMHfll6UXGk+zE9EUw6lASgbU+CALhHN4AIkDi8T4yh1jki1r0Jnx9GjL+SR+yBEQeKWgiChQCoNDKwFRzIp6hOGxRg52gLoHA2iusJbdBDW3/XUYlnET5ARasrlMuvpWcVJzE+Isz38ci6vZoGWtZzI8fhFdB6EVACJ2KwVj3YAQfOItpKLiXqaYB1AZANQ2bWbKS5ADMnG4wFiURUjZOcvQcMEj7BFACfqB2ICu8SHFsT2ta3GXs+K/US4lK3AcYYEaIqL24+9+Lm80ftUdXp6odivzz86tbs1iOTR85Pzp0Zbw0S2qbi+6dK9coBl93yo6NPDGFFGu6wYd5/EG9TXRQkub841MH12ee353cfHV3QP8tMfvaDpezx8YUnx4/uLPY8itQJHaIX2VZPEm/ExAGyEl6iLROC0IM0Qc0mVkQoJU6nZlp01h6/tv7y1mDzFEWDvOq39t+rZDZXbxGCnrBC9OuHAFXzi0GEE7oxcyxO66EtkEQASmGEiAIFuXRDKbfBgwxCr/X5g1KCazqt5qxiRFaBYkwdhbIFvDRkuIMsNTx/6gwHyJcBMVDE+1RIdAJlJAR/EYs7jpDaFWnN9Qpha191AeA3IjKVJiPuBEBavvG2tmlUell3nFymc5254+qBbKn99WMhG1RFwUuEBn/EX9WMCCQtiiEiutCuOKyrYAGGeyUUbTA4iqqjeq25WKm6pGC4vUJDt5WoqbEyg71C9H5Qt0WoBdRX2OV2mUr5W8/8C4tuwa8Fq8cMy1BEvz66eXnnoyu7V28e3ao/DVvJKaHtT1QSXL5Uffvg/aPuSBWxYqALHk58KuAiZt5H04RWB6xDXjq8nGzxJ0zjT/PgRaZl+ubGG3M7Kc7RvNOEiAU9TSt2YlvERQb1OfqCPDAUnkywKxZAo5AUQihURFRnNi6jF6bPitTfKzrlRyfdT/bfLVJcbPacrfbIhg0+jjbfqGnWF/sU3pcJtPUES7qKJZHBIdXiLNIOkuJeg68R2glt6+W4EaFAJu/44Zko5D4Z5raJFMqWSsww8l1sL6BeKo9l8kFYEnOK6RYSIiawCabztKihxUSGVsdqB9ECQkq9SF5kRaMH0FYgcPsCBFteuLFCHcsgAqclUjzuFQvqmGy/QShRKFEcFAqMxvGKmCcBVQcB/CUICXNWXy0jUBLwr8rPfUNKkJZCOhJI59qTw37YGhUBGtQDaOtOAsyq1ylZ1W0Z+SE5qYpKJ90b26+8efY7Jh2IljLiVHTYDIuW27M7H+9e+2Dnyo2DLxftoqJtDQFywG96MCp/sv/OrD3xb+qqdQaAX7mFYzeYB3oZrBGppWom3UiHb++/P2uPf8bQf9YHSeJaM31z47Xj7gSrs5STzqc8zwG4bnQDr1Kw9BooFtiU0ZaWzkxQwIKdO4nObf789NlHRxck84jTe+wtDz4++qQkEoVdE0M8eaPkdnpgqliR48FDi4oIMUIIcwlthWSTJJdnkV0bDoOghIaA4IfpO/+A3pw4jMBvTtAwkFcVrd+LCMmqXhSaW8ix9W9X5AwAh+YZLXpUF8HZilh2PRDw4Z0FkYwbaFQSqOV4d1rzXtwObKJC0fAZq3N/IA0nkbb2olvw/pOqHtCKQlJgGdgllQKQQ7BJnpuGUTbzhpUm41SQStdG3KAHFmjNQAj2PUB1GMgE0qmHReXFkjQaON21J5I2dUB2G0rPzRb56tAcNRDE3xxAzfyHtv6dF/6NYRm23RJrFBR8/OHcVnaOd/bme7dmd8+Nzz6+fnHUjCQ4Twh0RKv64N7Z2weXTrqTSTOx5A76A6KTF1HjfgMqmecvWNKwDN4+eO+4O5k2k8j903h01hUtL06fn5RJCvtIQg7mDST1F8lVHJqSAWIdqpk5vJ6lC/p/PS3FVKSInnQnL02fvTh6RE4VZ1kg3z/8cG6LIvjuTYMXPCKF8YQgFCAswpG9cTzhMrkiQpskGmtwKi9IawMgGIgRJCAogcVSn3q2VYSp3Id5SEmBSk2CPc5KxAYKT2JXJVBffBCgPFS5GgeBthS/HJmxBOhiPno1aqJHdYTYuoKryLHALQE7tXa5QYDbdZYB0W5BobJvQB7xrotdJIbhqeQ9bMPd/Krg5Qbc6OE2MNbRz3ggK60jLkUZ5pf7h5XUE8ws6gwhSqg0GiEkarCrBk6WFYhrAazRaoS1vGw5xPuSWQeM0cFNOutrnECwouW4Pf7Fx/7Ka1svpCqLJPHQU49eExEZNkMzO5gfHC2Obs9un5ucfXz9selgwutiCNgW6sBAm69Obt6e39X6VYYIGre+BXh4wObSKkwg9HIqtUjcX+5dnV3/+eHPIZFPAYCIMo8Mz7289sLVo+ujMiTw5flg1kaBP5EbiQIiJAGxNtNIGAm+Q1Va2V/Xmj7v5i+uPbfWTOun9fQ0VpoX++O9d3zGaDXEgz/MjyrtiYySIjBLBtY4UTkUCtUK2gJYhQGqHBHoiRAGbPSrUWa+kpxC6uFkiCALj2iiE5G+IuZ3FHlCqr9fu/nahampavFEEewNBdo69qI1V4oKYqJWvMsx9C0os4q+qK/b1ik7zBBxXBYgVPbbYvUunA2y+C0RbgPSu1oceJxDkYr5XajuPI0zUDFQweoC/c6t+i/vsfFgxCpVzqwyaGrkK6KLFxK3pbf2dKmjZawL8iIuVfAWrGeaSat72muucTb1zl8VN4DiVgdvasGRcpeBFflCVMR1bwfZpbUXJxd++fl/fVTGVautOV2nKqgv7mkuXnXQDFT1uD356vDmO3cufbRz9XBxFAbrg6xqvR1S3jq4tLc8GGjj7wUJcmnbhUEXjoG/Fu1SdX9Ng+r1ooOf7r9LgDiVB9pJOTfcfn39lePuRKXg8/6GCm4oKeRTStqDmyJ9/rhmVQwNHM6qiz2u0b12QA0SHRFZdMsLo/PPTJ6SPradwmIBbW8dvMcVCWIFeCIG0RYLq2/RXBLIDPtAj/TuHpiY0bY+ENfCZPGzBN8yTixGppMvpBDCuSJi/lk+nylTs/Ia95PLng6/+FenCN6BT46bSyAzoEuokarFQQf9C7sxBWN0nlvQ6It4H0SNUo2OrfZGa416TL6KqCOT9CkG2oLbSh2z/jADKkLygqJMsdWqOWyGtsaRyWelUCASrResmRzXsIPo1BJIJSJS1MmIBYOtFUOKOB9EaATg+AwB7JiZ0SmuzIoZIbVUbxUQbKw0dUa17qonbObTZqU4e6quIsJ6wnpq0knEfU5dxNTqvf1t1/6HL/+7z248edKekOr3g59OhZslBI/63QLLbnl7dufu8d2z4+0nNx5fH67XOxag3uOJyo/33r6/3FtrppHP4Gue8OoJgFwkC8fqPep4y4g1Wn68/85/nJqtb/+o5aG1blRGr669uLClFx5wMRRaWEY0fb4LjgySbl3tJOuKkHSEBzZQCnUioZKJaCM6s5MXx88+PX5CREr0fd/2wXL4+fGNe4vdtEbxOaGpC5qr0nXsZgET0cSgzoKN4jl/P0IeMB0jLRtDVKzzNzojLoh41HvByyGE1jYEmZQmQF2DkKPwTWW65DpqotKZ6KDfyUK2YmpGA52QxtcFTshVpezSumvjqeqwABQkUXTArdaNeSSJllbPimLUYGziiVN37VkXpYdyAhRMcmUF1VcMGkMpqqqAWEXUa+AwXkJwaCwkvB5it/SgINBHgfHCEue0XMP9kBCgJIQNAy09BuqL3lk6kUQdetDWEvmsAg6c0FaA8oizWv2sfpBO5Kg7/jef/Vf+4oUfLrql1M8yG2tSzv6+O1J5M7+oSzp3j3fuHN8j2g7LoFqxk25YBjeOv7py9Inb0WiXTFXUrw+24YgkYDg8RIRiTZHy8eza/eXe9vCMnN5Dtaa5PDV+/LHRhePupKiCaSLx0EVlZOxRLY9+mO4BtJUae9AhTCLfCLhqptqcdPOnJ089NXmCXPu0HhWwfrp/aVE//AbMcyvX4EPj7SIQYo7HagpE33510kLuLxax/iDaCvr1Fd1WLIEm5qbpFA8hkjvKbK7T1elh0MS5wTD9DTPNfhA1K5h7Vk2ZicFGK1HGZje73xq1pE8qVJfqwLihqjJsiAwOYRHnqGVOOjAVS/9QSVBBC1XzGMVQ3IEhKXht8V489hjMrYh6a2zyxfv5OBx8sw6lkD/EKQl2HM05imsCbgB2vvXUqgAw4thTG0LdYCb1+aHrNUxMocQZd/awnys+CYAhcBGLSoxBiLZGZxgmiibOy6b330qKGnFmpqpFmuP25K89+pd/+bm/PS7jztpSf5VTWZ4kFuTL9rKi/D/6MME7RUvRsnOy+86d9y/vXLk9u3vSzik3/P79P/7s+Ma4jD3I0DxLoG3kXh3e/Wahcyn6b3SlIiqddW8dXHJ3kFl9uwfh7LHxxRfXnjuxuUpR72F75dGgS7LeOu8Wc+StHve1OYFkL821MbWoOrCsdmKNDp6dPCUiS2vhm1N4VGImIj/df3feLUT9R10BdqJARqWa6JzJEuxWNcqDUJVeQFcS9tHkOYPpVEFRBaBJsgNxqacnqP8TIeROE2ErXfO9hpABr330ugSLas0BaoBVjxSkF4uFsxwPj3qNQBFXhYLoqDNVI1szUB7HAxd8AQIuBqpb2tfEvEOKOLAiEYkAD0FbDQZXHehV0y+jyXMC6BBzIdaxCi7jxVSJfwpQFAE2uslVESQ0D9GWpZznBtqqwoUEnkq1zPt8cwiKFcSNXg4SMLCg+XWDkm86b2dHsoq26qhTQxgE1IHfxMdELXBFkYHkIFsO26Mfnv/ef/Ly39kebZ1086JNMNl6nbz6anSBp2uyCMuKG14wlUabURncP7n/wd0PP9y58uXh1yfLYxF5++DS3nK/aKlfFeAmui4AACAASURBVGC2mioUEwBYYLYsxb6jVKMZjNvExH6y/w6B49ujT7jd7NHRhRemzxy3x0WBfujoVVDBPZmNiCCOI7l+aGLkEbwra3MwqSmBl+a2eHR0od45WxB4p/IwsyJl2S0/Ob7eSRvhDwa62nCgsNc4MN9iqLP34Et7aBA2RcB8nF4kwgYbpBdZyZCQKyTXYCPLYgLXxBMRQpbclEogCobLUI6yzt/MZOCVULEWAl/FE8hcIglHaiCwrsZdCNyBUufuRBClnsCylA8zFF2QLbAuymp1FQa+DWq/6gHgvGMnQEhAXrxs0N2p1otlmAf2ey0Unx1uDnJD544OgcMWO7o5cG9uF/vx4MXQggTnAvnqbAGFGkvI1dMSWFHoSj2GS+qYWQr25FEUMVRTC1fVK5JgiRh+d+CoPfpLF37+P33lP3h0+sjhcjYoA+uLhhqSXOgTtdOyCLrwAJUESEBmIo00g8Fgb75/93jnibVHr8yuvXf/8tZo08Tw3QZct6RUwRB9tCUNrOaiBVzZEXt7/30BYz8tqBWR1tqBDp6fPDMqw846Cmjgs5LyXBh1K8lPrwThBVxT8V5ZW23UcbIuuvmjowsvTp/nRU7lUYtV0fLeweWjdtbUnQNhcPtaSC0tecSBT6knUElg0jtmiEMCIj+uWYGmXp4KgMMoXgSik1ZXfBfBKTzXp8TZOs5hIAmIJ9mOMumUxYPHHTMAu4N7gLZYFYoAThOCJusl9hFYQhAICW0RxeJmzJFAI3COD0NbWjfVuJyhiLg0rmFcTG81IZnrFancujGwX04BiGCjIaCir9H+i/Guc0Y0TDFZBefCA8HgyQFxWYC27lw0goqkw8oEA6RtSIBqLYzC20Uy2tbZa6LGHBvhk9HWxIqUzrrj7uRvPfU3//0X/q3z43OHy6Ohg6z4LIUxBNxGIVMPXFhOEtqyghii35HZmtKo6uHy6Dc+++0f3fjpY2curm2ujSfjruvMIrAwd8B1YBMQKacK7IV6aWJ6d3Hv8+Mvn548cVq6gcDGIvLM5Omnxk/cWtwe6rAL3Zpo61m0ArgZbQ1ZrQGUKPIpCyTyNdiJiiytfXx88ZHR2aUtG2lOkbO31hWRdw8uH7ZHRRufGAqDhEfCFxLUUU2we4KsFBQIwEAEIjFKmVKkLGSFMRBfZG2j2Xu21VTJSFphbbaoIDaoFkoCEssU5L6vZSCEQbWMtgLHYZEEJI29MQEBw7QZJSl4FS/UU6tai7QGMiuIUhQBddv7SjToHKfyAN+KTAYk8t4BGtGpDtCW2c8OztkwkVZQNaBTB5AGV2KoB3sViEQ+jMHXGgNrhBwQE9HTQzyHBUSSgK8H2HtzKiqEDPQDTMfqKgOL94judQSK4s2RNFQuE9Ei5aQ9WR+s/0cv/3u/9ORfnzbTo3bmIJvYK1NIgQxoEui4KOyiibKk4+gwEzXpxs34xtHX79/7cHG8uLe8d39/bzpdO7O9NZmOus77TeVVOBDSjNwnpYqTIKfgokVk0S1+uv/O05Mncr/y7R913GenTz05efzzkxujZuRfjBgMi/NxDxML8C6yEkme2JwBbX1LJnGtWtJNVFtrN5q1l6bPVVuf1u+oiwOFicgHhx8etbP1Zs16M1zBr2CBgLy0tJ6SIA9FW4wYoBS107M2F0laT0hvLRIvaj+jRVLqr4TQAwWb1/TD4plns4noIM3en2RqwbLQZ5M1OQNt2dLjYw4I6ArpqRg4eAq4EzkMl8dbHkLqSEtS7OQpQxDzg/UreKH4Y46AHQCmICFhYi4QNqSjqpdUFEwe4LVK5jllEesh76qSkGIgsRJCTnhR05pjX6vPD1CcBJbX0KotCgyH443vll6rf9NrDrvg9qxiJjZrZ3/54p//Oy/88kubz3fWzbt5BVnGh4/s7JcFiz3NCtqGJCHBbYn4uVmUgQ5+cvfdd3bf3xxttNbOT+bzk8XR4eF4Mjl7fns8GXv9dF2C2UIIg4+wapCgSBVVnXXHP91/71+98Eud2OD0fpZRTJbdcnuw9fTkid/bXQrY9IPJmZUETJt6oiDYUIAELQh7W3ZZmr0tKrKw5cXRI6+vvSx+T8jpCCNVNBjo4M7i3q35nSLhRgYeoEoTojGWWdTrW4DFXjgQOBG1SvwNrrXSoUoKg1TJ6ivBRusLfbSFB5ILJHzRW0iIUT20RYMramIDSZj4gC6a+2titkajnGoOXKoGZwNpvGIZ7qFOUU7mxMkmeU+pnhJpemjbszesqsoY89O4ke4tv4kGS0ZdMVZGQhErp4euYvxsDQgerCkFFYyYDH9JUhIAuMor4xDQkESrWZ/YOCiPDzjzIKCmA2Nget5WJ1XDt86qPQOVEAIS67XWujrIi5vP/tvP/ms//8j3Nwbr827emRUtsVpCJS4VTuvltIvGSfDIhxWfWArJTmxSxjcOv/ztm/9vUxpXA+sPlC0Wy+VydnQ4mU7Onj83mYwZtCFcwEw1jbnp0U8Vj6fWuquz62bdKd5bmuPhxcmz24OtpS2hWVfTYmsjoIGWdNhlKBoLaj//ORRbBRKdCg3LbrndnHl9/ZW6ZyWnszJR1fotwJcOPtxZ7g2Kf00Xu+nM+EjfBDSWaCv+eqBtZjxJ4STIegqDa/Ui3zVLDCqBrZpQFYnoM8xouwqyaW4Cs8fBeeYogcIqOICAmZVAyh9sA6UGbimZrgNfgbb9FE7MTBLjClEWUV5ZGjakHCaL3zNgosWo3UhGW+E2PJSoqAyYX/6zeh7AWm978Df9Yw5CHbX+sRKGlYAH2OODEQZYYMDUD3aHHFpP85vcAMm4n0Hrzyuof+pAOCuYV8TrE/+I90JYjTyDHzRfTh9yNZyEA5VXN7PW2tZaMxs34/Vm+vTaE3/72X/5n3vkz42bkZnNu7n4z5NYakZAjD3CUIuiXgSe17ccLdA8UFwQKWiszMw/gvfO7vvv7nywPTqztKVi2Iq2XWdHh7OjwxvTten2+bOT8aiUIqpW70fw5DDaI9GoJImaqWqjZW958N7hh29uvN5Zl1z+rR6E7JfXXrw4uvD58Y2xjutX/WM+wkbQgEcSlgR36yc22Z9FQeeDZdU84bU8OXliWIaLbllvST6Vh5l11jXaXD66cm+5Oy0T88oRSMqZ+yJWS4ggDHMogdvyZhqUHrP6Zb7WdZl9+WQQxAq1S11X8St36GyYaWwww7Yrum2HPiOHNxbCvSnnTGQcrAsDFFXp7bvUCUH3y2omOQ6eBNoGNRZxAiZs3AFgoTwSBIE7jrbqqKE0twDjKDL4mMrMrBMD9DCb4/YZapY4yJv0NAtoFETAWLJ3zkl3NJyRhJ5EHlhaPJoMbNPhhRxLBdXJEr4mctJ7aHov6AvhM0ctl/rAKZyus+CqB1grXWtdZ11n3bgZrQ/W15rp2dGZP3/++//8o3/pxc3n/N2uS0oF76BIpR0sNS0/dtcpDiM8GQ5cAjQGjTUNyuj28d1//MVvTZtppU6arZ50m9nR7OjgaLo+PXN2azqZDgaNqNY516InKUaZXU5mVESk0Wa/PXhn//365dwDPTU8qvuHr6y9cHH4yNXZ9YlMxLpIQLEOyZn8vCILBEO01GI/IO8aT3S7inTWrZW1Nzdel9P9InMxEWm0EZHrs88X3WKtTDuD9B/TIxgRYQhSvsykbvUYKNEWOW0AIRFgZB+mDHcsRC9O9CU+wmLClM1om8qbpnHASXtoKwwhoG2vrpjYgMUAIa1+o2XFoHplv6kT6FRjMjVV3KCKrl0kzhLur7uIm6DVyb06aRWBTOjHSpYg+Ca3OJiMCW1j1zndhGBxOFKNUKF+H1TFwtRjVrM6FHJ5dDrWBbIEzpl3drzggFeE5mKCAVrpWms76dp6m1LC2Iej7cpj9SB7+MsPHK+ijTaNNo2WQRlMmslaM54MpmvN9Om1J17ZevHlzRee33ym0ea4PTnpFggGZ+heUwK1s7YR0eTGD7fABVBGqCHXywFUkKkiKkVFfnz3rct7H28NN9uu5Xl1RqvFrNHj2fHR4dFkMjmzvTVdn45GIxHpug44ZL30QjLUpTTaHLaH7x9+JOIl6FT4rEu0thyW4TOTJ//p3k95ZfazpAJwEExLQAjRIxNVgixPiR6D+ddauzXY/LmNN6p/Tk0SMenEGi0fH127tbg9KkOTTlO+kRICpxQriimnksD599A2LdOICBrbERpZ5wNTZCDaCkCQsOsZioGC9rJyp5lkZSAXDzEgb683QjWvLw5QRBxtiGHVOYLPGAgxCtoI8SahbZ0sFwSwFJdqlCtXipWiUBLwt8NS78YkgTESGxIFuioHEU704Soy2lT6hye76OlYwEpGmKVsIatoG7vjAo0owTkQtXfjLTCift3yLz3511/ffnmoA+6rWvWdiPYSpoed3FzGWyu4Goc/gMN+aFEd6nDUjEc6GDfj7dGZc+Pts6Ptc+PtomXezufd/Hh5YipFtKm/1oeM7rsisMjj2GCPqK70NubOJhmJp5i1evD59Yro17Nb/+D6P1pv1jongMZaFaUsWURVm6aZz+c3v741no43Nzena9Pp2kREurajaxIZh9mtNhnlq/mte4udc8Ozpykd4L7jN9ZfPTv8vcP2qNEGXGIlOelExbukUUHNcAQ5lwBpLV3Hzd+JbQ/OPDd9urWuoLX69g9Vta4VLR/Prn11cnOkwxq9mhaA6UUk4t3+UQn4QBsfjrawU8pAbMeIY4Um3RbWZF3DviLA3ggwLL4oeHSBpLkpCl6Ak7AbTk7hRAdCnhETRtXw9Sm4i0iKN6ItXkFpehjahllw3zF4D/4Vuq2wl0QD6QRKcPuBXzfJgEmw8It5sXtQRe7fTkEFREXYz0tIuw6zPvkVdLB8vyZO8osigeOWVaKO89mqYk+ayb/4+N8YloERKZk+qZGx9F+iJ0IE9uPZ+ZR8FvLR8KqZmXWdmJktrW2tXXbL+/M9EatfOdiUgkORMBaoQwoJyEt8An6QBMVIP/J/Sb6L4k9UqUZuSvm1a//wy9nNaTOpOBtStVsxWRWj1VeaplmcLG4f3RlPJusb0/WN9bX1qZh0XecTjQaMeWDDMri32Png8MovbP+FRG1O4VEv9Z2NV7aazfvLvYEOuihZPZlPekATiEO3JhlxFW01njDMu4GW19dfFvfT6dxHIaCRIvLJ7NPd5f65wXYrLdkf3I2aHPjlf3OZYGKAg3514br7RQXAp5rYlFA0wGKFDAiXVukNxFwDcvaVhP7cHCCzkfFEckXJ9Nb12dRsA20B1Qh4QzMnD6KtP/UKuoq2wkpCigqRwDFIWFdQhAPInMw72vpU2WElBCOEBBlG95lvvJVgfz1gZPpGyxq4T+n3YegAowTUJdFAiMeMuHRpETPbXxx0iXoGPmKetvqWv2ArxyEm0hv59TiH/9I0HGveQAcxaSivEQwIEZQ9uItKgiVkDUXFWMkkHSiW0yB6BcBlNyqj3731B79z8/+bNOMKslwP8dbbrnwjHVK3HjYYNMvF/N6d2eH+4WRtsrW1uba+LmJAW61Tol401OGdxd3Lhx//wvZf6KyrPxz57R+QDtonx48/Mjr76fFnIsb8BVYyE74RbSV5rY+2K30rzxUTG+rw+xvfcXOd8h1dze5i77PjG0NtrL7mwwLpRMgbNJ5I0m1piPpOgGzqNjKiBdqGch3cjikufbS1n/kxB3kgAVdeDMNKvySIxHkJbYX0dsDEkBW0TZcyzhO6rS8LCp1jsKmgU4cX1KdL2qBuT2hvK3crBaOpe2Zkg/ifX4NJ3ENb2DykDGJrn2mxRPZvrMdNwKwJ2eBVnuUA1UCBtr0KAyWBSne9OobHgmuQNdo0RFDqBLBBKIr9twJ0UUt44QTMzgaoR7IWZGrcG1dwP4awnbAUwlySC+yxtlB+JEEeqw5sZcgQ7aMthotwUVEpd092f+XqrxvVeJyu6L0CbRUSFPMasQ60HSyXy73dvdnhbDwebW5vbWyuq6jrtqzdKo3oSTe/fvy5iNQvbJRMLr7FQ+GpV9deevfgMioHveLyK8rwz+C2ybuBtjyFJVAR6tZo+cHWm+I85BTWIj4xE5HPT258evzFyL/ZBzGOCZNDOcMKGsfWm1N9aFFRgvUDaEuAZsvtwRYb/H3dFi/i3paUoX30JAvhlITyZ/Ck/rmAAcrN7tAiBuDzlaqq1e9wUK6g9sb1dAuiY1JfBQApxQQjBKvfuZnDVL0QVkKkLuSaWf1ov4pRvuWtZSSXrv7UCTkLVVO/T0utF1vVYBltBbeCCfTjam8vCAblgFWqxiXNgJR2/wg0jVCxnU6jcimmrqo9EUVxO6vHvYeh+h+wgeNXPUzirYwvnGm1BRQOoSISJzLJ/Jli4XGsD1MbMsQzEK2GCILPfFeGV0JHht6gd1mYsdpzZZ4YDrqBmHTrg7Vf+eR/uXH0VSON1OhSqXEZAi7qtbtK1KqPzSt1fRgCoWmatm0PD45uf337i0+/3N/bp03o+k5sWIY3Tr76dPZF0YJu4xQeVm9cFfn+xnenZdpKZ6hsTgwcODKbqznPt8Qg5NQcEE/G+o8yTTRBUify5OSJ88Ozp7b9xRWJichnxzc+P/lypMPOpyFYUZSvpAAYywlWpHhReJY6NvkyIfv6iwJrENQIi4QzSqL1US2dzGROPAy1Hpas6QE7G0oaoprYgjphYXDF8cRlMdGBONUETMAP5gQqt+VeNb3+moLc1BSIk7ESrzp4rlyMgPZmBmkeX+a47RdTQd8JyuQrDS1Vo0H1c934GrTXiTCI94O6LdCAnGoltzwCAv+F3JRNgl+CTEsguiaOTp7n13Dz9o5gwUyn5NIDTUXQXqcy5vKOPGyeTAsaMm7QIwMBg4BEgNJOJYHTjlXnewm+aZ5+gRAQ8i1eonEtEbHWbGO48X/e+L9/79YfDsoADDeHDUI/jU1CzaGrZfC5k0BbbbTruuPZ7NbJyc7d3TPntzY2Ngp+D6MTG+nwxslXV2fXn50+ZdLpKd3dxfD83uYb02a83+432kjCC/YmJEdhlDAVaV3fQw4NquHtsO4PNr4rCBFyiG/zqDR/oAMxuTb7tLVOVPF92kgGf+ax0m+xta/bxluZ9kosUyRWJ0DtIMv9hdegkIQ/At22mphkw5EDyeCaBHXbuBpwnBMTlBBNntJohX1WIjaIrMsddBioHpsSzM/HYrxD9GRitkBGEK52xcM9oEusWBxSCRT1MwsZ3wJ36qfPkm5bevgjmDTYJgoFkvZhaOs816wIuAGYX0KLktTgwCdNY6Zo8NMwUgo0SaGFa2BYQFW9ioa+Ej/lIPQ8GVAC1vCJ8wuEJZwqqSxxOhFOCL/sVsNuIpeKEGHshvc0rTMGD5gVxB1aA19h19n6YPqTe+/8j5/8+nF7PCqjzjovzSImWiIXYOFUZqNE9XXb+q9ixWtN5blm8/n89ld37g12t7fPbJ7ZaJpGVUc6vD2/+8ns01+Uv8IUlNN4qH/PwPrTkydvz+/WidXrdwGauvKrAStoq+B0GnfduvNWMIu86Yeb3xN/Ndreb/mol/p6fuuj2bVJGRm+h0yC8WUMIpsKcBTR9BsHwpkTqoikfeCLNLJvto8/r+1Tj/nh1xV8AkGrsF0Ws85X7j8y+te/MwMhHpiKDAj5GK6irahiQ19AQiBKVk5t4q0f5u6u5z2rinu+COBs39OtYJpuyOg3w2BeHj01aYIqBTXMuq2A2NGidV3F85whiKmsoG0ldimpEAqaVySII/S9qQQKgCPMQ5EKERGXTGwvAi+fj6HAWBO/laCxlswjkbcYgMutvmSGxsRA/EJ9jUsoo1cYCGQazk+LoinhnchwYAm+CjDAPEu6eQEOaq2bNOPPZ1/9tx/9yldHX68P1ltpfU2KrMm1u5qHi7Qe2tJrbi78jxq24iaQdrm8c/vOzt2ds49sr22sT4eTYTO8fvz5UXu0Vu8nEz0ttK1z+8HGm+/sv18jgBlFZRtHWh9tbYXbWhwdVqbaICAVk2b8+vorNMi3X0K9Tv3MyM3FnY9nn4zLqJPOWS7CUaL1VoKmxCuyom/g3UBqIDJfYUZZAmsxEcoIMIKy5KAUIyMQKAJ+RSaJdtyBQVVW0BMtKvhFtQR6eIls1+QjqT8XWskEArjCqm9rBT+qiFh7L/M6YQKRzepcDY2cMB0rqYJGYpADHBRlRS/Fjgo0SJdx1PHUb60VpapBdsvCZnjDxOdX//YL1KmjgXSfYB4i7IEjnoi2oEEeZa5v1HUICT3WQvMI7JueI4+cJ3slqZdUIe8O+zmcw940D2pLfcWjK42mbv0aeJRZcUkNgRWFXPEWzFXXrrEuNBJ0ffTtcVkfK1RmLifm6ZyS8dd13aiMDhaHf/fDv3/5/pWN4Xprrc+VWps7yczUBBGhvkjI/aALXjeiUotBTzBYUry+l1JM7PbNO19cv3Hn7r3upLt2/OlXi1si0lmXS9efEZF6D0LpDzffbCoB8Bg3KNS+NBFsngBTmKyJ1pnQb0ArcMZKEq2V9jvrr02b8beZ9s9YyGfHX9yd3xvowO1fTewbF4g2iCFQbxUrUsCWsv7VaSteSWcJQBlJGbKvEwcwWU2nGDmvM2waTIRbShWaKu2FKYnFKNrIdJAURCPWiLkxQjyrBk5orK8E1ms5XfHZCziZeWUP6prupEEj56kXRIwMCJveHrQoMm61dFhiIJiIYXapcbagKXXyiivWksNrkSLyHh5/EfYWUQjM8YkGhw2ClvMuVlGNOaQNdFJTcPneTL1cJoOxuzMwEIHRVu6FAl0QEHsh2Fe+Y6j8pMDkESYsuWJwUJ6n0CaCoPf5xVwTH3ZLiqK6i5LVg+InU1iaD3TaFIyt2bAZitnf+/hX//D2jzZHG8tuSWuQooJagIkqLCg0cy0t4nynus5Ynjx+/ZMjqUWqE2uaRsTu3L49HI5+vLf3zvalF598blAGIlJZbV1LBOuf8aFw4mvrL22WjXvLXYSSgGnguobZ0r4BH9HPhrXd8gr2aCJaRFtrf7DxnVP8ALEAgYqWWXv8wcGVsY4765yFucGN3QLAgyxbwG2JlcJY8JWLRiT6Wh4kxQpSmUIuGK4KzmJLRcAMsolUhFsVbrK0Us8LEKUVhssH8qJP4QXf12Ieb3XXy4DM6k4Wq0Yzj1sB+iioYyU+lSHgXMUaLVWjzOgSt03nWgJGQ+nGjolTbhO/I8KpDDc4EvCFL0iKnYlVGoSVGtiPaLZukIMworqZ/FzHaHAxBbFQz2q3k5Iz1pe8iAWdDMmZu/MKPuqSCboKUDdaRRXU392gwW3d4zgs5pk4+Oo8BZTKq2jME8hVixxeRAlC3+49jeeC9paPIMQUHS2cmJvVuy//7pX/4f/68nfWB2uttQpyr7WLYq4FCahXhCvIsv2eGRQtpg9MnRmuPezOhKZpiumXN7/+J9d//6Pdq18d3py387pR5j80jQj+WWj0DY86h4EO3th41bPDMnwju+sMjbzPdYOaJcRWIFRwXgCMU8WltT+3+Z246Gk8gKCyu7x/6fDyqIz4DcDKxlvpM5RcAWGvM5bkUq8TRFtDafFejNyWJ/IssHsnVgDoKFGRr36kLwK8SMED4uaEGkBmxCXCrgBPJTNZg1NyM8GiMsicyakBS4LXCI9I2q761HFMUTkrZGDyYoQIzzhzsICPmC7ODBxYM58lXfCaExJGYm2kKBiSKQfeyYBlpUp+yvdTRCCwWOFqygohvQz3GYBPoTh4xJCKspBapl+JM7qfpTeXLLGyrNNdK8Mn3pvMQdLJWYL2kctjOTGegF8nVmys5pY3+M3oYrqJs08RVX3gh/N8jwkxs0abRbf8ry//d7/x5W+Pm3GHWaukuAFHdlB3N3AZdHjQIB8Xqw3xM7VACj2Bf1fHd9JtjNevH3720e7VC5Nzt2a3z4/PPjJ9ZDIYi0hnRr4gIhGsf4oH7frDzTd/d+cPpAgSuZZLMzZx3pu7lzA5vAtUIreKMMGRrbWPjS8+MX4Mwf9nmOfPWgIw5Pbi7iezTzebzVZasNBI4liG13tQK5QEESSDg6tbf4WwOxZideks2KfaFaYgxgGLOVCM2EPb1HRy9sL8cGXRcoQ758BKHSwT65bAXxkEFLoleplLSo7+GsnLrSdJ6eVqQr2YN+DiTNdxGNqNv5p6PUnIm/DFYc6RF1ZQusLQO8oD4AIne2+bdrjDBkJwgiHY7shqRCaSjblnuFNUIo+MPoqxVReHitS7A8Vi0ahRgWjevgCyPCG/AW0x8ThIiFuI1Hgu2bK58tSxGWfCXlDSNXw9UXpRSh74w6LI+NrQwjelOWlP/stL/83v3vyDSTN27sqQRp1KmN7bqECfTOt4BaMVLAp0eM1PpljGjTtEhIkNy/Dq/vX95cFTzRP353sHi8Pbx/e2R1uPrz86GUxy4FoaWf7Ujz+3+XOtdMOgGMmqlceRfwjpC5Ckj7a1djgxBjQV0ZnNv7/xnWmZ1BGDy3zrR/2uhg8Or7RmwlkycbCgAN4o1qh0vkwRYF9ELo4ibvr8A20FDEb6aCsZ+MJYQRnJhU0ehrbgqCwQkXYKllGNDTaiFNYSxGt+MhAjEiDieJNAlTF7cJDqZUVMgK0PWlHf1QbjZMX3n4SzBaqxQgsEac/xFbQlOgWIVe+wnSA0eg6GMhTjuDIr0Ohrnktau/Sj2cdQyZgEA7B7FayNUJNRDOANJEwoJvSfrKKYSDJfQlsW/Ae5rTgx0yybEm0tF7QH6gOs3q88cFR/niz6HoZRPThPVBFPkFQvMic1MZFhGe4vDv6L9/6rP7j9I4IsqlZKVzcJky9FikDKiNLC+gGCkWtvZaIJc3pVS0MMHJbh17NbXx/deuPMK0MdqurR8uhoeXT3ZGd7tPXkxuPTwTRSGzDwJ2IZWfDF8SNPTR6/eXK71A0xsBkDubZ0uDubXQuaYiZQBiY0Jc28m7+5U3RhmwAAIABJREFU8fqkmfyM+fwzP47a2dv7lyZl1ElHsoUgo7cdQ0RyoIL3aQSZLzexVKwqgXc//UmKfSS/qq6cJdJDQ0lnaRrReNWK2v0wV5XMo/BKXRfDUTPEE20Ltwmq5EmaI8CwCrIVNxVqXkVJYy/qAKEIFBfKXOTwc6D3SVWY6tTQ7rlZa5TFrl9VzGo+8S1sKrtcBeyDtIZT/KDK4wwESgkwscOn6sDrm6RQnIWGUAXaxinuT/X1eQm06jIIDeo8vr4LPTTO8+Nc4OZllf8XLgXX44DqUpDGDGFrsirlbPEO4Y6iJJdXA4OaabqoLxb1SbT/lqR5+qU4aZ+M1jWmRYpqGTejj/ev/Wdv/ed/eOdHk2YsApXEM0m986rmURUrXhMr0WO/py4OOpdz55tXEgZrnasixHCIJYsh8msKWVOaK/vXDpdH9RvL6jdJnrQnt2Z33r37/oc7Vw7mh3SMkNhK5eSMoYc/hjr4wcabS1vWJDdnr4a/6m0HaaOiFkBPMK9lfrRHnoFGeYEa6ODVtZdEZPV7e0/jcdTN3j64NCwDk46kxh3vDjGpNMjcS+o8h2UiyrvGQsTXFwTWDBCJrEfBrB6NY/iWY5wJrWdOWv362XTCt4RsWom2BhbomrwZ3xIUTbS61fkOF9AN1IfVTEtUTbVksUDwDNOo86Gm6WpJKHxQeWsvUWPci31Ftd5bgYF1ALdQEEgy9pi7ht5DqK0mV3A2L+oF1BFiV6brAt3W1Q8n42KAByH+IBWdzbIUAvFFpCDIDUgowv/mYkxbhmLhVRbKCAuw5LPqBAyXhF18FnQYZyrOrgEeIqb4vQe8ReSVQqnHBwn+WGT1sopCXAr0gaRh1FpfYF4P5oKyLANtTOQf3fjNv/fx/3TvZHdcQTYURkedoPrUDFTMMOQqW0bk4xo1WIIz9KIs6wlYcMSDqGr94soP71/ZXx48Mj7ftfO69kYbE1l27d3jnbvHO2dHZ57YeHxztFFbac9FR/SI4QcfjTY/2PzuP7z9j/Gd3wg7hBCCVESt3uygLB5Q7/oRYQK8U9ETW7y6/uK54Xbk1Wk8WEuuzT67v9zbbDZaa6vfyKYV5BV7uNZZZJBibc5ZrQOqAVXEtH5UA5iVjFLXGYEFHHWY60JPiIzNsZtSy4ODnxCh9dg4igdWdE8ioir1pxyoJ9S3sp4FtBURG9AkAUsqsA3yjyyw+irJbCoi9fecvEhFX6omQoijSckVSrQZuGBuACMkYqfM+YibjLDLwiJIEwdVzgM4JIiESGHvqaOK1PgFutcpgEym/jJ8rcGHMmYGZnDnpkRHicnB/QW4ljzpXgf28a1Ait59/nFtWZmnBUQamhARiCWgXAZEdFjXaIqoq7jS8eBenQdGgsnUY6Xb/vwHTkZleOv4zt+/+j//4xu/1WiZNCNQv1ojk7rumlN1VfZ54IoyHGgBujB8JmHyukIQYaRsT6+iijAswyt71/bm+49NLi48VQwTK/WMnfn9e/d2zwy3Ht949Mxoq94EFmj7DXtl1WGvrb88KkMuiG42uFVVTDpnJdTVPRIQfZKYg8ObNaon3fEba69sD84IQP+0oLYu6if779TbZlPgWj4qtEhPjSpFAklZnOuKKIUxErIcQ1cn3MTQAZ0mcGrMJMJPkKNEYQ0+qxJn8RSYizt4CoJSJ105pQefsXpLRJiJ6IBIGmRBnOO6BihoXxH8DpzmZqRsiqkjP/0SyOuk8/WEW5woGb4BTeQkqYjG7KWPtly2gCtTSrRwugoIOjRTIW3wqRisr0J64UArXht4PYu7AVi6UZt6cBMCboS7s7+09URiwkKWtGALQ/e3yAQ2CCE4zVPwTtguUJghGLpspDKS8oF5UupSIn/qvpMIne+VaE1sfbA2bxd/fPet//7jX3vr3nubo434CADAO81FWfpZlrj9YIxXsRRRPh1FMmgqEbAZBdBsCfR6qZiZWKNl1s6uH3zxwuZzhQ0KxlIvREVE7i/2d3fubw03H1t7dGu8SRkko22vKpmJyNZg8421Vz84+miow8S2EOEEW+SvBzPZhAh2bsClhHRWF93i9fWXx2VU7/w9XdGgtfbHe+802nS502DTLURM0G9hX43Ej+BBW+pQqdhkIL/wzAqQCdwMvmDATQ9tFxnEowq8g8wXV7PcPGL+jj14Bb7wvMyirbu0Xpx9lS/EVFUGhkhxnmJAqZiZEUoUUUCC4PkULTQCUYhteM8bAywsDUNa52uIw8mrPWF8jgT/PtryxbwPrZodR+hOXNRTkXWgEjOnNbwocIt2SPrECooR7BPcJIbEKwLIUNBXUCxgQ74ZxTAxyTtVhkjShFl5nqiGWLcl82CIiHGjsekc6j3udMzTaFByTxOTbmntpJmMyvC93cu/+dXv/O9f/Obh8mhrtLnsltVuYcpkWhRGABraEHje0dYXnvct3BQoahLxiw3brCfAF3AP4thUtBMbleGl3Q9/4cLPj5pxZ61I4r9pp7DRIlIOFocf7l7ZHG5cXLuwPdpaG66JSOcynTA6yRo2mrU3N15/++DSqBmZgPY5IUDSaJTPvgqYEcZznrxjacvzo3NPT56sriun993e9XFvufvJ7NP6y2AOq8xdFkwABtxrbPOZpsCruiBlDDvMpUiEQQiUbiKD2qcYNHhNtXlCW+K1AWGBpwLUFkDSipLA4IhJUU/A81Uloa5zgG7iobIgiJWTMKEREOigoHXRIMw+wSBfdV8JwUDqjHJcQduUUCTgtoQD4SnAvkDbTBPqUpWUOkqRW6+WyYCAwBk/zF/MtbNegZMgisk3o5jkWRlhFKwwyG0PxYASIFsZNtj9UpUOOtlDW1xYgkxigdHJkLQCMt2DPYRLamuep+Wpr8wTMCzuaeuW1jalOT8698n+p7/19W//H1/+P1f2rm0PN6eDsX/cy1mlmMI+/UKWlSxmsITLa9+W2iqwqAeUhFQ2a0o4w8Vh0L88p1GPB2Xw3u4Hc1tOFb8CCcMls/ugRUvRcrScXb1/bWO4fm5y9vzk7MZwQ/poi3C1gQ6+u/HqwhZFS2td4mUZJgIviEjOPyDnVamMiFS0zLrjNza/e2H0CN8+FT7LCvHWwXtQe4D2gbZUYCXjYw/42HMEisbahJgDtAHxCeyLNGRPHE0YqXS9QsxEybFQGFbOiir3DWgruKCmYiuh9Eh0W8jPgSQ0CLRF1NdrIhB9UE8zDKVRVsFxgrbTOgSKQBiyiZRkFuOAfbjul6yKDqxu/EksILUZJKF4NaWwOe9KCQ0wEoAys1XgShDqh6EYdYqHoJhECishr5qNhQfvJl7cR7HgjaGp5K1BpH1vbzG9oYRv1j3LuddTEnrFJysJK2gbIkjEj7CRl7ZrB6U5P9m6fXz31679r7/59e/85N67ozI8P95eWhs/joD6rbVzWkXbaNClr9u6TzwzIrZRVIVeEnqKZvEyxZN7qgp87iZrtPny6Os7J3fPjDYZYD2zZ4AwqWjbaDNbHn+2/8Wd43vbo60L00e2Rpv1DHq5tvNPj5+4OHrkpDspol3SFh9AWwSEKEOEOVQv6cRNpajOuuOXps8/NrpQI+B0RQMR+cneu3jKvpt4p/hPcFssQYRcJDpnRhHcgPg3S5JnlBwjOZV+QUrzEaBtr+NmbZA+2q6QYu+n0zXTKYZTgIIhgyIDJT+xQbgmskUpXlUIQHCrpOQSCeDQrJCBF+XcRYcgyBX0DDCWN4BGkKX2qQm/g/8xZBBuwiyBetenL5ADkNFuoUTeWPOIK4Bq/ntVO0UpewDFgL7sRZOS2u83kiIQIPYgiiU0x9jIsTjcwn/uZgmmlrSMaBxCZhLuVSaQpaQghhhnpDIMYoXixd/MbFgGG83ks8PPf/WTX//x3Xcu7105Wh5tDTZMbNEthT5MzaMKp+hCI8ER4MObF0ywg5o8DxfniK6QxcaMMRTVOT+JBWluNERV5dLuRy9sPItm4kGzi6AGGgxX0fZkefLV4ua9k92t4cbF6YWzk20B2lb3bQ+331h/5Q/u/2hapiIdmEDGJhjcQ95fBm1Ikjpou4kNZfDC9BkRaaVt5HR+eic/3j64BMxCrIVUymkwKnxFAY1AW2csBlbFMqaslH1zh5IghLwH0TbjJqQYxBQ4jjseKd5n35LqR34XIQKoxbvYQI02Ex4THfBg0FmFB8XSgkGK8gLyXli0dLAp0lkSygBXk736oIm5JZ4DU1oKeUSz0sleEmqqwrbgLwLGkpAYPl7VbY2BDXlBgs/yahLpFM2/G3JlDwcolgiTEAicm2QiTe8CDgwWcNARYZua920Jfzw+OLD0YbE/TwZlZq9EWxATR1qLiUbz5TapayuDUlTLOzuX/rcvfuOtnUu3Zrdn7WzaTNcHG510KBxRHOER5ZxBYyJRqw94H1MmtWxENJgwSYd7HqKBRcKlhAI/RGH2kp+7Cmu0vLvzwb/05N9otHTSrYowK25CGaj/q0rCol3cWd67P99fP1p7bHrx/PQcrXBuuP3a2sv/ZOf315u1rsMWCQIPRjDUe2WEKEePul6PKSfd4snx48+Mn3LXnBKZZRhfPbq2u7iPcIUjU6Qgrnpoi1QSQph55LAtIIxCiun1ewQPFET0v0AeXMQRgAOBY/XQNtdwIZDwLEkzDDUKaOBZBO+wtKBiCO8YMrNBmm+8ne7w8SZHEfVkX0L3m8R/FVbwPu5hnM5zHhkh6GrghQCuAHcuAyKwq3J1HSlJNPrntFqS4UrsK+YE2nIrz+hXFZW6cYD4Bnl3lHNuaWlFGCKYWB+ngnuwkisgrloL/k5JEaQJVU0igrDRb/m0nmBAnikpyhk7EosPsdrDBpU6bjRJQIfIlCJFVWsLLCZ3Tu7+0d2f/NZXv/vR3tWD5dGyW47LaH2wbmKtdZLroAS3lHA+nUVCC9tw1StB4BhE53jlz8JSYB9qT1QH1jRDC8MgAISJSNHmg/uXl92yacYi7AdIBhTlG0UUx/hAZo0WU1l2y/sne/vzgy8Ov3p87eKF6SOddUXLS2vPN+LJCL8xPsB9eggVCAJ/RHEpKifd8bOTp+ommJ6eOEut40f77yylrTdawBICe4QZUpFQSw7MhdCihHh1S+2o33XJEyUhcGUrwNHYcI/I7duHWJxh15AXOBFcBBb2ZfkC6Qs/DKeIxvGOhIwsVRkwtaJmkhAilxQ0JwAiCLhaCXoGtBUSDieubj1BbrjPvJrVSAzCbKrFBOeCGZdq1KKQHhBZ0QX7ZQXRTbQtJbA/Dx59ubu0xG4CBiCt8EtH3yZmBaMk8cWo64ABG34Vgh2DQA22+uMMFW4KeJ4l+4D8V6xAoWVhiZCoU0JZqx8f8HiuA3NyBYBmIcuIKqwMd1dL1Z1DDzMpWhppipYiZWntSTefd/OvZzf/6Z2f/t7tP7qyd3XeLepmUaPNcDC2IEHVmT5D96ffH+yQ5cW1qDBoArQQImKifXdGRCE74VVATCo3K2Idg15Y02BTqBc1og+Xs4/3r7159vV6v71Z/XJzmD81mPhvJno1uYwfZDhcHH58/9rnh18+vvboE+uPPTl+7KW15744+XKoQ/Pe0teh/sMKgk5RkfaBv6kB9xCdd4tnJ0+dHZ5Z2rKR5rT4rKDG/nT/vUW3GJZhArW6zA7slbWdINWjmSmRSAnjT5LXJIREcUEg1wwSlljgGAaMgYKC5HeT0CFJ4mBNj3ommIQnWcC3qGgnprEi4dVYhwe4toehg6UfrmBQlXzWOoNQNBIdrdarjtdelHvWguiLgDfjYwrhADVwNkdHJcty2UnQ/6wUAqBaZau0CbIEe3vIHqYiDKl9JYFSJf6ENXr9ckk+yh24pI9OGWEcUYi3ok/3jgGA6D5nHFQ/dznE079ErOu9kI5AZ756SRNiaFT+OrJfC0cUKfWbAIuUotpoY2Kz9nh/eThrZ4eLo08Pb1y+/9Ef3fnxlf1rJl3RUhlEvVEf0wmW7H7hFp94a0Gt1gNBvELDW3EbYaBtwBeYJEoGXeEvMx4MkKpgtBEvbGCBthwB1NVE3tl5/3vnvqPaCVcl6DYAd2CbgbpAc4C9n6ImNl/Or96//vXRrc3xxtOjJz6ZXZ8MJ13bCdrzaqqaxsx+RL7RPhjGQ3VpyzODMy9Mn/XRyumBrFmRctweXz/+zH+eErzEyYNDlazMVhlz0ZILEa1/SlQsOtKTDMKXdULFr5IuWCT3LAYc5ECqMQFMp64Bg2YgJttVpgWuUOHYAySqHZqkAGIfaMCCrIG2hCfjxjSt5X1qRJfP0Emyet12LHEBFkNIKIqeUJBgMCeKmpVciYC0oSv3o2JC6BfQyLutI7sULaOHriKTVtFWMkt30UKZfZ6/kE2CW0HfIQiQ1rK/Q+WVtGyUZNGhDovGpjqrP89LLkRU9Op1ficQFFwMUWP54oiHqCOKCq4i2mjpxGbt8fHyeLY4nnXHs+XxrJ3dPrl77eCzj/evfbx/7frBZyftfFiGwzIAsJKSuPKC4ioJsuBPl6cFO0kkD6kxkkRRJSkJgkaHUUKINg4EimMo+ujnTPvkRx8YUxDaLL6q1rXv7LzfiNZdPCyRNVNxY70FbCOYUVbAcD1qVESGZTBbzqQz2+t27u1OtifNqBGRrutCw+Z2PHyNRdOdppi2is67+TOTp15ce04A1qfCZyshKFrePnh/1h7XO2clgaw7O2igcJ0AMtOIZ00gu8IcjaQNQ1gPAtzcyQ7+zMW1jFwWRutBvAFAYbpebRAsgTCtjt2aDhCLFQVGp1NqCyIDWiLpp2R5AszgRg/acyYKSV+UBOXI3tezGSP/JgXtoS0GTfPgLlV9Ca10jI1OHMpB/F+Itn31VtJzEik/DgBQwZJR7v8VQKXjuXOrEC+5eIvJEpEFVUI0ndh13a2TO7P2mOEauGl9WHwIpCoD1wcNcsBjcLzyEnG1tmsXtmytXdpy2bXLbrns2tYWR8vjveX+vfnuzsnuvfnOvfnuznzv5uzW3ZN7RUvF1kkzmQ4mZtbV5abKU+1DTyJaXEKqSZICpzpTsAfqkEdPCwOhFgFD2Yu7C+J2L/FzNcuyHk1+vgIa0Z0j3in3oFz7shg/nx99eW++uzncNOsCRjUiPpf6KMACZUR5SRHmtomYjAfjx0YXj+4efXFwY+vM5nR9OplMJKEtaAvRVuFSjaIsYmZFy0k3f3R04eXpC5V+npZooKqttUXK2weXDtrDRopHGVs/sCWUK+EBiGO42oGqWkljhHglarQCTZBMrMa+8hiI9iGxBKMC7hPEOVtJqoOkXHMKAidymWFzIvPDuo38og1Asykkg3PAlexgct0XkZRB4qBnAE2MDtP2kVridi/fzKrmDJbJHEXKpM5cJR1FPIwdL6AtZ8OBaQbfH+FVgn9K5EK4J8WZEOTzkFGQensghpRlnXXmb+gIB2Ww1+3/6vV/8Ed3fzJtJvWzRj0H8g+ETppN720ehbcSAwbyxX+8Etiia5e2WHTLuS2W3XLRLRbdctEtDuYHs/a4KU2jpX5DVaNlUAbnx2cNvKaTzjrUEEv1WNRCOARNSOAm5PMBZ3GXlnHTRkFRRaNN6J1rCpKhFOYgZaGkINKIxE5NhE1+gLn27JhaExGTomXZLd/bvfxXL/7Fef0Yq0msn3COps4iXvtomwC8+qpIOVmePLX2xLNbT1/dvz6/OR9Ohhsb6+sba9O1NVHp2g4daUgrYGfRkYJOW6PNM5MnB6VZdItT/Lkabk59ePjxcXey3qz5T0u41foEEy9GRQEEZ0TzlI1TPHaB2vkwmM7R1hGJTSM7I4NPMjQmyhxzexA3eRjcymDCv+LdnE2ajEBKU9drIjIQDSwQ5xfiuyIiLE4P6a9TDfe1c/PX44ykA7sskFkElEUUF3LABY/xayrJAoSKWCNUoYfcX2BwVkphzKaPtukluLb3YjzqTDE3aozxWQGgrVDK6CkJeILU82m2XfvJ/rU/vvuTjcF6m3D2gQcra6KoEUD2DafwOEtnSOqYRFWrqJqfbI43zsiWeWpBQRZbWsvMkHS3A83FRi03dmwuvN9X6NXJHqjzJtEIrOIJop511fsnSv29KGGmGFxBtCUDSp1TEtdSv5dqaO3H39u5/IuP/dV5t/ANgywRCKpAYq9B8+OwftGtV7bFMxtPPj599PL9K+ujtcVice/OzsH+wXRturGxsb65Ls5t3cRZd8O0PTGWtjw7PPP6+ssioqf3WdsaAwNtbhx/fXtxp/QXF85MvC+LAHiSCQQhtYe2Gvgl9MPD0FYsWlp3PHPXuAeASCLtqfLFSsL0kTFAOaGtiDcokK16y4SkFSvqVZcBynDtojAn0ehughASM2ocUv8S5kalIgHYcYtU1LrqMvbbiduK9eIHMEvLggkKURa1MqYmqV7WRfYayJUdZbzkgBOuZI8hgbmKbAwWRozhqyxBGW1hEBjLI6xeUcfNeL1ZW2/Wlj8LZzEfQmWKlIei7MPOejDAKk6uvtJa10rn1cCXAGrIvgN3QaRClvUjtv6hxtd6KyKpdLq92LgBk0AAyCiQBVE9mdVZx2OUMCMNU4FAHD0gFtBD21SgLUWUis67xeW9K/Vr91Ig+go9C1h2UsWO1keQYQQpExFZWnt+vP30+hMDHXTWlVJKKctle3937+hwNr6/t7m1ubG1XoUmlA4ULLIek6K6tOXZwfYb66+ISCGmncajEysilw4/vLe8P9QBXJHLdo10gV5Mt62iLQqDn4sXA6lxnTgXaBuEUSWLRpGX/SqnjigV4vxZ5raq/RHTQMoVYVxfU6/+o/ABEn1FsIyJ6ACdHuGtt71lKUKi/XY/93gijwOyShguVCzFEngus8vnD3qdcwW8AiG7wgX6haCfnTF9ZUAI+LinvKaKwCKFCCEGkYxhgkDPKGL9jw/k2QsIbLphHoktnVgnXWdtJ53E0Wkf0EXC3DPCCZg6cCP4BIEoGQWszVAIwToNZEJZP7HsCpoM1mQhI7NEyHu1pv4It8JhjB5lOes5FQtSCARJglREuqGeRYKLZ0WAvYG3oKAT+JnNfLoaSMYb3hT55UCrujPfvX7w2dNrT9Qv55bVJisiMbZiA4vR+gjQFlFcRBfd8vmNZ8+Nzx4sD+oWU0XbtmsPDg6PZ8c7O7tntrc2z2wUp9nCG1XoQRNd2vL8cPvpyZNLa5tTFGdFzTrR5v2jD+8udjaadUiEgoBCYki8RmzKiJkP0AC7uA64raFQBpwBnT3AfGrgXWBNCp7Y447ALaWMlyrBymVXaoMkNUA0wo7cNpaA3CTYidT7uiw0UKR4ZC2oIusx91Zzb7hS9xH5eW0Y1NKV4BWLc0Woz8UWCFYX8oGFvdJNEoxsrxFe8Htv+RlGmPEMM7D0uh0NyFW0hCoFoJMAKqSY2FbLKjZDCS4F+0NNB7yIFdGODIl3tSUIQk3wMNXEtyQR1Z6U7sehBqC9IgHQPsNObyk6QppaYBOLaYG9Aqoyk6eeyhsFUBycBmGLyb1XwwM2rBNAOFSiQdEAeVD7E4CxMwl/17Ua0+xpAVJLGpdvSVW+yDs8AgXjDrQ5Ws4u7V5+afO5xWJZSsJggXKWCnBdZc9CIr1THL+saJm38xc3n3lkfHZnvjtoBvXjAKZWtGhjnXUns+M7J/Oduzvb57a3tjZUC+PNc0W0s25cxq+uv8x4kdN4VCFkoINlt/j8+EalTZ11Xv2CmXoRF640m6BScMG6AbLszREa+VxiVtQz92/ixXhFopWwfBl0NeB8XmYNNgIbE8dWPtE8h/6sEJwoMVhLz9GIRisKqFdTM+OmrqhYdaSqWI05Z+8qompFAGnmh9Q/rPJWFbUCeNQq7igqTTECmFpRBxaHAp+RONzVIPIEUr820FbJt9K9ksLkcEir1yvIfSyIGIzZiABS6j8m8J/4e+IiZqlzU0KxihTCcykeLjFtPtJVcKK7tQZsUVWr2+tqJIuraCuElUoHSzHVujY1K0FpIZyQh7t/vCq7KXxMo89quFjeylG3jSOe1upU1LBAkVoDqsbuaOLakKioFERXfduKAvmKd39eOwCYYqL+y0p+3RygNXT9ci5Y1ZkWVOcK/OHpFNyqRRit1fKOsk4bELpVSKgA0WhzuJy9v/vRqIy8/zT4VVULfKqqVrxI1jdL+FxNVQqzwU9VXdjimfVnLkzOL7uluq1921BFi5amaUxsuVjeuXnn06uf7+7uLZetiJRSUK+klXa9Wf+59TdEqsVNTulRfwHsyuza1/PbozJEu1Etox2gq8KKiLFtyfirQOQKcZ2jag00QwNtEueaAvtqb+13kjsIKgYSqTIX3/I0rte1DpSo7tyq/8tEjXeNq8XczOfGaXtGoFQYVtTVBTiCinZB8KmcmOH7DYKZSChxzo0Rh1Q2KvlR5YVAZ8HivExAtyhBUuLaIvhNk4QHvHWAbJL9iKGo1XdYwBSFK3WSgExh5wkO6NMAZQeTq+YVli/1ts8vA8bJa3lx5qeqnAnWiSlIE2U+SUwNs640rf4RYK5Fgxv4uyUJSkhbkcxt3VpexxUIy7ckSAFZGgwjYPEUcYSWUAY0DheoOR51CmRSLDVaOScOSo+DS+POFCck8bsacCbOheEfaOrhtDxLRS+Ny1VgFQ3HIe6CaorSvG5SN13SmhCLZiZFS2vtF0df3l/sD0oD8wkXIBWv2W5anxWVoE61akRsiYjJoJQXNp//0d23W2tRNI3GF5Wi/hPkrbV3bt7euXNv++z2xubaYDgspYhZ27Xro+n3Nt+QUxVnVbXrrFH56OjaVyc3vcwkkinG2kR2CQ+LMEkcPvvctgPUJPzCC4KERabVB04xZBQH6gLWPVpq8RfBD+dUnFCflWEEQGq0Gibph3NESHjUYnRBdaGPVXo/nOMzHDiQBWVMwcxLR9yBFKkjbszLL6yQoWIrsJd9nkIiZJMJaLzVw5Q91RwPfN5eTuCtGgURZw8MAAAgAElEQVRYtEaHpmkxaFzpaI1FhcihrGgsIMm1yE4KchUtjOGCShKGcrwkUtHBAA2ngRzCGXQWJGJH1wA21c6raMuapCm3ibZhd0WdC6PCRiF1ONAral4PHUmGDS7vO0RFE0xWq0CbV6hShl4Hcj7jtI+2pPxeQf26aP7cmRgbp0SFCzlHIf1SNaimTuIx81/zfWAeYzX7BmWwO7//0d7VN7dfO+5OihboAnB9DipB9QiqgVjigChERZt5N3/tzAtnRps7J/f9fiz1SQbyuAFEGzWzu3fu7uzcO3PmzPrG+ngybgbNk+PHtwab+LhtjzH8Mz+sdh8in8yu7y32zw/PtbKsrvAU51oJfQgthzMRYERwWyRjrExICMTSmom2iFYBJUgXyaeEUsGaainsYHm6PqYvPmNNZQMjcm68TlzOCG9I4ViWWKl9mieNGXobb3OMmw6ecehzrKagx5T3a45u3iC5NlaJiwsTzmrUjcVejywE1xaci+nxXSdXKrxiNMFOnlxTAPKp+JseoUSrWllwRZ8NeSiFGkV5xugeXwohTp2XeBeghlY5yH9cQQBYji0pB6AG1kX55UEC48XaeRpZrqpxcYLmHa9Q8lESpNrXwSIJ+LF+N7waRQYXZVAHalzWq2KldEj9V32F6kytFIKQcsWHczQs0REeLkR4wJnispFgmlZLQIVOB2FVgZdZH6p58R8TBpd6sCki3+3sc6wQDnwwkaEO7p7sfLT38XQwda0fnN5dT4hHb6U+mFsI+I2gxCKL6Lxdvnbmlc3BZpUOjFNARvog1Xumqto0jYjeu7d744svb9+6M98/eXPtdfFfigzZ4NsICFX0a7S5M7/72fEX4zKquxho9L02CfYE1E+pNAW9O7DJpZmEQaRaChplAEoM4ApWglHqCV7t0ymKi6R3PE3dPVAoIe34RHlzgp/rHYdzNsO1CKm+hsBuJDGW7FTT6v2zCkxRb6VzO4MinOOV2OBwJQKiEnVbEvcBFQRh0v+ft3frkew8ssUivr0z695d3aQo6kZpNBpdRtLRDAY+BnyBMQ+GYRwYsB/89/zo82LgvBiG/4Jhe0bmVSTFi8hmk82+VHXdsypzhx++tVbErm75jGeGTMyI1Zm59/6+iBVrrYidWaW36R0hU1WtCPvv2UcBihPtUTb64pRCHp/r0tIAck3dqLhUJ5bjjAENiSr2J33L7H5+yALVTzPJoXH9UFE5H0MMzRl9NYzlCTplF8fyzFit3J4VF0NszuIOjnFqb/H8NfeYfmnI0HfjvCCndAiQ5TLlVz2vVRLidBizWCcVK3J80TWnMDCg88BgH0Sbk3tX86XQ8VicWOuwxIKJaBULwMPCBh9Obk4/Of1smsLxhSglmW/Wx3Assi6IM3ZsZW7AaeN6Wr+69cr3d1//5Pyz4Cq0lTwjjgVm3H0chgg7Ojq6PLk8fOPO1xeP7ywPtsdt639OnNf553lb77+Mzeyzq4efXn6+bIuwSdBnKtFaWNCt9XwqKerQSHvy84oAf5aR9PIqAgB3xCedodGrylfMLbCxULjqYJ/lMlQelpWDUWUkZsD4BE0ShNyrc3nB6sFFG94M/xGlzDX5JHnDIaRB6jJusDBEEj9sojqwkLUgSxR5h85obtUtC/xJdxe0sxHcpoPScYq01k5d47oMN0fCLUvHcRJaxSg+EUtT9PmgqypmxIq3pZrCvDBq3ABrW5Lp9MmkOjeNPlAQuCw9ljm9n7qavmbmn1Bh3CM315eFIUPJMuegWAlQr4g6XSesa3YwEGohl0fRT4acmnw3jLYSIqbG3AC2DXZNzY/1wQhQUDOZxZ3nDcqw57YF0M62vQ4AXSkPN6mlI9y6+WYwZx7N28PLr764/HI5LIwEboQQqwnIR3KZbzfCAzMMy6AZvnL214c/3xm2J5tYeCpFU2Fh0X1bAakYhmF/ufudxf0Pn3/8wfFHn51+cbm+6r8JSH/s8p9hbIPH/Onq8y9WXy18OfU2E4HNm9y4dSxg0QLJydLoyWymRXVwq3jR5RZV0KSzKDSnQ7rPRZAkx/pZxxr8qXxNpN/uy+feQGZwh+mydVGZ3Lk8cAdg+TCLkZXmGuqpMqOfvCeHTR5wIeIMKThKlZM+HSMN1Y0K19ixSgB8oZPI+npUHFwdFowgSfLSb2vQaDRcTD3aLQsCtewgr82rgMP4IM7hRk20K3ELmlSeVTJOK1mD0AmDBZlupyyzOkTZRkuH3/cdrNocioIOmcmMu6nIIGyqPKWXbYEiktfkdagJjgZMQzBOZHqM5PA6HkyBQwEybnoZlZGuNUtQrQIUlvTE4beMupf2ddYF4XQwPkoQcceVMlU5w4jcQK/m5bD86urrT88/+/7ud8+m897CIxVcRggGkS0XSbLOcOWnwt2atZtY/+beL3eG7ZObU282FUU0rgpJoGt09Qhhf3XwF/uLvZvp5vT67Ozm/OnVs7vLO9/d/c7eYpdc0ZlAclwg/rJHh/TowyY2H11+ir9vPrGnxZ6c5ybzy6dHqX25fDo+zW2DrES6lMtg+i0zGTzEZ8TnZEtdQpa5DhwSu4mKslL0TWVvQQEhLSPwoRiKOnl1TjlMgB+RZ9nJmlegsBhparb8C01s9mRO5cj6DpE3vS1IVv2Vy4579iJAIfXDRcGWx6Kw2acQtfBEhQrTpsPF5nQkaA8xtgnSiTXmVg/xtJH4soW3dLukrjTpybCZaxg5nI27ccstgCicPQ75ych8yXFgR5AXk+GzzFrdaIk7PU4oy1kozkFW0k4KIYsnqwgsZYrpjG2BSx0hOYWAqsdOtjW2NTh9sKVRMkv/XU4XlJ4QDSui1QUJ3do2LQy8gPaF42PZFl9efv3p2ed//93/4tTOU7rT95jPE2UaTpQ3VgAb5w6bWP/izs/2F3vH1ycSvmL+vfzkKj2i0357/9dTTGE2ttEsLm4uLteXR6ujO8uD13e/e7Dct7p9Moz9ecJ188kmN/9q9fUHFx/vtG3+YTeUJBiH9SVhDBj4UF1aUSOqKmuZJtSZFksOdSuNeeqm6ULmRjZPavM6NtUkwelADa9h15rl9YrLsuZC6t7Io6q8qgS54Dr6GLFkT/W/zba3LE9u2OiGXJotJp+RcXUVLEWUKrHmdEGmhqF3xDAxvdUgtFh7bqS6rmZyX9YHAvJEog2nZQ3WrBCGPaMHitBuK+aMy8bi6dKiVLLKjJYuWQsbi3pOEy1mKXY7aJoTenFC4ey96emJeUKmvxEvdVIKhrhkI9mW1ZYAoH1C+NLbqrEIhJFLyl3I1uV4EUYRHX9Q90mGuLDxZDKTZR9J7NynBIzCpmTmFErWn/ymAKfWZlYK4RqFVDRIMxmt+TrWfzr//OTmdHR+uquvyfJtJW1zrZ2VS3FDEe62CV/4+PM7f/nl5SPqCNfF4Yd1Z1tllhT128NfmnOY5D620SJWm+vHl0+PVs8Plvvf3/ve3eUBpWVGsn9uetv55avrxx9cfLTVllOSIN1NFkE/V4gXCXCqv6RUxmFmS4mLGWOGCDe0IrLn7OziHioSF59sW4wnAE+ajoIPDkVJnh5JrUEoiSfYG4nAbb4SC7PmoDEaEQ7vMKps+BXBzioN0qvTfpMcSbnu1rpRdzpssHhkk2vlaw68a+3dmkJmPFpgaSE+7GXaFBu3cqzTiXLJrE0NQXhu80amArNqeGzucLHJQS88JIOwU1iCmxt+17XDqjoskbsZv8DTPyLP5OO/3osncLM+vGEi2cPiKNvUXdq8nmV9vcH7cLIF+gD0A70qMIFlKh1jCx4IPWsy/8Z0A6RdMgKc1Ny8dWvi0fkgGjMTHHd0AYG5dhzuIIrmtJ99mfQ5HUqkcQQiOtoCH09oWD0USvZdhlf+v2M+SniB78aVCoQAq6wY94VTmPUP/2+35WfnXzy8/GqrLfsqQQ/1YQgusNifada/YWHCut7c3Myb+SY2v7v36/6BgY4xJ8rxN4IwZWc/EObuU0yvbb36+s7rbKZImc0HH5q3zbQ5unr+3rP333n63vHq+RSTF4Z96fS2a1GzZmafXH12sj4bfIh0hCR9QKWHITjxnBxWJGzqtd0LXHiGP4nuiuBwJrZXXX69Nlzi4v6GCUkJ5/+xZQIpw/8LyXiSeMQqrP/WMWmepl40Dda/5sC1ugOW/eiJ23CCpD8LoekLGOGzwqVlpFH+bPgLKGkVxEGUB37+Gi+CfaERLb2tat8hHllitJ5uZrwaLBqkBcrkQf4kjeGS81ZYFoAWEZpr83UXFweWd9iPVtTp5Q94FQdKbLZg+lS59DrqFGS0ARG6qwsFw1r/qgJMkkO/ZAhChxAdcHJlyOB1iEPnxWx52labZZlB5OhqZkzlAjszG/oSE0+pLUJAgq6rL96VmjTK1osUzGh0mwqX9mnol9DX0znkRMq4SAvyTfpidAS5TYRXs6nsCKjYuDFtXVEni622/aezzx9efvXzO395db1qQh+XBvwHbTRijs2ZLhLKewg1m5h+e+9Xo4+ruDY5shRJyhHqu1eMbWL6zb1fjT4AVKJAekRHfOPk+uz5s/f3F/s/2H/9zvJg0RZGqsU65w2Yu5+vL945e3+7LfFt4Ll3i4RxhNXOy8wnmOuQVw2hNY0vB3zE/gQ0WCKjGlvtinbVRGr8wznId2dPJ70amzyAka617qj7RmfvE7KrzKOlFSetyzarDjig6Aseo4BT2CJmWLbzhqJXUFhSR74B/iVylkFS80wbwxdcF12P9qPZHBkj5yEhBAVrw2i4xLbatjjOa6JdPKMj+zXRjMFUuRb+//1wTRIspAkiUGmDGlZT833r9GWr3ZYhuoQusefZkoo3jC0Q2VclQKqiBnKHWEYIPqxl4HmutRoyABvo8DOQpVWjpjoXktqqjpxopM5ydNQhA5o09mYYnLqmAcZCVGEztn3PHpGRE4152ZoAXBISBGHRqJnk4z9jG59cPf38/CEp1RVu0VqtGp43GchdICklS27/3u53X9v+zufnD5RQvo/r9hxRmJlZW0/r393/63EYulG1NCfwJUR9t4d+fnP+h2cf7C/3X9/97t3lne1xy17Gtp1YjzfP3zp7d6stJ5uCU4kwDi9UqVRmhk9ewHrWRLEY9PBdwqomJeJN8l9iq8dTmaVa0SvQ/4ZeZtkT5rlU0XQ5e3VXHMvwjRxcaf5DVusRhtesnTC8+ciMMR9JwTIowLicn/ZXp2L5TpFIEFKo7k5acnZ8EroH/eF4q0gwN0K7VLJCNnHMeJPHpN5ZsMoqKbrM5q0kyWSl7J/88BIbcG5kROfz60AVcl+zvN5y8rpvl0nnSnkHfEYIve8RC3kljxnDB9txsZN7xj3yMmaqUKts26FF90a6I3wr5RBBLDGac5nkKiDdp8pId1+B7hOOHb5AhFtbnWRbY2diJZmge7AbUU2AWhdWlrkIUyahONNpMSz+ePrp09XR3rC7iU3RlUi4qyArDJJdXPEpHIzQ/+7+X39+/oDYcglSjyTsQOSiFsPi53f+crBhg/tUaRmqQVWC3a354uLm8oOjPx4s97+z8+rh1l19LIGfTAAEHl0//tPVg8PF3XVs/GUDUxAGiYP/TMlnf9IrH+HnHT5EjXt0kIqATrZF1knMMBmWHrC/WozzjG3z4lwq36m3BadDqACeuYNdTVmvtZmARD09TZfC3mCQXSaK41muokOU/aTnAIz/B4HUOwNQMSdue5lGWPdOjuaXFiZV3lB4KU+aIkZXUGeQWc7ZKGPwAIPXBzadsyKUDg7ttCBDz+jcU6jZ/P9Bs7MHjSZFrotYqJIRcFBzWCPiNBeVleTb3Gp+cAbD/Av5h2qkv+tQ6HzaZ0qc32aXK6sgVUFOIpPbD+OTbuxmjFRiYjwG1dGzc7kYYnTsMRIqBU/W9+BOTZl3iKVGBUggOLJj1E2Jj/TpNZm8HQZdB4q8YAFAyASF84ZFnyj0M5rbFLHVln88+fjp1dGiLYBTlh2lHetwMgNTb9bPB7qQ3jjXY+7+N/d/M/W5YWRz3ElT6toz2qxtYvOzg58cjAfUBMxZ4Hdc8INqscCsuW8Ny8v11Scnn75/9Mc/nX5+cn0KwJiFRfMWEW+dvde8sQ8A6ALx0CAVFCZ6knI5555hHHv2+XyPJsbjYJcOAc4mpJmBgUOZ2xYe1AC3L8/MKkkFjeqMgsEzJHFEijvi1XUs60o+iWBAa8+9mTinIyDCzEdTI1e6U84B5a+EB6KWxKoduX5wj9lRabluWckcZtCZhZohz2NDdYw86HTIYWeNKNAmRbLD4ZIT0TBFQSerKwHOQRb5Zz9mbKuQlE5O7zPC3jOEybk6CX4IpK4kDVFToOnhmSN2OzR39W2cTjA4ZMCcG1jthYTenvggVRmxJ3NYljczUUxJlcscFNGSG51l4pB4k6nAsVYAWlxrDku8HGtUmrRMSXwYwsqE1hlPtcphZrEclh+ffvp49eSXd392uRGxlq6hvzcK477Y4swnCUKpm//izs+2xq3NtOE+a2r4Ayq93UzrX9/95fa4FfhdhR0pplELw0aImdTcI6x5G9pytVl9fvrFk8und7fuvrJ9/97W3X7B883F70/fWTo+aVCcbPo5Y7CrYRTIQ4hJWxmUTkK8EzddoQRD6dalxarG2YXl+U0OpTyRl+TyqvmceXNZZgOb334bTuWMQ5ojm11I2TQz/k4fWFyjENNRkFsZCR2dbCslUpEUhqBg4ZQwPeltHYJHeaOnoAro/4h+MUikyMHMWN4O74fQkjsNDiuhNDByixTq/t7OA9BabuCf9RDUYMdQ56QZk2Fl4Euni7AF8JRzg35M0KLmv+ExUMlmcgi9sh202I1h9FPA99EtuBZB2NQ7aMGWRR6T3pZcJkKArqaHh967uJi2ojSXzDrtVN8d7uX2s2ejQtqiKU7XSL0OeCjwp8is1C8sCTAA25RjMGXG2XwF2LS5r+L647NPrzarwRtPD+3ihMJhKnPL4B+8kOgzANIBmf3F3s/v/HSKqS+P/VgoRFh0mLuvNqtfH/5id9yZJCRBh4EQdG/HvgHgULVYmDVvy7a43tw8On/00fHH7x99+OTymZldTldvnr67bGNwoiAale8LxJLuqXhbS+4zucsAfwQ+q9H5KlSe3dCGPFgAZsJ4QGSN1dETAJoDbxRva+ILPoNza6l6lReabZN2OCjQDpYHAtk9BWHDmWXHy0i/xO4IDEWHEAQl7IFx9qAadtWhxMSpNyhDiRTizEmC2kCjZqE4rYzDrRwr125GaWI9kMUt5JlyjWAep5aDFvT/EjFNHViy/xKOzccttlXI8x1QQ9glkIglbZDxoIY9ypzEptNChoxDAze9H5iYOXwjudAfqJ9Ii2C3hgacGBu7SNP6ihEw2NsolwzBPKVD664pNuMGjPkL4X5+SUP/lSNi1Dqv26vUbhtGLoJP0C1lU2ch7JDF+7rAE5PF9rD9zvH7J98/vbu8s57W9BVsyITyanMYiGBoEXVGTtsd2/A393775rN3F7aYfMN9C/gItrtvYvOd7Ve+v/e9Zv13kDZaM1krL9dW/rn1EP4sIlprLdrNtH5y+ez56vTJxZMPbj65iMu9thsx/+2vkJxs4esPYrryTO2G5O0LYA2siwYMyTbBq9xCtPkV5UZlPNOBWqluowZk5SUc5I7raenO8gddKFWeHShWh/GB5/JHuhDRW3JZimyvaClk1miRxvktlJJmdp2FKghetVLoegW4eneFLCoZUCnqH6q8KGNQDPNRe2Bb2pnkbP1X0KEOSwH+lR6OVHl+OAHK44wWKjP1OGnXWZYa/SDeTBrSgEuF0tb3HX144SI3S4Fhlo3shMv2N5HOnBOcLPaXyoKpTrKMkgVxLK5VSodikMzElwor0gzkkCiPDx0htkVAQvBn9RIFRLReYum+FKBEV4elTcu2fOf4/dObs1e37t/YTXOBpdyPRhzlHDQgAXL5WQrLm6VuEbHVlr89/NXNtN4ZvDp+cCIB26xdba5+e/irw8XBFBu38uuepSCR0UumKbO9kAUmgFprzVpEPF0d/a8f/++PHj96/bXXt3aWGT6CId1KhwmLi7usOmrUyiKTpNTgtgTMbIY1yOwnYmxFA+IcXnrmqYsnTcY0PK+VzQ7kssk3PH2RTONG+JraapAO77K4e9hIgMP7gIBInynNYL8oM7kg7oXy3oRmnq01p0/P95QFO9k19GIYPo6JxXbNNOoxYNEIduNyK8t7EqyJziSd2lO0tNaWd9SanJh9Mw+R7O2nU7ByHNqa5pszotPI1KmEZiKzQLmZMbyytVLgNNQUWpNNbXLK7pWdlOJ+GJGBZaERdFevY7letR3aaQQ+KQ1zQw+RLK8ehcgI1xEe1j+aDfiKeYyDVoIo8Nu8ZTuQA7cII0D1ErufBBntdGoQ1G7Rxi+vHj28fPST/Tea5WfMLazHn2Vngnvw09Bq+mj3rX9u3JzZdP/+7uuv77x2enMmsYloZO5c69V0/cu7Pzvc6h8GsGQPcUJrnNAEntDgSgaReJOAWVjzFh5vPXtvvVo/fPBwubW8f//e9u52/8Nl0wTJV3Yr205JcDZn20qyRCX0zqZ6QwzhCfanQfksDQGBjyTaVC5U/anWUKhVDMlI1EqM2fNiWyB1zrZT2VFqnIi1cwpW0fpCYXdc3BOo5ebuhu+j9DENqLeZxj4cjwamtDi28e/f5KGZ1W4yHfzAjx94/9MeGHg5p2aR5YsJLdZs7PY9zJGreo+134kKxzrz0m79r6ZYH1WGKLq9hAn/9R4vJXF3D/zhvN6pa6RqrVnntB7lOkkwzm3RKMDt9ZMphBlcYqKbXYkUiAl/TcY5ZAjMkkOdt3d7TNbv657/4RwNGdzoSwCrPrvUFN28YZWcuzJnei9TrI8auIU1mSB9UsDNvPEf0dmKTgFF2HqtCtrcT+DrgUCNRQGZW+vbQEdgAH6/Wix9fOf4vdXmauh/miZyYN6z0ePfuCYFkK/w/zFF1WEWNu2Nu78+/MXNdMO7KDyMW+7vbO4/PfjJ3rjX/7SM48TNEz6mtZi7e7Pcrud/9FRAUpr709XRg4uvhjaY2fXq+uHDL7/47Iuz09Obmxt3a62ZkXDMQlmEbPavRU3oKZLpgk5QJNhlDvOGCXpj4VMvaHiFwLtCLZoBUCTBfrb+/S6YLhoJeVujOQZRcnl9PRF0HWTq7vcsMFc0489ctvEoSyEBz/Rd9O9ndn8VYi5L5kJz16ff2l9PDqgg2O171rclaem+U1Z8sm10Y0CzVRgxgjUUxAjAQRYPeVWyLIbM4WRbtnyJS14XdGBcq3FfWDhF1yl638YjLDdgMLAlGojfS9gWNEjNJyHwcCUG1GrJc72T4AGkk556AILcHFkfNDDBy1j/ATyj8Cbh9ibWTP9il6I7YwCb9/MyJUZKpFMFmGUG+socJ8OJOIZyOAV6HklrUFZN2hNGsk8rAZCp2zPQUQ9jhNmibf3+6O3VdN3aABQjCr2OSKMz6eqQkonEeSF4oCjfxLQ37v7m8Fer6dq99XJgoGWA/Wa6+fH+j767853NtHHSqbgV6TN2c+BaU0HRBnp9UZRsYW8f/QHPubv70Iabm/VXD7/+4vOHJ8cnq9XKW2tDsyRbJ9uyvUD3Frx/JSKuTtMqbSG7BjvYb2ciJeI9DtMdxijtKlBDVr51y8vSq8qW9tN4XYNueelY0kHwEpVttRDpR0jl3Wx0z146W7S09eyVjBM1tqCONwQNumu34CYvJyzzu1p7WKRxAJCTCuMFe0nrBc3mUNbYqnO9aNYcbFUmAJ66mZ25wVajY9J8BBH71jgWeHTjvJPYDtNTCKFjaCjCwjsVUDncbjCQYWMMca9L/iifQhQ09/JOhIhStua9AHoZk68Rbca99GCRb0/FLYG3kg1s1DQnMlgQjUzM2I8jVU7jgpPpSe0BXTCIDCjokKWV6btgp4q+x8AEaPGMVpmveEQs2vCH5388vTm/uzhY02PLg88acVerBHkTameBQ8cWU8T2uPVXd366aKMmEjVVvY9YrS9/dvCT17ZfXce66U8yI9/mGcuc2FlZZw8lqc0S/EBVe/PZ2wwv6t/dh2HYrDdfP3q8WC7uHt7Z3tne2dkxt2kzaZIQpQiNNlC4oJ1jjMGZAdfEFWgubeIdK7cnWKEoCBNPY16RKTWuipbWaC/dZnDVGnh2VB1pWv4rBwg4dSF6VaJzr/q7m05rR4/Jq1F6ShduEhZjqQLCAQBRKJW/ZAIqqOV2EpkcfUNyYfAEgR5set+AAkEu2f1CGY1G2/GjgkyPEbRVsrPFyBv161t4OBOFawMpTDFdBp1SRMaVHYKJh9jNB4g02H8wP2mwukGSvgGViQQ2EN5plo6/BxFWQRXJAkK/ISOX9rbvBL5McHaul0zp3AhaDrbiQaNBMbcyWUBCacBpxfUO0g9sKSpYOOuXouPE/qzsn72R4SgnW5pfbVbvn3w09YkLWdxNS+y4c5rtfkWjt6XzxA+sRXc3n2J6Zevwpwc/uY4beBgryDZr5tfTzU/3f/za9qs309o9gYuCTm/LbDJUZZ3OV426Cwm7jtX7Jx8RpCINK2w7PXn05NHDrx9//fT87Ly11obBapnDhpm4Kdiw09467STsLTPKNZqxSEFNDuiq/WO7AxfICOXlWFskSlE82dpEO2V5DBknAzZjW+3I+H/1Qv20kBDr3wcDF4fYttcDJx+FbYG06gyCzYpRZmH0LdsS1iFpOn2NZZrZeIrlzQqFO9aCgQB4Aqzk5Ar4FkbNs4N2crBGJmIQmAnaq54EdzHZv4xD/2kPVp+Rw4x9M5Nu5LsMkpNkQ5CurYJgw47au5pkI0YNcg3P4P14OvU9To5X861+vfRXRqdtZjnX8MygF/6dsW2QRpJtkXzXfConCV2PELeg9zVSSFcW4tALH3svFzZl2IwAbJpha3+oK5Ebrb5Qe8oAACAASURBVD4lPDzGYfz9szc3sUlAz1msvw95Jp86KL2MzHN+0Q/2dWwOF4e/uPOz1XTdx+agIlgNW8fm7uLgjb0fjj52FekHOgMERmEhkdNRy8m2CnaQQswGHz46+fRsfT4zwimDmGIP47jZbI6eHj3+6slXX311enLqrfW5Lb0tDi7MBZorbCs6pn0slVcsJIpCbGucPHVau8W26G/Inm5l6FDIvePVCGMYjaTp5FajaZ0TdNDXVLZ16nLnWTBMopHlLIiGTmwhtyOgYm6rQsbgTIgtbOuVbTm3DbIFa4Q8DqEy8mZh4yDbutg2eQFSRtoCtDBH9mp3pNsGCkh+A6//q5Dof/wBtuksIueRRGe9uUu27bEsk9vCCnWSwtTOk8YQ4BCFBF2K98s5XQWiwVYVjYAMLrELB4P39n+8hG0japbBtlT3vthQNvG+bmDw/4yIJU8aqbd0MMQhVca4cDRtgQkUhMzlgM3L/kwmG4Ox4FkcfsWat384eivMHLfCzP4Mi6XnF/CKlegRsNKnbWJzf/vwF3f/cjWt3Ftw1Aq7ZX49Xb+x98Mf7nyvE7EG3TyTK+cYMMvbenWvsDCu5YaF2eDjm8fvbmLSXsSXyDQ9k7uP47DZbE6OTp98/eTLB1+enp4298q2gZ/YMZL7DIA1o7ctNtBEuLTHoD+xbf+RLTGn6liXGkPTiBZ553Vd7XrfExdT2NZkgctRLDIeW5wsa4Za3K87cgPzEqMrYo3yReexvYBBfc5BgbQT9OGaCwaf1RiAVOHCHhWMNzsEWk3yKLmO7o4oYn1RbFArBnOEyPcssczY9PLcWADv0DiF5p9Mlv+CB7OFdlXGy7vFg+GjD+CozRh9TRJ0whpXx6lI23pinjThk6IJWer/JjPmpJPGFwOOftrgHNaMq9HQoCQBC9KrvLLlMlxjUoJFiBY/cissUQMRpv9HpfQ5fg2G0Y/Axcpychgu9Dp+KpvGFjvvWjP/8vLRl5eP3tj7Qd+4ckmP0Xc56zVCauGhhGKkCTm0sGnw4Y29H7yyvLeJdcMvGcTuB2+rzfUP9773o/3v30w3gw2UO/I2Wh/Uk+u6mLVzneVFGCB3i1j6+Oazd2/iZuELAejWgi331Nl2nDbT+dn56urq+bOTg7sHB3f3+29IIN3Oi84oPSQpLEbFSlJmvuT3UCZEiVmmhEHoXgkel1DnwLheMchNsCE6ils0IpM/0GWyCvlkDg0MfhZLx4c/ApgR26LtctZ3F/IIUlkErTPhTBMRuD1s7FVYpiGk8T52DwYnby4PJZcFF8qmEflhgGFQ2CeixBheDAKSRWFvs4gMW1dHi6dEacTAN/4oFtWys++YgSlBDJ3MxHE0uEuqzikqHW6xjwSHfLLVxMplwTCGlYGuAaQsRacBcv6YRNzfS+lnPb7U23YKxobADH0xKiPikAvr1Bs8tkQE9e5qmED37lTffgQ50DuIKFtkVmACCYEHcvpXp6F39FC9wi3+8elbrX8EjIcyL/AnADWeaq530ErKaPZwulmzdj3dvLb9nZ8e/OR6c92sNaSiF465+xt7P3xl65VNbPIVMFlZgtPeknSEhvKay7e62dCGr1ZPHl0+5qqAkBDJgphlb83ItsMwTFNcXV09ffz0wacPjp8dTzHhSqxZFjeaITlZ+U04pzJkkOdBnwBXhNYe6kDIgqyCJhRQZaKDjgxWUtMMelkqNMos3TfaANQCaZcCoDYZOiFP3nqAW4W2sxTRMDVsy7x80tHVfIvhxGpOU2Ru3n+FAlJZWNGiGfsBMWmdJJh5awQ2iRpVAzlmEfmMbRvg07dMtnZObTCL4BlYWS0v7dFKWr+dh+N/3dmxBhgAf3sCu41ZsCCi7uz8OnWQxMysNc0Tyqha9hZmoHmZq7jhg7cGdM7Y1gDkoCbh9k+/DdQZ2tHjQ/ShxTJQlW1bC9nPiFbXJ8PH9CV5IBSYW9ARsLH2oOVwum64G/yVClI0UIbmJnLMIKfez9eILsxXGm1V/+y1TxH/cPRm638RIfhHDyz/l4YiLQQJ10nm+lsJyaRuvp7Wr29/96f7P15NN42/w9vNmvl6Wr+2/epPD358M924NS9/yAMnIgr4n7wgX2qWC8yXwmLZFu8e/+FiczXg88ONe3ZvEUU46TZzBNfLtLUWETfX66dPjj7/+POjZ0ebaW1mrTV3emtDe08zCLadQN4TOdzhRcG/PFZsS89U5wewaBPYloYz+nCuTxWm0OzCbD5PKFY6yvI6AecAJPI9UgitNtl2hNP1MPP+LSDikz1Fh7k1S3MbsioaH7g4E4SdYE31hIJgmtDPzS31jcoiwJiKQvBc7z7wbwhblO6ObhdbdzZI3ZNgzoYKcgiiGUFSe2Dz4B9d/zYe2R0zwTKaxtaA6cNG0OaEXmXYGELszT1DYZlVSzTANyBQ2j+BaSQfJU2QlYHlnxRwjX1oiukzQa1o0oNLA7mnK4qYfXWULozJ4ioSBOqBIbKAQzEOhgYXyMR/zPD1KgA4aJocxtaMBMKVEnMR1v+KiLHU3zl+/2a6AfvmtZHa6rf7+YJFxkEEM2kz37ae1q9u3f/J3o9W0/XF5nKKTd/oYH6+vnhj7wc/O/iL62kF6iqnhtXBRTi5Q0xLASES3GYHymRbbevtoz9cri+bQ+XNzPD9TubGCJMsGgZaZeoWEZspjp4eHz07Pjw83L+zt1gs2tBCXycjDbKP7PkKRkcBctpDJSI4OeV63Ix/jRcM2M8yUfNNm0SIIm9uErX6B4CUTyJIyFBMRJqqj0MDYpksPPJGhGdieEoag5DBSEZM15DqQrr1vKRzQGVGapO9oYQ4kFsHc1YIlyhPsGItnT+YT6wFIE89KuqA9kd4nBewKefmbJsL6r/Zh5d+pjhHsISyzC12H0puAThlwTvQq2swWP/ZKFCeMug9eTBJCiFRmQIi/WcnTSd3FQ9QpmUgwtDq+utcnysAWraRrCkfGouyJj2h36cORHVQNLV+kDOw0TWJ0wCtKo1T+SlMQwNdC/MIEAh26O6Xm4t3nr//u3t/fTOtk3PoFAx5jFQwMS+ZiQntrQKOHNpwNV395t4v/8c3/rvVdN1/fYGZubeL9cWvD3/+/d3Xb6abbqXBtM4SwJWZNgaAJcR3FPsOlW5+Hdd/PP14NV3vjbu9nwENR7U4HF9RQ8S2rgDJoZuZ2dGzo6Oj47uHd/b395bbW0NlWwmzqN+UGZEg/jt/kv0RF+bMIt4b6SAEiqBJJr48yZJ8SmLmWWBs9WqR8zyQ0C9saxYjZJ6YSXEqBiuIZy4JakBLxNiIbVnGElfPfMsaiOzMODkhgcCvBId3MfNg8/6EBAV7rdpGY5sjWktNLHgkoPsyOuemK/hWONZ4ccmwxklYQpmpyJKzTHMqjV7dSkvMaRpuvtrsSWOq+XOARzKGnJlZKGmkM/SnlqaVNEZ7QEqEyUP0XS2QyRljYQJQlnP216YniY/IhIGn8W8pp8KUc/3+SExQB4QHciw1XZEgwnFilkEn8uF6Wv/+2dt/d/93N7aGoVDo+W/TAWyvTKZD9NQrEW2mDd6uNte/uvvzv/vb3znbOeTA2/Xm5nx9PvRf0JXwMAoSKZSzxWRbAcBuvTXC+q8w/+T4+mT0QULAwuNclicVxRabW8b/iW8zfk/3+NnxydHzg8M7u7s7O7s74zhO00QLTO+UByVNmDHTBEBaT2aWR5nsq6SZvbSuQ/7gbScm3iTS5UJ6UlcMzk31lPiXLMMfRhwMzGC2J55mKB2HsRQhlxxlYLF9vJK7s1x9l/1wjE6S80gsGOux6kKNLC+kfrgyBGHH5RM+zoi7/IzV163ikW4ohZek0cHyTT+cTOKymRhGqjXopJZReIFbtFPjTpg5UJPxYAVBPMBlZJmgyJWmPr21Mgkys2QQJI3KYOhk8lzSLdKHqXvvFyDzaXrrXB/NRwq4RJMbFw5JVqFylYPJ8b+B7U20jc6GBBcUCexR/XbFegLJza2ZX2+uf3/09qKNF2trzjnUjIjcEu4m4wzeokRYYbBepM39Zlo/Wx3T5vT/YOlDa+Rri1IbxnI2MT4PphAqm/O1hW21rfef//H45mRso8hGqoj2RpO4tLFkWxCMns460o0yM3t+9Pz0+ene/u7O7u7+wV5h2/B6Vgkq3SfHBQCTIkUezBKnlLgUT+FVtwzkGhFnShcYrFwoCo8rMFRkIdkynmLl0Tjg03a4RUwwkm17vSb+61p4Dl41iiEIq+0X9aXUBVfJCatVGwHiMC2gaKcxusn8hSoK27oJApmAyraW5CZsfPMMWx9uFRqdDlx6YkamQQxjzi2JAKNrKn7dasDq9Mz61TKEL2Vbg9bRLRuSll6gJA3sXcSb1cxruVBFdpV8BuFhzBZrJr2tlts1nzZB/iNq7iPdamFbF5ZtjkOdhSOXmSQVp16IhOeILy6/fHT5eH/ck+uUCBa27VcurTzTzUFZjseMFdvM3EesrmkaNNcgEauj5Mi2lD5mps4JZqlguBdtfP/ko5Ob071xtytzrkgy1vMkMa1siz3WJ4EyL6nrbHt6cnZ2enF+dr6zu3Nw52CxHDdrelu6T09l7VziJW4lgPiZso/L9qLJhgYTBIWcTznZxcNLbSR0+8llS17KtqUa0xibxYheVeEyNu4zzyrCs1uGtqdRHZI8KGFsdGiKtcrUsc3yb6MIiJdfZFsTU4sqSoq9O8NyaZlnUzdpdC6a23JnGES5yNYYqW/jUQYZxsvLh8zZFhuyINg6MRsDRm5Rv0rznrw7azxUSZVtjSEss2yOEHT2vCSHEGU62A+jL8ecTNybJY7w5/ryXhl3HJVt9WQoWUbD37Nc2VbdtIoOi04SyFYd5YB/RHmbCiebhYTp4MPF+vLN43f//rv/+eXmqvVPMbjiNOecYGmZQFhGJS7LUfZoBhMWSlR1sJ5iJuqNkk9awLA52xp/ZloXbfz66unDy0c9CNMLzI1EpX5HNr3ZpERBb24TPW8Rr86252fnlxeX52fnO7vbh4eH42LcbDZJsnmyHDRV7mOF5njhpWxr0hWNcwBlRkIzCwa93s4XsbI2S8m9wLZl+hDWfy1dgN/FqGzHANHOVjT0MAQ9qg7fomEH7jSpOFlaYW7dn3dd8pyOOI08hmAduIk1SZgbxrsIPy7bddyVVgt+qoM5oIMxATQr27wvq4NPM7sg8L81kjXrm0U8XLf6bKZtPXJwgYCsnAW4qb/mXscm8DthTqb2HsQy/UZJcbwgTjO4HRdt9gV1i0txdbo8Sht5Ar14PwSbMXxYoY8XnLUviXVmk2MBPcePJGGnScERZaudxCLQxPb0ghL6dQFFgh413cNNDQ+wgjYQeoc7Z74dIoMPp+uzt47f3Rq2NGHogDYSuAxH+qVuBAJPObKAFTu2QH6miUBcor5XT/IMqHh3BVMkjTEUV9EzipTFdtv66OzTx1dPlm1pqJ0eR/zAnlCDl5IkkkUmqeeAo6dC/eltzWwYBne/urg6fvb8i88ffv3o8WYz8RNgpLb+AzBibhxUGjgsOryKndQA15N8AdIeqoB97ZhniwEKDjpHLL7/Ozh2AthxITI4PKvxDWCwEZFGe+VSOSIPEukcF4Y4CQe6MXFB6PeK8TRjBCWNlpQdd8Vx+iCRGqoTTK9uQerrqSydZCKbwpkZ03R9Ljgdchyazc7rEjinaH0bj2b0CkHrUcRA4wNOxWiJzMr4DU6mGsUeFgaLo2o827NDxzBzVHxJbMsQsrlEyhP2PW7or43TP1OnIgmBHclBDdsJnli+jG6pQyRnoqYbZRrQm+WWg7TfxbsTbH85dF1IRzGH6VIBRvBTFOSZuozsEvobm7eL9eX7Jx/1X3RgxnKS6lAncaYcdhCYbOXVPIQirvjnxs1sHgXJJ7rgnCRk4LIAjCArRiIsIraGrU9OP/366vGiLYKlIXOfN0lCqyFdBynCDG6IWLF8SVqVNoc78f77Fa+vr29ubs5Oz/Z2d++9cjguFlx5iHNN9c7FGYmFJtdfZnvF0XiCrZIaRtpXY8zJW9kCILq3LkRHaHVVuKKZjf2PF0Tg04AWlW0Vvabn8s5EM80U+Ov307erV3KeGO2cPLycOS1jn6KK4LU3axAmoqNOE+bHqth6mPi/6LeMzETRC/VubP+ktKkV384DtdTALlKBQl9iN4IphycJ1S6h0MMZ2xLylW0hqEZeLwdZsjQqAeFUp0+LFf1TqAxvaSJZDcAURbOMRMOtgZQ5XHCimaWKpTNZlqwvnukh5AdvjeaCiyX0coxiJIHsmUt4tYEUFIGBzVeTYjWmYfDhyerph6cf/3jvhzfT2mVqyTRk1EjUh0eDWyanNvIm//QCG0ZLXqSdDELZanpTzPovMKH9I387IacuhzgffFhtVp+ePbhYX97f2l5Pa7YHFuE6FyPv2pD8u2AIZEaYtdDnmgkxwIsyW3Hev+AwrafT07Ozs/O9/Z179+6Ny4W3XpRg21DD6qJU5GxK7iPOWGORgSaumO5gHi0J1fIECDVO2RPKX/1Q2daMV5S7MfOx55rOSERkpm6Jta0OCJHu2W7oBWC08caYqTdED2tIejD6tNKy3zLWACdJm+kggGFRnKD1xAz7KtmzrEx3jT7oTDTUopWIznrfCtFSLxAM5lHWWv2Dy2aZ7tf7bBgQMofZfRjDI1yjTHtdZNvIeITC6dIp+R4MvdHQobsxDg+YdZR+k7PqfqZHXtQWzC0rE4bnto0yEgRRkHd/wJg5WCgzTKt0QLYVFnLzsn4QFdoYAxKNbAt+DiYEbIvQL9v4dHX87vMPfnnwV9ebkxzRGgxFZVu8JMZtGWUZEDxawTDNLcq4FUQU2jIzayVrUd5FxFDT++wHgFq25YPLLx9cfLFsS96MClJ9j0bjv0grWjViLRYL1rIh95a+yLKVqDsuhsFBqWenF6cn53v7e3fv391aLodhCIuYSCY5vbVqYKmjMiW8lCKlgqMQimWM6+SNaLMJswNhQW5AwwaVsskWJtvGaLoXVZ7PwUASHpdW6xkVY8Y90g+k68G1aVVdoZd64ELBYyj75n03KF3akSQg1iMWIt7EujmSKCRrSQ+V2Izn4RRSPR3g8c2zbc9Pgk6OMNlWgHGqMeQuf6LJlywXqNQ8lMFC1zi4epyU7QLbtDKI6espkwSNsUWZIZSByynWwQtaSRqrgfMcElzp1vuWIp2P2dze4hxeAhNRhbawraCjgxRD0UZiEcUptjWybR6aEjj6eHx9/IeTDxfDGDdQvJfaWA4sGVZxcQmxdfx5aTFemI4KEWVuZqb8KI9GkrcM/+0baeER0/aw9eD84Z/Ov9galmFT5Wn60FAA+CiiR/UAJDQumCUJkeYYjNtjrc7Ylvi7OL84Oz3f3d89PLyz3NpaLMbOttmCMRVq1U0XKvMEI3XR2Oo9elFSV/sZujucLTK6xl3DhQL5Yr9+xtHlk/VfYt1lVS3NMhLt7jx3QiD9Ofg+Y08/C2abGVrzWklIO91J+oDIe2ely+qsWE2T6tAIWXGRiW/KRKu6IfC+DvrmCRYPCVwx7WSVnEfTeBDCshkMDIcNoaOyVQjdKyMPGfk7svJyHGlG4tJYjPlECF1PWRYGK5lz0tKWkEAlmpaownXJnGw+RTWkC7PEjsLRcx11p5xk3PZb6MvA+UH9N1PdkX8sw8T1cPjR579pE8Iswpu3TWw+O3vwZHW0aIsoVy6xS4zm9lFiEniVq7F5KzP3mc8nWojvEEzYsJiSKnmTlUQoxSrezD87f/jo6vH95eEmNv2wkirMgVxDk7kdtsh3pkVFi15sDvLlNeRexYQqkRLlPgx+dXH58PR8d293/87+zs721vbWFFNMQSfBM7GkivEIoV22l0+WK2kGk2TrnGuBSkI/ZYYETTqKGa1bmI3GnANrAl7RuyrrPdKVKWk9UYGOW3eEValO0nTQL95m25iVEVVFaTZ4rBlOLSGa/gcmiD6BbFHZ1ogNvEUpdkWVVvubf4DkVSMSkpkJmqGcnjVEY6EzgdvQLhHo+Efpqy3JywpD0vXR7N8i3Ftsqy14cSE1aVF7IrQkpplITVon5gInunqT3id5dcasDm3utAnxud9KtuWCfIY+yU9GxBh3yRri6GXn3SJtte0vr77+8PSjv73324vNZW/Ok3m03eTAKOFhxSTbhhIq4i84N7ppdgs2LzuWUyrSLbY1yoZFmI1tfHZ9/MnZp4PjDz8mKgv9ZEspK1/uSzKG4CKhwGi6cU3L250yh6VoSRFEgZA3jMPV1dXF+cXu7s7O3s7e/v7OztYU+kKZsU8uJUVTj7zhBy4XkUQNUfzMi24xaTT/RhtD1QDlWUlquaL17yloNemOuq8yi2wz+xbgYxm1klvJO0sxGUBs62TReRkRu8EUUg5FiXmrgmrCjqoaHScc5Viw7HkpZnXpeTCsZj2eIf+2Hi46M4HNMhhmZbXGht8AArW+jLBRGkOc2hNJI0huId7qlBILciq1VqRj/RbbGisjyaw7hjnbmojw9tyWsJ5hgtP6PuISLcdttrX5+l7KtvyQgVabACvXTFmPJK+iVN17iKlLg9f3tBwWDy+/+vj0T//Zq//2fH2BEIKzXqBRjlWM/YmJbUnK4Soem0FXR4DwRJpGk1uiEEVc/WXabR4RW235+fkXH599uj0sI6aycrvFtgAUJuU5rKGzq46m2L30b0BeCuBM6sqyebGkus62i+FytTq/uDw/u9je2Tq4e2dnZ3viHzqXCZ2zLfDS166i07bkeX3OtkK3lW3nJMGVl1BwS0XiPyPdExnaGHiD+S3RI0rx9heApqVFmYAXti0BTLYVAzDACawEjWvBMkX0thwHZ5uMvbhZ7U1ykuARUeUjdSorLnij7Nuk2owyYUAgAr2SKycE9HEZKakZ2GU+Ca2BVW6UWYYmXQ+f8FCDYyTZLPrCGGUe4VnQNOD6uEHHJ9hbkOMHXNQFl36HUBOky15zQuqpT4wZx5/FbyUDgIlU6JX8g1Rl5C6WBZ9k4d0azdjQhuPVycfnf7qJm9b/fHepgbrhalpzkjATn4RvaV1L4EN1K2F2jQmkcIWsosDJ1K0qKsu2+PrqyYcnn+4MW1PHVJBdvaYK6EOpeCqbkFn7CFYl+Rhr1MHV2pgRsrNe19mNy3lN1tzbOKxWq6urq4uLy+3t7Tt37+zsbeMX00SRZO0//Wg6Wcsa7xWSvlNGqxCE5Y904YVt5RKl53AyI2+UUDs7uUjmbPYKopfuuVhUShL2kX0Y5cVYfF1mgkxdQo27dzOXni/OACkt4txWM0yjFQnLuw08VMvL2+pWGaJOEiR+3/jD9R/2cHQklL7avlhyrzbdd0ygl1BRfdmN590GRiIsMGUrpZc+R/c654VJz5RFX6eZHN3OrE4l+ajtDqtT9EMU1MaagpIOv5itxLYwjMzSb/Et9GSYSWGbpkjRj7kuYeIuZ6EkDYMEaNbDY9HGT84+++Liy+9sv3ozXTumdUqBxS22pWmt8mHMYdYxEhYzr5cMnkYGaeQNcS9vRwGHZDPB1KKtNtefnH12ubnaG3c20wbiCvJJuz0vNKfkQ7WLRU1CY4PMPVB8a6cFUY0MFJZaBDlFg1zXfzHNzfXNzerm8uJyub28d+9wZ3cHXBsMWqjUXGgUn4aKzyxIVsQHcWie4KcjKJUKl0g9hEAFfxxlVRi1tClpItmJqKSYV0/sdFgLMTwfWwFcsFSi08NwQCSvUSWYZj5JJGc3qTZ2awRotDXBaUKCkaMTMGl2Odys/Mq3xLK8pvp2r26xtHmSq2DVg1q8IIZBzRQgRJLjyJQk23JMx2mEuiCXZ6ZdEtsmU8370pki32riJca1VbZCE4VaEYCs9dI78VwaamqwrdEYMUz5rB0MN0vW4ZYZjYJDNQasPOA+ZzJkaveI2B62Pj37/PPzL364+/3r6Tp9X3/kxGvmEI3FKm6XmSL1R306MppZYrM2XzdUFQsckbcrcmdhi2E8vj5+7/kH28PWJJ0hNFNJ1D9JYHhhuVkxV9847ZqnK2eDLsZKNLmcYrItqZn70E02vAtsu1mvL87Wq8vVYmtx7/693Z2dDCGd6MwXAFoke5QJ8aCqKfOEPvIobMvMIDHqiFL+++nHJHZ88hpwQVZR6P3XIacNDHMgtYFkW5n5zdoiD4+mJmfWJvT4la40QBTKECiGmbYMUkQ4frm0pMA0VDa011ip0ZziBUFmJqiVKvAbjb+dBxZBfoRAWdzKIKNhajAIDPhS98rEVjobtcYWrPQghUs5C7wpa166aCfi3J0OG5TaFH6FELlO6cSRzlsGnu/R1xxMOyIcHGiWaAoAwFKKdV8evzJT2HWeYpOUFbfbnXlzoBoGR+UYhW07mPTNnc5ALM/wWLblZxcPPrt4+F+1pYXxF8MKt6nz6V5JxOqiaI/Mw6OFhbW+s6CXT3LyEFeDB2iPUkZZ/9lQ1JcsLBY+Pr8+fff5B1ttGTZZrQbTWqyxkAACAEkm3GVcw+aUhq85mKLRrSMVYV6KSQLRv+bA3YbgKK/ptG3emptN07S6XD16+GhYLF559XBnZ6e11ppPUyHZ7JGtBMIK204wbOUlluuL3tbgjFzi21HihmlBjLQKYPf+7S36lqhjpPzUOaBGwJOvslGVfJlaW3SvOIFKgBaVZMGiSYLBeKxXOgREQSp+jWQTnEqIbZtZeJOK4zqedsJnDKuTYoWSt2/y4SCrnviZayN3zlsnN8OXfdIeERrGtxCvcMqII4vHTYpjdArmzLJaE6eQdR4yds9uZa4B7ygzk2zb8gPzM1upRt9pkIkpc4v+5zu48ERzsXG4SJBwy1dm1L7IenoSPwnYOusr1WapBoxh8eJOHBK3ZoGc6Vq5kT+efnx8/XxsY0mXmRl+T7d2ywIw4FRWBnvVHI1PkBb6hVV3DQvOXpaEqitG5HPgl8ZJxmzT/AAAIABJREFUbjQ3/+ry6weXD+8v722mDdZFFWGmzbw5+5Qew2BVmrAgBe6+GCGTJhBqBDA96otsaxQ2RBjs1lTENeqzU0TE+vr6qy8eLcbF/e/c397ZGsfRvZVfdJv+muUwo1Q3C5tgWrpfs8Cy881cL9fAkVOYfHK44fMGaMxQxsa4MCeyBZocGd9BMwGoUkdNXUft52sAoXgslvQDJJgsRfhURF0EDPko3QgcVk+2aW5LFXeVKamAeZQcp2k31pew/c09mCor83PuhTzal23Jbz2SWrZLOq3yAHtHBBjbTkkL0ZSJjrK0o0yeMifmyQ3ZRAp0kneTyeWmorAZFwBvy0iHhjmWro+7Z1ftHNYHSoQzJd3ZJv1SfI2EQl8PJ4tTyyL3Tc3Njiba8vYJnUjw8z9hsTNsvX/60aPV4zd2f7DarEBFL7J4PywHn4Azq4wbRv1S/Ex7ZVjZuxQSk1Gpp7XkJdP8wCJs8HaxuXz7+XsLX4ghACq1r4ZOSIXkkVMXDQupxEmulp0I/qWxcmYmp2VuypKmFT1JaUbFpfBfLnWZs627r6f1Vw+/WiwW91453NnZXiyX7j5jW97xrmxrKrfZPMGDGkc0B48SX2Z2g3xtZiOl3uR+uu7BykQBRnpiXhjr411r9E+aKNJeeLpVdaRZz4xRcM2ZL/ZEt+5V0KJotxwkSKuDSst5SW3WqBXcEonbgmEqPQEC/k0+XP/H2anDMNBD8EnpRjIelTSHiJDGIKuEUoCKQbPhCU2oo9Eswy/RpBpFT5eB1Er7wJlG+zJj5eAAJjsjS7al6qMTVdKiDIGIJUizOhUnCfIWOF7NxtIqgxX344VGe7DFgQk1yzCofHFKTicTLKAsnyy2h60PTj58fPXkrw7+YjWtyMWcWteTGrMWkq4Z2yInChQyU4m17JpgV1hTY9N2g2Wlj2YxtOH0+vzNo3eXbRFxu6uGRc1niBLwrRFRluUuzLLkXDmWUQ02GFqWqYFx13FEVa8IbI46UqyFaZJgufdw/P3d6esvHy+Wy7uHB9u729vbO63ZZqPP3FplW2IU1ImQC7jM0i22LQeKZAng/j2FoNeHImFyYKHRXtSodwYkKWvApLfQxIjqZ2wL0ixYYLgS6HqxL5VDDHNxaxaEkwr5GicMgK0TpCjECC3X6paY2YLwnFvaN/qIcpHOPeprGQwjLoHrrG9PwjWYLalJ9uFmZbMixnQ5ZpaGVl5QOqV2YDarTJm3FAKCAC6RZE7CpZrQ5JYOvszzZkcVaxclQ1QSuUF6WvMC85DxoxmwxBAihvRS5bQ+El/n1HkypDZwPARLeFiMPn599eRPZ5//p6/+XeGLer817X6xHqg3S4tLPBe2TSeLtKplTLfLcwlDpqBQtcS0YWaDt9Ob0/eef7jsX2PTqmBXEjsZqir580JK4yLcFTzTpfZbrrWrKQIgZVNJEJaa3lq2EiazhnwxNaSWcPdhHKZp/fjrJ4vl8uBgb2dvd29vx71tNpseW0asUnUhsKzUEns+SdaoHT+JydzMRvWqhJYEtofTS6GTZEFWkV5JpE5PKxktKggMUBpLe8I3zAmG5cPcJhdUm/tn2FZUrPJSwvITCLklo6coP8tRfCsPhZ4m42XTzOy4jcaF1SpIGIueMaijoNw1y7uHvfBofWeQpFioybaGIivA6avAf523mLiiwMgu5wZJt0V4S+rqQsCYZsoPqYtyI+Y1m1U63Q/JqWPCOUnQ+iy5v1Bp9VsswBwtmyyEhXDvYbY9br/9/A//zfXJ7rC9jokXSUZ5kWklabxbrQn5C+5Vq5BnEH0RGZVtu2SxtOZs7u7mm5g+OP34anO1P+5PsZnlU/4nHQiHQR4mgqwr8zrkKRSR5EfbNIu1DKLVAUvpheUG2UpYcQa6bpIVBz7lX+M4xmZz9PT49ORsd393Z3fnzp0Dc582G6AFnG2u89xmW6yesiO2zVnQLbY1s9FnRTPzts6NlEkCA429SULlc00Q6StRPvk2vb0bFc/SJMXMJuBad8ozrW2xuTMzxlsd87ktV63bSUX+LYkV9/4M7c+3RrUhackMU7msIDEZg4RLokuRYzvqOl8OpCvb8jaPPoGQxAh2o6fsgiYiQK5eDhzaEpIXk58mAWyrp9j8p8gaKc7Fjy50lxLOkFhiNrKSYQZykDrreHmg8F6X8iLbvnSSwFI0XSdi8mlrWL71/A8nN6d3lgfr9YpxphtO+s78pcm9xS+iRZmBGWXWsuS6bN7GWxSw9F2lz2/m62n9j8/e0u9kQC5VOSFNUqadgQgqJi2OZ4VpCbfZVmlmgQbpAVku0ajaQ5WXmlJAUPC6iLrfjOgL3nY6OTo5P7s4Pznb2985OLzr7hMmCX7LBNxiW/0stg2DsbS+rBLw/hiLoXDZHL2ln45ZrtRE7gI/dOvLk1P6ZGuzX+PsJk+ERv/2IKJ4VskIzRnVFYhhoXSESeBQZah5pYFNjBikAlLApuX9th4wi0Gc0/PMDKQAbuoDSmHwBoNQ0Ldb8REian78xuSwckaUJtLM5uFM1zcXgpmpNkQ9aD0C4lk6MlOJmIyKYTl8Q7nlYZg4vCRplmCl8aPks7WFoBSFsGIGOinUakyzXe9d0TbljCuUhDqgsbBYtuUHJ398ujr68f6PrKSweHLsi7pjVqm3rMtUOebpGYufrWwbqK/IFwoRy5KCbfvJ2zDZzT88e3PwISxSU5ykSQ5hMRdhDYKBMuhJpHQvhX01YJCZThm2svGZECXl20yWiAbCmoZCPJSlT7zWkYQP4xDTdHZ2fnV5dXJyvr+/d+fwTmstYuqSr+ltP3dlWzevJMv1I1H1pa45Y2R5mzZxa2rmztokEdMqUFaMaeiXuC34obKf3cPRxl8YRBh9KU9qc8+KibrRpIkJbrNtKIGCQG8AseW+UfnyfiGhQXXTz1Xj/i9/1D7M3M3dJiLMOb2qwfLsA6trRbHTyzLxs2iwVBErR3Xjsky8RYmHQIWnjO5DPqPQI7w0O15jbxKzUgU4RZ6pENV28EpBJ96no/1DQmmLy2DSTNRCo5YDd9PUUA6w+HNlgnKUqiRnn/NyI9QK0XSbkB5ARmcT0zvP//Drw18O3j91SvPK/9HZhGq+bjT3MG40oQlz8anE97a3DVFbH/7NCyQvaM3swfmXX15+PbaB9QgSqNYfWskpe46xMIVRGeEeQXpUZqA855b2HG1TrlSUku0QII6QhF5ydyEhCMKklLJLodds/o5hGKaIq8ur69X18fHzO4d3Du8eemORFv9P5nCxbeFw5oslppc6zEZLlqe1TIcrDAR/b3DJQZ9mqzNpdFMR0ktyYoPwRWoirte/5lA8aEi7ZWRYFgSJxKWzBVtD9Ury1IhreOC31hfR0/LY5dCSaz7o1jrp9jc2a+nz/zUeDs9CH2QW/NCoqdig7qKs3pkqUG7BX3PvnSX6hzBL54ioWesNWX+hyV4Z1QXcrbaZRcbZQPSPTppsiMq6v2b0tJRcD8dFQbGBGszRKDw7/5RH0olH4IO3puoky4Xg3is3AWAW+AIB68tnzJOmGPmP7oQaxaNzM01V6jpRT4p3j4jWGENJGFAd7lNMW235fx+9+d//6L/dHXZubMPzzAqfmkjSVRTw4M8eZjZJ6OGeg78D3DzPxNOJbVtycTcL2RS1niv7x6O3SPgRgV8B3lPmwlMngdpYpByHNWpUcjCZNZlfYxrIvL6CwMkX3RvnBJbknhkPfuGh8il8ETjbpFBKOK2FYdI192w9peub9dGTo+Onz+8e3r1zuD8MQ//jDnNkxtzb9jQxeSa3KyL2sBgNVrFgKqWz7wNng3ZQj3ohexkA0BqpbSlsm3Ew1hzVpbTsTB0dmoY+1hkvCm84fbiZecuhhVflibD++XUnJSgoOluTwGX1YSHRz21hZpNNLShz/xqPsGjeJptChju9vKlRyukVGwsNT01Pz4Zgpr8S0uHOH90iWlA3PM2Hi2JSvyjRHNxoak9rHHxL6bgld9009ZQ4P80PV6CmtM41+KEJdIC8z+RZc2Q5ta0BTwBEFWvnEk1Ypsq2uG6IDppr9zIlZUDyErbNBoMT7F4UxZaHxaIt/vHZW6c357vDLu9o439IiXjihedfwra9pvJbiuXWJSiHCEYHUyYo3JCqxwSWMBu8/V9Pf48KFQk7j7YQiBjDJrdFKDA8LZ0XCxkzqnkGLOcChE4uwESwkOWsT6lEb4xgU5K+EAU15Y6JmLk1DZaBKHpbipTYNmI6fnZ0fHx09/DOwZ0742Ickm3RINe7UeqZjXODqVcAwGRmPiaP4RVyNJ+hn7XSZoJJoRhOytVFrcxZs2OhWpn8E16RaJNonBMOWjui0p1DJeBP4wwml/HuQWHb5fOT0Fr1mMsqpS1ACzTZtDNs/4cv/rf/89nvV9O15zkYwH/qA6J169nm7XJz9en55wsfUzYBj+5toT9sx7rGqT03ba0nm0aCszCGOkeXFBgWXbCTZ4rNlHJUhOU1VQ9GU5ougcXOd3N0L94uwCEqeymWk+ZcVEETDrMUTZpKC4qjRSfEIzFV2RY8aIgStyGoKQqcnhqHGDO2FQiy3TKGtxNAe7o6+p8++fevLu9t+JGDGcP2xxS3SDZ/gNK19bR+bfv+37/+X95bHq5jbQoA9mXZscvZ24wak1vrxNSiuV+sr/7w/EPWPDlLAJMGmjpCUYSAynz27t+KIcuZkdVIK1lCr4SaZis7mKwcoornL2LOUNAscDe0d9m007zBVxlXVlrrvr/jZ8+Pn53cPbyzf7C33FqO41h+9WJKBZGt9bu/kOjRGMvELstJEw7+bBSUKCiX/vRDPCcsPpsJILfSG7kPDVVovUzMh2NQn3CjshlJIEb6pTXOAPaFBDeNxVAs5D544gSqh9smNnvDzr9/8B820ybd/sxqzPj2No/eekQJPnIe7r7dthZtjJgYsdmMi941va02a8wPZ81970G6AqdQ+ywNgjJKusguwlRqbOP6kgspQkWBZJ5Q+2Ehe56R9itvsdDxgOW7fek2w6woAqe3npJZtjxr/bJaVVokmxnbshaDLlsFylFKjx8ZS3wsLpqxr5y2psjM9bQzLP/nj/8XkezLH7f0N8hKfGLw8fj6+f/wo3/3X3/v703Zgi7mhqP8wEUDY32/es0SUDH48Pbxe1fTqmkWUAsnRIrqCROgZOBKDYql6YLS1Ryswuhq2MM309/wraQWtE4uYjUROcMgW5eiWNSI0zArBS/I5p69wtXw62meHz9/fvR8//Bgf293Z3dnXIz8WAIqUugsMoLYGx3u2CEpAmLvWkfeNl8vhzZWGS+9TTaP4mmRUQ7uOFrgSTCAiTKN0RwClSEOyXDBKYXQiV1ZWibyauVlnw18+xHyUGVTZu5TxP6w52NhUxbEn6PVBMDLX779yhSbSfwhynLjWLQG2Lj7Sndl4taBHoSn2ss0CBS2FP3e55vOK2DfJnJjAoJWOMvZqGgBq6Qiq/HtpIRmpcyLSAXsytSYa2Bch1CVba08SyNeWtQ+BBL5GDRfwy4uIKf0HZ7YehFvRj+ny1Zxb32eAMnH+qaI/XEvdf4/+niJr/XBh/W0/k9e+ZvXd147Xj1v3qSpRXstpbUyXhrHokEsPQtbtPEfnr21njZujYkqzGMGPoSbEZ1ZtQPoXmiouDyn5CvwfMZDpJYI5AwCqZm1MNJZCkY5WcZNIakguZWn+TxBnC0Tr7vDUvXOtmfPT0+PTw7uHOzs7+zv7S0W43ozWcm4cGhpvdKzjjl6mUEfa/RZHycnz7NEccEKiyc3a2rGw1B0QUostQZsVVKI8kokUCztBQ2YWoHi4bChrIT0rLMy0rW655/Ri5mbTzaBgrsmMVwsWkp8TSkNXzBS8EiFuVhNeDIsqeI22+LcKT0ClQphJj20FTxxErLe5nPL4hoewCv08dPsDkAKfqd/Mjl6Pa4Q+NK6tDSRamisoNBQRIkcNoFUH44OKp5FZ3+ebVGyapXNnLogp2fEYblDRDPAFyrbqo6TbRl2t4jsuMzcbGOTTUyjrit+CHIKWZ6WAwPa5raebl7bfuUnez/EbkhjQeDOHELOwcokoRBrpeSwcG//ePT2Tdws2zK9oHyYu7Hn7tYkCvQBOguNeq0KYEq+LFUaG+SI7Wt6CLUhxBwMWWSo5W7nGze6s0Jg86mgnHZGsHNk0YhIF1+eNbDt6cnp6cnZ+f75zs72wd07i8U48etknQ8r+VshPfwdRrX1CX32SXMjY7lZnEInL0XDYKDQ6SeNnmGularWGduqCJIqrT6J67kzf7TShbk8gUHmIMxD2u15eSbQ2GOI2eF6GBDi1LgpLNvYRBZkzQlkzrZKRsmQ+oBiHQgKK8NJq6zmUoA8NsiNOjGbiKQFoCPlymb3S8pbUi95n8HB0KXvu8W2Tt6jW05soOiVSKoWrsC6KDrJgJFtE5kMYX2SopBJo8tLw4tqUqYTHb3Wixg4CIDLYtXCSDkFzagJZplQI4OpkHQh15boFsUwnROsXW2u/s293/x4/42rzdXgjankSbgkq9WJqqQTEJroC/p2Rh8enD98dPU1UZrELL3lvNGSbYl1AZ8zU9kFwSBPN6ukwg1GA+KqL2OPnWopHtclFQVXH8F2O9XKAWCLEtRqzeJlnQvDqHUBXe42DIOZnZ+dX5xfnJ9dbO9u3713d7lY5J8nc8tdlsfI4giav3QfhDAiXDW7/Fw7y9xNdRvOEU4IoH3iRWYnanuNUVBd1wdMojoFvCJclwFVMTm01GIsTfKU0EIrHH4ilXWCm4HzkhmcnhkSdcMqEImI4lxQS9WlBcFnTMzSCNN/qrMg3MpAjuTGqsbQo7bfAGfe50UFzetbrCgpYUZlm7RZZcI1CWBkeXqUPYSj1mDOwurMGMDpywLNe5KIbgwqHjWclWwK36aOKISFbEqDagU8WS7hsw7NQk1Q+AxYBbUlWdW8mRZkTr/FQ73qGCPSF301Xf/04Md/sfejs/W5WxNey1xuZnUYXauOw6QbhE1ELNv274/evtxcDT4oGj3BgfKY8SD4qi+Afn7urMKcFtUUx9Q3r3Ut+mOd9gsEzyr9zvqqnORJQH3yVfux+ay4sh+Jymv5ZUwtE1oTWeTLvbPt1eXVarW6OL/Y3t6+d/9wsVzoMwliSPHkGJmBVI7oP1hGKy01wtI/AFFJFvsTomjO3Nm1gLp0JQ0NjJ13go2HBv1DUdO0zaJpy7uosikeRp8IZyVcJmkWq4K6oA6y7mo0BG3L0Xr3din3OVWiBSo+kAKjJHpliFodnTGLmCbj9AFi2W8Kl1Ha+wX4foCOSj6zLKwJL3tKoir8RkS8rAkn3GkZvDBqqp1bmX3eEoKwPFpkBOAEyZzPSp37aCN1Kl+ip6wSZiBZ4FAejc0mL2d0t4gbui6FtbgfQLdUdZJ/2QvprggdibesOFxHIveb2NxdHvz84C+Xw3K6ORtlibKjS0iaZb+TFiEpY6bNYbE1LP+fo3fO1xcLH5BGsi2JyVHP9CG1qe4RdICAd59sNj6F9AR5RV5fq6GEs9cFdIxlAaZAiRojrFGI8OCSPuWcPooZV0qUNRcL8LrQGhJNMkDHREa2Dc3MrlfXN9c3YNtX7y2XCxYEI+cWESOQCg7zsgtWbS9Aa3NPYUJ5LUnZXrOod/KsGkKOOLNjK7chuKn5WY2+COGcs3v2FGRbswSM68ZQpGflkpoOMN71E0j5+Xl6KvIAoY0cQeRj3jtH/2pEx5iW19PU5EHpIm/xC6XbZiPwEg1mX/stLG5ixDpkECt5kSXH4IWaP2uTUTe9hy6uHvULiaPpbPyHp70Ki/79FbJG8eEztkWTIUvDaPC7MUQ+F0sc1n2ZcJEsTdNUQiiNpRmaZZ2uwDRkyNlNT1qZ2zZycqRo0z4EUwX2jPC6DrEtK7KlH9WkJ9za1Wb1k70f/fLOz642q6E1Qg78ZMi9RwQ+IMoqn4MCzwJAZtE/U7i+/PD0o5vpejnuTVZl2z33AZ+XdY6d8RKRWWBRSoH6KQj8/jWHnoSgHPdsNZFmqMQz0+G0aFYEpnzNoaMETFBzypNFCPDBWMOnlxRLYKCKfKZnH4vuCWBk+SdzNufn5xcXF9u726+++sq4GGWZegXj74rz7LfaXYDPVCoiYqO4v8C2BI/8LN6TxZBqY5lJ+lo6p6TEWU8XTLs5jS6ObhpE+K1yhbNwJjedE/1P64oJZkh7H2GuEzMxxSX0opz7RIUScVRraupWU84svcuMbQtboOjn2mPmsz6vpC1tBU0BQMV/6+8lEJ9IpboTz28zlElomNUvrCUuqQ7myXzdPYN2zRkzbYsxEAMDN7Ol5X6Nr/STRe3x9Aa16Twl1s90UeVdp+ur8BdwKFUopomAqJMEN8PXHFAtqElVTxpJZ1sx31dxo2ZR/ryAdeb06+n6B7uv//LOX6021/0bicir2DMou2azUjGhnAEs/UPEZqst3zl+//j6+cJHN40MyWOkt1LMCm8jSIPc8YJ0AtyFVxL4anQiwd9Zl/6DYWSmkTlWRGXbTuSq0Dw+2RY5wBf4kqWzklk9Tg3T3Fbj/QZdC+6ZMO1vazjR5fnlZ2ef7+zu3n/1cLFYjuNgEVPEKLPmIFaZbyHYddse4esoV1OvSqSy1Wfm5WqsZ6ZEYs/rFyE2z9v4SaBFSGkcOgN6oSiOdiwb5HTbrGfkPkWf4g1gGMlYRIWNZawLqwnpxS8ypNQVJ9uixtmxJNu6wCeA1OkMu186L+hG9jZWKkPh5N1CzrtYo2RP2sy4FQ3aY+g+LQ51lnRCuqaDc1et5+Ck/1dFJuNiOZhx2pFiLbLEKnAqDi1hloHRLeD6JNnMMIPBQM/gsKjEZXXJtehrSb+qCBfVGJvUciw4QFpVsiwwUbRyLNSDaGZhsWjjzw7+4pWte4+uHi98lDCb0UyQNoRBXiEtoTJEPNsUsTvsvn383rPV87EtiBIxIZUlIc7OxWo0SEsz6QQ784pOdhevJBBc84SeSOU2Jd8NMyN1IrcLCQ19KWJUFIAEX5UUkRzFxgvBJvq8jEWs6DUjb85rp2K4S2Tcry4vP//0fHd/9969u8vtrcUwjIiDpZinmWOdlQ2wnRLbZj0bWsvsk4QtiXfflpgvuUJWEyZSphquJwcCiqczeTbv2o02im83ln1qWBYJColduDnDjcPM5o66GFqdNcHNc5jsQFEDn6EBGpJtScaC3rKOwCVfRYnnLnRuKywrT+piMyuY7qP6/FnyOX9Q2aN+RNhW12wc4srYiNJ1XYpn5KVDuAH02CfyXUHgwJ6npGE1XpJfCBeKWHD4Uk9pmlsU6FtBOQJrogO1Dij4+jaSCj2gCeyMM8Wl92eScy/1hbSup5tXt175N/d+fTWtmrfiWWaQfQnbkrTmBBwlf9aav3f64cn69M54MMWkFj4YQ57ZS76UsNnoL1fPawL+0hUx5rwaVa7QJA1XjI1Y+ZcJC6AbTRuDpjmfnKXKb2eejlIlhBSzLkspeq1GkkG2E5yusQAEp3EcVpdXX5xd7Ozt3Du8M5ZSCC94qa0TVUPKzc1VtiWW5uaMAkA11bYE9EjLF64N5+QEEaS9UXJFaEw/TWQRDoS72AtBm9qMtkT0K0OTRaHXXQwyb327rSoBlFrXC8XtCPcokW2zAXeSCK+V3pYPRdZVQS5h8jkjMv/GUM6okpkyhQyqntTCmktb7c5WILyEm74YEpGAEZa6alu9NtJEa6BayQumjSrGTFCnZRMOmTnumSG0kk8Az+qzbI4V9nS4Tv9GSSWmuDKATsxc+jgA1ksddsOq0NNslaWEu7tfTzevLO/97b3fXG5WzQe61CzwRLwxSVYUtuCGRsbMYjJbtuWD84dfXHxJLYiZ/Mm/FYNs7NRYcU70ztcBQlS95uIS86ibtAOWI1hlmjyXHKRk5SinQCyn48ZCYvln5iHJ7K+yqylMKTErTCbDNVt3WGKHVoVAJtteX64+OXowupxVjTA5p/JC6bSzKHNUIvIobOvZx2kBpeTZBCe/ANNEMbhcpClbxSCXT4EoJLDcs3shWUUsRXiYfhRKmdQatXdOQk05UxlVKiZjlwxxtVa2FCWGfFfOR4QtE8pLKc5PnWwhtqWNnKVNYE5GRS9p8O/ZjvQQzNhWSEzB0ZrzdOmhAGzANetL7gALQsiYIULfKI0vOCK8a45DnhQnLnWRbCs26+Rf8l4Il8RIx5J9hALE2LD6qxclTUYhl9L4mBFOGgoacJEi53UpffU/2vvBG3s/fLY6Hn1I5ac5STecvgR8AeKe9T8ISkzTzrj1f5z88dHV42VbckkMermMNIHEhjqs0ek9PT1S9TmSzpeybSpv6bFSU+sOKKjaX2XbGScxVYIMGFRsi7d1iOS4o/bCxszUm5WgAPcOS0o+tbSwLRkb0IphNNusRnmyeYQlnAyq8Croi301saPqk+FMFJB9BTebXNUXz11wW8EdYthWpiguhlXjgtLySlXzVGBXWDbJK1NCsdNEsUwSTPRDFpX6Oc2YQCoGpgdmzCW/6sp7+rKj6AjoMSzWRQQC/bWSpZkZc4/CxZVtKeE5BSxxQgrLvATbnd1HEGXOtoa+3ci2xrSDDROJiXLQMhzRzFqjjF3xmrlKNo8UHVxbNpqpAzvIUycME0/g4GoQewhnyiWjQbaNedI4vmVk2HQT6MFImlUm7BMllaS7skG2dd/EZm+x97f3fzvF1IAJsqZAROskIjBVZBkVvMi2O8Puh6cff3n5aGfYCdNsJVJn++rmFimnBLfYVsQA/jLRTU4h4I6ALvOsrXoDTOsU64m85ZLAn4X4IfmlkHLmO7faLCNVcnDexKAlw7MUoqaGvFxDw7OJYhnDiLCn05fPH3w16gifRTjRYsgoHIoYVrfe6RDnUmIsV9OgEhCqtqxM/yOdkAWJOA0oa41WghrHUCborCTmlCXrAAAgAElEQVRJrwQvZsILAc2aFYiMntVoqW8LrsxLmjgE0KoHZk2Q2Ih4pz6pH3DxRFGOpB28xF1G2Kxu5mybeRONFLatdKlQ0leUeR6zxyaOUKyjQGOi8xQJO4K7uknQIKQEeXaSbveRZcpQwq02gvuyAhwxvLZcih+rYdujEIptBTb94HMcCvwoJbY7KujZeEGJlmhS8iUPeFL6Kx+ksnOzdWzujXf/7at/u9qsWmvOOsT2ufiy4KSOF0YKdaYSYxtO1qcfn/1ptbneG/fW07qKhP+/5L3dtmTXcZ05Y5+sH4IgCRAoS7Zly0Nu2y3Rask/Utt0u4f8Au7RvuiX6IewnqOv+84voUtbLUuWLcE2aRIACaBQQKEKPwTxU1UZfbHimxErq3AsiZRE0jkGiVOZufdeK2LGnDNiZ54zzUnLH31HtgVY4gzoyaREBw8Iu75cVHPA2QB1R7/lkya1YjrotlQe6HSNUkiz7YhRSG3X1KhG8mEueW5LWgctGfgl21UVVQzFjqkP4u4H//lt/Wud5A1Zfq2bRJjgr0RApiYxATH21e1Mm/3qAcPna7adE6rUWE6XFoObMcyo5WikIjks7OEFMclL71jLrAiizN72rPYuFMOqK2zZrn8msUAHs10hmeqMVJbRXigoAbOpjpV22ebmNZohyFuxbWxR7P2Ixr3p3Vka0ys122IrqgYKjQb6AIoN96D0mAwdeLhBTLXZFY9NScv3AlAMVRXpsgYWvF17GJeQkFFHhND3ZhuHi6qJIgvd2HafJAyspWPZEC7RXO3mcD89FeG/5pCQdM7zizdf+NWv/fInTz49+IsMjkgOROxcNn2PgWPCzZRuHbe++4PXvvfxG7eubqYVMDRRPdFcolnAgrBVE6nSh43e6EQ0e+RheCoh7bc0vagqUoCdtIMSdLRmAyPiPvGkiFTarRgEkHLRi+BwtX+p8mOHRc3RLUULXC8xpEOpPI7z+YP3739w7239a+mPdWoQGeXeZXCpcCTM57Ct3SC6iUJMeSrNwgTVWy/YFvQjL/RxztBAuToNigx+Fzdsm0FrQ5YCIi982DT1b9OvQcTggIz1gVFKJW2SwAwMzGVNsUp+v7h8i4ElezTcouiJxuIy2MwfICr4ywWE4bRA4eIrCCbi1h63vB2omoGGq6MHKxkxVF6R0v5HGOo98iDcnRtuscCe+CSYUXWMPV3b8Ape1/ywHTAMdqHZlv0Mh2DtWb95uk69ZMLmS/3sxrax/pTDkH+N9ZtEM/vvUsTon+S0rYopP6KtTMJNZo2b/JWZtfC8cZz+wdd/9RQ3pE/DyEonOrX+WkVSwNBtZRBSyf6GUSoiz0++dHX7tY+//9rH37993EqdC4Ulmtpx6BNgBvIghm3I1WbUjjEC5x8X6WpZ7ZeGgpU3bVvO0xZ/D8fW9bsZ2RUD5a1COrrdbrYl3AH5pcMsQJn1x0JW2ZuViahiyk7x0fn48P1337v3ff2K9DvSb+nUg9JBuA1gSlEav6QffWvG5L3y8firRRFuM2cH90Vsexw0+9nvQcAm2wbTjpRi/Qkc29kilQrI0XNd9S1+KX2Uo1vm2dpQbJ+kebsxrFVHprL23VEGT6MviiHhpVdWZSU1T9grLYQSYxRUaDZw3VnlHsTJsDZ6BLpdalNMfQI98CNFDwQ2VV9zKNDj05rlL+eyfSG1nTO1WMHdjBmNkQabXBOVAGc2FShfAKXN0pDxIybuIugmKxj+AwHaQ7hNbxfQY1hzVM3ao1D9GaGBNeurebK9bA2cwn1pfcXprPPN4+Y3X/7NR/mo/mCSWcYd+ewX7JGDtsN3LzVEOjPiUOjVH3z/3qf3/8qtlx6fH+P7uy2ipAO4pJRx+B8EHelpC1GDVhyQcEB28as2IlTfX+tM0i4vkDWItNmBKrqjdr/ErdaqjLa4dSFlRnamJid1h2rXUja3qAcWrYoeNoMSGC6w7fzxJD/4/PP7974nSa9Ivy1JJ1X1q5Ez2LZ0x51SwLArsxlmW8tRZjEg5F3MUbszR5LbhJXNti5HdSZlAaNvt9S5tazko8+LbS3QVtoVNVx4pZpgD6BdzNyq0+gJgfpScnhcMRlsvdnW1yrXp4EmejWW1x2XYTCGI+QqjS0wZTWAT7MrCB86DJBPUu5WzXYriMPL1yY8IsoxQ/JQ9Gm2RXtKTPbmpEiv0IuHwsimX+fym3aUuphTx2i3KmUFo81HJcbDCAbH0cQps+1uEkuknqoSiiJXE2dUY9EKv5jgwO5qsFHWTsMDk8znrm7/xku/9iSfHMdBLCe1mr3UldR359Yqh6KXZ4mbx817n7777Y++c/PqRoo23WmcbLuiOlY2uljfYuxxUK2Mlqs745HJtRwqz4ZSZjxz+WhkaNtZaQx4F240+2vBtpViEt7MHZCe0NWmCHS2r1t10u0I850uCqETx5P84Pjq/efu6M4jvfvKIlkVz1IeW48ETWfTjLu+2h6upSu2ZgusRCV/pXBVtmqL7Fj3KbgdY9wPto12XpjQibrENDV5yUKf+xrZL5JZjNA83BItuYfe6nn48PDwlAOIjHVuLfgpQ2sl531adqFKMJnGIT0FlHYHcpMgegTAurcJxHdgg3dCgsNytYtdqWtyowu9VAh8zsA+u9iIbvrzQNIUhZnFqXUa/MVGiu5qx7qI5+gy0bViOQOnhACChFvGTWXowA1Vl/RTVeJE2pubgRluxUianwrqC31O+KmsiH75q3/3xRsv1F9Lio2K+8RbMJrhE3h79YTifOvq5rc+uvdfP/rO7ePWWWc3AzkFxilpgvfclXxjnpiKDdIgFqIj8Vlay3BvcgaDOHYmO5k7QKF8A5QU2zaR6TqPdzlQQtHSxq56m8RAqryvKS42ZHkuLxDH4/zg+Or9444k3fmG/u9XxOM05+tDzAKzR54oclGKEiNYIueWdgCd7DTb2vxR7uP2Awwpm5cK9mYuIp7i5aLEMIUgyJhEVK2QXdGGuqj8CmVfa4QfLskNNINtu9iFaNLsIyStTZpQ8iCgQwRptg3uiWeAMM9AjC385FNDGYI43GC9wWyb4bd5yUibt9SbWPZtLrEihK3IZg0TrJjjjbBvNCgQNgBDMRYFQDtGJLa1S3ugq+cKm0yrA2Yr0PSvMP9ohLBcssvF4LQ90DZ2uSBF9JAOGf6yjjQ/RRz/7K/8xllnm2KQnH6mxzLmDzPrnIBsNyZ14zi99cnb3/3otedvfPlJnt2IGB9JRFYMN7YVJKOOjdDU8bbuTabvNvh8oInWbmaFeV15SKdGbZRKcXm3iQCUCw23PAc1LdTuqUvhmrrUpTIKyZ4ho/eSGUe94fjg0ef3v3SnYPF//RuNx4ksqStwsi1ktrNtoIDIwWWEc9RjY72wtC5ly4t547Vh3lbsuxve2HYBiSeTIqWVTuXGtqJ9avMwaq1tDa6g67EB12xrxmTZg5HaUnQhUKAxovVMeqDRKv6ABAh7t6CevoDXKPnOZkzTw0jyYFvTw9aIoY1mwQVms60BHA6YAbjReCteuQBhErJ1bcTf1NByZAglGj/YViCo2LZ98KqiHGrYi0hfeAAHHGYd6EVHr0aysMxokbHoKunNR9mSqYbmWjBvHxWQoiR98+XfjHVeM+pCN9QazBsqEhqmh9Jh9bWC03H1wyeffOvDVz89f/4VfSXzCbWXFVQbtXaDdBqNw8G2KvVpHRAAdjtlpt441TgrzC1PCNY0or/ckYspOqfDDnR/3chtSe42oTl4zAT2QsLuDYpANoZ13GZI0vnDB+/ev/s93XmkO9+4IFnV31NggsN+vdChAgYUbEvNNkWNCHdVjAhnqu8nGtxuQ6mb1iGzQYUSA/oU21oXcqTCANgGG0LxuKR62sG1CD/N5Lpuvx0QBy824YJ6a8im6XCBiyI3enB74FSQ46bVBtXERpFXzGqebNuThJ0h7IEu/XjrTlw2alli9hTdzS5A1cSN5M+yQkggvSFy6jU/xdTsqkoxdVlkhHNQ0i4EWKvmlgGcst1dnepyR5Kym2Q/ORv0jW3DDJKQYidtsK1GCUc8ySe/+OW/8Te//AtpSG5C6anMHMfKIKAyAaqvknkjbtz79N3/9P5/fu7q9nn93c9iOahjs83bpM58g+PTKL5REbLVkKSe22JRC/4Zzql717WhgXlqI0F5e9u2A/CI0iQwkrp1ZJeSXyURnjddCON4cmdbi2pKenLog/Pb79+9q1+RXnlljguaZ6d7dK9ebOt3+XMZE/K97Kcj3JCvdOFkDJJlRi2cqWz+m3sbjVKEF1JPmC7MxfYzHFuHmVbrrE57XdBWwGZI8xXnl5xCQIUCqfGmQRKMBtwiRZcTpCIkjQRir9tUN71U2WqG0hJfTrqj6OKVG6ghn95yjCBuslSxKlx1KDvyvI20EYNattD92pwGWfdW1mULHubk6Zu1bHX7LUtbZnhsPPLghKLf0+31dTajYNTGjsM6vcsh2nWORqrd7rbARXdfkLQOCY1XLJ795su/cYoTfDxqEmzLMjP8scM8xy6umFTeOG48/Pz9//T+H92+upU6D2WtHBENQYlKIhIxNJ3gV62nPYzLQT23LRcEbw3ID4nBgqGNLfnFM0WlCveGEsTKa9kArcCXSe977BxjGUUGKVxppK63bDhrFLJCiuODJ2+8/8pd/Wvpd+QbXxePUy1w0NdkW2+zBDXajuuiJqMpwjfL1+FwEbNlBijM6oJaLylx3Ep3iqmN7LJ7rLjZlgKIKONXnUeHcuSxSlgtqFUQG7v7lcg5yrS4rZVF2hX7fMW2kBPwZBSqqr/FIC6PaBVJavDCHrutkuE8tJZjRwukILRlV3yroWyYqSKcwJV9IwFdSOpHVVSoBpSyDGEV5ibLI+24VhfJOkVR6SALs209rZwj3SFtdax7kUEH1ovhIYYAwi1AAv2b9Vs1GN0sgy47PtuS6XAjwqCsy9ZFOmmLacGN8tDx6Pz4n975xzeuTo+fPJHrEPUmiqTTKgfvVdyYKbh2j4jM8/c/fvOdT++/fOulR+dHeKOyiWrbtHC40U5xYeKlIqAi2DLh3+5r2GuXb8U9LzxFQbyI3VCarWAbJIyoGQAhvASofMSCG6MRUeLdA3emNythMsqidavA+kTo8eGDd96/e3d9GUG/pS96nGD8vczHWJRONusjmXCPk9TKVLpZ/MsEBO0eY9buD9sNFvUcGXmkHBGXrBi7ctmFnsm2Xs7o49K/lR+Pt/prewrlEXVBZkOgr4LpNK9UlMPo3wAPgoz6ybayD1MmvyJZG9u2y6k8Y0IXSI9BbA4/+tXpKC5D+o+2tZRbGxKHRqSyW2HSbXroWEccqORqoGHE9SciDoq7eGuMgIYFsM5m+vPfQbefDsBTbLtiO74Z4P1ytgvaaQFdn7fs/Trs67Xhg4YpzOQj+eHu2e0t/O9jN1jaws0qgRpNAMW2TYrH+qrC+YUbX/3GV//eVVw9jic2e8owJ1ntPUmzgeg4WzxRlCOOj5988gfv/9HNq5tjqMAhNg0bDsMhyEMDh7kSs77jQ98SUKDBn64HWi062/XJEnC4cEmYB8sz7mry5oO3WK62Jgbo5j9i0Og4XU9DqB4bx5L8otRj/egqXNtYH/D98ME79+++7i8j2OY8i2ensm7Api8eZJYR7LcceAw+C/pI3FyXMzynKlgXqOluaUS5kDjCXYsZ0Iq3rJlDwicOWIoN2bjTbmyWUVmRZtOVxbJ5Wf7eexZNSImd5bndj+cJi1t6Xth9Tda1THNCYGwk7Plqq4lPUf2BHRd7hx3gFnPbWEuADhCOVvIQvW3i5mqhRHEEsRmZIIYJbPPM62/UBLaqRasNm/fkt2iwbZu2aLY1a7SyLCUupZpc5htUiAEYhljxfC6l5coqXvSanb5jm0Akyu+JWOkUc9sVwmLb9TUHscK6ALbEXBYjMxHx2fnzb975zedPXz7nmY3BpnInK+gQC7iXh0iRrHOZp7j64MmH//7BH966unVWrvU1TK213dBzfGKWTEdWOaWgohVKxhCYS1eIv+bQTYU68ShjtTZokb9vnGlrVtCp7+E8Xa8D+AZoZXjpokkNB7tO17JcFMLIBtQh3XlkKM8ffnq+f/d1qb+McM2D3/Md7Nlsu/JeZIDuWR1jGzUXBQFxsy3zu8G2lsy+vWHhCk8XZnEIQXf3QdSGKU6NlbY3o0AHyuWNzUmC7A3Wc3Q12Kxs5JQa2xuR0oILm6/BnMQ7KE8L0igDD4RrV0DdgyMPaJdDWFeiSqoQl7SNSQLji6pE3Oa24orU6J0nX7VCR0fDoQY5Zls8lIcr0eRkqmvBIRZmTBXdoFhmW1lMhvrQiTlgzRq4PdgTsq+iVe/T6yJInBSBmWxVlZnYbh9Dzsfoe+KQY59qAlsBUqm8Oo5Pn3z6T1/+x/BsFXj7kap0ro68NMOlASiYuOjkiKuHn73/ygffeu7qS2edW4FMBntn4ztEVG1XQyWhgCHgZILvfqyejMFhy1jmOJGovjnsMg3VJcEwSe1uiRi2IURkgqttAEW5KmoGKGyM5Ac87F6Hbef5Q331/u07uvP5/DLCNY8TcE+TSTeW9owyqXdKLvfrVGOESxcsvapKShqeeqrcKCYCOnNO5hZJLURbUAdVnG7I2/DAq56j4dRQZB4Ew9kP1HEVFJuEWc/ZBgrnEemevaXFPdPl8Ckde5dkwKKRrqxqEYA285wmMFhxDCRqtLyRNaatwQxXQEAYj9yD2FHkx5Uw82db7qcZMbyJpq9xqaJclcWuJqJiZtYbjGLB7y5C8NymEBspujNZZ5iTTwwwr4FqZohdJgSKd/VJTVyMkQuHYZzDZuOdtEorHzePm7/24jdOV6dPH3/Gb95IWHyyrYZ+2dcmSpi4Jmadocf5+D++/8o5z53G6ZBq1ucikw2cUUCYsicpYGrvXCBqJ6Ny79pJ9q7R/VVxV0mrZw+TGGpmts3JYJYJy2TBWI0Gvnh9sm2fziiVMw2UV2N6fKivvKuXpcsvI1zzOBUaLNxbMbphmmGw+OQY6JCBXbKNeHa12mHhJ6vzHgAZyh1Gq5reaoX1tkurMZif8bLzMBmD4Lma+loeKnBK47YEeoQojC2t6bOFv4231K5u74pLX21Zu9gHynHCnM9Bkn2aj4WSCP8MR2PSa0f0OH/7rzGnSkpRyOdkWyBvXq+aUo7GnOy4OEtlotl2ASvLm+LL2t47nmnGa4XIisxICFWHc9F4y9AE4X2khpYD2+KYxXKx+dQ2yebhbMz37mYIJ9vWRsPRVnz25LO//7Vf/iu37tSW7R69d03nRUnaloz39jZDkRlxPM7Hv/vgP5yOU/amyCmlMu61UL+VC5602kQ1V4A5bHs8V/BZ8FmOI1tLB6a6v9nn2nINI9OyQEppGw3pnUfC3OJhBM1E0ktZUZZtIlt0DtjsFdwPP310//bLBdqnPif7RY+TL62eEw2ZbWM42Hbbb853QambrUhTgFxFTRFl4OQnoYgErVrsV1ECYqPFcEffzE2pxgXbWguAiNk2WqJFH9eMdcm25qtus+rYHFiqAjdoGmhzthF4FkTH2zMPuRTN2J5hODWkYjglLkS1VVsbDq6jOIJtaHMhq9YIol3PaAPq3NCqNNLWJF61OKprBEOQFbXJqGV0tC7FzaLCegbW9OPz8ot21rmx+P2WVh/yIIvXunWTz5Bp81A2uC0gZD2boXe2rUUecXzy5NN/9PX/5aVbLz45rztgOdd/4bwGv1ZhZHQU6Mtr8Uccjx4/+r33/uBGnNJRHSkWKQY8DO4vimeWcONwJMDDk4tOA0cQCCoOoY5gyCDkGrG4YNtZcMW27XNsyF3aTmbTLLUOQAsUG0AzeEPV4gp13fi689kzv4xwzePUDfwqGdiFJ+G/1gmAXbqNRteCvVjNUjS4Cr9uKK1IHeHNJC9NakovVgpMbHrmuEO/VzzkwMwv8//OtjI+2FoXkVnEbKtNc8W1RCM49Nq2FfDDtqCtyN3UEK0ctgtDsDAQ40VhfVPmYNjW/TBduflWLBtx9JaKi7z32JmLIPbATFCwvOnyf/16x8lsa7HNuQ3HzklMVy5bt0I2XXBpcoK0GAnVKhUFtBFswAcQGM0FEx/BmCM0BRxEVPx3mDWLSE8SiAIhjFAoHufjX3/xV587femzJ58fcGQnIU3j5sA0MBpeGytXbELx6sffe+fTd28cNzyXi5CD05ZU/WTstsnLLfs9Vf0CLFWZ1j6qMrY2YuAw0NSgpKckDRKOGC+r8wbbzoWKUnImXYAbQGcjMNgWyc9Q5FkP882Hd9+65ssI1zxOtXwL52AXERGiqxhMRckO1MQAUvOWE9OZi8mllxHeqsg8VkGtYHu0xvlwHzZvK/axJ+SZFsdzWyjYrbcbStJQIxqAyTocD2BEjbXHHXOIxZ+cWvs2C4It1nVqrevaLMU6sFDDp1sQNg1W617VykD4bIrkDXhLexQ7hj0asida6OiiX0+2acNT4UGtO8WRtdlANWCU8jqV11CSawrWbtKjI0ev5CLwWSxqudlalwcZmmGXSZMsK7bX+qTb8QUcuGW7qRBjgEKRaKfg+Pz8+S9++W/8ref/xtoHVNiOxQWEAGMoRh9tokkskZXgd9/7/WN9F3/ONeXItYzEBYtPtm2KwDyTWCzJnDEwSaioId4TdzG0QVn/8BYQDHANuoJPbbQXy4JS+7aImUmojFsfVREtu/AWNNeny9RDvfnwlbeu/zLCNY+T5xfNtoZ5Im/RKCuUs22Hsrk1e24L9pCmAhCQSU8zKaI2N20X8HsK58WqtmJN/rtR4EKjuW8jwaij4GS2NUVMJa3z1t277reHaq4QuhfO5R8DsBRaqrRdOi3QG/B6/FsjpIVB3EortR39ngnooWc67LkyEvi0yllNX7TMsLcUe3i3Lfcca1RdJZQ1NV56VFkCTkQQEErROKzIx6gHMiN8IjRdpUO18i+0p3EoHzusnNRYFzikANvQpsIKM5am5pbRIIwUlywrL9jWzsQEehVXH58//vUXvvnXv/TzhiDogl74QJAw7KzSLw1t7DRGSMcR/+7+76/DiTnjmSozcyaLA0GWCCuo6TgpniXpIyJ4+zZuVKa3kBrjwCrQHoEh5t6CmBLInFF3EbpK+yxdV8KcrOuu2rE1aZFcDLwS2Op51ln68OE7D99667/7ZYRrHqdZwBv/s/tMFK4VUsItGvsB/VbJjiFo2NEOc9xs65YaHT08TnCEF36Lb3JEuG5auU0+uEtWG8lU/z75sDCysc3SmiJGc5frezRUUbGtyGybZxhkGOOBPtqxiyEFHp5Tk2/z5MYjXaErEZFi3iAYIHGORnl9itNctj6zPwpAmAfrSh789vmSJMKbB942neVputqfyZ2NyPiIccF8bJbRy0gbYKMZqDuNMchSMCInrdZ3Rap+XHRQZzqiKIUN1O+UzsJ6JSl579r+wURnpdg82OHkTiIlcuT6msO4g1lse9F+ly05Ij598umvvvDLL936+qPz40NHYWhlFwPTrZGBuz4Ga/mXJybrGxgF9w8+/8ErH35rkY13yuXD9eZOyLYpRQdgKT2Oqt+B6vW2ep+LlVcC6Ni2OSL0B4Ue5qygoL4IIgvpWhagZjyd49505tziRMOK+VHz4DUyX1fdkglfrWI+Pnrw9p/wywjXPE6ysymUe2xiviiYmV0WqYS3Jg7AwEiksD5o7LqH050/l6I/VqJ6Ny9R6TmwbbUcbtDmKyqVw1anQofprZuPbZIQ5geQovGSy12dQtlB0DdBEaR2XXxpAoCAbQG2jkEWSbmULas/nFOmoz0rYDzoARPDMbxt/XUEcbuUcYiHPUURZpdhrGOYCfUQfGmLW5oql6cmCXCu7zlOhVB7pZE2dClwYz4v/3MjbhxGIMbUSpN37qg+VAOfntiMzRfbYhqSjgnnpFpZlft2+m5AnEP2i5Vzo++Tit60wvYoH79866W/+9X/SVLmOeKkvhHkdgY8VQG10+Rj9iv4FEaB5nyKq99/+IefnT+bSeArgy3x4z7aCls59za2rtblZOlplDn+iMRq6D3TqS3XNkKjYxMvEVQzkQXDXEBvwbf0QvV3eyjPNmW0s0hTuB+iIqp5olKkmUwSds7Q+YNPHr179zXpT/RlhGseJycHlKOTEe0QzEk4QirHPiYBXCD6CJs3LChK16qlAVIgXecwSm1Bcdcx2gRzlEZqEFR7427qpbG6Zgk0wmyrKI8w+r5hrjQRxViBzoQ21v8XHo2EHYQVZrOqNQmx9S0yT1vMhmyAN3ykwtFswYQeHOpNYHZjXUCsU9LQ+NzB9Fvq1IAqJ90GN7r8jADfQmppAYeADjVeB/fMuC1+9TfGrDB25ZK8J8IO0XfSanVUmh0WKERDicdljcKBNBbNtiM+k1uqCSH3cej44ZNPfv2Fb/zS878o6TiuCodJPGMs1TMBvylsc6lD9czonDpd3fi37/3+o/PjMsml3F64Ry42UTRUhf2ipjkvQplH3Llksy3QZQZmbKg3v7XJIVOnBdXeKDwN6+YMb2e6pszrVCt/HgOUdnU5IK3qHplFXcWHT55/9/bLuvPZn/DLCNc8TknvYPryDZfyZzIzjERPCkIF3RjU27A1bWfc/2QDXB587W/Dpol5ghm93H7nxLaaaKvHYuGlNb0pfK6YK2YtI4GNGgO/cEU06GJjWPIAp8P4qo0PnF3V0v+dUyWe9AiLtah27tKqCgkOqBCYJGq9+DX5ScmlkejBOBesZzsygtk+xDcGR3S2oUzjoOswB8tnuPBd3S3CY9Syb9ZEMRnH8rZ3ZEnPKZBK1buLKEAH9sCUXheBYmdTq7G01YmSgPYQEPom0+sA3pZHxCdPPvk7X/3bv/T8L2bmIfdCbSdW5n2O2ggoEXcQLIytWpJSv//gPz46P751dVNO2trWJUwQL5RFPV0dbnEkFHbNI1UAACAASURBVABtFV36YrbtwCd9wZQHDxmoeTd49WNFCiPjeYMsndH2v1U3yF9w+djKpdjC6q7q4KSID8/Pv5svSX+KLyNc8zgFut3a7O2jG2awwlY44WkoCXHsKVHhsGq62Vbeb1VdC52JU6OBryU6whoRNgt2zDRANLqWQWJyF+x6nmvx6nAjLHCOnECRDVZBpHsVH7g5L0rYZT5MZO8P/KrQN6qg2WsRuK1tbR+cWLB6WRVBkoycmA1aCoEi/MpR5jYVXe9CJnNC+VlsehhwjmydpWNYGKpxjbqWJHhupE0tdaS9cTjgMWOGQla8Whijz1dMwwLdz8kanWOG6Le4VFPqCA8ki2vNQ4s3znm+fXX7733lb0t6nI9vHDdMoY5u68igujahfZ+gJ3cr/jePG//to1ff+fTdBe5zZZ0iDwCbbZvRnHXusC/vkhsjPmWHI5hryoVEnXRq7PlpVwmXVV8jTEl4K8XzwrMBsxWvA4fq+41VkzYQ5YCc7TLZ57M+/PTR/VsvFWT/NJ+T/aLHCdxir2ho3GXVtnIstSchqFJJY5UMuJTJNdHQL2JbPYttqTGGGFuEbQd1EWEjzy182pAQVhvCFloz5OXq1lq8QDrCjcvM1IDGrrs2ZZPZbKt2mOPYnW1L2mGM6FFZwDsFKKn2i2wOtmU3zSDdnuATpfGk2kpaMMaM3poq8XEF+5/yFzQxo195BtvKy09q33Cpsje/9iSBF7qF7uoTrePaJPDIGG9L4N6aOhSiRg5DvLuRimpfW+hbduRY90BdjQ2EIA0vhEnx2fnzX3zuF37la39X0qGD23GLQTq6g20rrI7FmFX0O9ZBp+P0ew/+4JPzJ6fjqlY5xj8kDewYTrG/sVugAry30my710m6VJ5qUsPc5rEONZIb2w5R6Wtp0PZUfW+gqnTZ6q655qgsEsEBFbyXCJ/zg4fv3H/rz/JlhGsepwURqbs3GJ9dkd8GXPEIESzQhWeDhGP6WXuoL/a2GpU52bYk10Q06vwZEc5WQBN/NwzuRmrH7Qi9ZjXbBiu2vX3WyFEbjdQFikJQhKKtVqllFeYkoYNREB/8wf66wFLh+M8pAARjKyTsC/FVR7MiIe4iLFHvciniITyxdeWUi5pt5aKsQy5KsYlcXLostzvWliqZHkt7wGUFDDvgzscK0UqcpJAw+/WtN0ldsq3KYHX/VA6Dhr/eMt3ICKez4qzyrsgdh3nE8enjz37hy3/tG1/7n10WqxhtKi/ZNsneaKLhJPU7mBv83oP/+NGjj9fQYB//1CbiEhPWaeUl206mL5xv3nY8k7ttwuBUk6VB58KuGVN1UO2KbTbfTAPFMi1/tjjmoLFG+Gyehc9fnM/39eaDt/6MX0a45nGS0E6XzGhi1X2sFW2/G6GBJKt/c3D3m9wHqQtTsmatuJjbNqGNn4PMYWkuIxx+Kx5V1IzsgNq+m9Zz7MJH4xeh2rkQ43KbmKkhWP/JQJMM7ug5ULP+EPwV9LRfw+7JQ122494fPYjsHslzAWJRRDHKiNSmQpsHBqvriKLMKstEj3EHzEvzwgVnb7qV0nalSdY/VNfdeLE4Y9uKPGv0UlHvBHjNBQ1GTki1JI8IAK4It2HS/rAdMFcS6Rf3kkINNC8Priw/W9QKMtTFrlDqUPzt5//Wl0/PPTo/OsVp1MRyEPYmo/Yc2/VGcMemykGc4urTJ5995wevPc4nt3Vknkfn2stu5gPGlNQF1AZFeGhsm2om8B1Riqcw7EoXbjeia39yaSOqmXarTEtuR2ZX11VhfllPtVtA2AUecdw/v/Hgj//sX0a45nHqrhNjV2RJjBm4tJ7OFtIFBMxQMrytM1NhWCUt+YR+oomPOnQyMAGFgrau/tekFzZE8UEzqD1mYczmNMFpxSgsN03HPLtYXVpbWjM9ToDRLjyJg5cUN7Z3Y1tT3xbeFNJnyiTQqmtZ55Nt0KqXfPTEy64oMS0yY8TsSwFGbVzMbXsE4vmL09HUUORZrmd6nJ2C7W86itGTBIZ6LhvfOm//1RpvSvN2cDb9SQxRtATSHYHaAa/0lDYGhzgwzGZbA7x2xlNpXtkERnqUj1669fVfe+EbK3VNsl6dfQAu2HeTsgFl9wxhRZ4zbx43f/fBf3jvswc34iSEowce5jGJCgtvtkWTmV17GVS1SHnrpmrR84byZkaSsmx1rG4+xiS7KKLptyqzcej3h6LcTFDSIzLyiWpLAgno2Gq3j/ffe/vBG2/+KF9GuOZxWuKOkehbyaaelQ3QdGizNWZES0sAkUTObNtsGSrsAT9UUtCs5FO3gGxFyumqKUHCv/Qb4foBy6KqD9eC7WXV3Jj1kNNynWCCrzmozxdbE/zs2wCxubKCmNkWwFTwei+UYtvIPqPDW+zE782rdBD5VdlH7CHEzjGHWtMWj0fZWxFbMWjB3tyd3jJy6iu3PeP9vhMuqV9QFUKFUs9iW6IxtWctoRmxyDsgbPv/ZAbQ6r//EYYVYYt4xvr0p8iG0zdQnT0x4cDa21FX7UFfpYCvOdhTbSq9rnTE8fn507/15Zf/4Yu/KulYH8Bvawnt0e7PkCYZ45snQlTW4o5zPlHoDx/+0XufP+TXGiQn42+WoAXdKHRZb7ZnzBQPfBbhLYXKTodDPYqhK2QW6EqYvIiJQ97blVm1mOKPXbBpiMg4bB1Kob7L/7mxwM8ukn3njVd/xC8jXPM4yYA6bFqqMZADG/V3GthJ9Fv5oHyUvSwx6v7d36apsZWkiKN9UE+J5iRhdR9QjKXPJ/WtlVbLKueS2E09/Cnq2a1pkFhPtNT/aIsQq8whoV7LBdsehwcepnWNBRarrBFKQTMj+pPXQZlzdr5uVP8qzQv1K0sHfAeTqXRR0kEHJc+B7PVitFfpF9vuBd3z+MSQ4EFLWgG4R4awKX6B/hLBwUDMY0mxU79nttmW35TfrQCEF8ahCodUFkadP8IgXGlRs70P8wglQ9QoMWEYuBqMbpq55mi5OgXVDnSfMIYMjfQn5/Nfvf3zf/PLv/Do/PgUV5Nk58OEK1VXOGxmaU6tSbhoSdIfffBfPnz00Qs3vnauzxoYh1qf+e8GwSqk0ZyjXoWYKrOg1+pxxUGrQIU0PGJQ6oLJDgL+EAdsu+NwVmbWn9/gOmQ4vI6K8T5r69tC/TWHqtAj8+EPP3vnjVelH/XLCNc8TkO94bxqlJc69b86ejlS7SapSqPKZjAUPCHPKc1OMJw5eMpQkUVEplm1P1NQCaq2d22m1dIca99dM56eagXsHXJdAM5gZkPbt8AYNmVgyQ7McHrak8mOcpBBWYfqepO2CXBWGzAvWK/U3ZG4uDFU0VatrO3FsIJyCPGJ7V8Iaq+4asFdiEWg/XH4ely02pR2dr0IuKtriKImdq1CBTNmZ5Kdftu9OnRBwm5+vN4de1WWGbU4KZh+1Nt5y3QU9n9DZ4m0vWvYorYICXgkofO60sHROc9fPj33D178+yI0f5Kijer+3U5wbo8qIjPz1nHr7U/eefOHb13FlUjnXiWV+Rz9NUmrpon2a1Qr+ltJUrcvFZqscA4TEt2MzpKYVdEzomJOoxIcmkQb/OtaQ09h/a3mcqiIpxBLNvL98/Pv3HxJdz790b+McM3jZK8g394oUS9dUM+TvasodhrTWxNOqM8Inon4MHe0BjK03Gg2YPfmAeqD1WoRslqaHpwnOR1tmmD0Bp6LPsx7yAoGQtggiQ1VXrlsTCBRMFMOcsCJqVJtO9wKcIzZFuO7Jwb/SP9uL1hAG+VfPbRcggGd9jzANSIXbEbYpEWQ+04NpmkIJqaoI56jXAoxpeAj7HQadeHyqvBSx3Ejea9UZhbPX2ojdZQaubM+zXz47ak0zHztzKtDa3OEKSzpqDZkxSVIlcxK2PaWtHXOx/n4pZsv/q8v/UNJ8dTQ4JoHFjRbAizgdpChVz781lufvn17/eHFHZxuvAR9+aZFGnLgsMjMlyin27Y6e2iwUIf4wgQmXFex05fm/ovOhqlbOKJZrs+sFfbVW/fSaQ6Doh0BRi7P75+fv3f+sX0Z4ZrHqdAPaC7YlsZk9jxDJ0brQjmPvknaseXeY5cWSjFs3Ui9C3HpUTOyveJApTkshmqjFeCSiQ1o1Mim3I/0pGmZG+qt2HYE7Cm29erEHgRXTKPfdIUYFV+MPk7MkML+eLKtKlm6AB6rttmSSrGsh5Wy0QPjRiVz52iQEQFYyF6kjDJ3HUjDaE6MgBHF8Kim6cKvPXso03EkiMUQPZEJnzocSlwYAom5x3AVpNGjdeJYhM0Rcu9fLATBDnEbF+LYWUOBzFaz0f73SZ5fuPnCP/r6r53zPL8G9id8GJeVz0l8Skn/5cNv3f3k3ldOz591rhXSs/halVkP3sJjM8hqulVn0g2ftVWGCV3RYFsDHgPDkHRPaLI+P+kRAzSNqbU0i2PTmebcgzZG66LIOKSHP3x87+aP88sI1zxOrqHJtm3s0DrjproFb9guwcfaIPnZjnGRqQ9lIihYs+e26yyBYI3iphNReRyuPVuHmN6r2ZbMCArYLBzODSm0kdnZdjQuiyhz7Pxptl0LzKb1gkhEL7nC23SGDsASxYDluYUeNr0owpbAZ22bGe6hpxVsZ+GunLgJzxr0wvjEKsFm5c1jXrItexgtaNFzIWrFgsXS41yyLUF0rouCp+Dacvte31QIrylKs9JEaAbaHN+YUXVvlWAJvaZhyBbVEci1XW/WNABvn46rb7zw9444Hp+fnI7jT1O52wN2ZJ4g3YiTUt/+6NXPz48iIs8lkAOHYLMVLav6LdTccgSMdulGhHE49VkQcEv9Za9hGhWci4CbcFv6ZjKao9xJmys8E7CbGZ0skcqzIuLhe2/fe+NV3fn0x/hlhGsep5UfmGJjW+zKmLw4zGrP4FrKrZxbO+HmZozoc0jCVOQ+ty2dsqfxpE+oZUHfkwQ/6SRdsm3tuujFBoNdWOpX5igVDwTagCmabeeTF2y7eMCa1GwrWiWe7EoHkvswGt7FH85+o4ISFjFpdxLt1LEE67nG9U4wpufag5yH3ebW2saMkNt/joYmu4ppqtQViiiXc+qnWV3te8xtW82IXc4n0WtlpbmS2SjfBkCeJBTd5l71tuskMeq6QM6aZugAtzkau2DbJaa3r27+s5d/U+sXSf2JhwbPfFTMFKk863wVV9/+6Luv/uB7z119iYnWDGFfq7V1U1G8bFZhlx0YXLuPf/rYCEPN9T8q5KLbG9DXoMSeImObnG8fmzgzgXvDpwvZdLK2c1YEny6Q9O6P88sI1zxOFcohAU2D+yQBpBgw7RVoV21m1HPbrvEoWyAAV963r1tsK4cyQTUwohgYVEz/0uo3iQ1+aM7Kcey4GEiqHTSvk8yit2HANqaO6dOU4U2B7Em/e8/UdNjsNJZXWVAI6Be3QZIYFHxatDlerwB9F3q2H3A0G55mRHtWtZ9xGckyMjtJSBk+s5T6Zj7Tl9FVF9sqqW5iWHhzotUtgPe1TxLkFIZX6CJuUuhJQpsxsgWXjJFTbgNxkxQzQ5DZoz/R7hCOtVYAloo45/kUN7758m9wkWvq9E/xKPca+u4PXv/OD167dXXrbBGIJIRhyxh96zGIH7bJCyscUocJofWYyyDezEA3+nb46QzliHf0Ur6IbYcFXkuvdrKuuc6wTTt7UrcWdJbiuP/k+w/eeEO/8uf46YKnHycLjbryV0DSrUXScahAZkDjEdgLpJzCZOUo2fL0wgP6qr7utP+ooMiLSYhBgoE9jUx7W4ljIeLKH/3TENJ22sOlsYV1PpqoaLYVHnIBrn8EjYsaayFFbDbPFBZ31OXl1Js8J4um1YHTQrnbJxN8ENhxH0sWNrcX2euvoLpiaEuQoY5h7cudRFOsXREewjSPSqDO+5aGgAi2lXMPDRfbNkZr8XWYZzTI0Ihi43CIJExcjDg6seHzC5GO4com+/FdvkrqyHKPI5h1ZDR+myB+6flfvHPrpR/Ryc5HSX6EpG9/9N37nz34udt3HudjYOUQthpb4x3XgUPgYW1Oq75DKHEXBc51rWSMISps27ms6+LVosMXz2Rbl8qI+2wZFuTS0tAyFxkZVxHvvff2gzfe+PP4xtf1j1MPs44xEKiaLpI8uInNbUE4MuvTbFFvT2fAdwcPPEO2eZJKEcvvzxsuPb6wz5jnPLILOQOw9y0eDbaVsDPH0Xr4zPzZZpQNzMj6pB1GZLGjZi/dZUu0kk9wl2NaEh04eVhit7eOuW+6Lg/NPKH7NwFlpyeOLJatNsBcx4fXUchgOpT1O6GN6TqrfaU8Gl5UWnjgY/dmW8QI/t/YtmPvTNaxboLGlkz+JJ2y9e7BXrIjkcocQQy7tRVKB5Ffpo6iD192JJ+vluu7Gi9U6aiKoD4y12dxG6qCzwfK7W0FLJW+v7FgdKyhwY/zkUrlVVx98Oij//Lht28eN9c8bhG7R9V8tkFPhbDHXBU5e5LRjI2krUqpD8/St0eHl/s0HjhJlFI5k/6aQwrMErGtWlfrx/r2uesYRYDq5qnIyONKevDevXvzywh/gY8Tza+wnMZ8o0K8h8GbMtXlcnkfzCM42HC4haIy94oHaVmMttE0hjDb+Eha35ph/OYDLsu8J1IgS03FcpLCRk1uPj0qqzxR6e1T6iW34w0hHT3jVqrP4XY3GEaISxvl/ppD39uR1t9A4V0Gc/fb/hZRZcVHphbb0nG3gZH6CxBroYLw7IYoBkzhaHXstkfem21pCLEwB6my86uww7bVUPfS668blM3BePtkds6IpVMngmjb211LpqK+iyP4YeAQJql2xs0byu9GBbaVymQMvz3WPKKhHoEu8aZNkf75nX/SgPxxWNqIOOdZ0ps/fOuVD7/13I3bZ51d4jHGrBFSfb1zNoELhxTAznI1XGpjIWRUjkYEBrJN1TTFGkLjP3JiC2wKubRN4e1J9YdzcLj1Hiq53taXyYjQEQ8++uztN74r/YWOC/w4Ve1BCeV8utA61rSWPNoaAC4gF+w4G2zR5rCa5zajci1rXc+USrlmWkMFCzqhoPzSVLWdo3w9c4zq/pqUSNrIk6QYLaV9S9/eKJMTddcKASEAnpMYwzXhLDmKDsbozGiM8EZ2AQnxRQ3K9ngIQJdbBte05cmbcX5mGc4adBSJfcFm2qWVOa4SqACZbRmsrNR0c13shOVm3j6uV8hYBjorpkPy3XGWJkcHqXziQFcnVD2UGZoqvysdyiiwF1Dtv6iMnj20tA+oTtUniwGpiB7J9S9lnl+69eL6XYgG4Y/+yCwG+/4P3/zOD179+s0XHuWTofpzsOWOSSXEIDUHAxBCVwVAX96j2LZGCsQVePi2xYqXPLcF1tvNrkJqDsC7ONe5N6ftknCWR52kwZehiPcfP3fvxl/XnU/+XL+McM2jvqdg016bXk1X9KwHffeAboWjEE/BOZQYDuFoObfrKSBmJdzc5d0ddyG+uRD32RNVR7uI+IKUHP3RKcM0bqW16ARSxo8PoUh4pK2Ja1YyAVgOwiyodgwt8Baey41dML/oENo5VriK95m5EI+YOIVCIGWEX90zLsT3Pf6eEGnxs0hktM0ovYq0uNYNogqC50A9e9OKcWaJ7pIRbzRGeJZdB0iyAhdC0EJzrRXPcd2HMo6v01JJZGrc57XwRZBRV0X7DIew2FRuGqqs0zHj3EYa/vqs8z99+R+d4safvma/8LFwcnVcSXrlw2+d8zxDs4CTHa/WVLUzcVNuHOqCcAcCsrOz+RH6ow5AyIFjchYMfAmWPJlHobyegAkUu9NOPNMsZDuK5WTff/zcvccvSn/uX0a45nHKcmhl88pwUcHtaS1wxakt22nyoIGicQ63nFSqGFqKRIykSyJfvKOSCdHJucfl2ip2xbtHEZRzSb+Zz2BbqTl06ry802HxZf6G5QfbokPFYZZu8MOxQyF6Y+34ZwzCPMyTtrCOcrEtPNnDsGLbgJSHQuEUMKLDH9TaY5DmiKFHjBfWuEIUmJGqa22ESxlFmX23J1pn7FGQHZDaGgd9adkqNylgQUNQZ5J68YgAxrO5Qh5v4V0Lxqo2KV0DdUXVtnJc1x6usIGwkbwjjkfnz/+3l//JVfzZPzP7zMeqtHc/fe8PH/7xl66+dM5zC4Hk7YypyOQzoURVlxSJ4dex3HE4JjCUtXE3qrLI5SL/9jVSqWSfq7R5BrPXZ6etYY3nk1dnPfjhZ/du/PWKzp//52S/6HHqeBSNbpZkM3BmMmw/8jGav6wib2gKIOeIj0axV3nRsQxjyFuFCx6Owko2b7Zosq1MrpNtNZLkgY4rcA7XR1kOtk20g4prWtTOtkgqFs5sDjdwPqhyY35a4ekBfEd4NFvTR5ptcwpjYZQs+4IZfRaF7y50aor/4Rm84OgpF11B7IQLulQRULq2YOw+qyOz07ggM1lm51AlxiYY6Vi/iyGW397ulky2BUNTsZwfrbRtIix2r4a7prpI2fMVaFzDASNfESndvrr96y/+fWFCfywPrIfe+/zhHzz8o9tXt88dmcwM+03jZe0lcIkdfd+jyOltN7Ydz5KaVizVEEjOz+z2DFh3UtlPUp3dPKsqjfDubKseAPa9FunqrAfv3Xv7je/qzid/MV9GuOZxsinFc7Y76XoZd1GNrRKlYShXWQjGdMl5bit14My2dV5zczBFoiDq2OESaFC68MaUqEnrgm0bWyZ4t4m8C7EB+puThHZKbPaKE2+U2Vaus2xRbkZkfCUN1WfmgjHava0kFjicfLPtlHeNyQr/N+e6vmAd0yNoqwnksJdA1qDHdUqbLLxN5XxWggWrxaRFt2aXOWrXrnHYoDY6Q1O5n2Vi50bZVK0v9Lby8j2x0sa21vmOk2JPm6UHFOA/pjEY88NQPDo/+vUXfvXrN14YKPsxPByf7/zg1fc+f3Dn1suPzo+XfXf/l4bJAA5WEAlbwVrvCjsQjRCOEeqz2VYFyHQHwNMSE62ZSdnBVaX5Bh2DKbkbGmzbi8kcc1tdHfng/r268fUX9WWEax6ngRAPberHCoIZszBjphiaaH6sGpn9sCcBpj+11QnmurzRMVaXBuuSQ91k2v37zi4Dus5qu5N2fEO4tVUMh7pHGoQrSIIpYso0b8MYzJLqyhftbkU9laVEIsLb7EPSBVFEpWaV1Qw8/tWTkuy221I3sjIo2MYMpoyt+sy2MIaYzXXeyqaXgqYvRtkSTExTVXiVmIcoiX6P6Ygtspup3tLKU0Cb1iyhWsSwm5UcQdS4hZJ+snsPJiAu8kavtTSylzGGDTUqoCK41NVxfHb+/Jsv/8Zzpy81QH9Mj4j47Mnn/997/+H2ceuc5466MCSo7bDmMNyoZRobxaikp6Vw2pJROijeCLyvO1Xf5BzcJtTSgiEGhLcoxPrfMOGaZX1S0vHOo+/f//73/4K/jHDN42SX8gx3Uq8JOjAdqmpNM1NtU7a+CV/CXRe3krJ6rlPubCtYvhZKjM2vDeaNbd3lU3VudKs9qjNTsp6KMKUqkpExYDs/iK8HDuGyX13BkA1b6ip2+NZzQHiCdsodhU3z8FGtBfxscxFP2Y0SpWgVgW0z2Cnk2S0buQymdawktVGXJDeEGpOacAEy5gQl1ig4vDjNV24PSqBMfrmkg4hS4eEtQXybxQ2apHLDxQphDJhNfGpnI4b8ivN6eqKLmUXrks8XA+BIBAUVoXiS59986R8ccWiA6sf1+PjJD3/34R/cPN1Kj6AX0gFzTBdbOte4oUfzS76zPVqQ2pVD2GxrBwL28AfYNZImkoYWl/J7BD7YtgZONEGe3a3MWQvXls7Hwwd373//+3/xX0a45nGq/jXtAcfgrjQkcblaVqQsPApdbHugWhd9U47ffB6ZecCNkZl8oFG4oe1O0kis/JEQ+okyaL4NsukFeRnJPTzpT1inlmThpse0e0w72kW2iQekOCfbZurwAGrcClw7s2tTBaeVu/XrWB/LMUWw0x46RfXPLQFxHKMbH3ajf3sytjbd55bjjgpkXRZ3ACcGM7Z28abwtPDthAfVwdE4Tb7mQD6K8rfJTgq2TaX/qEb37mSk0l2k6UZCGXmo/lCAvX6J3QErtlmfDBFR/JHpoUyrc1nUVBZIvV9GHru6tGjHIFhlxKH4PB/9na/80l+9/XOSnuT5sCn/kR+pPOK49+k7//XDb3/lxvNPys8WuuzMQT3fzsDgrj0dXbG4TKWHDDbGGBAjb4Ww7ivM2xwJubhby3JWXNwkkN2ClB8ZbxTnwE01cQmUX53zwXt3773xnb+ULyNc8zhR1djMgfnBZ+FJs60I9adliArr0GWZoZHX6lK0ePBoJAfC5dBqTF8ktVqVSVNZj2TqB8rpZjkw5lDPUuJ8+9nEzsm+MbbJKGZeolP6IrZVxtFU4NDwxmkdi/oiMJRadLSUD4bwh7mL+OQ1Gu5asw0PyOZL4g+ryKKkHnqO3bVb9qG4eHcHOHPsrflHZltx/m0khHuiIZWCP8TRIay6S0WxcpCtxQPLitogh71Mz4sqGkfxO1vyMWbbyvzFJMFx1NbZYFp7ADL2G9ZSy2hM7Hd061znzIj4f777/96+unU+n3HvBteP9DjiePXj128eN9Ztr4Ief8OoWG46qagvu6Utko9YDf0IlhjqDftbtoSghtlWOwOo3SjGk1lULSUCW1v/bgdib7tiWd8gozK0OsRQ6MEPP3/7je9IPynjAj/in/+7/0Pcx24RVkXGbYfwthi97CfCdOI2l6mcNMjK/QEtqhsx2XP1Pxb90aAmXgmUr+rI7rl3KwZi59ACL7f8jMTggIvUjk2YvuEqmeEk+dZZm7sZtrrVUCtKb9L3cCqG1Q70hi5bUlosDx4C+i1RvGRbcJ9OHtzoyHit7ZiHKNCQWRDanUK6W/eQNpszIsRYHinZU6GGLcZsaV3anDijaRNUKXYHI2q3QtRNKZTX3lPrVAAAIABJREFU8EwMml+Qc6ynJwn0wAUctYGr7gre2NKG754pIk4NWEWc8/w4nzSrGltQ0TNrNZ/5D5AmonjEcTpOjMprje0XvVYYD2DVrXB3AmQH0C28yo2mqzhnwEYI2QxLjY1fRGvq3HQL4hEheyAToptGMoJ0huLB4+fefvyi3v3jv6wvI1zziP/93/5Lo6Hb6Qq83OvVc13BEaNshlgNXiVDkr0i2aImNJJGuYijIGucoUcM462U9uXy3RIKR1UbSFOnkOhxAvZSitFLdE/uqptsy47hZvmtfTU1dTpQxd6gabCaR4tbTc9I2dtu2/XGerGNbGuQ90HngZUny+ieqAaA72Oto3JbI+OgJ07hMBgE7T1H2Wukrpl8RBOmJoCDbH3RWsJ2pxq8dHi50Kh4+I09lHaZITb9HtftTU9SHTrflD5vna949AX7kc/46Qvf8gVvXPOyXsTgxrX3Jj6MOTq6KSY4lwSfGTSdUsytX4R7pY1teWkG2Euf1sIjxpm09aamJed/YSqUDx8/d3d9GUF/mZ+T/aLHyXruSSv3hxGO7oDxQ2tQOuaIfU+mJ1n9pH/C7dBsMnBXKWVyz6UDG/3aVFIwgdndl1+zNlMHRMVbylCv1mqnuBzHqFwuI6Cg2rpTurwLcHGrocdK64JQhBT8NK5VQWeAJaUth283lPbPC3vFhrgBzZP2KBYOOkdft+dGxa6OWlPTpNww0UaYddOlut4exHBlyOZ/DaSkwQBmW0NF0aXoUXJLQRBKLuDmn5t9zG4Je8/+19M8SaPR1L5G4M0g9A42ehP0JIJmzzyEzkO/DWC15RjE1zfcu7Gz9mznHS3cwgk6SNi6nu2X6BO6KmsvHvuMBGyjLiWGJMJ5Xv+LkXxBkFUkuUlSt27ykz3Adq+x8pXu/qZoqgCDI1rBjdDx8KNP7p7+8r+McM3jtIIKueWgK8nWa7BtT00wu616LY7r2BwVwbEq8PRMcyUJ5zxO4e4VtNQBnfRF+P36tnxfq5dv2AOlBOXuk9c6vS812xKOcNlTda7S6W3DJogtVsvZLAWneaNl7oLeNNJ223cRbAjNtg59xL66uRYCavK2v2hKBLxyfSCeRcE91y3uouiKdT18rRWNDF+w7QRQzwHR3g59HRANQujZjkYxAti13U2xZ/QtIBpsywIrGmjRNGNt2eTIDqvHKUmbJiv2gfIL7sWbyheGbQa6QYx+2xjmC8VHLasiQnOzU/KX0Me4tnH7NNtyAlKc6/RFssZh7Dgkc80A3cy1xmpOEozDwDGU3+8hkEaFjY/NrGWEjofv3r37vf+mOz/8S/8ywjWPU9f9iini1xEJShlyM50FkjgMMR2gMbD4pvDT5CLP9YZslRkOOdaDbXmbpEY5VmZb/vS+giwSt6hsto18Frs0ezVubL+7OJpt61y7t21eoDuowATjjO1mOVFaagDxw7b1jGzbskcnbTRTUWeb5ls722q2303VbaJAefqwEY9ajrvNEQxa5+jBi2Do5rHECBUIWqPDHzVQC1L9WImGRWFdGW2aTw5NtTozlebfInJqIZNVP2ZOe5LgCNblGqTaTGSlLWxIBek3OanHGI2wjW0X3GpVM9SpJr1mWw+SKLnLHI8FDZMYdF3a2NYQ39j2KRyyNJDT/TDwoM3SCOFGuJXRbg/6EgSoQmKebye7SFY/EV9GuOZxUgV3Y9vOiOt+IaicfijLZzVT8bauB63kZBj8FtJhw0ptO/u5bIWQXDtdd37w8JJYawLLjz5C0EO3SLGQSB9v42sD02TXdrPoy4DL0CCYmiRoVOZ6jC7NUBrNZ3RjTh17ALWCZZuNk8u2nm6odtV3H9fGcSOKaK5ayxkUjB5yfC736wWNpI2+xduk7NdGkJLyLLU7sXNbYmqmBnKlDdG78ZqaEwgLfpPKc+mqiaB7IW7aWFPNFYGe93XZMjHs+zRBpPqHUgit+Nri2ttGA7hHL74Dgq1v4hu9eHc0pVAa5zbGg7OoP+whpBcN8fLUpBt9ee933GvCaNmz0EeogZNQCE1iOE1jJZps68i5k5iGN6vkBtsia8W9y8m+8+j1+9/73k/OlxGueZxURVsAcGl0l4OxMHsWBRRX4TkovoqHyFXFtNKmtCo5fx49AjILMtzKKjxQqLdFn7fhl6OJnW2metITrHDoCj6x3F736EYFRp8TTratcMz7YAgMd0rHe3sY4AAHl4AzUxqhrgPLtnqUUcVR87rsqmueQBrRgr0HVTvykavFQUk8xgAgnTQ3JBvj2LMF4zmHgq2LoytOE1totHkj+mWzi4HktsXyAFTLM28+sOqZC1l9i/h8TxJC1+DE+oxDDb+fybZwXe5RFGzb1dKuLACDYhs01HlzjJy6WWgcmlRdowuE64X9WHEsuK5RTgWluwZ7qrXCBdC1FwRzWFSOHgDY8uAYgkMNT+KkGIculESwWlUWonBTx8N3797/3vd+or6McM3jdNFxu/attDVZ6zbS8rV33BJ5DgJcvDuKex2W6vw120I2e6zRbdsQVc+EU/ax3W0Xd5blKTTxC/W7F+lu0v0UBV7H8JLZpbBk4rFhUDE3H65nA6hW9/DtiYiVzdwBp1F5uX7jNYyewlxn3yzvuzvt/Nf/+HhhcVv0WkhIo3xRxGjuvLbqXBxe+KcSSnitkOSDDqFDwfUE36UNitl2uR2Ebkzd3cKHyT/NIKN3jirGTOe0IspfmJDGlQd6rCOLCizrfnohz2wtDjPbssenoyjvR2h1dy1AzMrg4MK2JuLA6PLzURReifUh9QvRy8H4/Wq6rj91AtG7sDKySmVO6VDjIMvdmOR4V0PKGQ9DMnwu5F820KPBlZxVNdt2wyt5XPAT9mWEax6n6fFgW9tNRfcQkEG37kGDKmMeOlDVy/qp6Wiworm8wDDUUqK6XKv8o8juwK5kX6ndrAzljDzG8AxHIfXyue5a5mBBKQ6GemXC1u7Q6GbbUN/IhRFmKTZNlHQtto7BluZ9Ym4Dz3nLiKFx7uBYBrKUMG2FFra1ZaMUd7btm7+jj8Po1mFEA94gHsJm1wgAu8kluuerqlubPXrRJnKD8LAkwrvBFkLiq3elh0kaFnD9ZxPqdolsE4ttK8E9VO6pKN6Qmy5Wb5kVNYSLFG9uebAt0SsZdNqsLsmGy+rCm7BuqP5wjv1/8Rs4DKAODm03RoqrTaibWexXqj9dUUrLJ3sk1Z+YEDoTQoNKC+UQMr0a7ChEsftFxD+yl0SVeAbR8NPOtvCBlFcPf/BJzWR/4scFfpzcMjfbYgKADpMvSWCZqGvRXsXJBk4a9Rfui8BJtEHA2zSZDwMxjaNtc+LMbEHJ/bB2g1Kh7jqR6g7B9laXYSOR4Ulv3UOiZ7NtMEkoFI55wzoa8nYHqj57dAxhvqYZsa5yO/gvVc1J+H4NRk/el6VW+LZnsq09mEXJW8W9EKYgvPY1TQiBJ253WuPXItRiFo8mbdVUAEqaVBtqkEfdiXDZ4wh4wOAM+YXiDllxQz+HylLTGFyTWygREBDVTB02Zs7pPk9Y9mMbnsDsIm3yQGPh0H6cBRiOYKA9Xt/izYHxBqWcHpWlnsdmaep0I5YMxJ43VzHWSW0OqFh3H6IHXsgTkwMyK4zVxrZyOi36sO3a7ll6/8ntt08/pzsf/wR+GeGax8nNjL3mCkm5D/fmRBjk99wUQsHpjna5GWu4BNiIrMmjARiTZNa1sM0ZbQbdjMiejjX1yHgZnqmkvXwKo2dLYvn1I1Qn80tRdn9yBqKAbQddUxE2ioNwA9Qvto1xaMLRfisVF2Xey7WEQ101AL0MhyzGWdMqNurtS9bp1uzRVsIzsrF/7CSG2/EwJdZyug2wHCmcTljG/4UMe9kQD2EAPVJDCmPmrkqGYVc5uR/xparrJOHBgcAPI6/S3xHDFmX0a299MydDTG8bFEZbTC8fCyvqQF2KA4f2r7kzdaNz64AobPP1wgcO2FVqm1InBTlLQaDOHDDAG1Efo+ic3byo2E5p9Dyjm0AHrPoTniHVGcrj/Se33370Nekv8y8j/NkeJwrYeNWcArSNSTMHXrPOYOvf3CmzbXkkOfcWZtqxPuPG9sxGpaHGbTzaujZoSLrvJNWx3fPYsxcFCAXeIARTuHT7LQt1LuPBLuU7n0VKDaVBuGbb2lu7x+ksMCjMXSbbQo91PDNTfFU4wpUmsryO9vJaH4azsNdg9zi2ljlZjNr7jAsSlO5Jxhr9NGdt6Imz9Cs4RtqItXy4cwQku//A4rUQq5voymWm+yYLptl2sMuIYnZT01puMaAetqGMCKIIYilE3yejYNz3meEvAD6sYEEa8hopc1+aY90oDuVHuJke2EDXifpu7Dpm669irgtqMOeHC1p9P2UAJ6lp49nJd8AqGH4qlE/i4Q8+efv0c/WOn9TPyX7R4yT68J56Q1NjdOKUdEiHKjkxdOT1fxq04dnT5CqYmEGYYrB9s23gndbytHoRXzSdyToBSKavMW78tlqA3WrJL4K+oQmuK6IaegG7UN3ohZpHc468dj7bHXAPap5mWxER9SSsA+LPB0i63NAF29be8gL6xW1PsS3XnB3coPbSGUDSDIiQ1aa6FGGvQS+kc0W+R0EjncUlPW7s/+JZ51SvcpQybHJEs52lhM7npCSzbZD6MfGso6pX4umqDAXHTralDOqKRNb2drGtHcloJH0k+SrvsRCfY4kLaQE8c9C/FNV1LMhsOjtpkJ1lR6O7vRXPhBhBZBPzcEnNtixvk2n0Gz3xaqyTzQA1ADmdj/v37959/b/pzsc/yV9GuOZxKlI0k5gWnCkcV5Ef5CrXhEZ/jUWSaNyHiagKdho8+W1X1EJamNLWuc5jFYyT6eebRhdpMh5gL15QSXRbgKhzF5qkqi52OO5vqAvAY6Rxp5f3GnB1+e4HwmO/3Df332fb5pk6JaW3NucyJ3bWGmES1ctZ9aw1uXjK2/Za9AVsGw78AAEJdUqbSvGzvVC/0s6f+XjXI2OHwbassbp7xk5hL1dipwJQa7mHBUR90AN+QIXWGbPBtr4uTFRcEQ1ezaGMtE3BG3PLckeODbkQiwVFY0kFVWiCrU8/ToSMkr4aihg8mfMFoKoRIJffKPNEvWBq4nHRKtBXggCulb6wcB/udRcIDGrLaMTpHPffvfvWT8OXEa55nKRBk3vL5Kap7YW9rjEz++u+v5sxXrjoz9RdsOilsRx2GHgA3pmQi0YRmkVHrecl23LAaNSGH5d/LBdVSd86t2peB+BaTMpeKWpOqcEhGmi3pxkzAII4JwlztjBqtStTPtQU1Q0zNVMADshPsp9xDLsNdcGw28n8FyPHC7ZtOjRCirnSmlRMmU1WOW06fh7W76aI62XHXU0MTaN4vMmIqJRCseWcMUKlIUZskHzsREVk74VyaF+OcOJLAsRAIoyEe5LUcfT9HuDUaU6MqS3ylKoJ8II7Q5XVFwyVo4R6vxXLZvHsWFmO3NHTQHrBmymx96mxx1hajqMG25LlzZUU+NGrZeeP05Fvf/76Oz8lX0a45nFSjKJb0SVDc6Jn5sh2AesMday7wZW/3AtLeDO5aJjntQ5CsTLRBD8aTWjqkr+2jdZd7MJaXFV1m20JXiyUsWBLDK9fzBxZmk1NO38u2ZMEc0gGPFoEuf4PgRlGpue2uqg62MjWMdsXudNuipDwGrK+lc9LM8oUvRJCNtEv4aHVTbCTXpHMmIsdTjSdh2gmZyueJIyhS53Qd7XQjhaOOrB4WMV0HZap0bBLzFNyosgGYbhNbq+3aBCkpPPd0cjdOVMZ2eiRzSZUWP7f6a6C6BkNtdGXrqgBYs3clEfotBmHJtyBw5IxGi1rQo5oNCidyB7nCGL04EaZ7hX2FqWtMXvyFK1Lf9gNaw9oKnNwdZX3791957Wfmi8jXPM4oWm94VayAlR0jbqnCbvUHBmb3nZ9hloGdsEfizUw3/4pMtbH9ro1ct+SmfU5Qjxn90NDdsEWtUblI5FR7FTva0DVLd02eoc9+eiiROG28w8wHSDRXqSjIx31aYAqyEBBvoBtY3HscSwrNO8GreLssZpd2hK4tuQZcawefo31An1strVdUw1t7HPaLcKkdt6QQbNtjNvEvE2hNONd8ESu39WMpmbUKfGVSTC67FvIYKeMduqY1ozgl1rbcpWB5t4Y8KjP+z4tekq3GEOkKnDCGrvhW+ja0DF2W6FVeK/NraMdcO9Qme2eJo6gR+/zUh55gKg1s1mpuxhxRmo0C321jDzKuQT3C4jGoXBjOIbnNsVmTJFGgtOheMo2jSKqkn5Ke5IYXl3pvXt333rtp+nLCNc8ToESgVe1UGcMmxfyb8C3AEeqcYi9agJUqNiWVk0+4frd9hqsJN8SKK9mmTRn2Eb7rhuslOvPcLittYeK5M9w2Cc0dWN0S6LrA+SqTSbLN+s9tXy2xd2WQuCSAlygurrXd3DcsmMgL73tMdxjSsW2TEwxsDLbcqzb4hx5jPZq2HgIcL2XxWWQE5iWlAZGKNxo9gJ7ORUkL4e2OIoBM2uaSSkecbRYD2+bWr/nv1VOMKaW2kqx/kJNO3XnOEOx3jREhz/RUKyYDuFwc3U6oL2iMeZQToHtdZjB1gkj17KMi7UlbHWMnCKcQHaLmuhsbHvrOx2I5MCh6jsd6m5qpCxq68lm15oPM2J4GwSgohE1PSQj/rKEer9TGGle6h1VEscos8SblWAebS0iuc25ajCefPDJm6/9lH0Z4ZrHCaiYLGErhBmbV+W5ZIuqVg8ZqpNf+Qt7WyOp6rvZFqBonQueUzcuY+QIUlZue+q46s8jADawANm6ULBXExvQCrlZamfIeGBVrQlflLOXX7Ax4XcMi4OWnwi6odmXL/i1IFyYKhxXsVp1XqqA+JNOVgi6usU5i0wsouWAGCJ65FfpTJvaYDSJHtGRJI6x3hCRfber542qBNhPRedjZTFtBNU3O8mNxinVbXlxuOdGZhmkPiDBwbbLvmadwv0MaruzLRRUCljWFwSoRcfncEpKrLLEJEiLHe4UkN60adodjMNEEMOMPK+3nrW37R6To2FbFifbdhGN8SkY4EEMm20J1UhvbF0sTkNWVDNw9kir41jMnL0ZDzCkM1BNxYuPvvTXjp/LOx+/8lP1ZYRrHieoE7EHrzHNm9Bi+hacRFENthOOkWMGDwuaLrtEgypQq/GjiyVh275N0T61LlUsq+k5G1vCcIyaoTxBcq3Qrb+oQ2FYG7P78tMrqWAgFtFU2lLuaVizi8tg1pMisMQygunYkXy3Es1nmDsWO8i7nRfCErDtymzfusEhCy4uv66Bg6VFLHcs0ETR/M+T0RsT5iqaGn3JddJkAT0E7XpWtILOV9hyiR/85Wu3HHe4enoLqg20EhA5g6JE7OVdLaCrWGzwBwLCphtEcg4yPTfY2gSxZTVI1/K34mNgUOtp9LYqZTgY07tGOEKl+hvbhpsjUgxnmiL65m+LmwUahWPjggncBa+JUS3pkJ4skv3sq5K+cecbr/x0frrg6cdplTFkqcbkxA1RdEGHAzfETVrQ8U0CMOVj8a7tRs3PSwon5kfPIjcnOLguoO6H21s3QujKILXmx4zsEbwUzYHCT7tmXaRwvL1AW50WnAYcZDrdXtqpwj+muLYR2IMczrg/Q6adbdXl5/E1mKYwgHWbrjbJY5jYfVzTvMccsgGp9CS6BAlvbGvj5o8wNbqKVhFaU8gCVg64MTanhOE3hCOy96x5FmZ/KXOJT23mcuwbBBq0ZvcuxDbHOdQ+sVdbG0LfyAB5sjpPdLky+lizbbtfht8tAn15NjsqEkwF6piuFiI4/BHQQnV9bjO5mcAWC2+fyJ8aDSty9EjDvHUVuH6qIqR4ovj4k7921JcR/s1P4edkv+hxsvexFgeGSCbPrQXIho7bkWZb2Zc02yL7GhmL6Zy5Y1GXBNvlMBZjjbmAhvarXmNx2KRVf32AidpLKAXoQWkVRnvbDWxmW0zoaMzTwGm2FeZnWHOp9xBlVKqkJtuG2XoMv6oC186xpE2yG9C9RNH0FmdzXe3E5Mx5m4zXGBV5hfW2UuJ5LMxPK7zWPGbml2z7lKZmZhtKNWRWlnFoboY7CTguXjHefMyeiWJRE7saXfYFhoVZqTYq5kh9LO0JayJbsjXWID4M3pIJJEScupiQ1q2CyMbWwHstn0VhnmHEtCoViF1j0Zaq4JpwM5I3xmjkt5ZILFygVa8jIVaIVqZ+C6GDbd1WrRCdr+7ff/Ot17+ddz7+xp1v/CyRrKT4rd/7Pwsf9FE93qEiIcvhM0SBmhuLoKQxOvK7xkGDOQyRhFDdcdRb/RNMAcDrzJut6B9pAMd4A9rqA4MQJG+VTWvC+SiLsIQouEuZJdhTeKNjoU0nm6jnmCTY39UcBCv0VMzENJZ4Q12dK7jctYgb7Vrods5yVu+YHMfo3pRdb+xJOjHl7H3ZbS21uB45jsCz1ovJylyOJwnmlWwvgGczejnQUdyg3Xgk59BoAWi0Z1sIN8aeGyUV3WwNo5IlqKYoL8xPj3GUY2Eum0OK9P+vJ5vlOUpPTxJQigFw051na80A9CwsDiZgv93bmbMVI5A+dvQX4MatEsSvlHTOiHM8fPett17/du3/t/Uz9li/59tDKGEvFwarLPo+Q3Zv1HB9agpQx47P29jtuY2v/rGdqK0kPBaGH5cKaoxWva5v46gqUxpAgB2mrTYGGHj640newrY1yMLSPlbHrktlHKrEz0AILL9dtGQ6ZMSBe2jCKnYxbW5LHJMESV1t2kqxb1C0BY5p/wajj+IbXeoqdiimzQz6IEdZlHmb9r0JZhPZhcZOhwZhjTW5wFzhbhzGhNZA7xRRmiN5XzF7dD4EIGagpF4tQ1j5AK6id05SAwiTZDfM/PJCbZtJgMEkoSFYgpMdw0rxRAbsqG0/DkaVURJLGw3FcDKjWgpXYcWS/TBkLucR/Htw0PpVU7CI3Nec3txK3CBdnSLvPn793ddf/2n/MsI1j1PaATbbFjSr8174aNtXHCQZ6dGV2aH38N31wB2pNEv3seB5cFAZ64GkNmCCKZqMbTWAlpnYg7LkflC9ZiYEk5eMVC4oTX/IA3qe7v3CVSsJlvfyGcRZxNfyt8FieMtUKNarmrYK1+LOVfkb6jl9PXwoHxAYFlX4KG7ljSV2V5gaxa4yO9AjErwEBh8TYTR1ii9sGVwBvIouZn+M8g5aHYoV5KE+oDH02OKpnjX0Wq2+RrfwdtOzri0VynqgFAYw3pomG7Y1LfWoaJF7o7ZtnAfDLCohIbMiw9KANytrO9sGUyMKwqG3KWFKsbHtqJYIj8ja3/RgKGnG6n/h+6EtLa09EHmfRbRSI1d1YES+d+/uu6+9/jPwZYRrHqdwl9+047Gr+4tQ8pm7rrmqyMarLWqdwHN3zPEi57AbKnKqgl96CpS2+WPxmDrLycCOGU9Z1CPCPWZm8rlJKfkAsGdiIOLgYjUtCMi/Pnir2VhXMCoaUVeNdNlMpWYM6C0puD2Ssd9HjiJ+Gy6UoX7hchGzPxJFBVlXBo0G9FwfvMVAwo+DbSEVqScJbNvsLaysy26WrSIjD4K+Wg01RaGS7bz5OY6jPZnZVsrkd0yHB/jc2GQKvyLrCZGMv1L71R3lhE3qwNuyIjdeEDgj1PpZmfw2co8IkPbuAy7YNv1HNYISia6WHu5SeEX764O3HpxYzddfRmiSDo/xVnqOw214DfwXlIDEwRXHcGNUSybKUOrSnoosqpEumQRwydHCt2mPZbYUIpsijN2IfO9evPmz8mWEax4nM2w3gTa4RZbFrViEwlK4m2gi05KoYews3uE3ALT1e/6rkOA24WXqXPiRMk2Hp0fi22a2vcZ8xDDU7QIgQd8u0DpD1cEhrI5RoYWI/g38yzf0/YeyU1L9iw7VgPLyM7M/aa7I7gzHkEEDm4rk9q+rMYgInwPTnKN0Qx8mM5XtLR5bV1avIgNBLSVlFBwa9zfmxGEY+tzY9lB9zaG0ijHOwsdg28j0LRyquWAy2VZ8hc7qqu3u5EiZMumWBNcduM+EN6GN+vM1jHKxm0VBVkP3DwvAx2iXtjudGeSPIQ8o4k8+CIQebGU9lxRDR0PH+kMR8si3wlts29W07jZy32xGzZpFNLKszloskst5YzV5TtvwzPS6VSxj0razrUui4N6gCY+zlgHa3pSn84dfffO1X5cOvfI7P6tOdj1O6obX2pVBZyWJlqpyOawAapYuBcmkWXikPBcouTcMYRS4mqYxEmX7gC2Oj5kZJxwMUPgaTVyM0VSbRzYeNc9wHazW2iiQJiPR6Zh7Iacorxhuu0r62fiC9ojhAmYvuJvOOg12UDZ6UeqlIlvPekY0mm2D806/DPbtV3pvKorAE1WCHfWebAzXlpiwab7Mub7QxrZOtbZJQhCgMUkmCM4lqKMLlixyWayOYbP0RQ1XihzSeaGLAqg0yLvkV2FICMzs2sw63SNbvLAnHJ9GzriTj8Vci0p5S+MN0f4HN6QgGPskYedaUKkhW9Yol9E8r7ODKkwcmiC6YCMctSqnQKkErGOg2ipXFR559bVHt34+bpzvvPPKu7+l3/6dZ5DTz9Aj/sXv/auypyXqueV2zG3Xy5Ko6XFTWRb7alNR+3Wk53f939VsrMxnla6artVq6bXSU3HMcKQ9AesV1zYi6NzVtZ12mjYOwftVFUp5qhmy+z55q+H98D6xIOhJXevshOmC5cHLNxV2g8Aio71KtbJ7eL0Q85kwo/hZxeCjMcXW/smE6WShKAiggghcMDImlWCL9JPTTOZFG8HL4w6TV9DjjY0kxeATIsmN7Xovk7xSPnQbg3v2jzMuxzoaHQc6WWN0PrgIgTG79IjWaUAhhuIn2dtg4VCDjTKjsyYb7sMRNL4vg0iooEJenmlryRn4CMZJJoFuIchr+pYCPsjtsd9REa9W8upJ4/g/AAAHp0lEQVRrj279/GfPrxP+jH2E65mPE9PObWggdaiso9QURZgxEe6WQhoW1V4jyHEBj/a/VF8YOKe3RjzJc9Xptx0xU/ekNemiekaUhrzlVsPngUFbhdHHzR1rm/TV+wwhLjTYNrq4bJopQi/fI7GK9zBIts6jKvGxyhx+NNWsHbZopKY9TnFY3+Mbszi/zXdB8CLVE2YLkU0m10PNlma6VB0JL26iCb8710IrXMsdUxDMca+u/eRaXqMDoelBuGAw47U66AFcX9dNGWxLGCqEaxAhXPpG41h9BULYzYqNoQYDr87afqSKos6djpitjju92lL9OKKzDWUIYi2LAVKDerPcBUdijJh6EX5yvX/FrrfWNVdaW9eojqjDruP80cc/Hy+tFf6PQLJaf+9WomtrzsNFzrmt7e2oXNr9mES7TxKoGHOTGVDdu11aRmoPSYxJ6iRWuQwuvtpFbEZvcrNDMytOY2h/VPtqL6xaG0zdEu0l8Mo6RRsBufJaV1zSdhX4yxYLFfGHC5rqBcVuKBxDtIhAmoIv2NbWEX1Zix+eaDigQSBwDhQR9VNLioZINzlPehNhrbJtamQto0FiLWuB+FkOQAl7txUPLycajKLj5Z7rBGzT9TPYNojhIE0BIO9EAG3KUE2EMI4rgp3kjrS2QzqKhSeOkmdFUd4WO72zbQEeBI6WagqqeVkWEHxLR6IK2lpjqqQyINzMAdXBth0zWt/Q8d47b7756rfOdz762fsywjWP+Bf//l/VjxUyuvOGBL368LOXwwQKvynKk4SeLDh3/X+2RdkZE23ROrjxYwql+jnHymi3P1WKyMXWz6mfHcci2N0LTgNnKmHAgb5w3YKwRvD6tbpuwvLPaCy9/IRbtuWjcdswoWYvmyRkxxsK7tbQKWeSwLuGyZ+TBOhsRB/dtR6vq3RVo5jzunOSwJu3SULFBW3ydcdaamN0tfu0ufbhYdKIB6/5IyhzeVxspbPZVoynGmbboGeAgFV4EgXbor6DpnN09KOMkhQ/PUlAdrdJQp/3Gf2metXuEfYg9nxuuGBpXppWqxmyLtk+oSXdPsW1PAW1pI5YFckWEH9b/+M8Tv1jGTDcTPPl8Fn42ekPsDCN00T2hjBuWU8bLuQ1MIiYP7sP0+M4Foc0/AVUktBwbJME1UJcfr6RbUlYpsr9MOaokVf/CACPHxrOJuDEZcZnLazFURTwSMV3v72dQek6UtXPFY9gjKoCYh8u2xm5o6fJWJ0h90xItJ39PknAGdWL0aGmbNb+7Ps9hJmb9n0Xdzca4tj0kaO2nzLf09v2u8dUQQ5eg9iHOWmVRuI+EMG1yuuNnpz9WeGXoYj91GMuOu4O2OEJWpvz0VL3BZ9A6donqkDnROSIoT1Oy3p4hsWxtrSXN4FlmXKoal0jbWzK05GuZzdno7GouqHuuW5bjbj32av3Xn3tZ/jLCNc8TmVW5yNa/tdnizStkUwADBo5Cktalmofcg0n6rECFLcOXyPOQTWbLwO4K+Guv5Vt3pIX1xMKS+rL20rpLlOS1Gtj264/bzqHPfMV8ZijncoGHJvKsH/jomPNti9zRGvXjMZNCLexVUlPsW3Co6PlSGeidtpGrULmuW3IpbM23xzKpjWJwbW18ubpANd1kMaCV4OPrtIrPXWs1ozT98HWTtfPfXOsPdnEL1CreNQap5FNhk3W+UoPiIK+0hc1YQ4Smkycib5P/0nUTHXIq0xOa8VN1H1Rl+ZadJcbSqEcReKpnCcNUr86+NRrrmUVaj3sIhFq/UtXCGzrtPWtncm2GvKtjDzeeyfvvfraz/aXEa55nOKZT4ORgBm2ScLlaCi3o7oiZcNBKbjFIXm8r8+QWCWNmWsq198GWL9FWTmOaf3n9INbIO914p4fjC7VB2pR3Fl5tI0+BlXmkTrHerYe58mR8jm0W1TTyQCjpC7WJj5ZZYziXoLroEnWx/Y4bWuStbNt77TTJkKVKZ0jDumsLsX+gUOO0JkflDpLh+LslnbbY//HT0J+XJqWvIVhfTjaS28tqPj+/+3bu3EbMRAAUFAFeFyHMpXgJlyvq1DqSIlCaZxyHeCAXeBI5tK8pxkef1gAC+AOIqXxZIwzQQ+XZ4kjITF+CZknxTr9IqdHK6PTr9KXqDuDmYAZ4TRube4V6p51qXdEGiM1rqlLrk6VZjpKuupFrm8/+pcDkX+K1mZSYvT2ZhLnnVN/8sp6yTV3WVs7vjbLeVgCR2vRnlr7/Pzx9velPb+3P6/f+J8RHni6+0pfNWPtHIeIvD9/HhXsuZ7HcTM/l2zrMTJILdRL1JD1ppbqoUerjhV9PNfuFSttP7aRs2APNT4Pu96tN/JhRM1Yz9rauK3LMwWZua3Lsfd7S9tRaclsrzc7vRWvnR/FjpUccZ1R1kZNmYaxGb9mI9scvFHq7hBnP0uutjed64+cG7XLN4ZkmaCzUVufj+dqI7NcTqA6AmWITqFL4JLCUmBZUssMreXWyZKR9prLNFumzpbmpbc1iTeSUVO5ZTHWMb3R1/0t/dG/j5+ttfb6u/1atjcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/Hf4k/SJfqkqqVAAAAAElFTkSuQmCC"
+ 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 87d39113d..68f96dded 100644
--- a/sources/shiboken6/doc/index.rst
+++ b/sources/shiboken6/doc/index.rst
@@ -25,95 +25,92 @@ Shiboken
Documentation
=============
-.. ifconfig:: output_format == 'html'
+.. grid:: 1 3 3 3
+ :gutter: 2
- .. 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-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.
-
+++
+ .. button-ref:: typesystem
+ :color: primary
+ :outline:
+ :expand:
- .. link-button:: typesystem
- :type: ref
- :text: Type System
- :classes: btn-qt btn-block stretched-link
+ Type System
- ---
+ .. grid-item-card::
+ :class-item: text-center
Using Shiboken.
-
+++
+ .. button-ref:: examples/index
+ :color: primary
+ :outline:
+ :expand:
- .. link-button:: examples/index
- :type: ref
- :text: Examples
- :classes: btn-qt btn-block stretched-link
-
- ---
+ Examples
- Known issues and FAQ.
+ .. grid-item-card::
+ :class-item: text-center
+ Generating Python stub files.
+++
+ .. button-ref:: shiboken-genpyi
+ :color: primary
+ :outline:
+ :expand:
- .. link-button:: considerations
- :type: ref
- :text: Considerations
- :classes: btn-qt btn-block stretched-link
+ shiboken6-genpyi
-.. ifconfig:: output_format == 'qthelp'
+ .. grid-item-card::
+ :class-item: text-center
+
+ Known issues and FAQ.
+ +++
+ .. button-ref:: considerations
+ :color: primary
+ :outline:
+ :expand:
- <table class="special">
- <colgroup>
- <col style="width: 33%" />
- <col style="width: 33%" />
- <col style="width: 33%" />
- </colgroup>
- <tr>
- <td><a href="gettingstarted.html"><p><strong>Getting Started</strong><br/>Install and build from source.</p></a></td>
- <td><a href="shibokengenerator.html"><p><strong>Shiboken Generator</strong><br/>Binding generator executable.</p></a></td>
- <td><a href="shibokenmodule.html"><p><strong>Shiboken Module</strong><br/>Python utility module.</p></a></td>
- </tr>
- <tr>
- <td><a href="typesystem.html"><p><strong>Type System</strong><br/>Reference and functionality.</p></a></td>
- <td><a href="examples/index.html"><p><strong>Examples</strong><br/>Using Shiboken.</p></a></td>
- <td><a href="considerations.html"><p><strong>Considerations</strong><br/>Known issues and FAQ.</p></a></td>
- </tr>
-
- </table>
+ Considerations
.. toctree::
:hidden:
@@ -124,4 +121,5 @@ Documentation
shibokenmodule.rst
typesystem.rst
examples/index.rst
+ shiboken-genpyi.rst
considerations.rst
diff --git a/sources/shiboken6/doc/scripts/patch_qhp.py b/sources/shiboken6/doc/scripts/patch_qhp.py
new file mode 100644
index 000000000..750789698
--- /dev/null
+++ b/sources/shiboken6/doc/scripts/patch_qhp.py
@@ -0,0 +1,62 @@
+# 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
+
+import fileinput
+import re
+import sys
+from argparse import ArgumentParser, RawTextHelpFormatter
+
+
+DESC="""Qhp file updater
+
+Replaces virtual folder ids in .qhp files preparing for
+registering the documentation in Qt Assistant."""
+
+
+VIRTUAL_FOLDER_PATTERN = re.compile("(^.*virtualFolder.)doc(.*$)")
+# Strip "PySide6.QtModule." from index entries
+INDEX_CLASS_PATTERN = re.compile(r'^(\s*<keyword name=")PySide6\.[^.]+\.(.*\(class in .*)$')
+INDEX_METHOD_PATTERN = re.compile(r'^(\s+<keyword name=".* \()PySide6\.[^.]+\.(.*>)$')
+
+
+virtual_folder = ""
+strip_pyside_module = False
+
+
+def process_line(line):
+ global virtual_folder
+ match = VIRTUAL_FOLDER_PATTERN.match(line)
+ if match:
+ print(f"{match.group(1)}{virtual_folder}{match.group(2)}")
+ return
+ if strip_pyside_module:
+ match = INDEX_METHOD_PATTERN.match(line)
+ if match:
+ print(f"{match.group(1)}{match.group(2)}")
+ return
+ match = INDEX_CLASS_PATTERN.match(line)
+ if match:
+ print(f"{match.group(1)}{match.group(2)}")
+ return
+ sys.stdout.write(line)
+
+
+if __name__ == '__main__':
+ arg_parser = ArgumentParser(description=DESC,
+ formatter_class=RawTextHelpFormatter)
+ arg_parser.add_argument('-v', '--vfolder', type=str,
+ help='String to be injected into the Qhp file.')
+ arg_parser.add_argument("--pyside", "-p", action="store_true",
+ help="Strip the PySide module path off the index entries.")
+ arg_parser.add_argument("file", type=str, help='Qhp filename.')
+ options = arg_parser.parse_args()
+ virtual_folder = options.vfolder
+ strip_pyside_module = options.pyside
+
+ try:
+ with fileinput.input(options.file, inplace=True,
+ backup=".bak") as fh:
+ for line in fh:
+ process_line(line)
+ except Exception as e:
+ print(f"WARNING: patch_qhp.py failed: {e}", file=sys.stderr)
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 d42827c0e..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,17 +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.
-.. _use-operator-bool-as-nb-nonzero:
+``--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-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:
@@ -194,12 +202,21 @@ Options
When '-' is passed as the first option in the list, none of the options
built into shiboken will be added, allowing for a complete replacement.
+``--compiler=<type>``
+ Emulated compiler type (g++, msvc, clang)
+
+``--compiler-path=<file>``
+ Path to the compiler for determining builtin include paths
+
+``--platform=<file>``
+ Emulated platform (windows, darwin, unix)
+
.. _include-paths:
``-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
@@ -209,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>``
@@ -234,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``
@@ -249,6 +276,9 @@ Options
``--help``
Display this help and exit.
+``--print-builtin-types``
+ Print information about builtin types
+
.. _version:
``--version``
@@ -289,6 +319,12 @@ QtDocGenerator Options
List of additional XML files to be converted to .rst files
(for example, tutorials).
+``--inheritance-file=<file>``
+ Generate a JSON file containing the class inheritance.
+
+``--disable-inheritance-diagram``
+ Disable the generation of the inheritance diagram.
+
.. _project-file:
********************
@@ -306,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
@@ -333,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 d6bb12653..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
@@ -19,6 +19,7 @@ Functions
* def :meth:`isOwnedByPython<shiboken.isOwnedByPython>` (obj)
* def :meth:`wasCreatedByPython<shiboken.wasCreatedByPython>` (obj)
* def :meth:`dump<shiboken.dump>` (obj)
+ * def :meth:`disassembleFrame<shiboken.disassembleFrame>` (marker)
Detailed description
^^^^^^^^^^^^^^^^^^^^
@@ -31,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)
@@ -78,4 +84,64 @@ Python objects instances of any Python Type created using Shiboken.
creating their own bindings as no guarantee is provided that
the string format will be the same across different versions.
- If the object is not a Shiboken based object, a TypeError is thrown.
+ If the object is not a Shiboken based object, a message is printed.
+
+.. function:: disassembleFrame(label)
+
+ Prints the current executing Python frame to stdout and flushes.
+ The disassembly is decorated by some label. Example:
+
+ .. code-block:: python
+
+ lambda: 42
+
+ is shown from inside C++ as
+
+ .. code-block:: c
+
+ <label> BEGIN
+ 1 0 LOAD_CONST 1 (42)
+ 2 RETURN_VALUE
+ <label> END
+
+ When you want to set a breakpoint at the `disassembleFrame` function
+ and you use it from C++, you use the pure function name.
+
+ When you want to use it from Python, you can insert it into your Python
+ code and then maybe instead set a breakpoint at `SbkShibokenModule_disassembleFrame`
+ which is the generated wrapper.
+
+ `label` is a simple string in C++. In Python, you can use any object;
+ 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 ac5e1c826..d950b6c32 100644
--- a/sources/shiboken6/doc/typesystem_arguments.rst
+++ b/sources/shiboken6/doc/typesystem_arguments.rst
@@ -8,66 +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>
- 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.
+The ``class`` attribute accepts one of the following values to define the
+conversion direction to be either ``target-to-native`` or ``native-to-target``:
- 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:
+* ``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.
- .. code-block:: xml
+* ``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.
- <conversion-rule class="native">
- bool %out = (bool) %in;
- </conversion-rule>
+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.
- .. note::
+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:
- 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>`.
+.. code-block:: xml
+
+ <conversion-rule class="native">
+ bool %out = (bool) %in;
+ </conversion-rule>
+
+.. 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>`.
.. _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.
@@ -76,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 ac22df558..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,16 +35,250 @@ 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. |
- +-------------------------------------------+-----------------------------------+
++-------------------------------------------+-----------------------------------+
+|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.
+
+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
+
+.. code-block:: c
+
+ class TestOpaqueContainer
+ {
+ public:
+ static int getVectorSum(const std::vector<int>& intVector)
+ {
+ return std::accumulate(intVector.begin(), intVector.end(), 0);
+ }
+ };
+
+**Case 2** - When we have a C++ class named ``TestOpaqueContainer`` with a ``std::vector<int>``
+public variable
+
+.. code-block:: c
+
+ class TestOpaqueContainer
+ {
+ public:
+ std::vector<int> intVector;
+
+ };
+
+**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
+
+ class TestOpaqueContainer
+ {
+ public:
+ std::vector<int>& getIntVector()
+ {
+ return this->intVector;
+ }
+
+ private:
+ std::vector<int> intVector;
+
+ };
+
+.. note:: Cases 2 and 3 are generally considered to be bad class design in C++. However, the purpose
+ 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``.
+
+.. code-block:: xml
+
+ <container-type name="std::vector" type="vector" opaque-containers="int:IntVector">
+ <include file-name="vector" 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>
+
+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``.
+
+.. 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>``.
+
+Now, build the code to create the ``*_wrapper.cpp`` and ``*.so`` files which we import into Python.
+
+Verifying the usage in Python
+
+.. code-block:: bash
+
+ >>> vector = IntVector()
+ >>> vector.push_back(2)
+ >>> vector.push_back(3)
+ >>> len(vector)
+ 2
+ >>> TestOpaqueContainer.getVectorSum(vector)
+ vector sum is 5
+
+**Case 2** - When the variable is public
+
+We create a typesystem entry for the class ``TestOpaqueContainer``.
+
+.. code-block:: xml
+
+ <value-type name="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
+container.
+
+Build the code to create the ``*_wrapper.cpp`` and ``*.so`` files which we import into Python.
+
+Verifying the usage in Python
+
+.. code-block:: bash
+
+ >>> test = TestOpaqueContainer()
+ >>> test
+ <Universe.TestOpaqueContainer object at 0x7fe17ef30c30>
+ >>> test.intVector.push_back(1)
+ >>> test.intVector.append(2)
+ >>> len(test.intVector)
+ 2
+ >>> test.intVector[1]
+ 2
+ >>> test.intVector.removeLast()
+ >>> len(test.intVector)
+ 1
+
+**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``.
+
+.. code-block:: xml
+
+ <value-type name="TestOpaqueContainer">
+ <modify-function signature="getIntVector()">
+ <modify-argument index="return">
+ <replace-type modified-type="IntVector" />
+ </modify-argument>
+ </modify-function>
+ </value-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.
+
+Verifying the usage in Python
+
+.. code-block:: bash
+
+ >>> test = TestOpaqueContainer()
+ >>> test
+ <Universe.TestOpaqueContainer object at 0x7f62b9094c30>
+ >>> vector = test.getIntVector()
+ >>> vector
+ <Universe.IntVector object at 0x7f62b91f7d00>
+ >>> vector.push_back(1)
+ >>> vector.push_back(2)
+ >>> len(vector)
+ 2
+ >>> vector[1]
+ 2
+ >>> vector.removeLast()
+ >>> len(vector)
+ 1
+
+In all the three cases, if we check out the corresponding wrapper class for the module, we will see
+the lines
+
+.. code-block:: c
+
+ static PyMethodDef IntVector_methods[] = {
+ {"push_back", reinterpret_cast<PyCFunction>(
+ ShibokenSequenceContainerPrivate<std::vector<int >>::push_back),METH_O, "push_back"},
+ {"append", reinterpret_cast<PyCFunction>(
+ ShibokenSequenceContainerPrivate<std::vector<int >>::push_back),METH_O, "append"},
+ {"clear", reinterpret_cast<PyCFunction>(
+ ShibokenSequenceContainerPrivate<std::vector<int >>::clear), METH_NOARGS, "clear"},
+ {"pop_back", reinterpret_cast<PyCFunction>(
+ ShibokenSequenceContainerPrivate<std::vector<int >>::pop_back), METH_NOARGS,
+ "pop_back"},
+ {"removeLast", reinterpret_cast<PyCFunction>(
+ ShibokenSequenceContainerPrivate<std::vector<int >>::pop_back), METH_NOARGS,
+ "removeLast"},
+ {nullptr, nullptr, 0, nullptr} // Sentinel
+ };
+
+This means, the above mentioned methods are available to be used in Python with the ``IntVector``
+opaque container.
+
+.. note:: `Plot example <https://doc.qt.io/qtforpython/examples/example_widgets_painting_plot.html>`_
+ demonstrates an example of using an opaque container `QPointList`, which wraps a C++
+ `QList<QPoint>`. The corresponding typesystem file where QPointList can be found `here
+ <https://code.qt.io/cgit/pyside/pyside-setup.git/tree/sources/pyside6/PySide6/QtCore/typesystem_core_common.xml>`_
+
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 2e41758cd..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,43 +138,50 @@ 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>
+.. 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>
+ </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`).
.. _variables_and_functions:
@@ -185,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.
@@ -200,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.
@@ -208,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.
@@ -223,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 79add6d57..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,327 +84,473 @@ 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"
- 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 ``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.
+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.
+
+.. code-block:: xml
+
+ <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>
- 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.
+The ``return-type`` attribute defaults to *void*, the ``access`` to *public* and the ``static`` one to *no*.
- .. code-block:: xml
+The ``since`` attribute specifies the API version when this function was added.
- <object-type>
- <add-function signature="..." return-type="..." access="public | protected" static="yes | no" classmethod="yes | no" since="..."/>
- </object-type>
+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 ``return-type`` attribute defaults to *void*, the ``access`` to *public* and the ``static`` one to *no*.
+For the *optional* attribute ``overload-number``, see :ref:`modify-function`.
- The ``since`` attribute specifies the API version when this function was added.
+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.
- 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.
+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
- Within the signature, names for the function parameters can be specified by
- enclosing them within the delimiter *@*:
+ <add-function signature="foo(int @parameter1@,float @parameter2@)">
+ ...
+ </add-function>
+
+With keyword arguments, ``add-function`` makes it easy to specify a default argument
+within the `signature` field
- .. code-block::
+.. code-block:: xml
- void foo(int @parameter1@,float)
+ <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.
+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
+
+ <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>
+
+The ``return-type`` attribute defaults to *void*.
- .. code-block:: xml
+The ``since`` attribute specifies the API version when this function was
+added.
- <container-type>
- <declare-function signature="..." return-type="..." since="..."/>
- </container-type>
+For the *optional* attributes ``allow-thread``, ``exception-handling``,
+``overload-number`` and ``snake-case``, see :ref:`modify-function`.
- The ``return-type`` attribute defaults to *void*.
+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:
- The ``since`` attribute specifies the API version when this function was
- added.
+.. code-block:: xml
- 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:
+ <container-type name="QList">
+ <declare-function signature="append(T)"/>
+ </container-type>
- .. code-block:: xml
+This tells shiboken a public function of that signature exists and
+bindings will be created in specializations of ``QList``.
- <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``.
+.. _add-pymethoddef:
+
+add-pymethoddef
+^^^^^^^^^^^^^^^
+
+The ``add-pymethoddef`` element allows you to add a free function to
+the ``PyMethodDef`` array of the type. No argument or result conversion
+is generated, allowing for variadic functions and more flexible
+arguments checking.
+
+.. code-block:: xml
+
+ <add-pymethoddef name="..." function="..." flags="..." doc="..."
+ signatures="..."/>
+
+The ``name`` attribute specifies the name.
+
+The ``function`` attribute specifies the implementation (a static function
+of type ``PyCFunction``).
+
+The ``flags`` attribute specifies the flags (typically ``METH_VARARGS``,
+see `Common Object Structures`_).
+
+The optional ``doc`` attribute specifies the documentation to be set to the
+``ml_doc`` field.
+
+The optional ``signatures`` attribute specifies a semicolon-separated list
+of signatures of the function.
+
+.. _Common Object Structures: https://docs.python.org/3/c-api/structures.html
.. _property-declare:
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`.
+
+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.
+
+.. 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
+
+ test = Test()
+ test.value = 42
+
+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:: 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.
+
+.. _configuration-element:
- It may appear as a child of a complex type such as :ref:`object-type` or
- :ref:`value-type`.
+configuration
+^^^^^^^^^^^^^
- If the PySide6 extension is not present, code will be generated using the
- ``PyGetSetDef`` struct, similar to what is generated for fields.
+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.
- 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.
+It may appear as a child of a complex type such as :ref:`object-type` or
+:ref:`value-type`.
- .. code-block:: xml
+.. code-block:: xml
- <property name="..." type="..." get="..." set="..."
- generate-getsetdef="yes | no" since="..."/>
+ <configuration condition="..."/>
- 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 ``condition`` attribute specifies the preprocessor condition.
- The optional ``set`` attribute specifies name of the setter function.
+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.
- 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*.
+.. _modifying-virtual-functions:
- The optional ``since`` attribute specifies the API version when this
- property appears.
+Modifying virtual functions
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
- For a typical C++ class, like:
+Some C++ virtual functions are unsuitable for Python bindings:
- .. code-block:: c++
+.. code-block:: c
- class Test {
- public:
- int getValue() const;
- void setValue();
- };
+ virtual void getInt(int *result) const;
- ``value`` can then be specified to be a property:
+In that case, you would modify it to return the integer instead (or a tuple
+in case of several out-parameters):
- .. code-block:: xml
+.. code-block:: c
- <value-type name="Test">
- <property name="value" type="int" get="getValue" set="setValue"/>
+ virtual int getInt() const;
- With that, a more pythonic style can be used:
+For the binding itself, use the common argument modifications (removing
+arguments, modifying return types with injected code snippets) to modify the
+signature.
- .. code-block:: python
+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:
- test = Test()
- test.value = 42
+.. code-block:: xml
- 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:
+ <add-function signature="getIntPyOverride()"
+ return-type="int" python-override="true"/>
- .. code-block:: xml
+This causes a static function performing the call into Python for the override
+to be generated into the native wrapper.
- <object-type name="QMainWindow">
- <property name="centralWidget" type="QWidget *" get="centralWidget" set="setCentralWidget"/>
+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:
- in addition to the normal properties of ``QMainWindow`` defined for
- Qt Designer usage.
+.. 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 d7cb50dd6..54ac6412f 100644
--- a/sources/shiboken6/doc/typesystem_modify_function.rst
+++ b/sources/shiboken6/doc/typesystem_modify_function.rst
@@ -8,35 +8,37 @@ Modifying Functions
modify-argument
^^^^^^^^^^^^^^^
- Function modifications consist of a list of ``modify-argument`` nodes
- contained in a :ref:`modify-function` node. 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.
-
- 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 f9e705b4f..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
@@ -253,7 +253,7 @@ parentship also transfers the ownership back to python.**
See `Object Trees and Object Ownership in Qt`_.
-.. _`Object Trees and Object Ownership in Qt`: http://doc.qt.io/qt-6/objecttrees.html
+.. _`Object Trees and Object Ownership in Qt`: https://doc.qt.io/qt-6/objecttrees.html
C++ Wrapper Code
----------------
@@ -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 4b8a05447..705c2cd26 100644
--- a/sources/shiboken6/doc/typesystem_solving_compilation.rst
+++ b/sources/shiboken6/doc/typesystem_solving_compilation.rst
@@ -6,73 +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 ade5e5aa6..e979c4ee2 100644
--- a/sources/shiboken6/doc/typesystem_specifying_types.rst
+++ b/sources/shiboken6/doc/typesystem_specifying_types.rst
@@ -30,614 +30,838 @@ 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="..."
- 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** or **field-name** attributes to reject a particular
- function or field. Note that the **field-name** and **function-name** 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
- The optional **target-lang-api-name** attribute is the name of the
- primitive type in the target language, defaulting to the **name** attribute.
+ <typesystem>
+ <primitive-type name="..."
+ since="..."
+ until="..."
+ target-lang-api-name="..."
+ default-constructor="..."
+ preferred-conversion="yes | no"
+ view-on="..." />
+ </typesystem>
+
+The **name** attribute is the name of the primitive in C++.
+
+The optional **target-lang-api-name** attribute is the name of the
+primitive type in the target language, defaulting to the **name** attribute.
- The *optional* **since** value is used to specify the API version in which
- the type was introduced.
+The *optional* **since** value is used to specify the API version in which
+the type was introduced.
- Similarly, the *optional* **until** value can be used to specify the API
- version in which the type will be obsoleted.
+Similarly, the *optional* **until** value can be used to specify the API
+version in which the type will be obsoleted.
- 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".
+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* **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* **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* **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* **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* **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* **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:`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 **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 *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 detection of inline namespaces requires shiboken to be built
- using LLVM 9.0.
+The detection of inline namespaces requires shiboken to be built
+using LLVM 9.0.
- The *optional* **generate** is a legacy attribute. Specifying
- **no** is equivalent to **visible="false"**.
+The *optional* **generate** is a legacy attribute. Specifying
+**no** is equivalent to **visible="false"**.
- 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-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 **package** attribute can be used to override the package of the type system.
+The **package** attribute can be used to override the package of the type system.
- 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 **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* **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 *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="..."
- 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.
- 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*).
+.. 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 *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 *optional* **python-type** attribute specifies the underlying
+Python type.
- The *optional* **since** value is used to specify the API version of this 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 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* **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:`declare-function`, :ref:`conversion-rule`, :ref:`enum-type`,
- :ref:`extra-includes`, :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="..."
- isNull ="yes | no"
- operator-bool="yes | no"
- hash-function="..."
- private="yes | no"
- 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** attribute, 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 **revision** attribute can be used to specify a revision for each type, easing the
- production of ABI compatible bindings.
+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* attributes **allow-thread** and **exception-handling**
- specify the default handling for the corresponding function modification
- (see :ref:`modify-function`).
+The **revision** attribute can be used to specify a revision for each type, easing the
+production of ABI compatible bindings.
- The *optional* **snake-case** attribute allows for overriding the value
- specified on the **typesystem** element.
+The *optional* attributes **allow-thread** and **exception-handling**
+specify the default handling for the corresponding function modification
+(see :ref:`modify-function`).
- 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* **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`).
.. _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:`declare-function`, :ref:`enum-type`, :ref:`extra-includes`,
- :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="..."
- force-abstract="yes | no"
- hash-function="..."
- isNull ="yes | no"
- operator-bool="yes | no"
- private="yes | no"
- 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`.
+.. code-block:: xml
- 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.
+ <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 *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).
+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`.
- For the *optional* **private** attribute, see :ref:`private_types`.
+interface-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.
+This type is deprecated and no longer has any effect. Use object-type instead.
- The *optional* **since** value is used to specify the API version of this type.
+.. _container-type:
- The **revision** attribute can be used to specify a revision for each type, easing the
- production of ABI compatible bindings.
+container-type
+^^^^^^^^^^^^^^
- The *optional* attributes **allow-thread** and **exception-handling**
- specify the default handling for the corresponding function modification
- (see :ref:`modify-function`).
+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 *optional* **snake-case** attribute allows for overriding the value
- specified on the **typesystem** element.
+.. code-block:: xml
- The *optional* **isNull** and **operator-bool** attributes can be used
- to override the command line setting for generating bool casts
- (see :ref:`bool-cast`).
+ <typesystem>
+ <container-type name="..."
+ since="..."
+ type ="..."
+ opaque-containers ="..." />
+ </typesystem>
-interface-type
-^^^^^^^^^^^^^^
+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*.
- This type is deprecated and no longer has any effect. Use object-type instead.
+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.
-.. _container-type:
+The *optional* **opaque-containers** attribute specifies a semi-colon separated
+list of mappings from instantiations to a type name for
+:ref:`opaque-containers`:
-container-type
-^^^^^^^^^^^^^^
+.. code-block:: xml
- 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.
+ <typesystem>
+ <container-type name="std::array"
+ opaque-containers ="int,3:IntArray3;float,4:FloatArray4">
- .. code-block:: xml
- <typesystem>
- <container-type name="..."
- since="..."
- type ="..."
- opaque-containers ="..." />
- </typesystem>
+The *optional* **since** value is used to specify the API version of this container.
- 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 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>`.
- 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`.
+opaque-container
+^^^^^^^^^^^^^^^^
- The *optional* **since** value is used to specify the API version of this container.
+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.
+
+.. code-block:: xml
+
+ <typesystem>
+ <oqaque-container name="..." opaque-containers ="..." />
+ </typesystem>
+
+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, only the **type** *shared* is supported and 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="..."
- getter="..."
- ref-count-method="..."
- instantiations="..."/>
- </typesystem>
+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 ``::``.
+By default, the type will be in the namespace of the smart pointer,
+for example, ``std`` for ``std::shared_ptr``. Preceding
+the type name by ``::`` causes it to be in the global namespace.
+
+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"/>
+ </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``). 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?>``.
+There are predefined keywords indicating the operating system (``windows``,
+``unix`` and ``darwin``).
- Other keywords can be specified using the
- :ref:`--keywords <conditional_keywords>` command line option.
+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?>``.
+
+Other keywords can be specified using the
+:ref:`--keywords <conditional_keywords>` command line option.
.. _private_types:
@@ -646,10 +870,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 795c9d97e..c32eb97d1 100644
--- a/sources/shiboken6/doc/typesystem_templates.rst
+++ b/sources/shiboken6/doc/typesystem_templates.rst
@@ -8,51 +8,126 @@ 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`, :ref:`template`, ``custom-constructor``
- or ``custom-destructor`` 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:
+
+Predefined Templates
+--------------------
+
+There are a number of XML templates for conversion rules for STL and Qt types
+built into shiboken.
+
+Templates for :ref:`primitive-type`:
+
++---------------------------------------+--------------------------------+
+|Name | Description |
++---------------------------------------+--------------------------------+
+| ``shiboken_conversion_pylong_to_cpp`` | Convert a PyLong to a C++ type |
++---------------------------------------+--------------------------------+
+
+Templates for :ref:`container-type`:
+
+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:
+
+.. code-block:: xml
+
+ <container-type name="std::list" type="list">
+ <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>
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 4cb154a79..aebe2cd5e 100644
--- a/sources/shiboken6/generator/CMakeLists.txt
+++ b/sources/shiboken6/generator/CMakeLists.txt
@@ -1,18 +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 Python_Interpreter_FOUND))
+ message(WARNING "Some dependencies were not found: shiboken6 generator compilation disabled!")
+ return()
+endif()
set(shiboken6_SRC
-generator.cpp
-shiboken/cppgenerator.cpp
-shiboken/cppgenerator_container.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
@@ -21,17 +49,24 @@ target_include_directories(shiboken6 PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
${apiextractor_SOURCE_DIR}
)
-target_link_libraries(shiboken6 apiextractor Qt${QT_MAJOR_VERSION}::Core)
+target_link_libraries(shiboken6 apiextractor Qt::Core)
if (NOT DISABLE_DOCSTRINGS)
- target_sources(shiboken6 PRIVATE qtdoc/qtxmltosphinx.cpp qtdoc/qtdocgenerator.cpp)
- target_compile_definitions(shiboken6 PUBLIC DOCSTRINGS_ENABLED)
+ 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()
configure_file(shibokenconfig.h.in "${CMAKE_CURRENT_BINARY_DIR}/shibokenconfig.h" @ONLY)
install(TARGETS shiboken6
- EXPORT Shiboken6Targets
- DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
+ EXPORT "${package_name}Targets"
+ DESTINATION "bin")
+install(EXPORT "${package_name}Targets"
+ NAMESPACE "Shiboken6::"
+ DESTINATION ${LIB_INSTALL_DIR}/cmake/${package_name})
set(shiboken_generator_package_name "shiboken6_generator")
@@ -62,3 +97,25 @@ configure_file("${shiboken_version_path}"
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_git_shiboken_generator_version.py"
DESTINATION "${PYTHON_SITE_PACKAGES}/${shiboken_generator_package_name}")
+
+include(CMakePackageConfigHelpers)
+
+# Single build-tree and install-tree Config file. There's no need for separate ones because we
+# don't specify any PATH_VARS, so the relative path of PACKAGE_PREFIX_DIR does not really matter.
+configure_package_config_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/../data/${package_name}Config.cmake.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/${package_name}Config.cmake"
+ INSTALL_DESTINATION "${LIB_INSTALL_DIR}/cmake/${package_name}"
+)
+write_basic_package_version_file(
+ "${CMAKE_CURRENT_BINARY_DIR}/${package_name}ConfigVersion.cmake"
+ VERSION "${shiboken6_VERSION}"
+ COMPATIBILITY AnyNewerVersion
+ ARCH_INDEPENDENT
+)
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${package_name}Config.cmake"
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/${package_name}")
+
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${package_name}ConfigVersion.cmake"
+ DESTINATION "${LIB_INSTALL_DIR}/cmake/${package_name}")
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
new file mode 100644
index 000000000..89cc9fa77
--- /dev/null
+++ b/sources/shiboken6/generator/defaultvalue.cpp
@@ -0,0 +1,120 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "defaultvalue.h"
+
+#include "qtcompat.h"
+
+#include <QtCore/QDebug>
+
+using namespace Qt::StringLiterals;
+
+// DefaultValue is used for storing default values of types for which code is
+// generated in different contexts:
+//
+// Context | Example: "Class *" | Example: "Class" with default Constructor
+// --------------------+-------------------------------+------------------------------------------
+// Variable | var{nullptr}; | var;
+// initializations | |
+// --------------------+-------------------------------+------------------------------------------
+// Return values | return nullptr; | return {}
+// --------------------+-------------------------------+------------------------------------------
+// constructor | static_cast<Class *>(nullptr) | Class()
+// arguments lists | |
+// (recursive, precise | |
+// matching). | |
+
+DefaultValue::DefaultValue(Type t, QString value) :
+ m_type(t), m_value(std::move(value))
+{
+}
+
+DefaultValue::DefaultValue(QString customValue) :
+ m_type(Custom), m_value(std::move(customValue))
+{
+}
+
+QString DefaultValue::returnValue() const
+{
+ switch (m_type) {
+ case DefaultValue::Boolean:
+ return u"false"_s;
+ case DefaultValue::CppScalar:
+ return u"0"_s;
+ case DefaultValue::Custom:
+ case DefaultValue::Enum:
+ return m_value;
+ case DefaultValue::Pointer:
+ return u"nullptr"_s;
+ case DefaultValue::Void:
+ return {};
+ case DefaultValue::DefaultConstructorWithDefaultValues:
+ return m_value + u"()"_s;
+ case DefaultValue::DefaultConstructor:
+ break;
+ }
+ return u"{}"_s;
+}
+
+QString DefaultValue::initialization() const
+{
+ switch (m_type) {
+ case DefaultValue::Boolean:
+ return u"{false}"_s;
+ case DefaultValue::CppScalar:
+ return u"{0}"_s;
+ case DefaultValue::Custom:
+ return u" = "_s + m_value;
+ case DefaultValue::Enum:
+ return u'{' + m_value + u'}';
+ case DefaultValue::Pointer:
+ return u"{nullptr}"_s;
+ case DefaultValue::Void:
+ Q_ASSERT(false);
+ break;
+ case DefaultValue::DefaultConstructor:
+ case DefaultValue::DefaultConstructorWithDefaultValues:
+ break;
+ }
+ return {};
+}
+
+QString DefaultValue::constructorParameter() const
+{
+ switch (m_type) {
+ case DefaultValue::Boolean:
+ return u"false"_s;
+ case DefaultValue::CppScalar: {
+ // PYSIDE-846: Use static_cast in case of "unsigned long" and similar
+ const QString cast = m_value.contains(u' ')
+ ? u"static_cast<"_s + m_value + u'>'
+ : m_value;
+ return cast + u"(0)"_s;
+ }
+ case DefaultValue::Custom:
+ case DefaultValue::Enum:
+ return m_value;
+ case DefaultValue::Pointer:
+ // Be precise here to be able to differentiate between constructors
+ // taking different pointer types, cf
+ // QTreeWidgetItemIterator(QTreeWidget *) and
+ // QTreeWidgetItemIterator(QTreeWidgetItemIterator *).
+ return u"static_cast<"_s + m_value + u"*>(nullptr)"_s;
+ case DefaultValue::Void:
+ Q_ASSERT(false);
+ break;
+ case DefaultValue::DefaultConstructor:
+ case DefaultValue::DefaultConstructorWithDefaultValues:
+ break;
+ }
+ return m_value + u"()"_s;
+}
+
+QDebug operator<<(QDebug debug, const DefaultValue &v)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "DefaultValue(" << v.type() << ", \"" << v.value() << "\")";
+ return debug;
+}
diff --git a/sources/shiboken6/generator/defaultvalue.h b/sources/shiboken6/generator/defaultvalue.h
new file mode 100644
index 000000000..d518d134f
--- /dev/null
+++ b/sources/shiboken6/generator/defaultvalue.h
@@ -0,0 +1,46 @@
+// 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 DEFAULTVALUE_H
+#define DEFAULTVALUE_H
+
+#include <QtCore/QString>
+
+QT_FORWARD_DECLARE_CLASS(QDebug);
+
+class DefaultValue
+{
+public:
+ enum Type
+ {
+ Boolean,
+ CppScalar, // A C++ scalar type (int,..) specified by value()
+ Custom, // A custom constructor/expression, uses value() as is
+ DefaultConstructor, // For classes named value()
+ DefaultConstructorWithDefaultValues, // as DefaultConstructor, but can't return {} though.
+ Enum, // Enum value as specified by value()
+ Pointer, // Pointer of type value()
+ Void // "", for return values only
+ };
+
+ explicit DefaultValue(Type t, QString value = QString());
+ explicit DefaultValue(QString customValue);
+
+ QString returnValue() const;
+ QString initialization() const;
+ QString constructorParameter() const;
+
+ QString value() const { return m_value; }
+ void setValue(const QString &value) { m_value = value; }
+
+ Type type() const { return m_type; }
+ void setType(Type type) { m_type = type; }
+
+private:
+ Type m_type;
+ QString m_value;
+};
+
+QDebug operator<<(QDebug debug, const DefaultValue &v);
+
+#endif // DEFAULTVALUE_H
diff --git a/sources/shiboken6/generator/generator.cpp b/sources/shiboken6/generator/generator.cpp
index f40aa6c94..a01326530 100644
--- a/sources/shiboken6/generator/generator.cpp
+++ b/sources/shiboken6/generator/generator.cpp
@@ -1,173 +1,43 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "generator.h"
+#include "defaultvalue.h"
+#include "generatorcontext.h"
#include "apiextractorresult.h"
-#include "ctypenames.h"
+#include "abstractmetaargument.h"
#include "abstractmetaenum.h"
-#include "abstractmetafield.h"
#include "abstractmetafunction.h"
#include "abstractmetalang.h"
-#include "parser/codemodel.h"
#include "messages.h"
+#include <optionsparser.h>
#include "reporthandler.h"
#include "fileout.h"
-#include "apiextractor.h"
-#include "typesystem.h"
+#include "arraytypeentry.h"
+#include "enumtypeentry.h"
+#include "enumvaluetypeentry.h"
+#include "namespacetypeentry.h"
+#include "primitivetypeentry.h"
+#include "typesystemtypeentry.h"
+#include <typedatabase.h>
+
+#include "qtcompat.h"
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QRegularExpression>
-#include <QDebug>
-#include <typedatabase.h>
-static const char ENABLE_PYSIDE_EXTENSIONS[] = "enable-pyside-extensions";
-
-/**
- * DefaultValue is used for storing default values of types for which code is
- * generated in different contexts:
- *
- * Context | Example: "Class *" | Example: "Class" with default Constructor
- * --------------------+-------------------------------+------------------------------------------
- * Variable | var{nullptr}; | var;
- * initializations | |
- * --------------------+-------------------------------+------------------------------------------
- * Return values | return nullptr; | return {}
- * --------------------+-------------------------------+------------------------------------------
- * constructor | static_cast<Class *>(nullptr) | Class()
- * arguments lists | |
- * (recursive, precise | |
- * matching). | |
- */
-
-DefaultValue::DefaultValue(Type t, QString value) :
- m_type(t), m_value(std::move(value))
-{
-}
-
-DefaultValue::DefaultValue(QString customValue) :
- m_type(Custom), m_value(std::move(customValue))
-{
-}
-
-QString DefaultValue::returnValue() const
-{
- switch (m_type) {
- case DefaultValue::Boolean:
- return QLatin1String("false");
- case DefaultValue::CppScalar:
- return QLatin1String("0");
- case DefaultValue::Custom:
- case DefaultValue::Enum:
- return m_value;
- case DefaultValue::Pointer:
- return QLatin1String("nullptr");
- case DefaultValue::Void:
- return QString();
- case DefaultValue::DefaultConstructorWithDefaultValues:
- return m_value + QLatin1String("()");
- case DefaultValue::DefaultConstructor:
- break;
- }
- return QLatin1String("{}");
-}
-
-QString DefaultValue::initialization() const
-{
- switch (m_type) {
- case DefaultValue::Boolean:
- return QLatin1String("{false}");
- case DefaultValue::CppScalar:
- return QLatin1String("{0}");
- case DefaultValue::Custom:
- return QLatin1String(" = ") + m_value;
- case DefaultValue::Enum:
- return QLatin1Char('{') + m_value + QLatin1Char('}');
- case DefaultValue::Pointer:
- return QLatin1String("{nullptr}");
- case DefaultValue::Void:
- Q_ASSERT(false);
- break;
- case DefaultValue::DefaultConstructor:
- case DefaultValue::DefaultConstructorWithDefaultValues:
- break;
- }
- return QString();
-}
+using namespace Qt::StringLiterals;
-QString DefaultValue::constructorParameter() const
-{
- switch (m_type) {
- case DefaultValue::Boolean:
- return QLatin1String("false");
- case DefaultValue::CppScalar: {
- // PYSIDE-846: Use static_cast in case of "unsigned long" and similar
- const QString cast = m_value.contains(QLatin1Char(' '))
- ? QLatin1String("static_cast<") + m_value + QLatin1Char('>')
- : m_value;
- return cast + QLatin1String("(0)");
- }
- case DefaultValue::Custom:
- case DefaultValue::Enum:
- return m_value;
- case DefaultValue::Pointer:
- // Be precise here to be able to differentiate between constructors
- // taking different pointer types, cf
- // QTreeWidgetItemIterator(QTreeWidget *) and
- // QTreeWidgetItemIterator(QTreeWidgetItemIterator *).
- return QLatin1String("static_cast<") + m_value + QLatin1String("*>(nullptr)");
- case DefaultValue::Void:
- Q_ASSERT(false);
- break;
- case DefaultValue::DefaultConstructor:
- case DefaultValue::DefaultConstructorWithDefaultValues:
- break;
- }
- return m_value + QLatin1String("()");
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug debug, const DefaultValue &v)
-{
- QDebugStateSaver saver(debug);
- debug.noquote();
- debug.nospace();
- debug << "DefaultValue(" << v.type() << ", \"" << v.value() << "\")";
- return debug;
-}
-#endif // !QT_NO_DEBUG_STREAM
+static constexpr auto ENABLE_PYSIDE_EXTENSIONS = "enable-pyside-extensions"_L1;
+static constexpr auto AVOID_PROTECTED_HACK = "avoid-protected-hack"_L1;
-QString GeneratorContext::smartPointerWrapperName() const
+struct GeneratorOptions
{
- Q_ASSERT(m_type == SmartPointer);
- return m_preciseClassType.cppSignature();
-}
+ bool usePySideExtensions = false;
+ bool avoidProtectedHack = false;
+};
struct Generator::GeneratorPrivate
{
@@ -175,14 +45,16 @@ struct Generator::GeneratorPrivate
QString outDir;
// License comment
QString licenseComment;
- QStringList instantiatedContainersNames;
- AbstractMetaTypeList instantiatedContainers;
- AbstractMetaTypeList instantiatedSmartPointers;
AbstractMetaClassCList m_invisibleTopNamespaces;
bool m_hasPrivateClasses = false;
- bool m_usePySideExtensions = 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)
{
}
@@ -196,17 +68,19 @@ bool Generator::setup(const ApiExtractorResult &api)
{
m_d->api = api;
const auto moduleEntry = TypeDatabase::instance()->defaultTypeSystemType();
- if (!moduleEntry || !moduleEntry->generateCode()) {
- qCWarning(lcShiboken) << "Couldn't find the package name!!";
+ if (!moduleEntry) {
+ qCWarning(lcShiboken,"Couldn't find the package name!!");
+ return false;
+ }
+ if (!moduleEntry->generateCode()) {
+ qCWarning(lcShiboken, "Code generation of root typesystem is disabled!!");
return false;
}
- collectInstantiatedContainersAndSmartPointers();
-
- 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([&](AbstractMetaClass *ic) {
+ c->invisibleNamespaceRecursion([&](const AbstractMetaClassCPtr &ic) {
m_d->m_invisibleTopNamespaces.append(ic);
});
}
@@ -215,156 +89,65 @@ bool Generator::setup(const ApiExtractorResult &api)
return doSetup();
}
-QString Generator::getSimplifiedContainerTypeName(const AbstractMetaType &type)
+QList<OptionDescription> Generator::options()
{
- const QString signature = type.cppSignature();
- if (!type.typeEntry()->isContainer() && !type.typeEntry()->isSmartPointer())
- return signature;
- QString typeName = signature;
- if (type.isConstant())
- typeName.remove(0, sizeof("const ") / sizeof(char) - 1);
- switch (type.referenceType()) {
- case NoReference:
- break;
- case LValueReference:
- typeName.chop(1);
- break;
- case RValueReference:
- typeName.chop(2);
- break;
- }
- while (typeName.endsWith(QLatin1Char('*')) || typeName.endsWith(QLatin1Char(' ')))
- typeName.chop(1);
- return typeName;
-}
-
-// Strip a "const QSharedPtr<const Foo> &" or similar to "QSharedPtr<Foo>" (PYSIDE-1016/454)
-AbstractMetaType canonicalSmartPtrInstantiation(const AbstractMetaType &type)
-{
- const AbstractMetaTypeList &instantiations = type.instantiations();
- Q_ASSERT(instantiations.size() == 1);
- const bool needsFix = type.isConstant() || type.referenceType() != NoReference;
- const bool pointeeNeedsFix = instantiations.constFirst().isConstant();
- if (!needsFix && !pointeeNeedsFix)
- return type;
- auto fixedType = type;
- fixedType.setReferenceType(NoReference);
- fixedType.setConstant(false);
- if (pointeeNeedsFix) {
- auto fixedPointeeType = instantiations.constFirst();
- fixedPointeeType.setConstant(false);
- fixedType.setInstantiations(AbstractMetaTypeList(1, fixedPointeeType));
- }
- return fixedType;
-}
-
-static inline const TypeEntry *pointeeTypeEntry(const AbstractMetaType &smartPtrType)
-{
- return smartPtrType.instantiations().constFirst().typeEntry();
+ return {
+ {AVOID_PROTECTED_HACK,
+ u"Avoid the use of the '#define protected public' hack."_s},
+ {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}
+ };
}
-void Generator::addInstantiatedContainersAndSmartPointers(const AbstractMetaType &type,
- const QString &context)
+class GeneratorOptionsParser : public OptionsParser
{
- for (const auto &t : type.instantiations())
- addInstantiatedContainersAndSmartPointers(t, context);
- const auto typeEntry = type.typeEntry();
- const bool isContainer = typeEntry->isContainer();
- if (!isContainer
- && !(typeEntry->isSmartPointer() && typeEntry->generateCode())) {
- return;
- }
- if (type.hasTemplateChildren()) {
- QString piece = isContainer ? QStringLiteral("container") : QStringLiteral("smart pointer");
- QString warning =
- QString::fromLatin1("Skipping instantiation of %1 '%2' because it has template"
- " arguments.").arg(piece, type.originalTypeDescription());
- if (!context.isEmpty())
- warning.append(QStringLiteral(" Calling context: ") + context);
-
- qCWarning(lcShiboken).noquote().nospace() << warning;
- return;
+public:
+ explicit GeneratorOptionsParser(GeneratorOptions *o) : m_options(o) {}
- }
- if (isContainer) {
- const QString typeName = getSimplifiedContainerTypeName(type);
- if (!m_d->instantiatedContainersNames.contains(typeName)) {
- m_d->instantiatedContainersNames.append(typeName);
- auto simplifiedType = type;
- simplifiedType.setIndirections(0);
- simplifiedType.setConstant(false);
- simplifiedType.setReferenceType(NoReference);
- simplifiedType.decideUsagePattern();
- m_d->instantiatedContainers.append(simplifiedType);
- }
- return;
- }
+ bool handleBoolOption(const QString &key, OptionSource source) override;
- // Is smart pointer. Check if the (const?) pointee is already known for the given
- // smart pointer type entry.
- auto pt = pointeeTypeEntry(type);
- const bool present =
- std::any_of(m_d->instantiatedSmartPointers.cbegin(), m_d->instantiatedSmartPointers.cend(),
- [typeEntry, pt] (const AbstractMetaType &t) {
- return t.typeEntry() == typeEntry && pointeeTypeEntry(t) == pt;
- });
- if (!present)
- m_d->instantiatedSmartPointers.append(canonicalSmartPtrInstantiation(type));
-}
-
-void Generator::collectInstantiatedContainersAndSmartPointers(const AbstractMetaFunctionCPtr &func)
-{
- addInstantiatedContainersAndSmartPointers(func->type(), func->signature());
- const AbstractMetaArgumentList &arguments = func->arguments();
- for (const AbstractMetaArgument &arg : arguments)
- addInstantiatedContainersAndSmartPointers(arg.type(), func->signature());
-}
-
-void Generator::collectInstantiatedContainersAndSmartPointers(const AbstractMetaClass *metaClass)
-{
- if (!metaClass->typeEntry()->generateCode())
- return;
- for (const auto &func : metaClass->functions())
- collectInstantiatedContainersAndSmartPointers(func);
- for (const AbstractMetaField &field : metaClass->fields())
- addInstantiatedContainersAndSmartPointers(field.type(), field.name());
- const AbstractMetaClassList &innerClasses = metaClass->innerClasses();
- for (AbstractMetaClass *innerClass : innerClasses)
- collectInstantiatedContainersAndSmartPointers(innerClass);
-}
+private:
+ GeneratorOptions *m_options;
+};
-void Generator::collectInstantiatedContainersAndSmartPointers()
+bool GeneratorOptionsParser::handleBoolOption(const QString & key, OptionSource source)
{
- for (const auto &func : m_d->api.globalFunctions())
- collectInstantiatedContainersAndSmartPointers(func);
- for (auto metaClass : m_d->api.classes())
- collectInstantiatedContainersAndSmartPointers(metaClass);
+ 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;
}
-AbstractMetaTypeList Generator::instantiatedContainers() const
+std::shared_ptr<OptionsParser> Generator::createOptionsParser()
{
- return m_d->instantiatedContainers;
+ return std::make_shared<GeneratorOptionsParser>(&GeneratorPrivate::m_options);
}
-AbstractMetaTypeList Generator::instantiatedSmartPointers() const
-{
- return m_d->instantiatedSmartPointers;
-}
+QString Generator::fileNameForContextHelper(const GeneratorContext &context,
+ const QString &suffix,
+ FileNameFlags flags)
-Generator::OptionDescriptions Generator::options() const
{
- return {
- {QLatin1String(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."_qs}
- };
-}
+ if (!context.forSmartPointer()) {
+ const auto metaClass = context.metaClass();
+ QString fileNameBase = flags.testFlag(FileNameFlag::UnqualifiedName)
+ ? metaClass->name() : metaClass->qualifiedCppName();
+ if (!flags.testFlag(FileNameFlag::KeepCase))
+ fileNameBase = fileNameBase.toLower();
+ fileNameBase.replace(u"::"_s, u"_"_s);
+ return fileNameBase + suffix;
+ }
-bool Generator::handleOption(const QString & key, const QString & /* value */)
-{
- if (key == QLatin1String(ENABLE_PYSIDE_EXTENSIONS))
- return ( m_d->m_usePySideExtensions = true);
- return false;
+ // FIXME: PYSIDE7: Use the above code path for all types. Note the file
+ // names will then change to reflect the namespaces of the pointee
+ // (smart/integer2).
+ const AbstractMetaType &smartPointerType = context.preciseType();
+ QString fileNameBase = getFileNameBaseForSmartPointer(smartPointerType);
+ return fileNameBase + suffix;
}
const AbstractMetaClassCList &Generator::invisibleTopNamespaces() const
@@ -372,12 +155,12 @@ const AbstractMetaClassCList &Generator::invisibleTopNamespaces() const
return m_d->m_invisibleTopNamespaces;
}
-PrimitiveTypeEntryList Generator::primitiveTypes()
+PrimitiveTypeEntryCList Generator::primitiveTypes()
{
return TypeDatabase::instance()->primitiveTypes();
}
-ContainerTypeEntryList Generator::containerTypes()
+ContainerTypeEntryCList Generator::containerTypes()
{
return TypeDatabase::instance()->containerTypes();
}
@@ -400,7 +183,7 @@ QString Generator::packageName()
static QString getModuleName()
{
QString result = TypeDatabase::instance()->defaultPackageName();
- result.remove(0, result.lastIndexOf(QLatin1Char('.')) + 1);
+ result.remove(0, result.lastIndexOf(u'.') + 1);
return result;
}
@@ -422,17 +205,19 @@ 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(cls))
+ if (!shouldGenerate(typeEntry))
return true;
const QString fileName = fileNameForContext(context);
if (fileName.isEmpty())
return true;
- QString filePath = outputDirectory() + QLatin1Char('/') + subDirectoryForClass(cls)
- + QLatin1Char('/') + fileName;
+ QString filePath = outputDirectory() + u'/'
+ + subDirectoryForPackage(typeEntry->targetLangPackage())
+ + u'/' + fileName;
FileOut fileOut(filePath);
generateClass(fileOut.stream, context);
@@ -441,68 +226,63 @@ bool Generator::generateFileForContext(const GeneratorContext &context)
return true;
}
-QString Generator::getFileNameBaseForSmartPointer(const AbstractMetaType &smartPointerType,
- const AbstractMetaClass *smartPointerClass)
+QString Generator::getFileNameBaseForSmartPointer(const AbstractMetaType &smartPointerType)
{
const AbstractMetaType innerType = smartPointerType.getSmartPointerInnerType();
- QString fileName = smartPointerClass->qualifiedCppName().toLower();
- fileName.replace(QLatin1String("::"), QLatin1String("_"));
- fileName.append(QLatin1String("_"));
+ smartPointerType.typeEntry()->qualifiedCppName();
+ QString fileName = smartPointerType.typeEntry()->qualifiedCppName().toLower();
+ 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)
+GeneratorContext
+ Generator::contextForSmartPointer(const AbstractMetaClassCPtr &c,
+ const AbstractMetaType &t,
+ const AbstractMetaClassCPtr &pointeeClass)
{
GeneratorContext result;
result.m_metaClass = c;
result.m_preciseClassType = t;
result.m_type = GeneratorContext::SmartPointer;
+ result.m_pointeeClass = pointeeClass;
return result;
}
bool Generator::generate()
{
- for (auto cls : m_d->api.classes()) {
+ for (const auto &cls : m_d->api.classes()) {
if (!generateFileForContext(contextForClass(cls)))
return false;
- if (shouldGenerate(cls) && cls->typeEntry()->isPrivate())
+ auto te = cls->typeEntry();
+ if (shouldGenerate(te) && te->isPrivate())
m_d->m_hasPrivateClasses = true;
}
- const auto smartPointers = m_d->api.smartPointers();
- for (const AbstractMetaType &type : qAsConst(m_d->instantiatedSmartPointers)) {
- const AbstractMetaClass *smartPointerClass =
- AbstractMetaClass::findClass(smartPointers, type.typeEntry());
- if (!smartPointerClass) {
- qCWarning(lcShiboken, "%s",
- qPrintable(msgCannotFindSmartPointer(type.cppSignature(),
- smartPointers)));
+ for (const auto &smp: m_d->api.instantiatedSmartPointers()) {
+ 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);
+ if (!generateFileForContext(contextForSmartPointer(smp.specialized, smp.type,
+ pointeeClass))) {
return false;
}
- if (!generateFileForContext(contextForSmartPointer(smartPointerClass, type)))
- return false;
}
return finishGeneration();
}
-bool Generator::shouldGenerateTypeEntry(const TypeEntry *type)
-{
- return type->generateCode() && NamespaceTypeEntry::isVisibleScope(type);
-}
-
-bool Generator::shouldGenerate(const AbstractMetaClass *metaClass) const
+bool Generator::shouldGenerate(const TypeEntryCPtr &typeEntry) const
{
- return shouldGenerateTypeEntry(metaClass->typeEntry());
+ return typeEntry->shouldGenerate();
}
const ApiExtractorResult &Generator::api() const
@@ -515,29 +295,32 @@ 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;
}
-QString Generator::getFullTypeName(const TypeEntry *type)
+bool Generator::avoidProtectedHack()
+{
+ return GeneratorPrivate::m_options.avoidProtectedHack;
+}
+
+QString Generator::getFullTypeName(TypeEntryCPtr type)
{
QString result = type->qualifiedCppName();
if (type->isArray())
- type = static_cast<const ArrayTypeEntry *>(type)->nestedTypeEntry();
- if (!type->isCppPrimitive())
- result.prepend(QLatin1String("::"));
- return result;
+ type = std::static_pointer_cast<const ArrayTypeEntry>(type)->nestedTypeEntry();
+ return isCppPrimitive(type) ? result : addGlobalScopePrefix(result);
}
QString Generator::getFullTypeName(const AbstractMetaType &type)
{
if (type.isCString())
- return QLatin1String("const char*");
+ return u"const char*"_s;
if (type.isVoidPointer())
- return QLatin1String("void*");
+ return u"void*"_s;
if (type.typeEntry()->isContainer())
- return QLatin1String("::") + type.cppSignature();
+ return addGlobalScopePrefix(type.cppSignature());
QString typeName;
if (type.typeEntry()->isComplex() && type.hasInstantiations())
typeName = getFullTypeNameWithoutModifiers(type);
@@ -546,17 +329,19 @@ 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 QLatin1String("::") + 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)
{
if (type.isCString())
- return QLatin1String("const char*");
+ return u"const char*"_s;
if (type.isVoidPointer())
- return QLatin1String("void*");
+ return u"void*"_s;
if (!type.hasInstantiations())
return getFullTypeName(type.typeEntry());
QString typeName = type.cppSignature();
@@ -572,9 +357,9 @@ QString Generator::getFullTypeNameWithoutModifiers(const AbstractMetaType &type)
typeName.chop(2);
break;
}
- while (typeName.endsWith(QLatin1Char('*')) || typeName.endsWith(QLatin1Char(' ')))
+ while (typeName.endsWith(u'*') || typeName.endsWith(u' '))
typeName.chop(1);
- return QLatin1String("::") + typeName;
+ return addGlobalScopePrefix(typeName);
}
std::optional<DefaultValue>
@@ -587,29 +372,29 @@ std::optional<DefaultValue>
if (type.isContainer()) {
QString ctor = type.cppSignature();
- if (ctor.endsWith(QLatin1Char('*'))) {
+ if (ctor.endsWith(u'*')) {
ctor.chop(1);
return DefaultValue(DefaultValue::Pointer, ctor.trimmed());
}
- if (ctor.startsWith(QLatin1String("const ")))
+ if (ctor.startsWith(u"const "))
ctor.remove(0, sizeof("const ") / sizeof(char) - 1);
- if (ctor.endsWith(QLatin1Char('&'))) {
+ if (ctor.endsWith(u'&')) {
ctor.chop(1);
ctor = ctor.trimmed();
}
- return DefaultValue(DefaultValue::DefaultConstructor, QLatin1String("::") + ctor);
+ return DefaultValue(DefaultValue::DefaultConstructor, u"::"_s + ctor);
}
if (type.isNativePointer())
return DefaultValue(DefaultValue::Pointer, type.typeEntry()->qualifiedCppName());
if (type.isPointer())
- return DefaultValue(DefaultValue::Pointer, QLatin1String("::") + 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 = static_cast<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);
@@ -634,41 +419,40 @@ std::optional<DefaultValue>
std::optional<DefaultValue>
Generator::minimalConstructor(const ApiExtractorResult &api,
- const TypeEntry *type,
+ const TypeEntryCPtr &type,
QString *errorString)
{
if (!type)
return {};
- if (type->isCppPrimitive()) {
+ if (isCppPrimitive(type)) {
const QString &name = type->qualifiedCppName();
- return name == QLatin1String("bool")
+ return name == u"bool"
? DefaultValue(DefaultValue::Boolean)
: DefaultValue(DefaultValue::CppScalar, name);
}
if (type->isEnum()) {
- const auto enumEntry = static_cast<const EnumTypeEntry *>(type);
- if (const auto *nullValue = enumEntry->nullValue())
+ 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,
- QLatin1String("static_cast< ::") + type->qualifiedCppName()
- + QLatin1String(">(0)"));
+ "static_cast< "_L1 + getFullTypeName(type) + ">(0)"_L1);
}
if (type->isFlags()) {
return DefaultValue(DefaultValue::Custom,
- type->qualifiedCppName() + QLatin1String("(0)"));
+ type->qualifiedCppName() + u"(0)"_s);
}
if (type->isPrimitive()) {
- QString ctor = static_cast<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
// bindings will tell.
return ctor.isEmpty()
- ? DefaultValue(DefaultValue::DefaultConstructorWithDefaultValues, QLatin1String("::")
+ ? DefaultValue(DefaultValue::DefaultConstructorWithDefaultValues, u"::"_s
+ type->qualifiedCppName())
: DefaultValue(DefaultValue::Custom, ctor);
}
@@ -687,25 +471,25 @@ std::optional<DefaultValue>
}
if (errorString != nullptr)
- *errorString = QLatin1String("No default value could be determined.");
+ *errorString = u"No default value could be determined."_s;
return {};
}
static QString constructorCall(const QString &qualifiedCppName, const QStringList &args)
{
- return QLatin1String("::") + qualifiedCppName + QLatin1Char('(')
- + args.join(QLatin1String(", ")) + QLatin1Char(')');
+ return u"::"_s + qualifiedCppName + u'('
+ + args.join(u", "_s) + u')';
}
std::optional<DefaultValue>
Generator::minimalConstructor(const ApiExtractorResult &api,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
QString *errorString)
{
if (!metaClass)
return {};
- auto cType = static_cast<const ComplexTypeEntry *>(metaClass->typeEntry());
+ auto cType = std::static_pointer_cast<const ComplexTypeEntry>(metaClass->typeEntry());
if (cType->hasDefaultConstructor())
return DefaultValue(DefaultValue::Custom, cType->defaultConstructor());
@@ -715,27 +499,27 @@ std::optional<DefaultValue>
const auto &constructors = metaClass->queryFunctions(FunctionQueryOption::Constructors);
for (const auto &ctor : constructors) {
if (!ctor->isUserAdded() && !ctor->isPrivate()
- && ctor->functionType() == AbstractMetaFunction::ConstructorFunction) {
+ && (ctor->isPublic() || !api.flags().testFlag(ApiExtractorFlag::AvoidProtectedHack))) {
// No arguments: Default constructible
const auto &arguments = ctor->arguments();
if (arguments.isEmpty()) {
return DefaultValue(DefaultValue::DefaultConstructor,
- QLatin1String("::") + qualifiedCppName);
+ u"::"_s + qualifiedCppName);
}
// First argument has unmodified default: Default constructible with values
if (arguments.constFirst().hasUnmodifiedDefaultValueExpression()) {
return DefaultValue(DefaultValue::DefaultConstructorWithDefaultValues,
- QLatin1String("::") + qualifiedCppName);
+ u"::"_s + qualifiedCppName);
}
// Examine arguments, exclude functions taking a self parameter
bool simple = true;
bool suitable = true;
- for (int i = 0, size = arguments.size();
+ for (qsizetype i = 0, size = arguments.size();
suitable && i < size && !arguments.at(i).hasOriginalDefaultValueExpression(); ++i) {
const AbstractMetaArgument &arg = arguments.at(i);
- const TypeEntry *aType = arg.type().typeEntry();
+ TypeEntryCPtr aType = arg.type().typeEntry();
suitable &= aType != cType;
- simple &= aType->isCppPrimitive() || aType->isEnum() || arg.type().isPointer();
+ simple &= isCppPrimitive(aType) || aType->isEnum() || arg.type().isPointer();
}
if (suitable)
candidates.insert(arguments.size() + (simple ? 0 : 100), ctor);
@@ -745,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 (int 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;
@@ -765,7 +548,7 @@ std::optional<DefaultValue>
}
QString Generator::translateType(AbstractMetaType cType,
- const AbstractMetaClass *context,
+ const AbstractMetaClassCPtr &context,
Options options) const
{
QString s;
@@ -777,94 +560,141 @@ QString Generator::translateType(AbstractMetaType cType,
}
if (cType.isVoid()) {
- s = QLatin1String("void");
+ s = u"void"_s;
} else if (cType.isArray()) {
- s = translateType(*cType.arrayElementType(), context, options) + QLatin1String("[]");
+ 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() && !copyType.typeEntry()->isCppPrimitive())
- s.prepend(QLatin1String("::"));
- } 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);
}
}
return s;
}
+static const QHash<QString, QString> &pythonOperators()
+{
+ static const QHash<QString, QString> result = {
+ // call operator
+ {u"operator()"_s, u"__call__"_s},
+ // Arithmetic operators
+ {u"operator+"_s, u"__add__"_s},
+ {u"operator-"_s, u"__sub__"_s},
+ {u"operator*"_s, u"__mul__"_s},
+ {u"operator/"_s, u"__div__"_s},
+ {u"operator%"_s, u"__mod__"_s},
+ // Inplace arithmetic operators
+ {u"operator+="_s, u"__iadd__"_s},
+ {u"operator-="_s, u"__isub__"_s},
+ {u"operator++"_s, u"__iadd__"_s},
+ {u"operator--"_s, u"__isub__"_s},
+ {u"operator*="_s, u"__imul__"_s},
+ {u"operator%="_s, u"__imod__"_s},
+ // Bitwise operators
+ {u"operator&"_s, u"__and__"_s},
+ {u"operator^"_s, u"__xor__"_s},
+ {u"operator|"_s, u"__or__"_s},
+ {u"operator<<"_s, u"__lshift__"_s},
+ {u"operator>>"_s, u"__rshift__"_s},
+ {u"operator~"_s, u"__invert__"_s},
+ // Inplace bitwise operators
+ {u"operator&="_s, u"__iand__"_s},
+ {u"operator^="_s, u"__ixor__"_s},
+ {u"operator|="_s, u"__ior__"_s},
+ {u"operator<<="_s, u"__ilshift__"_s},
+ {u"operator>>="_s, u"__irshift__"_s},
+ // Comparison operators
+ {u"operator=="_s, u"__eq__"_s},
+ {u"operator!="_s, u"__ne__"_s},
+ {u"operator<"_s, u"__lt__"_s},
+ {u"operator>"_s, u"__gt__"_s},
+ {u"operator<="_s, u"__le__"_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;
+}
+
+QString Generator::pythonOperatorFunctionName(const QString &cppOpFuncName)
+{
+ return pythonOperators().value(cppOpFuncName);
+}
-QString Generator::subDirectoryForClass(const AbstractMetaClass *clazz) const
+bool Generator::isPythonOperatorFunctionName(const QString &cppOpFuncName)
{
- return subDirectoryForPackage(clazz->package());
+ return pythonOperators().contains(cppOpFuncName);
}
QString Generator::subDirectoryForPackage(QString packageNameIn) const
{
if (packageNameIn.isEmpty())
packageNameIn = packageName();
- packageNameIn.replace(QLatin1Char('.'), QDir::separator());
+ packageNameIn.replace(u'.', QDir::separator());
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
if (NamespaceTypeEntry::isVisibleScope(context->typeEntry())) {
- name.prepend(QLatin1Char('.'));
+ name.prepend(u'.');
name.prepend(context->name());
}
context = context->enclosingClass();
}
if (includePackageName) {
- name.prepend(QLatin1Char('.'));
+ name.prepend(u'.');
name.prepend(t->package());
}
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);
}
-QString getClassTargetFullName(const AbstractMetaType &metaType, bool includePackageName)
-{
- QString name = metaType.cppSignature();
- name.replace(QLatin1String("::"), QLatin1String("_"));
- name.replace(QLatin1Char('<'), QLatin1Char('_'));
- name.remove(QLatin1Char('>'));
- name.remove(QLatin1Char(' '));
- if (includePackageName) {
- name.prepend(QLatin1Char('.'));
- name.prepend(metaType.package());
- }
- return name;
-}
-
QString getFilteredCppSignatureString(QString signature)
{
- signature.replace(QLatin1String("::"), QLatin1String("_"));
- signature.replace(QLatin1Char('<'), QLatin1Char('_'));
- signature.replace(QLatin1Char('>'), QLatin1Char('_'));
- signature.replace(QLatin1Char(' '), QLatin1Char('_'));
+ signature.replace(u"::"_s, u"_"_s);
+ signature.replace(u'<', u'_');
+ signature.replace(u'>', u'_');
+ signature.replace(u' ', u'_');
return signature;
}
diff --git a/sources/shiboken6/generator/generator.h b/sources/shiboken6/generator/generator.h
index 59d1b9822..5b051b599 100644
--- a/sources/shiboken6/generator/generator.h
+++ b/sources/shiboken6/generator/generator.h
@@ -1,189 +1,40 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef GENERATOR_H
#define GENERATOR_H
-#include <abstractmetatype.h>
+#include <abstractmetalang_typedefs.h>
#include <typedatabase_typedefs.h>
-#include <QtCore/QObject>
-#include <QtCore/QSharedPointer>
-#include <QtCore/QTextStream>
#include <QtCore/QList>
+#include <memory>
#include <optional>
+
class ApiExtractorResult;
-class AbstractMetaFunction;
-class AbstractMetaClass;
-class AbstractMetaEnum;
-class TypeEntry;
-class ComplexTypeEntry;
-class AbstractMetaType;
-class EnumTypeEntry;
-class FlagsTypeEntry;
+class GeneratorContext;
+class DefaultValue;
+struct OptionDescription;
+class OptionsParser;
class TextStream;
-QT_BEGIN_NAMESPACE
-class QFile;
-class QDebug;
-QT_END_NAMESPACE
-
-class PrimitiveTypeEntry;
-class ContainerTypeEntry;
-
-QString getClassTargetFullName(const AbstractMetaClass *metaClass, bool includePackageName = true);
-QString getClassTargetFullName(const AbstractMetaEnum &metaEnum, bool includePackageName = true);
-QString getClassTargetFullName(const AbstractMetaType &metaType, bool includePackageName = true);
+QString getClassTargetFullName(const AbstractMetaClassCPtr &metaClass,
+ bool includePackageName = true);
+QString getClassTargetFullName(const AbstractMetaEnum &metaEnum,
+ bool includePackageName = true);
QString getFilteredCppSignatureString(QString signature);
/**
- * 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.
- * Simply search for the text "// C++11: need to declare (unimplemented) destructor".
- *
- * The protected hack is the definition "#define protected public".
- * For most compilers, this "hack" is enabled, because the problem of private
- * destructors simply vanishes.
- *
- * If one does not want to use this hack, then a new problem arises:
- * C++11 requires that a destructor is declared in a wrapper class when it is
- * private in the base class. There is no implementation allowed!
- *
- * Unfortunately, MSVC in recent versions supports C++11, and due to restrictive
- * rules, it is impossible to use the hack with this compiler.
- * More unfortunate: Clang, when C++11 is enabled, also enforces a declaration
- * of a private destructor, but it falsely then creates a linker error!
- *
- * Originally, we wanted to remove the protected hack. But due to the Clang
- * problem, we gave up on removal of the protected hack and use it always
- * when we can. This might change again when the Clang problem is solved.
- */
-
-#ifdef Q_CC_MSVC
-const int alwaysGenerateDestructor = 1;
-#else
-const int alwaysGenerateDestructor = 0;
-#endif
-
-class DefaultValue
-{
-public:
- enum Type
- {
- Boolean,
- CppScalar, // A C++ scalar type (int,..) specified by value()
- Custom, // A custom constructor/expression, uses value() as is
- DefaultConstructor, // For classes named value()
- DefaultConstructorWithDefaultValues, // as DefaultConstructor, but can't return {} though.
- Enum, // Enum value as specified by value()
- Pointer, // Pointer of type value()
- Void // "", for return values only
- };
-
- explicit DefaultValue(Type t, QString value = QString());
- explicit DefaultValue(QString customValue);
-
- QString returnValue() const;
- QString initialization() const;
- QString constructorParameter() const;
-
- QString value() const { return m_value; }
- void setValue(const QString &value) { m_value = value; }
-
- Type type() const { return m_type; }
- void setType(Type type) { m_type = type; }
-
-private:
- Type m_type;
- QString m_value;
-};
-
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug debug, const DefaultValue &v);
-#endif
-
-/**
- * A GeneratorContext object contains a pointer to an AbstractMetaClass and/or a specialized
- * AbstractMetaType, for which code is currently being generated.
- *
- * The main case is when the context contains only an AbstractMetaClass pointer, which is used
- * by different methods to generate appropriate expressions, functions, type names, etc.
- *
- * The second case is for generation of code for smart pointers. In this case the m_metaClass member
- * contains the generic template class of the smart pointer, and the m_preciseClassType member
- * contains the instantiated template type, e.g. a concrete shared_ptr<int>. To
- * distinguish this case, the member m_forSmartPointer is set to true.
- *
- * In the future the second case might be generalized for all template type instantiations.
- */
-class GeneratorContext {
- friend class ShibokenGenerator;
- friend class Generator;
-public:
- enum Type { Class, WrappedClass, SmartPointer };
-
- GeneratorContext() = default;
-
- const AbstractMetaClass *metaClass() const { return m_metaClass; }
- const AbstractMetaType &preciseType() const { return m_preciseClassType; }
-
- bool forSmartPointer() const { return m_type == SmartPointer; }
- bool useWrapper() const { return m_type == WrappedClass; }
-
- QString wrapperName() const
- {
- Q_ASSERT(m_type == WrappedClass);
- return m_wrappername;
- }
-
- QString smartPointerWrapperName() const;
-
-private:
- const AbstractMetaClass *m_metaClass = nullptr;
- AbstractMetaType m_preciseClassType;
- QString m_wrappername;
- Type m_type = Class;
-};
-
-/**
* Base class for all generators. The default implementations does nothing,
* 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,
@@ -198,13 +49,19 @@ public:
};
Q_DECLARE_FLAGS(Options, Option)
+ enum FileNameFlag {
+ UnqualifiedName = 0x1,
+ KeepCase = 0x2
+ };
+ Q_DECLARE_FLAGS(FileNameFlags, FileNameFlag)
+
Generator();
virtual ~Generator();
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;
@@ -238,7 +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.
+ static bool avoidProtectedHack();
/**
* Retrieves the name of the currently processed module.
@@ -250,32 +110,34 @@ public:
*/
static QString moduleName();
+ static QString pythonOperatorFunctionName(const QString &cppOpFuncName);
+ static bool isPythonOperatorFunctionName(const QString &cppOpFuncName);
+
protected:
+ /// Helper for determining the file name
+ static QString fileNameForContextHelper(const GeneratorContext &context,
+ const QString &suffix,
+ FileNameFlags flags = {});
+
/// Returns all primitive types found by APIExtractor
- static PrimitiveTypeEntryList primitiveTypes();
+ static PrimitiveTypeEntryCList primitiveTypes();
/// Returns all container types found by APIExtractor
- static ContainerTypeEntryList containerTypes();
+ static ContainerTypeEntryCList containerTypes();
- virtual GeneratorContext contextForClass(const AbstractMetaClass *c) const;
- static GeneratorContext contextForSmartPointer(const AbstractMetaClass *c,
- const AbstractMetaType &t);
+ 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);
/// Returns the file base name for a smart pointer.
- static QString getFileNameBaseForSmartPointer(const AbstractMetaType &smartPointerType,
- const AbstractMetaClass *smartPointer);
-
- /// Returns true if the generator should generate any code for the TypeEntry.
- static bool shouldGenerateTypeEntry(const TypeEntry *) ;
+ static QString getFileNameBaseForSmartPointer(const AbstractMetaType &smartPointerType);
/// Returns true if the generator should generate any code for the AbstractMetaClass.
- virtual bool shouldGenerate(const AbstractMetaClass *) const;
-
- /// Returns the subdirectory used to write the binding code of an AbstractMetaClass.
- virtual QString subDirectoryForClass(const AbstractMetaClass *clazz) const;
+ virtual bool shouldGenerate(const TypeEntryCPtr &t) const;
/**
* Translate metatypes to binding source format.
@@ -285,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;
/**
@@ -294,9 +156,9 @@ protected:
static QString packageName();
// Returns the full name of the type.
- static QString getFullTypeName(const TypeEntry *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
@@ -311,14 +173,14 @@ protected:
* Returns a null string if it fails.
*/
static std::optional<DefaultValue>
- minimalConstructor(const ApiExtractorResult &api, const TypeEntry *type,
+ minimalConstructor(const ApiExtractorResult &api, const TypeEntryCPtr &type,
QString *errorString = nullptr);
static std::optional<DefaultValue>
minimalConstructor(const ApiExtractorResult &api, const AbstractMetaType &type,
QString *errorString = nullptr);
static std::optional<DefaultValue>
minimalConstructor(const ApiExtractorResult &api,
- const AbstractMetaClass *metaClass,
+ const AbstractMetaClassCPtr &metaClass,
QString *errorString = nullptr);
/**
@@ -327,7 +189,6 @@ protected:
* for which the file name must be returned
* \return the file name used to write the binding code for the class
*/
- virtual QString fileNameSuffix() const = 0;
virtual QString fileNameForContext(const GeneratorContext &context) const = 0;
@@ -353,24 +214,20 @@ protected:
*/
virtual QString subDirectoryForPackage(QString packageName = QString()) const;
- AbstractMetaTypeList instantiatedContainers() const;
- AbstractMetaTypeList instantiatedSmartPointers() const;
+ static QString addGlobalScopePrefix(const QString &t);
+ static QString globalScopePrefix(const GeneratorContext &classContext);
- static QString getSimplifiedContainerTypeName(const AbstractMetaType &type);
- void addInstantiatedContainersAndSmartPointers(const AbstractMetaType &type,
- const QString &context);
+ static QString m_gsp;
private:
struct GeneratorPrivate;
GeneratorPrivate *m_d;
- void collectInstantiatedContainersAndSmartPointers(const AbstractMetaFunctionCPtr &func);
- void collectInstantiatedContainersAndSmartPointers(const AbstractMetaClass *metaClass);
- void collectInstantiatedContainersAndSmartPointers();
};
Q_DECLARE_OPERATORS_FOR_FLAGS(Generator::Options)
-using GeneratorPtr = QSharedPointer<Generator>;
+Q_DECLARE_OPERATORS_FOR_FLAGS(Generator::FileNameFlags)
+
+using GeneratorPtr = std::shared_ptr<Generator>;
using Generators = QList<GeneratorPtr>;
#endif // GENERATOR_H
-
diff --git a/sources/shiboken6/generator/generatorcontext.cpp b/sources/shiboken6/generator/generatorcontext.cpp
new file mode 100644
index 000000000..b50c2effb
--- /dev/null
+++ b/sources/shiboken6/generator/generatorcontext.cpp
@@ -0,0 +1,38 @@
+// 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 "generatorcontext.h"
+#include <abstractmetalang.h>
+
+#include <QtCore/QDebug>
+
+using namespace Qt::StringLiterals;
+
+QString GeneratorContext::wrapperName() const
+{
+ Q_ASSERT(m_type == WrappedClass);
+ return m_wrappername;
+}
+
+QString GeneratorContext::effectiveClassName() const
+{
+ if (m_type == SmartPointer)
+ return m_preciseClassType.cppSignature();
+ return m_type == WrappedClass ? m_wrappername : m_metaClass->qualifiedCppName();
+}
+
+QDebug operator<<(QDebug debug, const GeneratorContext &c)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "GeneratorContext(\"" << c.metaClass()->name() << "\" ";
+ if (c.useWrapper())
+ debug << "[wrapper]";
+ else if (c.forSmartPointer())
+ debug << "[smart pointer] \"" << c.preciseType().cppSignature() << '"';
+ else
+ debug << "[class]";
+ debug << ')';
+ return debug;
+}
diff --git a/sources/shiboken6/generator/generatorcontext.h b/sources/shiboken6/generator/generatorcontext.h
new file mode 100644
index 000000000..2e58d4346
--- /dev/null
+++ b/sources/shiboken6/generator/generatorcontext.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 GENERATORCONTEXT_H
+#define GENERATORCONTEXT_H
+
+#include <abstractmetalang_typedefs.h>
+#include <abstractmetatype.h>
+#include <QtCore/QList>
+
+QT_FORWARD_DECLARE_CLASS(QDebug);
+
+// A GeneratorContext object contains a pointer to an AbstractMetaClass and/or a specialized
+// AbstractMetaType, for which code is currently being generated.
+//
+// The main case is when the context contains only an AbstractMetaClass pointer, which is used
+// by different methods to generate appropriate expressions, functions, type names, etc.
+//
+// The second case is for generation of code for smart pointers. In this case the m_metaClass
+// member contains the generic template class of the smart pointer, and the m_preciseClassType
+// member contains the instantiated template type, e.g. a concrete shared_ptr<int>. To
+// distinguish this case, the member m_forSmartPointer is set to true.
+//
+// In the future the second case might be generalized for all template type instantiations.
+
+class GeneratorContext {
+ friend class ShibokenGenerator;
+ friend class Generator;
+public:
+ enum Type { Class, WrappedClass, SmartPointer };
+
+ GeneratorContext() = default;
+
+ AbstractMetaClassCPtr metaClass() const { return m_metaClass; }
+ const AbstractMetaType &preciseType() const { return m_preciseClassType; }
+ AbstractMetaClassCPtr pointeeClass() const { return m_pointeeClass; }
+
+ bool forSmartPointer() const { return m_type == SmartPointer; }
+ bool useWrapper() const { return m_type == WrappedClass; }
+
+ QString wrapperName() const;
+ /// Returns the wrapper name in case of useWrapper(), the qualified class
+ /// name or the smart pointer specialization.
+ QString effectiveClassName() const;
+
+private:
+ AbstractMetaClassCPtr m_metaClass;
+ AbstractMetaClassCPtr m_pointeeClass;
+ AbstractMetaType m_preciseClassType;
+ QString m_wrappername;
+ Type m_type = Class;
+};
+
+QDebug operator<<(QDebug debug, const GeneratorContext &c);
+
+#endif // GENERATORCONTEXT_H
diff --git a/sources/shiboken6/generator/main.cpp b/sources/shiboken6/generator/main.cpp
index 934e31307..9871df206 100644
--- a/sources/shiboken6/generator/main.cpp
+++ b/sources/shiboken6/generator/main.cpp
@@ -1,700 +1,369 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QCoreApplication>
-#include <QLibrary>
-#include <QtCore/QFile>
-#include <QtCore/QDir>
-#include <QtCore/QVariant>
-#include <iostream>
+// 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 "shibokenconfig.h"
+#include "cppgenerator.h"
+#include "generator.h"
+#include "headergenerator.h"
+#include "qtdocgenerator.h"
+
#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 <messages.h>
-#include "generator.h"
-#include "shibokenconfig.h"
-#include "cppgenerator.h"
-#include "headergenerator.h"
-#include "qtdocgenerator.h"
-#include <exception>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QLibrary>
+#include <QtCore/QVariant>
-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 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"); }
+#include "qtcompat.h"
-static const char helpHint[] = "Note: use --help or -h for more information.\n";
-
-using OptionDescriptions = Generator::OptionDescriptions;
+#include <exception>
+#include <iostream>
-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());
- }
+using namespace Qt::StringLiterals;
- QVariantMap options; // string,stringlist for path lists, etc.
- QStringList positionalArguments;
-};
+static const char helpHint[] = "Note: use --help or -h for more information.\n";
+static const char appName[] = "shiboken";
-void CommandLineArguments::addToOptionsList(const QString &option,
- const QString &value)
+static inline Generators docGenerators()
{
- 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);
- }
+ Generators result;
+#ifdef DOCSTRINGS_ENABLED
+ result.append(GeneratorPtr(new QtDocGenerator));
+#endif
+ return result;
}
-void CommandLineArguments::addToOptionsList(const QString &option,
- const QStringList &value)
+static inline Generators shibokenGenerators()
{
- 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);
- }
+ Generators result;
+ result << GeneratorPtr(new CppGenerator) << GeneratorPtr(new HeaderGenerator);
+ return result;
}
-void CommandLineArguments::addToOptionsList(const QString &option,
- const QString &listValue,
- QChar separator)
+struct CommonOptions
{
- const auto newValues = listValue.split(separator, Qt::SkipEmptyParts);
- addToOptionsList(option, newValues);
-}
+ 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;
+};
-static void printOptions(QTextStream &s, const OptionDescriptions &options)
+class CommonOptionsParser : public OptionsParser
{
- s.setFieldAlignment(QTextStream::AlignLeft);
- for (const auto &od : options) {
- if (!od.first.startsWith(QLatin1Char('-')))
- s << "--";
- s << od.first;
- if (od.second.isEmpty()) {
- s << ", ";
- } else {
- s << Qt::endl;
- const auto lines = QStringView{od.second}.split(QLatin1Char('\n'));
- for (const auto &line : lines)
- s << " " << line << Qt::endl;
- s << Qt::endl;
- }
- }
-}
+public:
+ explicit CommonOptionsParser(CommonOptions *o) : m_options(o) {}
-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 {};
- }
+ bool handleBoolOption(const QString &key, OptionSource source) override;
+ bool handleOption(const QString &key, const QString &value, OptionSource source) override;
- CommandLineArguments args;
-
- while (!projectFile.atEnd()) {
- line = projectFile.readLine().trimmed();
- if (line.isEmpty())
- continue;
-
- int split = line.indexOf('=');
- QByteArray key;
- QString value;
- if (split > 0) {
- key = line.left(split).trimmed();
- value = QString::fromUtf8(line.mid(split + 1).trimmed());
- } else {
- key = line;
- }
+ static OptionDescriptions optionDescriptions();
- if (key == "include-path") {
- args.addToOptionsList(includePathOption(),
- QDir::toNativeSeparators(value));
- } else if (key == "framework-include-path") {
- args.addToOptionsList(frameworkIncludePathOption(),
- QDir::toNativeSeparators(value));
- } else if (key == "system-include-paths") {
- args.addToOptionsList(systemIncludePathOption(),
- QDir::toNativeSeparators(value));
- } else if (key == "typesystem-path") {
- args.addToOptionsList(typesystemPathOption(),
- QDir::toNativeSeparators(value));
- } else if (key == "language-level") {
- args.options.insert(languageLevelOption(), value);
- } else if (key == "clang-option") {
- args.addToOptionsList(clangOptionsOption(), value);
- } else if (key == "clang-options") {
- args.addToOptionsList(clangOptionsOption(),
- value, clangOptionsSplitter);
- } else if (key == "api-version") {
- args.addToOptionsList(apiVersionOption(),
- value, apiVersionSplitter);
- } else if (key == "keywords") {
- args.addToOptionsList(keywordsOption(),
- value, keywordsSplitter);
- } else if (key == "drop-type-entries") {
- args.addToOptionsList(dropTypeEntriesOption(),
- value, dropTypeEntriesSplitter);
- } else if (key == "header-file") {
- args.positionalArguments.prepend(value);
- } else if (key == "typesystem-file") {
- args.positionalArguments.append(value);
- } else {
- args.options.insert(QString::fromUtf8(key), value);
- }
- }
+private:
+ CommonOptions *m_options;
+};
- return args;
+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"compiler=<type>"_s,
+ u"Emulated compiler type (g++, msvc, clang)"_s},
+ {u"platform=<name>"_s,
+ u"Emulated platform (windows, darwin, unix)"_s},
+ {u"compiler-path=<file>"_s,
+ u"Path to the compiler for determining builtin include paths"_s},
+ {u"generator-set=<\"generator module\">"_s,
+ u"generator-set to be used. e.g. qtdoc"_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, {} },
+ {u"help"_s, u"Display this help and exit"_s},
+ {u"-I<path>"_s, {} },
+ {u"include-paths="_s + OptionsParser::pathSyntax(),
+ u"Include paths used by the C++ parser"_s},
+ {u"license-file=<license-file>"_s,
+ u"File used for copyright headers of generated files"_s},
+ {u"no-suppress-warnings"_s,
+ u"Show all warnings"_s},
+ {u"output-directory=<path>"_s,
+ u"The directory where the generated files will be written"_s},
+ {u"project-file=<file>"_s,
+ 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"print-builtin-types"_s,
+ u"Print information about builtin types"_s},
+ {u"version"_s,
+ u"Output version information and exit"_s}
+ };
}
-static std::optional<CommandLineArguments> getProjectFileArguments()
+bool CommonOptionsParser::handleBoolOption(const QString &key, OptionSource source)
{
- QStringList arguments = QCoreApplication::arguments();
- QString appName = arguments.constFirst();
- arguments.removeFirst();
-
- QString projectFileName;
- for (const QString &arg : qAsConst(arguments)) {
- if (arg.startsWith(QLatin1String("--project-file"))) {
- int split = arg.indexOf(QLatin1Char('='));
- if (split > 0)
- projectFileName = arg.mid(split + 1).trimmed();
- break;
+ if (source == OptionSource::CommandLineSingleDash) {
+ if (key == u"h") {
+ m_options->help = true;
+ return true;
}
+ return false;
}
- if (projectFileName.isEmpty())
- return CommandLineArguments{};
-
- if (!QFile::exists(projectFileName)) {
- std::cerr << qPrintable(appName) << ": Project file \""
- << qPrintable(projectFileName) << "\" not found.\n";
- return {};
+ if (key == u"version") {
+ m_options->version = true;
+ return true;
}
-
- QFile projectFile(projectFileName);
- if (!projectFile.open(QIODevice::ReadOnly)) {
- std::cerr << qPrintable(appName) << ": Cannot open project file \""
- << qPrintable(projectFileName) << "\" : " << qPrintable(projectFile.errorString())
- << '\n';
- return {};
+ if (key == u"help") {
+ m_options->help = true;
+ return true;
}
- return processProjectFile(appName, projectFile);
-}
-
-static void getCommandLineArg(QString arg, int &argNum, CommandLineArguments &args)
-{
- if (arg.startsWith(QLatin1String("--"))) {
- arg.remove(0, 2);
- const int split = arg.indexOf(QLatin1Char('='));
- if (split < 0) {
- args.options.insert(arg, QString());
- return;
- }
- const QString option = arg.left(split);
- const QString value = arg.mid(split + 1).trimmed();
- if (option == includePathOption() || option == frameworkIncludePathOption()
- || option == systemIncludePathOption() || option == typesystemPathOption()) {
- args.addToOptionsPathList(option, value);
- } else if (option == apiVersionOption()) {
- args.addToOptionsList(apiVersionOption(), value, apiVersionSplitter);
- } else if (option == dropTypeEntriesOption()) {
- args.addToOptionsList(dropTypeEntriesOption(), value, dropTypeEntriesSplitter);
- } else if (option == clangOptionOption()) {
- args.addToOptionsList(clangOptionsOption(), value);
- } else if (option == clangOptionsOption()) {
- args.addToOptionsList(clangOptionsOption(), value, clangOptionsSplitter);
- } else if (option == keywordsOption()) {
- args.addToOptionsList(keywordsOption(), value, keywordsSplitter);
- } else {
- args.options.insert(option, value);
- }
- return;
+ if (key == u"diff") {
+ FileOut::setDiff(true);
+ return true;
}
- if (arg.startsWith(QLatin1Char('-'))) {
- arg.remove(0, 1);
- if (arg.startsWith(QLatin1Char('I'))) // Shorthand path arguments -I/usr/include...
- args.addToOptionsPathList(includePathOption(), arg.mid(1));
- else if (arg.startsWith(QLatin1Char('F')))
- args.addToOptionsPathList(frameworkIncludePathOption(), arg.mid(1));
- else if (arg.startsWith(QLatin1String("isystem")))
- args.addToOptionsPathList(systemIncludePathOption(), arg.mid(7));
- else if (arg.startsWith(QLatin1Char('T')))
- args.addToOptionsPathList(typesystemPathOption(), arg.mid(1));
- else if (arg == QLatin1String("h"))
- args.options.insert(helpOption(), QString());
- else if (arg.startsWith(QLatin1String("std=")))
- args.options.insert(languageLevelOption(), arg.mid(4));
- else
- args.options.insert(arg, QString());
- return;
+ 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;
}
- 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 (int i = 1, size = arguments.size(); i < size; ++i)
- getCommandLineArg(arguments.at(i).trimmed(), argNum, args);
-}
-static inline Generators docGenerators()
-{
- Generators result;
-#ifdef DOCSTRINGS_ENABLED
- result.append(GeneratorPtr(new QtDocGenerator));
-#endif
- return result;
+ return false;
}
-static inline Generators shibokenGenerators()
+bool CommonOptionsParser::handleOption(const QString &key, const QString &value,
+ OptionSource source)
{
- Generators result;
- result << GeneratorPtr(new CppGenerator) << GeneratorPtr(new HeaderGenerator);
- return result;
-}
+ 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;
+ }
+ }
-static inline QString languageLevelDescription()
-{
- return QLatin1String("C++ Language level (c++11..c++17, default=")
- + QLatin1String(clang::languageLevelOption(clang::emulatedCompilerLanguageLevel()))
- + QLatin1Char(')');
+ return false;
}
void printUsage()
{
- const QChar pathSplitter = QDir::listSeparator();
+ const auto generatorOptions = Generator::options();
+
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 = {
- {QLatin1String("api-version=<\"package mask\">,<\"version\">"),
- QLatin1String("Specify the supported api version used to generate the bindings")},
- {QLatin1String("debug-level=[sparse|medium|full]"),
- QLatin1String("Set the debug level")},
- {QLatin1String("documentation-only"),
- QLatin1String("Do not generates any code, just the documentation")},
- {QLatin1String("drop-type-entries=\"<TypeEntry0>[;TypeEntry1;...]\""),
- QLatin1String("Semicolon separated list of type system entries (classes, namespaces,\n"
- "global functions and enums) to be dropped from generation.")},
- {keywordsOption() + QStringLiteral("=keyword1[,keyword2,...]"),
- QLatin1String("A comma-separated list of keywords for conditional typesystem parsing")},
- {clangOptionOption(),
- QLatin1String("Option to be passed to clang")},
- {clangOptionsOption(),
- QLatin1String("A comma-separated list of options to be passed to clang")},
- {QLatin1String("-F<path>"), {} },
- {QLatin1String("framework-include-paths=") + pathSyntax,
- QLatin1String("Framework include paths used by the C++ parser")},
- {QLatin1String("-isystem<path>"), {} },
- {QLatin1String("system-include-paths=") + pathSyntax,
- QLatin1String("System include paths used by the C++ parser")},
- {useGlobalHeaderOption(),
- QLatin1String("Use the global headers in generated code.")},
- {QLatin1String("generator-set=<\"generator module\">"),
- QLatin1String("generator-set to be used. e.g. qtdoc")},
- {skipDeprecatedOption(),
- QLatin1String("Skip deprecated functions")},
- {diffOption(), QLatin1String("Print a diff of wrapper files")},
- {dryrunOption(), QLatin1String("Dry run, do not generate wrapper files")},
- {QLatin1String("-h"), {} },
- {helpOption(), QLatin1String("Display this help and exit")},
- {QLatin1String("-I<path>"), {} },
- {QLatin1String("include-paths=") + pathSyntax,
- QLatin1String("Include paths used by the C++ parser")},
- {languageLevelOption() + QLatin1String("=, -std=<level>"),
- languageLevelDescription()},
- {QLatin1String("license-file=<license-file>"),
- QLatin1String("File used for copyright headers of generated files")},
- {QLatin1String("no-suppress-warnings"),
- QLatin1String("Show all warnings")},
- {QLatin1String("output-directory=<path>"),
- QLatin1String("The directory where the generated files will be written")},
- {QLatin1String("project-file=<file>"),
- QLatin1String("text file containing a description of the binding project.\n"
- "Replaces and overrides command line arguments")},
- {QLatin1String("silent"), QLatin1String("Avoid printing any message")},
- {QLatin1String("-T<path>"), {} },
- {QLatin1String("typesystem-paths=") + pathSyntax,
- QLatin1String("Paths used when searching for typesystems")},
- {QLatin1String("version"),
- QLatin1String("Output version information and exit")}
- };
- 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());
- }
- }
+ << "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(QLatin1Char(' '));
+ 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(QLatin1String("version"));
- 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(QLatin1String("generator-set"));
- if (ait == args.options.end()) // Also check QLatin1String("generatorSet") command line argument for backward compatibility.
- ait = args.options.find(QLatin1String("generatorSet"));
- 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 == QLatin1String("qtdoc")) {
+ if (commonOptions.generatorSet == u"qtdoc") {
generators = docGenerators();
if (generators.isEmpty()) {
- errorPrint(QLatin1String("Doc strings extractions was not enabled in this shiboken build."));
+ errorPrint(u"Doc strings extractions was not enabled in this shiboken build."_s, argV);
return EXIT_FAILURE;
}
- } else if (generatorSet.isEmpty() || generatorSet == QLatin1String("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(QLatin1String("Unknown generator set, try \"shiboken\" or \"qtdoc\"."));
+ errorPrint(u"Unknown generator set, try \"shiboken\" or \"qtdoc\"."_s, argV);
return EXIT_FAILURE;
}
- ait = args.options.find(QLatin1String("help"));
- 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(QLatin1String("license-file"));
- 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 = QLatin1String("out");
- ait = args.options.find(QLatin1String("output-directory"));
- 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(QLatin1String("silent"));
- if (ait != args.options.end()) {
- extractor.setSilent(true);
- args.options.erase(ait);
- } else {
- ait = args.options.find(QLatin1String("debug-level"));
- if (ait != args.options.end()) {
- const QString value = ait.value().toString();
- if (!ReportHandler::setDebugLevelFromArg(value)) {
- errorPrint(QLatin1String("Invalid debug level: ") + value);
- return EXIT_FAILURE;
- }
- args.options.erase(ait);
- }
- }
- ait = args.options.find(QLatin1String("no-suppress-warnings"));
- 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(QLatin1Char(','));
- QString package;
- QString version;
- package = parts.count() == 1 ? QLatin1String("*") : parts.constFirst();
- version = parts.constLast();
- if (!extractor.setApiVersion(package, version)) {
- errorPrint(msgInvalidVersion(package, version));
- return EXIT_FAILURE;
- }
+ 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;
}
- }
-
- 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);
+ commonOptions.typeSystemFileName = options.positionalArguments.takeLast();
+ commonOptions.headers = options.positionalArguments;
}
- 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);
- }
-
- parseIncludePathOption(includePathOption(), HeaderType::Standard,
- args, extractor);
- parseIncludePathOption(frameworkIncludePathOption(), HeaderType::Framework,
- args, extractor);
- parseIncludePathOption(systemIncludePathOption(), HeaderType::System,
- args, extractor);
-
- if (args.positionalArguments.size() < 2) {
- errorPrint(QLatin1String("Insufficient positional arguments, specify header-file and typesystem-file."));
- std::cout << '\n';
- printUsage();
- return EXIT_FAILURE;
- }
-
- const QString typeSystemFileName = args.positionalArguments.takeLast();
- QString messagePrefix = QFileInfo(typeSystemFileName).baseName();
- if (messagePrefix.startsWith(QLatin1String("typesystem_")))
+ QString messagePrefix = QFileInfo(commonOptions.typeSystemFileName).baseName();
+ if (messagePrefix.startsWith(u"typesystem_"))
messagePrefix.remove(0, 11);
- ReportHandler::setPrefix(QLatin1Char('(') + messagePrefix + QLatin1Char(')'));
+ ReportHandler::setPrefix(u'(' + messagePrefix + u')');
QFileInfoList cppFileNames;
- for (const QString &cppFileName : qAsConst(args.positionalArguments)) {
+ for (const QString &cppFileName : std::as_const(commonOptions.headers)) {
const QFileInfo cppFileNameFi(cppFileName);
if (!cppFileNameFi.isFile() && !cppFileNameFi.isSymLink()) {
- errorPrint(QLatin1Char('"') + cppFileName + QLatin1String("\" does not exist."));
+ 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 : qAsConst(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);
- }
+ optionParser.process(&options);
+ optionParser.clear();
- /* 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(QLatin1String("project-file"));
- for (auto it = projectFileArguments.options.cbegin(), end = projectFileArguments.options.cend();
- it != end; ++it) {
- args.options.remove(it.key());
- }
-
- 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);
-
- const bool usePySideExtensions = generators.constFirst().data()->usePySideExtensions();
+ extractor.setTypeSystem(commonOptions.typeSystemFileName);
- const std::optional<ApiExtractorResult> apiOpt = extractor.run(usePySideExtensions);
+ ApiExtractorFlags apiExtractorFlags;
+ if (generators.constFirst()->usePySideExtensions())
+ apiExtractorFlags.setFlag(ApiExtractorFlag::UsePySideExtensions);
+ if (generators.constFirst()->avoidProtectedHack())
+ apiExtractorFlags.setFlag(ApiExtractorFlag::AvoidProtectedHack);
+ const std::optional<ApiExtractorResult> apiOpt = extractor.run(apiExtractorFlags);
if (!apiOpt.has_value()) {
- errorPrint(QLatin1String("Error running ApiExtractor."));
+ errorPrint(u"Error running ApiExtractor."_s, argV);
return EXIT_FAILURE;
}
@@ -707,32 +376,59 @@ int shibokenMain(int argc, char *argv[])
<< "\n\nType datase:\n" << *TypeDatabase::instance();
}
- for (const GeneratorPtr &g : qAsConst(generators)) {
- g->setOutputDirectory(outputDirectory);
- g->setLicenseComment(licenseComment);
- ReportHandler::startProgress(QByteArray("Running ") + g->name() + "...");
+ if (commonOptions.printBuiltinTypes)
+ TypeDatabase::instance()->formatBuiltinTypes(qInfo());
+
+ for (const GeneratorPtr &g : std::as_const(generators)) {
+ 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(QLatin1String("Error running generator: ")
- + QLatin1String(g->name()) + QLatin1Char('.'));
+ errorPrint(u"Error running generator: "_s
+ + 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 713706bf3..1634a7e83 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.cpp
@@ -1,33 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qtdocgenerator.h"
+#include "generatorcontext.h"
+#include "codesnip.h"
#include "exception.h"
+#include "abstractmetaargument.h"
#include "apiextractorresult.h"
#include "qtxmltosphinx.h"
#include "rstformat.h"
@@ -37,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>
@@ -44,25 +23,97 @@
#include <reporthandler.h>
#include <textstream.h>
#include <typedatabase.h>
-#include <typesystem.h>
+#include <functiontypeentry.h>
+#include <enumtypeentry.h>
+#include <complextypeentry.h>
+#include <flagstypeentry.h>
+#include <primitivetypeentry.h>
#include <qtdocparser.h>
#include <doxygenparser.h>
+#include "qtcompat.h"
+
#include <QtCore/QTextStream>
#include <QtCore/QFile>
#include <QtCore/QDir>
+#include <QtCore/QJsonArray>
+#include <QtCore/QJsonDocument>
+#include <QtCore/QJsonObject>
+#include <QtCore/QSet>
#include <algorithm>
#include <limits>
-static inline QString additionalDocumentationOption() { return QStringLiteral("additional-documentation"); }
+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
+ {
+ QString name;
+ Documentation documentation;
+ AbstractMetaType type;
+ AbstractMetaFunctionCPtr getter;
+ AbstractMetaFunctionCPtr setter;
+ AbstractMetaFunctionCPtr reset;
+ AbstractMetaFunctionCPtr notify;
+ };
+
+ AbstractMetaFunctionCList allFunctions;
+ AbstractMetaFunctionCList tocNormalFunctions; // Index lists
+ AbstractMetaFunctionCList tocVirtuals;
+ AbstractMetaFunctionCList tocSignalFunctions;
+ AbstractMetaFunctionCList tocSlotFunctions;
+ AbstractMetaFunctionCList tocStaticFunctions;
+
+ QList<Property> properties;
+};
+
+static bool operator<(const GeneratorDocumentation::Property &lhs,
+ const GeneratorDocumentation::Property &rhs)
+{
+ return lhs.name < rhs.name;
+}
+
+static QString propertyRefTarget(const QString &name)
+{
+ QString result = name;
+ // For sphinx referencing, disambiguate the target from the getter name
+ // by appending an invisible "Hangul choseong filler" character.
+ result.append(QChar(0x115F));
+ return result;
+}
+
+constexpr auto additionalDocumentationOption = "additional-documentation"_L1;
-static inline QString none() { return QStringLiteral("None"); }
+constexpr auto none = "None"_L1;
static bool shouldSkip(const AbstractMetaFunctionCPtr &func)
{
- // Constructors go to separate section
- if (DocParser::skipForQuery(func) || func->isConstructor())
+ if (DocParser::skipForQuery(func))
return true;
// Search a const clone (QImage::bits() vs QImage::bits() const)
@@ -75,12 +126,12 @@ static bool shouldSkip(const AbstractMetaFunctionCPtr &func)
if (f != func
&& f->isConstant()
&& f->name() == func->name()
- && f->arguments().count() == funcArgs.count()) {
+ && f->arguments().size() == funcArgs.size()) {
// Compare each argument
bool cloneFound = true;
const AbstractMetaArgumentList fargs = f->arguments();
- for (int i = 0, max = funcArgs.count(); i < max; ++i) {
+ for (qsizetype i = 0, max = funcArgs.size(); i < max; ++i) {
if (funcArgs.at(i).type().typeEntry() != fargs.at(i).type().typeEntry()) {
cloneFound = false;
break;
@@ -95,116 +146,205 @@ 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 TypeEntry *te)
+static inline QVersionNumber versionOf(const TypeEntryCPtr &te)
{
if (te) {
const auto version = te->version();
if (!version.isNull() && version > QVersionNumber(0, 0))
return version;
}
- return QVersionNumber();
-}
-
-static const QHash<QString, QString> &operatorMapping()
-{
- static const QHash<QString, QString> result = {
- {QLatin1String("operator+"), QLatin1String("__add__")},
- {QLatin1String("operator+="), QLatin1String("__iadd__")},
- {QLatin1String("operator-"), QLatin1String("__sub__")},
- {QLatin1String("operator-="), QLatin1String("__isub__")},
- {QLatin1String("operator*"), QLatin1String("__mul__")},
- {QLatin1String("operator*="), QLatin1String("__imul__")},
- {QLatin1String("operator/"), QLatin1String("__div__")},
- {QLatin1String("operator/="), QLatin1String("__idiv__")},
- {QLatin1String("operator%"), QLatin1String("__mod__")},
- {QLatin1String("operator%="), QLatin1String("__imod__")},
- {QLatin1String("operator<<"), QLatin1String("__lshift__")},
- {QLatin1String("operator<<="), QLatin1String("__ilshift__")},
- {QLatin1String("operator>>"), QLatin1String("__rshift__")},
- {QLatin1String("operator>>="), QLatin1String("__irshift__")},
- {QLatin1String("operator&"), QLatin1String("__and__")},
- {QLatin1String("operator&="), QLatin1String("__iand__")},
- {QLatin1String("operator|"), QLatin1String("__or__")},
- {QLatin1String("operator|="), QLatin1String("__ior__")},
- {QLatin1String("operator^"), QLatin1String("__xor__")},
- {QLatin1String("operator^="), QLatin1String("__ixor__")},
- {QLatin1String("operator=="), QLatin1String("__eq__")},
- {QLatin1String("operator!="), QLatin1String("__ne__")},
- {QLatin1String("operator<"), QLatin1String("__lt__")},
- {QLatin1String("operator<="), QLatin1String("__le__")},
- {QLatin1String("operator>"), QLatin1String("__gt__")},
- {QLatin1String("operator>="), QLatin1String("__ge__")},
- };
- return result;
+ return {};
}
-static QString getFuncName(const AbstractMetaFunctionCPtr& cppFunc)
+struct docRef
{
- const auto it = operatorMapping().constFind(cppFunc->name());
- QString result = it != operatorMapping().cend() ? it.value() : cppFunc->name();
- result.replace(QLatin1String("::"), QLatin1String("."));
+ explicit docRef(const char *kind, QAnyStringView name) :
+ m_kind(kind), m_name(name) {}
+
+ const char *m_kind;
+ QAnyStringView m_name;
+};
+
+static TextStream &operator<<(TextStream &s, const docRef &dr)
+{
+ 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, QAnyStringView name) :
+ m_kind(kind), m_name(name) {}
+
+ const char *m_kind;
+ QAnyStringView m_name;
+};
+
+static TextStream &operator<<(TextStream &s, const shortDocRef &sdr)
+{
+ s << ':' << sdr.m_kind << ":`~" << sdr.m_name << '`';
+ return s;
+}
+
+struct functionRef : public docRef
+{
+ 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 headline
+{
+ explicit headline(QAnyStringView title, char underLineChar = '-') :
+ m_title(title), m_underLineChar(underLineChar) {}
+
+ QAnyStringView m_title;
+ char m_underLineChar;
+};
+
+static TextStream &operator<<(TextStream &s, const headline &h)
+{
+ s << h.m_title << '\n' << Pad(h.m_underLineChar, h.m_title.size()) << "\n\n";
+ return s;
+}
+
+struct pyClass
+{
+ 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;
}
QtDocGenerator::~QtDocGenerator() = default;
-QString QtDocGenerator::fileNameSuffix() const
+QString QtDocGenerator::fileNameSuffix()
{
- return QLatin1String(".rst");
+ return u".rst"_s;
}
-bool QtDocGenerator::shouldGenerate(const AbstractMetaClass *cls) const
+bool QtDocGenerator::shouldGenerate(const TypeEntryCPtr &te) const
{
- return Generator::shouldGenerate(cls)
- && cls->typeEntry()->type() != TypeEntry::SmartPointerType;
+ return Generator::shouldGenerate(te)
+ && te->type() != TypeEntry::SmartPointerType;
}
QString QtDocGenerator::fileNameForContext(const GeneratorContext &context) const
{
- const AbstractMetaClass *metaClass = context.metaClass();
- if (!context.forSmartPointer()) {
- return metaClass->name() + fileNameSuffix();
- }
- const AbstractMetaType &smartPointerType = context.preciseType();
- QString fileNameBase = getFileNameBaseForSmartPointer(smartPointerType, metaClass);
- return fileNameBase + fileNameSuffix();
+ return fileNameForContextHelper(context, fileNameSuffix(),
+ FileNameFlag::UnqualifiedName
+ | FileNameFlag::KeepCase);
}
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(QLatin1Char('\n'));
+ const auto lines = QStringView{doc}.split(u'\n');
int typesystemIndentation = std::numeric_limits<int>::max();
// check how many spaces must be removed from the beginning of each line
for (const auto &line : lines) {
@@ -225,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;
- s << "**Inherited by:** ";
- QStringList classes;
- for (auto c : qAsConst(res))
- classes << QLatin1String(":ref:`") + c->name() + QLatin1Char('`');
- s << classes.join(QLatin1String(", ")) << "\n\n";
+ recurseClassHierarchy(metaClass, [&res, metaClass](const AbstractMetaClassCPtr &c) {
+ if (c.get() != metaClass.get())
+ res.append(c);
+ return false;
+ });
+
+ 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.count()) << "\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());
@@ -278,123 +439,113 @@ void QtDocGenerator::generateClass(TextStream &s, const GeneratorContext &classC
if (metaClass->attributes().testFlag(AbstractMetaClass::Deprecated))
s << rstDeprecationNote("class");
- writeFunctionList(s, metaClass);
-
- //Function list
- auto functionList = metaClass->functions();
- std::sort(functionList.begin(), functionList.end(), functionSort);
+ const GeneratorDocumentation doc = generatorDocumentation(metaClass);
- s << "\nDetailed Description\n"
- "--------------------\n\n"
- << ".. _More:\n";
+ if (!doc.allFunctions.isEmpty() || !doc.properties.isEmpty()) {
+ 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);
+ }
- writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, metaClass, nullptr);
- if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, metaClass, nullptr))
- writeFormattedDetailedText(s, documentation, metaClass);
+ 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";
- if (!metaClass->isNamespace())
- writeConstructors(s, metaClass);
- writeEnums(s, metaClass);
- if (!metaClass->isNamespace())
- writeFields(s, metaClass);
+ s << '\n' << headline("Detailed Description") << ".. _More:\n";
+ writeInjectDocumentation(s, TypeSystem::DocModificationPrepend, metaClass);
+ if (!writeInjectDocumentation(s, TypeSystem::DocModificationReplace, metaClass))
+ writeFormattedDetailedText(s, documentation, scope);
+ writeInjectDocumentation(s, TypeSystem::DocModificationAppend, metaClass);
- QStringList uniqueFunctions;
- for (const auto &func : qAsConst(functionList)) {
- if (shouldSkip(func))
- continue;
+ writeEnums(s, metaClass->enums(), scope);
- if (func->isStatic())
- s << ".. staticmethod:: ";
- else
- s << ".. method:: ";
+ if (!doc.properties.isEmpty())
+ writeProperties(s, doc, metaClass);
- writeFunction(s, metaClass, func, !uniqueFunctions.contains(func->name()));
- uniqueFunctions.append(func->name());
- }
+ if (!metaClass->isNamespace())
+ writeFields(s, metaClass);
- writeInjectDocumentation(s, TypeSystem::DocModificationAppend, metaClass, nullptr);
+ writeFunctions(s, doc.allFunctions, metaClass, scope);
}
-void QtDocGenerator::writeFunctionList(TextStream& s, const AbstractMetaClass* cppClass)
+void QtDocGenerator::writeFunctionToc(TextStream &s, const QString &title,
+ const AbstractMetaFunctionCList &functions)
{
- QStringList functionList;
- QStringList virtualList;
- QStringList signalList;
- QStringList slotList;
- QStringList staticFunctionList;
-
- const auto &classFunctions = cppClass->functions();
- for (const auto &func : classFunctions) {
- if (shouldSkip(func))
- continue;
-
- QString className;
- if (!func->isConstructor())
- className = cppClass->fullName() + QLatin1Char('.');
- else if (func->implementingClass() && func->implementingClass()->enclosingClass())
- className = func->implementingClass()->enclosingClass()->fullName() + QLatin1Char('.');
- QString funcName = getFuncName(func);
-
- QString str = QLatin1String("def :meth:`");
-
- str += funcName;
- str += QLatin1Char('<');
- if (!funcName.startsWith(className))
- str += className;
- str += funcName;
- str += QLatin1String(">` (");
- str += parseArgDocStyle(cppClass, func);
- str += QLatin1Char(')');
-
- if (func->isStatic())
- staticFunctionList << str;
- else if (func->isVirtual())
- virtualList << str;
- else if (func->isSignal())
- signalList << str;
- else if (func->isSlot())
- slotList << str;
- else
- functionList << str;
+ if (!functions.isEmpty()) {
+ 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";
}
+}
- if (!functionList.isEmpty() || !staticFunctionList.isEmpty()) {
- QtXmlToSphinx::Table functionTable;
-
- s << "\nSynopsis\n--------\n\n";
+void QtDocGenerator::writePropertyToc(TextStream &s,
+ const GeneratorDocumentation &doc)
+{
+ if (doc.properties.isEmpty())
+ return;
- writeFunctionBlock(s, QLatin1String("Functions"), functionList);
- writeFunctionBlock(s, QLatin1String("Virtual functions"), virtualList);
- writeFunctionBlock(s, QLatin1String("Slots"), slotList);
- writeFunctionBlock(s, QLatin1String("Signals"), signalList);
- writeFunctionBlock(s, QLatin1String("Static functions"), staticFunctionList);
+ s << headline("Properties", '^')
+ << ".. container:: function_list\n\n" << indent;
+ for (const auto &prop : doc.properties) {
+ s << "* " << propRef(propertyRefTarget(prop.name));
+ if (prop.documentation.hasBrief())
+ s << " - " << prop.documentation.brief();
+ s << '\n';
}
+ s << outdent << "\n\n";
}
-void QtDocGenerator::writeFunctionBlock(TextStream& s, const QString& title, QStringList& functions)
+void QtDocGenerator::writeProperties(TextStream &s,
+ const GeneratorDocumentation &doc,
+ const AbstractMetaClassCPtr &cppClass) const
{
- if (!functions.isEmpty()) {
- s << title << '\n'
- << Pad('^', title.size()) << '\n';
-
- std::sort(functions.begin(), functions.end());
-
- s << ".. container:: function_list\n\n";
- Indentation indentation(s);
- for (const QString &func : qAsConst(functions))
- s << "* " << func << '\n';
- s << "\n\n";
+ 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(prop.name)
+ << "\n :type: " << type << "\n\n\n";
+ if (!prop.documentation.isEmpty())
+ writeFormattedText(s, prop.documentation.detailed(), Documentation::Native, scope);
+ s << "**Access functions:**\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 = QLatin1String(".. attribute:: ");
-
- 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);
@@ -402,75 +553,20 @@ 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 = QLatin1String(".. attribute:: ");
+ 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);
+ writeFormattedDetailedText(s, field.documentation(), scope);
}
}
-void QtDocGenerator::writeConstructors(TextStream& s, const AbstractMetaClass* cppClass) const
+QString QtDocGenerator::formatArgs(const AbstractMetaFunctionCPtr &func)
{
- static const QString sectionTitle = QLatin1String(".. class:: ");
-
- auto lst = cppClass->queryFunctions(FunctionQueryOption::Constructors | FunctionQueryOption::Visible);
- for (int i = lst.size() - 1; i >= 0; --i) {
- if (lst.at(i)->isModifiedRemoved() || lst.at(i)->functionType() == AbstractMetaFunction::MoveConstructorFunction)
- lst.removeAt(i);
- }
-
- bool first = true;
- QHash<QString, AbstractMetaArgument> arg_map;
-
- if (lst.isEmpty()) {
- s << sectionTitle << cppClass->fullName();
- } else {
- QByteArray pad;
- for (const auto &func : qAsConst(lst)) {
- 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->attributes().testFlag(AbstractMetaFunction::Deprecated))
- 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);
- }
-
- s << '\n';
-
- for (const auto &func : qAsConst(lst))
- writeFormattedDetailedText(s, func->documentation(), cppClass);
-}
-
-QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* /* cppClass */,
- const AbstractMetaFunctionCPtr &func)
-{
- QString ret;
+ QString ret = u"("_s;
int optArgs = 0;
const AbstractMetaArgumentList &arguments = func->arguments();
@@ -481,37 +577,37 @@ QString QtDocGenerator::parseArgDocStyle(const AbstractMetaClass* /* cppClass */
bool thisIsoptional = !arg.defaultValueExpression().isEmpty();
if (optArgs || thisIsoptional) {
- ret += QLatin1Char('[');
+ ret += u'[';
optArgs++;
}
if (arg.argumentIndex() > 0)
- ret += QLatin1String(", ");
+ ret += u", "_s;
ret += arg.name();
if (thisIsoptional) {
QString defValue = arg.defaultValueExpression();
- if (defValue == QLatin1String("QString()")) {
- defValue = QLatin1String("\"\"");
- } else if (defValue == QLatin1String("QStringList()")
- || defValue.startsWith(QLatin1String("QVector"))
- || defValue.startsWith(QLatin1String("QList"))) {
- defValue = QLatin1String("list()");
- } else if (defValue == QLatin1String("QVariant()")) {
- defValue = none();
+ if (defValue == u"QString()") {
+ defValue = u"\"\""_s;
+ } else if (defValue == u"QStringList()"
+ || defValue.startsWith(u"QVector")
+ || defValue.startsWith(u"QList")) {
+ defValue = u"list()"_s;
+ } else if (defValue == u"QVariant()") {
+ defValue = none;
} else {
- defValue.replace(QLatin1String("::"), QLatin1String("."));
- if (defValue == QLatin1String("nullptr"))
- defValue = none();
- else if (defValue == QLatin1String("0") && arg.type().isObject())
- defValue = none();
+ defValue.replace(u"::"_s, u"."_s);
+ if (defValue == u"nullptr")
+ defValue = none;
+ else if (defValue == u"0" && arg.type().isObject())
+ defValue = none;
}
- ret += QLatin1Char('=') + defValue;
+ ret += u'=' + defValue;
}
}
- ret += QString(optArgs, QLatin1Char(']'));
+ ret += QString(optArgs, u']') + u')';
return ret;
}
@@ -521,11 +617,9 @@ void QtDocGenerator::writeDocSnips(TextStream &s,
TypeSystem::Language language)
{
Indentation indentation(s);
- QStringList invalidStrings;
- const static QString startMarkup = QLatin1String("[sphinx-begin]");
- const static QString endMarkup = QLatin1String("[sphinx-end]");
-
- invalidStrings << QLatin1String("*") << QLatin1String("//") << QLatin1String("/*") << QLatin1String("*/");
+ static const QStringList invalidStrings{u"*"_s, u"//"_s, u"/*"_s, u"*/"_s};
+ const static QString startMarkup = u"[sphinx-begin]"_s;
+ const static QString endMarkup = u"[sphinx-end]"_s;
for (const CodeSnip &snip : codeSnips) {
if ((snip.position != position) ||
@@ -534,19 +628,19 @@ void QtDocGenerator::writeDocSnips(TextStream &s,
QString code = snip.code();
while (code.contains(startMarkup) && code.contains(endMarkup)) {
- int startBlock = code.indexOf(startMarkup) + startMarkup.size();
- int endBlock = code.indexOf(endMarkup);
+ const auto startBlock = code.indexOf(startMarkup) + startMarkup.size();
+ const auto endBlock = code.indexOf(endMarkup);
if ((startBlock == -1) || (endBlock == -1))
break;
QString codeBlock = code.mid(startBlock, endBlock - startBlock);
- const QStringList rows = codeBlock.split(QLatin1Char('\n'));
+ const QStringList rows = codeBlock.split(u'\n');
int currentRow = 0;
- int offset = 0;
+ qsizetype offset = 0;
for (QString row : rows) {
- for (const QString &invalidString : qAsConst(invalidStrings))
+ for (const QString &invalidString : std::as_const(invalidStrings))
row.remove(invalidString);
if (row.trimmed().size() == 0) {
@@ -558,9 +652,9 @@ void QtDocGenerator::writeDocSnips(TextStream &s,
if (currentRow == 0) {
//find offset
for (auto c : row) {
- if (c == QLatin1Char(' '))
+ if (c == u' ')
offset++;
- else if (c == QLatin1Char('\n'))
+ else if (c == u'\n')
offset = 0;
else
break;
@@ -575,128 +669,175 @@ 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 = cppClass->typeEntry()->docModifications();
for (const DocModification &mod : mods) {
if (mod.mode() == mode) {
- bool modOk = func ? mod.signature() == func->minimalSignature() : mod.signature().isEmpty();
-
- if (modOk) {
- Documentation::Format fmt;
-
- if (mod.format() == TypeSystem::NativeCode)
- fmt = Documentation::Native;
- else if (mod.format() == TypeSystem::TargetLangCode)
- fmt = Documentation::Target;
- else
- continue;
-
- writeFormattedText(s, mod.code(), fmt, cppClass);
+ switch (mod.format()) {
+ case TypeSystem::NativeCode:
+ writeFormattedText(s, mod.code(), Documentation::Native, scope);
+ didSomething = true;
+ break;
+ case TypeSystem::TargetLangCode:
+ writeFormattedText(s, mod.code(), Documentation::Target, scope);
didSomething = true;
+ break;
+ default:
+ break;
}
}
}
+ 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';
- // TODO: Deprecate the use of doc string on glue code.
+ // 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;
+ const bool didSomething = writeDocModifications(s, modifications, mode, scope);
+ s << '\n';
- funcName = cppClass->fullName();
- if (!func->isConstructor())
- funcName += QLatin1Char('.') + getFuncName(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;
+}
- return funcName + QLatin1Char('(') + parseArgDocStyle(cppClass, func)
- + QLatin1Char(')');
+static QString inline toRef(const QString &t)
+{
+ return ":class:`~"_L1 + t + u'`';
}
QString QtDocGenerator::translateToPythonType(const AbstractMetaType &type,
- const AbstractMetaClass* cppClass) const
+ 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() },
- { QLatin1String("uchar"), pyStrT() },
- { QLatin1String("QStringList"), QLatin1String("list of strings") },
- { qVariantT(), pyObjectT() },
- { QLatin1String("quint32"), intT() },
- { QLatin1String("uint32_t"), intT() },
- { QLatin1String("quint64"), intT() },
- { QLatin1String("qint64"), intT() },
- { QLatin1String("size_t"), intT() },
- { QLatin1String("int64_t"), intT() },
- { QLatin1String("qreal"), floatT() }
+ 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 }
};
- 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 == QLatin1String("char") && type.indirections() == 1) {
- strType = QLatin1String("str");
- } 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(QLatin1Char('*'));
- strType.remove(QLatin1Char('>'));
- strType.remove(QLatin1Char('<'));
- strType.replace(QLatin1String("::"), QLatin1String("."));
- if (strType.contains(QLatin1String("QList")) || strType.contains(QLatin1String("QVector"))) {
- strType.replace(QLatin1String("QList"), QLatin1String("list of "));
- strType.replace(QLatin1String("QVector"), QLatin1String("list of "));
- } else if (strType.contains(QLatin1String("QHash")) || strType.contains(QLatin1String("QMap"))) {
- strType.remove(QLatin1String("QHash"));
- strType.remove(QLatin1String("QMap"));
- QStringList types = strType.split(QLatin1Char(','));
+ strType.remove(u'*');
+ strType.remove(u'>');
+ strType.remove(u'<');
+ strType.replace(u"::"_s, u"."_s);
+ if (strType.contains(u"QList") || strType.contains(u"QVector")) {
+ strType.replace(u"QList"_s, u"list of "_s);
+ strType.replace(u"QVector"_s, u"list of "_s);
+ } else if (strType.contains(u"QHash") || strType.contains(u"QMap")) {
+ strType.remove(u"QHash"_s);
+ strType.remove(u"QMap"_s);
+ QStringList types = strType.split(u',');
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();
- strType = QStringLiteral(":any:`") + strType + QLatin1Char('`');
+ 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);
+ if (!pythonOperator.isEmpty())
+ return pythonOperator;
}
- return strType;
+ result.replace(u"::"_s, u"."_s);
+ 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';
@@ -706,170 +847,294 @@ 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->cppAttributes().testFlag(FunctionAttribute::Final))
+ s << "\n:final:";
+ else if (func->isAbstract())
+ s << "\n:abstractmethod:";
s << "\n\n";
writeFunctionParametersType(s, cppClass, func);
const auto version = versionOf(func->typeEntry());
if (!version.isNull())
s << rstVersionAdded(version);
- if (func->attributes().testFlag(AbstractMetaFunction::Deprecated))
+ 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);
+
+ writeFunctionDocumentation(s, func, modifications, scope);
+
+ if (auto propIndex = func->propertySpecIndex(); propIndex >= 0) {
+ const QString name = cppClass->propertySpecs().at(propIndex).name();
+ const QString target = propertyRefTarget(name);
+ if (func->isPropertyReader())
+ s << "\nGetter of property " << propRef(target) << " .\n\n";
+ else if (func->isPropertyWriter())
+ s << "\nSetter of property " << propRef(target) << " .\n\n";
+ else if (func->isPropertyResetter())
+ s << "\nReset function of property " << propRef(target) << " .\n\n";
+ else if (func->attributes().testFlag(AbstractMetaFunction::Attribute::PropertyNotify))
+ s << "\nNotification signal of property " << propRef(target) << " .\n\n";
}
- writeInjectDocumentation(s, TypeSystem::DocModificationAppend, cppClass, func);
}
-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() || key.at(1).isDigit())) {
+ return key.at(1); // "QClass" -> 'C', "qSin()" -> 'S', 'Q3DSurfaceWidget' -> '3'
+ }
+ 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 Q = QLatin1Char('Q');
- 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(QLatin1Char('.')).last();
- if (className.startsWith(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;
QtXmlToSphinx::Table table;
for (auto it = tocMap.cbegin(), end = tocMap.cend(); it != end; ++it) {
QtXmlToSphinx::TableRow row;
- const QString charEntry = QLatin1String("**") + it.key() + QLatin1String("**");
+ const QString charEntry = u"**"_s + it.key() + u"**"_s;
row << QtXmlToSphinx::TableCell(charEntry);
- for (const QString &item : qAsConst(it.value())) {
+ for (const QString &item : std::as_const(it.value())) {
if (row.size() >= numColumns) {
table.appendRow(row);
row.clear();
row << QtXmlToSphinx::TableCell(QString{});
}
- const QString entry = QLatin1String("* :doc:`") + item + QLatin1Char('`');
+ const QString entry = "* :"_L1 + referenceType + ":`"_L1 + item + u'`';
row << QtXmlToSphinx::TableCell(entry);
}
- if (!row.isEmpty())
+ if (row.size() > 1)
table.appendRow(row);
}
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_options.inheritanceFile.isEmpty() && !writeInheritanceFile())
+ return false;
return true;
}
+bool QtDocGenerator::writeInheritanceFile()
+{
+ QFile inheritanceFile(m_options.inheritanceFile);
+ if (!inheritanceFile.open(QIODevice::WriteOnly | QIODevice::Text))
+ throw Exception(msgCannotOpenForWriting(m_options.inheritanceFile));
+
+ QJsonObject dict;
+ for (const auto &c : api().classes()) {
+ const auto &bases = c->baseClasses();
+ if (!bases.isEmpty()) {
+ QJsonArray list;
+ for (const auto &base : bases)
+ list.append(QJsonValue(base->fullName()));
+ dict[c->fullName()] = list;
+ }
+ }
+ QJsonDocument document;
+ document.setObject(dict);
+ inheritanceFile.write(document.toJson(QJsonDocument::Compact));
+ 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(QLatin1Char('.'), QLatin1Char('/'));
- QString outputDir = outputDirectory() + QLatin1Char('/') + key;
- FileOut output(outputDir + QLatin1String("/index.rst"));
+ key.replace(u'.', u'/');
+ QString outputDir = outputDirectory() + u'/' + key;
+ FileOut output(outputDir + u"/index.rst"_s);
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
// doesn't include the PySide# prefix in their names.
QString moduleName = it.key();
- const int lastIndex = moduleName.lastIndexOf(QLatin1Char('.'));
+ const int lastIndex = moduleName.lastIndexOf(u'.');
if (lastIndex >= 0)
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);
}
// Filter for "QtCore.Property.rst", skipping module doc "QtCore.rst"
- const QString filter = moduleName + QLatin1String(".?*.rst");
+ 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 + QLatin1Char('/') + 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);
}
- writeFancyToc(s, it.value());
+ 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 : qAsConst(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 + QLatin1Char('/') + moduleName
- + QLatin1String(".rst"));
+ QFile moduleDoc(m_options.extraSectionDir + u'/' + moduleName
+ + u".rst"_s);
if (moduleDoc.open(QIODevice::ReadOnly | QIODevice::Text)) {
s << moduleDoc.readAll();
moduleDoc.close();
@@ -879,14 +1144,48 @@ 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();
}
}
+
+ 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,
@@ -901,7 +1200,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));
@@ -920,14 +1219,14 @@ void QtDocGenerator::writeAdditionalDocumentation() const
continue;
const QString line = QFile::decodeName(lineBA);
// Parse "[directory]" specification
- if (line.size() > 2 && line.startsWith(QLatin1Char('[')) && line.endsWith(QLatin1Char(']'))) {
+ if (line.size() > 2 && line.startsWith(u'[') && line.endsWith(u']')) {
const QString dir = line.mid(1, line.size() - 2);
- if (dir.isEmpty() || dir == QLatin1String(".")) {
+ if (dir.isEmpty() || dir == u".") {
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);
}
@@ -935,11 +1234,11 @@ void QtDocGenerator::writeAdditionalDocumentation() const
}
} else {
// Normal file entry
- QFileInfo fi(m_parameters.docDataDir + QLatin1Char('/') + line);
+ QFileInfo fi(m_options.parameters.docDataDir + u'/' + line);
if (fi.isFile()) {
const QString rstFileName = fi.baseName() + rstSuffix;
- const QString rstFile = targetDir + QLatin1Char('/') + rstFileName;
- const QString context = targetDir.mid(targetDir.lastIndexOf(QLatin1Char('/')) + 1);
+ const QString rstFile = targetDir + u'/' + rstFileName;
+ const QString context = targetDir.mid(targetDir.lastIndexOf(u'/') + 1);
if (convertToRst(fi.absoluteFilePath(),
rstFile, context, &errorMessage)) {
++successCount;
@@ -953,7 +1252,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;
}
@@ -972,83 +1271,133 @@ 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;
}
+QList<OptionDescription> QtDocGenerator::options()
+{
+ return {
+ {u"doc-parser=<parser>"_s,
+ u"The documentation parser used to interpret the documentation\n"
+ "input files (qdoc|doxygen)"_s},
+ {u"documentation-code-snippets-dir=<dir>"_s,
+ u"Directory used to search code snippets used by the documentation"_s},
+ {u"snippets-path-rewrite=old:new"_s,
+ u"Replacements in code snippet path to find .cpp/.h snippets converted to Python"_s},
+ {u"documentation-data-dir=<dir>"_s,
+ u"Directory with XML files generated by documentation tool"_s},
+ {u"documentation-extra-sections-dir=<dir>"_s,
+ 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,
+ 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},
+ {u"disable-inheritance-diagram"_s,
+ u"Disable the generation of the inheritance diagram."_s}
+ };
+}
-Generator::OptionDescriptions QtDocGenerator::options() const
-{
- auto result = Generator::options();
- result.append({
- {QLatin1String("doc-parser=<parser>"),
- QLatin1String("The documentation parser used to interpret the documentation\n"
- "input files (qdoc|doxygen)")},
- {QLatin1String("documentation-code-snippets-dir=<dir>"),
- QLatin1String("Directory used to search code snippets used by the documentation")},
- {QLatin1String("documentation-data-dir=<dir>"),
- QLatin1String("Directory with XML files generated by documentation tool")},
- {QLatin1String("documentation-extra-sections-dir=<dir>"),
- QLatin1String("Directory used to search for extra documentation sections")},
- {QLatin1String("library-source-dir=<dir>"),
- QLatin1String("Directory where library source code is located")},
- {additionalDocumentationOption() + QLatin1String("=<file>"),
- QLatin1String("List of additional XML files to be converted to .rst files\n"
- "(for example, tutorials).")}
- });
- return result;
+class QtDocGeneratorOptionsParser : public OptionsParser
+{
+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 QtDocGenerator::handleOption(const QString &key, const QString &value)
+bool QtDocGeneratorOptionsParser::handleOption(const QString &key, const QString &value,
+ OptionSource source)
{
- if (Generator::handleOption(key, value))
+ if (source == OptionSource::CommandLineSingleDash)
+ return false;
+ if (key == u"library-source-dir") {
+ m_options->parameters.libSourceDir = value;
return true;
- if (key == QLatin1String("library-source-dir")) {
- m_parameters.libSourceDir = value;
+ }
+ if (key == u"documentation-data-dir") {
+ m_options->parameters.docDataDir = value;
return true;
}
- if (key == QLatin1String("documentation-data-dir")) {
- m_parameters.docDataDir = value;
+ if (key == u"documentation-code-snippets-dir") {
+ m_options->parameters.codeSnippetDirs = value.split(QLatin1Char(PATH_SEP));
return true;
}
- if (key == QLatin1String("documentation-code-snippets-dir")) {
- m_parameters.codeSnippetDirs = value.split(QLatin1Char(PATH_SEP));
+
+ if (key == u"snippets-path-rewrite") {
+ const auto pos = value.indexOf(u':');
+ if (pos == -1)
+ return false;
+ m_options->parameters.codeSnippetRewriteOld= value.left(pos);
+ m_options->parameters.codeSnippetRewriteNew = value.mid(pos + 1);
return true;
}
- if (key == QLatin1String("documentation-extra-sections-dir")) {
- m_extraSectionDir = value;
+
+ if (key == u"documentation-extra-sections-dir") {
+ m_options->extraSectionDir = value;
return true;
}
- if (key == QLatin1String("doc-parser")) {
+ if (key == u"doc-parser") {
qCDebug(lcShibokenDoc).noquote().nospace() << "doc-parser: " << value;
- if (value == QLatin1String("doxygen"))
- m_docParser.reset(new DoxygenParser);
+ if (value == u"doxygen")
+ 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_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,
@@ -1064,20 +1413,65 @@ 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 AbstractMetaClassCPtr &cppClass)
+{
+ GeneratorDocumentation result;
+ const auto allFunctions = cppClass->functions();
+ result.allFunctions.reserve(allFunctions.size());
+ std::remove_copy_if(allFunctions.cbegin(), allFunctions.cend(),
+ std::back_inserter(result.allFunctions), shouldSkip);
+
+ std::stable_sort(result.allFunctions.begin(), result.allFunctions.end(), functionSort);
+
+ for (const auto &func : std::as_const(result.allFunctions)) {
+ if (func->isStatic())
+ result.tocStaticFunctions.append(func);
+ else if (func->isVirtual())
+ result.tocVirtuals.append(func);
+ else if (func->isSignal())
+ result.tocSignalFunctions.append(func);
+ else if (func->isSlot())
+ result.tocSlotFunctions.append(func);
+ else
+ result.tocNormalFunctions.append(func);
+ }
+
+ // Find the property getters/setters
+ for (const auto &spec: cppClass->propertySpecs()) {
+ GeneratorDocumentation::Property property;
+ property.name = spec.name();
+ property.type = spec.type();
+ property.documentation = spec.documentation();
+ if (!spec.read().isEmpty())
+ property.getter = AbstractMetaFunction::find(result.allFunctions, spec.read());
+ if (!spec.write().isEmpty())
+ property.setter = AbstractMetaFunction::find(result.allFunctions, spec.write());
+ if (!spec.reset().isEmpty())
+ property.reset = AbstractMetaFunction::find(result.allFunctions, spec.reset());
+ if (!spec.notify().isEmpty())
+ property.notify = AbstractMetaFunction::find(result.tocSignalFunctions, spec.notify());
+ result.properties.append(property);
+ }
+ std::sort(result.properties.begin(), result.properties.end());
+
+ return result;
+}
+
// QtXmlToSphinxDocGeneratorInterface
QString QtDocGenerator::expandFunction(const QString &function) const
{
- const int firstDot = function.indexOf(QLatin1Char('.'));
- 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;
@@ -1098,12 +1492,11 @@ QString QtDocGenerator::expandClass(const QString &context,
return typeEntry->qualifiedTargetLangName();
// fall back to the old heuristic if the type wasn't found.
QString result = name;
- const auto rawlinklist = QStringView{name}.split(QLatin1Char('.'));
- QStringList splittedContext = context.split(QLatin1Char('.'));
+ const auto rawlinklist = QStringView{name}.split(u'.');
+ QStringList splittedContext = context.split(u'.');
if (rawlinklist.size() == 1 || rawlinklist.constFirst() == splittedContext.constLast()) {
splittedContext.removeLast();
- result.prepend(QLatin1Char('~') + splittedContext.join(QLatin1Char('.'))
- + QLatin1Char('.'));
+ result.prepend(u'~' + splittedContext.join(u'.') + u'.');
}
return result;
}
@@ -1111,10 +1504,10 @@ QString QtDocGenerator::expandClass(const QString &context,
QString QtDocGenerator::resolveContextForMethod(const QString &context,
const QString &methodName) const
{
- const auto currentClass = QStringView{context}.split(QLatin1Char('.')).constLast();
+ 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;
@@ -1129,8 +1522,8 @@ QString QtDocGenerator::resolveContextForMethod(const QString &context,
funcList.append(func);
}
- const AbstractMetaClass *implementingClass = nullptr;
- for (const auto &func : qAsConst(funcList)) {
+ AbstractMetaClassCPtr implementingClass;
+ for (const auto &func : std::as_const(funcList)) {
implementingClass = func->implementingClass();
if (implementingClass->name() == currentClass)
break;
@@ -1140,7 +1533,7 @@ QString QtDocGenerator::resolveContextForMethod(const QString &context,
return implementingClass->typeEntry()->qualifiedTargetLangName();
}
- return QLatin1Char('~') + context;
+ return u'~' + context;
}
const QLoggingCategory &QtDocGenerator::loggingCategory() const
@@ -1160,8 +1553,8 @@ 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-")
- + QString::number(QT_VERSION_MAJOR) + QLatin1Char('/');
+ static const QString prefix = "https://doc.qt.io/qt-"_L1
+ + QString::number(QT_VERSION_MAJOR) + u'/';
QtXmlToSphinxLink resolved = link;
resolved.type = QtXmlToSphinxLink::External;
resolved.linkRef = prefix + link.linkRef;
@@ -1171,6 +1564,28 @@ QtXmlToSphinxLink QtDocGenerator::resolveLink(const QtXmlToSphinxLink &link) con
if (anchor != -1)
resolved.linkText.truncate(anchor);
}
- qDebug() << __FUNCTION__ << link << "->" << resolved;
return resolved;
}
+
+QtXmlToSphinxDocGeneratorInterface::Image
+ QtDocGenerator::resolveImage(const QString &href, const QString &context) const
+{
+ QString relativeSourceDir = href;
+ const QString source = m_options.parameters.docDataDir + u'/' + relativeSourceDir;
+ if (!QFileInfo::exists(source))
+ throw Exception(msgCannotFindImage(href, context,source));
+
+ // Determine target directory from context, "Pyside2.QtGui.QPainter" ->"Pyside2/QtGui".
+ // FIXME: Not perfect yet, should have knowledge about namespaces (DataVis3D) or
+ // nested classes "Pyside2.QtGui.QTouchEvent.QTouchPoint".
+ QString relativeTargetDir = context;
+ const auto lastDot = relativeTargetDir.lastIndexOf(u'.');
+ if (lastDot != -1)
+ relativeTargetDir.truncate(lastDot);
+ relativeTargetDir.replace(u'.', u'/');
+ if (!relativeTargetDir.isEmpty())
+ relativeTargetDir += u'/';
+ relativeTargetDir += href;
+
+ return {relativeSourceDir, relativeTargetDir};
+}
diff --git a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
index ab2f2fd45..56e15e2a1 100644
--- a/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
+++ b/sources/shiboken6/generator/qtdoc/qtdocgenerator.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef DOCGENERATOR_H
#define DOCGENERATOR_H
@@ -34,11 +9,15 @@
#include "generator.h"
#include "documentation.h"
+#include <optionsparser.h>
#include "typesystem_enums.h"
-#include "typesystem_typedefs.h"
+#include "modifications_typedefs.h"
#include "qtxmltosphinxinterface.h"
class DocParser;
+struct DocGeneratorOptions;
+struct GeneratorDocumentation;
+struct DocPackage;
/**
* The DocGenerator generates documentation from library being binded.
@@ -46,6 +25,8 @@ class DocParser;
class QtDocGenerator : public Generator, public QtXmlToSphinxDocGeneratorInterface
{
public:
+ Q_DISABLE_COPY_MOVE(QtDocGenerator)
+
QtDocGenerator();
~QtDocGenerator();
@@ -56,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;
@@ -67,64 +48,83 @@ public:
const QString &methodName) const override;
const QLoggingCategory &loggingCategory() const override;
QtXmlToSphinxLink resolveLink(const QtXmlToSphinxLink &) const override;
+ Image resolveImage(const QString &href, const QString &context) const override;
+
+ static QString getFuncName(const AbstractMetaFunctionCPtr &cppFunc);
+ static QString formatArgs(const AbstractMetaFunctionCPtr &func);
protected:
- bool shouldGenerate(const AbstractMetaClass *) const override;
- QString fileNameSuffix() const override;
+ bool shouldGenerate(const TypeEntryCPtr &) const override;
+ static QString fileNameSuffix();
QString fileNameForContext(const GeneratorContext &context) const override;
void generateClass(TextStream &ts, const GeneratorContext &classContext) override;
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 writeFunctionList(TextStream& s, const AbstractMetaClass* cppClass);
- static void writeFunctionBlock(TextStream& s, const QString& title,
- QStringList& functions);
- void writeParameterType(TextStream &s, const AbstractMetaClass *cppClass,
+ static void writeFunctionToc(TextStream &s, const QString &title,
+ const AbstractMetaFunctionCList &functions);
+ static void writePropertyToc(TextStream &s,
+ const GeneratorDocumentation &doc);
+ void writeProperties(TextStream &s,
+ const GeneratorDocumentation &doc,
+ const AbstractMetaClassCPtr &cppClass) const;
+ void writeParameterType(TextStream &s, const AbstractMetaClassCPtr &cppClass,
const AbstractMetaArgument &arg) const;
-
- void writeConstructors(TextStream &s, const AbstractMetaClass *cppClass) 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;
-
- bool writeInjectDocumentation(TextStream& s, TypeSystem::DocModificationMode mode,
- const AbstractMetaClass* cppClass,
- const AbstractMetaFunctionCPtr &func);
+ const QString &scope = {}) const;
+
+ bool writeInjectDocumentation(TextStream &s, TypeSystem::DocModificationMode mode,
+ 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();
- static QString parseArgDocStyle(const AbstractMetaClass *cppClass,
- const AbstractMetaFunctionCPtr &func);
- QString translateToPythonType(const AbstractMetaType &type, const AbstractMetaClass *cppClass) const;
+ QString translateToPythonType(const AbstractMetaType &type,
+ const AbstractMetaClassCPtr &cppClass,
+ bool createRef = true) const;
bool convertToRst(const QString &sourceFileName,
const QString &targetFileName,
const QString &context = QString(),
QString *errorMessage = nullptr) const;
- QString m_extraSectionDir;
+ static GeneratorDocumentation generatorDocumentation(const AbstractMetaClassCPtr &cppClass);
+
QStringList m_functionList;
- QMap<QString, QStringList> m_packages;
+ QMap<QString, DocPackage> m_packages;
QScopedPointer<DocParser> m_docParser;
- QtXmlToSphinxParameters m_parameters;
- QString m_additionalDocumentationList;
+ static DocGeneratorOptions m_options;
};
#endif // DOCGENERATOR_H
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
index 4607f3f78..b8fec836c 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qtxmltosphinx.h"
#include "exception.h"
@@ -32,16 +7,17 @@
#include <codesniphelpers.h>
#include "rstformat.h"
+#include "qtcompat.h"
+
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
+#include <QtCore/QHash>
#include <QtCore/QLoggingCategory>
#include <QtCore/QRegularExpression>
#include <QtCore/QXmlStreamReader>
-static inline QString nameAttribute() { return QStringLiteral("name"); }
-static inline QString titleAttribute() { return QStringLiteral("title"); }
-static inline QString fullTitleAttribute() { return QStringLiteral("fulltitle"); }
+using namespace Qt::StringLiterals;
QString msgTagWarning(const QXmlStreamReader &reader, const QString &context,
const QString &tag, const QString &message)
@@ -59,16 +35,23 @@ QString msgTagWarning(const QXmlStreamReader &reader, const QString &context,
return result;
}
-QString msgFallbackWarning(const QXmlStreamReader &reader, const QString &context,
- const QString &tag, const QString &location,
- const QString &identifier, const QString &fallback)
+QString msgFallbackWarning(const QString &location, const QString &identifier,
+ const QString &fallback)
{
- QString message = QLatin1String("Falling back to \"")
- + QDir::toNativeSeparators(fallback) + QLatin1String("\" for \"")
- + location + QLatin1Char('"');
+ QString message = u"Falling back to \""_s
+ + QDir::toNativeSeparators(fallback) + u"\" for \""_s
+ + location + u'"';
if (!identifier.isEmpty())
- message += QLatin1String(" [") + identifier + QLatin1Char(']');
- return msgTagWarning(reader, context, tag, message);
+ message += u" ["_s + identifier + u']';
+ return message;
+}
+
+QString msgSnippetsResolveError(const QString &path, const QStringList &locations)
+{
+ QString result;
+ QTextStream(&result) << "Could not resolve \"" << path << R"(" in ")"
+ << locations.join(uR"(", ")"_s);
+ return result;
}
static bool isHttpLink(const QString &ref)
@@ -76,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 = {
@@ -99,6 +96,29 @@ QDebug operator<<(QDebug d, const QtXmlToSphinxLink &l)
return d;
}
+QDebug operator<<(QDebug debug, const QtXmlToSphinx::TableCell &c)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "Cell(\"" << c.data << '"';
+ if (c.colSpan != 0)
+ debug << ", colSpan=" << c.colSpan;
+ if (c.rowSpan != 0)
+ debug << ", rowSpan=" << c.rowSpan;
+ debug << ')';
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const QtXmlToSphinx::Table &t)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ t.formatDebug(debug);
+ return debug;
+}
+
static const char *linkKeyWord(QtXmlToSphinxLink::Type type)
{
switch (type) {
@@ -133,7 +153,7 @@ TextStream &operator<<(TextStream &str, const QtXmlToSphinxLink &linkContext)
const bool isExternal = linkContext.type == QtXmlToSphinxLink::External;
if (!linkContext.linkText.isEmpty()) {
writeEscapedRstText(str, linkContext.linkText);
- if (isExternal && !linkContext.linkText.endsWith(QLatin1Char(' ')))
+ if (isExternal && !linkContext.linkText.endsWith(u' '))
str << ' ';
str << '<';
}
@@ -285,7 +305,7 @@ void QtXmlToSphinx::callHandler(WebXmlTag t, QXmlStreamReader &r)
handleTableTag(r);
break;
case WebXmlTag::header:
- handleRowTag(r);
+ handleHeaderTag(r);
break;
case WebXmlTag::row:
handleRowTag(r);
@@ -397,33 +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.setHeaderEnabled(m_tableHasHeader);
- 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;
@@ -431,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()) {
@@ -462,7 +501,7 @@ QString QtXmlToSphinx::transform(const QString& doc)
if (!m_inlineImages.isEmpty()) {
// Write out inline image definitions stored in handleInlineImageTag().
m_output << '\n' << disableIndent;
- for (const InlineImage &img : qAsConst(m_inlineImages))
+ for (const InlineImage &img : std::as_const(m_inlineImages))
m_output << ".. |" << img.tag << "| image:: " << img.href << '\n';
m_output << '\n' << enableIndent;
m_inlineImages.clear();
@@ -471,13 +510,14 @@ QString QtXmlToSphinx::transform(const QString& doc)
m_output.flush();
QString retval = popOutputBuffer();
Q_ASSERT(m_buffers.isEmpty());
+ setAutoTranslatedNote(&retval);
return retval;
}
static QString resolveFile(const QStringList &locations, const QString &path)
{
for (QString location : locations) {
- location.append(QLatin1Char('/'));
+ location.append(u'/');
location.append(path);
if (QFileInfo::exists(location))
return location;
@@ -485,25 +525,170 @@ static QString resolveFile(const QStringList &locations, const QString &path)
return QString();
}
-QString QtXmlToSphinx::readFromLocations(const QStringList &locations, const QString &path,
- const QString &identifier, QString *errorMessage)
+enum class SnippetType
+{
+ Other, // .qdoc, .qml,...
+ CppSource, CppHeader // Potentially converted to Python
+};
+
+SnippetType snippetType(const QString &path)
+{
+ if (path.endsWith(u".cpp"))
+ return SnippetType::CppSource;
+ if (path.endsWith(u".h"))
+ return SnippetType::CppHeader;
+ return SnippetType::Other;
+}
+
+// Return the name of a .cpp/.h snippet converted to Python by snippets-translate
+static QString pySnippetName(const QString &path, SnippetType type)
+{
+ switch (type) {
+ case SnippetType::CppSource:
+ return path.left(path.size() - 3) + u"py"_s;
+ break;
+ case SnippetType::CppHeader:
+ return path + u".py"_s;
+ break;
+ default:
+ break;
+ }
+ return {};
+}
+
+QtXmlToSphinx::Snippet QtXmlToSphinx::readSnippetFromLocations(const QString &path,
+ const QString &identifier,
+ const QString &fallbackPath,
+ QString *errorMessage)
{
+ // For anything else but C++ header/sources (no conversion to Python),
+ // use existing fallback paths first.
+ const auto type = snippetType(path);
+ if (type == SnippetType::Other && !fallbackPath.isEmpty()) {
+ const QString code = readFromLocation(fallbackPath, identifier, errorMessage);
+ return {code, code.isNull() ? Snippet::Error : Snippet::Fallback};
+ }
+
+ // For C++ header/sources, try snippets converted to Python first.
QString resolvedPath;
- if (path.endsWith(QLatin1String(".cpp"))) {
- const QString pySnippet = path.left(path.size() - 3) + QLatin1String("py");
- resolvedPath = resolveFile(locations, pySnippet);
+ const auto &locations = m_parameters.codeSnippetDirs;
+
+ if (type != SnippetType::Other) {
+ if (!fallbackPath.isEmpty() && !m_parameters.codeSnippetRewriteOld.isEmpty()) {
+ // Try looking up Python converted snippets by rewriting snippets paths
+ QString rewrittenPath = pySnippetName(fallbackPath, type);
+ if (!rewrittenPath.isEmpty()) {
+ 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};
+ }
+ }
+
+ resolvedPath = resolveFile(locations, pySnippetName(path, type));
+ if (!resolvedPath.isEmpty()) {
+ const QString code = readFromLocation(resolvedPath, identifier, errorMessage);
+ return {code, code.isNull() ? Snippet::Error : Snippet::Converted};
+ }
+ }
+
+ resolvedPath = resolveFile(locations, path);
+ if (!resolvedPath.isEmpty()) {
+ const QString code = readFromLocation(resolvedPath, identifier, errorMessage);
+ return {code, code.isNull() ? Snippet::Error : Snippet::Resolved};
+ }
+
+ if (!fallbackPath.isEmpty()) {
+ *errorMessage = msgFallbackWarning(path, identifier, fallbackPath);
+ const QString code = readFromLocation(fallbackPath, identifier, errorMessage);
+ return {code, code.isNull() ? Snippet::Error : Snippet::Fallback};
+ }
+
+ *errorMessage = msgSnippetsResolveError(path, locations);
+ 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;
}
- if (resolvedPath.isEmpty())
- resolvedPath = resolveFile(locations, path);
- if (resolvedPath.isEmpty()) {
- QTextStream(errorMessage) << "Could not resolve \"" << path << "\" in \""
- << locations.join(QLatin1String("\", \""));
- return QString(); // null
+ 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;
+ }
}
- qCDebug(m_generator->loggingCategory()).noquote().nospace()
- << "snippet file " << path
- << " [" << identifier << ']' << " resolved to " << resolvedPath;
- return readFromLocation(resolvedPath, identifier, errorMessage);
+
+ if (code.isEmpty())
+ *errorMessage = msgEmptySnippet(inputFile, lineNo, identifier);
+
+ return code;
}
QString QtXmlToSphinx::readFromLocation(const QString &location, const QString &identifier,
@@ -515,44 +700,18 @@ 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 = QLatin1String(""); // non-null
+ QString code = u""_s; // non-null
if (identifier.isEmpty()) {
while (!inputFile.atEnd())
code += QString::fromUtf8(inputFile.readLine());
return CodeSnipHelpers::fixSpaces(code);
}
- const QRegularExpression searchString(QLatin1String("//!\\s*\\[")
- + identifier + QLatin1String("\\]"));
- Q_ASSERT(searchString.isValid());
- static const QRegularExpression codeSnippetCode(QLatin1String("//!\\s*\\[[\\w\\d\\s]+\\]"));
- Q_ASSERT(codeSnippetCode.isValid());
-
- bool getCode = false;
-
- while (!inputFile.atEnd()) {
- QString line = QString::fromUtf8(inputFile.readLine());
- if (getCode && !line.contains(searchString)) {
- line.remove(codeSnippetCode);
- 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)
@@ -562,7 +721,7 @@ void QtXmlToSphinx::handleHeadingTag(QXmlStreamReader& reader)
static char types[] = { '-', '^' };
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
- uint typeIdx = reader.attributes().value(QLatin1String("level")).toUInt();
+ uint typeIdx = reader.attributes().value(u"level"_s).toUInt();
if (typeIdx >= sizeof(types))
type = types[sizeof(types)-1];
else
@@ -615,63 +774,97 @@ 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";
}
void QtXmlToSphinx::handleItalicTag(QXmlStreamReader& reader)
{
- QXmlStreamReader::TokenType token = reader.tokenType();
- if (token == QXmlStreamReader::StartElement || token == QXmlStreamReader::EndElement) {
- m_insideItalic = !m_insideItalic;
- m_output << '*';
- } else if (token == QXmlStreamReader::Characters) {
+ switch (reader.tokenType()) {
+ case QXmlStreamReader::StartElement:
+ if (m_formattingDepth++ == 0) {
+ m_insideItalic = true;
+ m_output << rstItalic;
+ }
+ break;
+ case QXmlStreamReader::EndElement:
+ if (--m_formattingDepth == 0) {
+ m_insideItalic = false;
+ m_output << rstItalicOff;
+ }
+ break;
+ case QXmlStreamReader::Characters:
m_output << escape(reader.text().trimmed());
+ break;
+ default:
+ break;
}
}
void QtXmlToSphinx::handleBoldTag(QXmlStreamReader& reader)
{
- QXmlStreamReader::TokenType token = reader.tokenType();
- if (token == QXmlStreamReader::StartElement || token == QXmlStreamReader::EndElement) {
- m_insideBold = !m_insideBold;
- m_output << "**";
- } else if (token == QXmlStreamReader::Characters) {
+ switch (reader.tokenType()) {
+ case QXmlStreamReader::StartElement:
+ if (m_formattingDepth++ == 0) {
+ m_insideBold = true;
+ m_output << rstBold;
+ }
+ break;
+ case QXmlStreamReader::EndElement:
+ if (--m_formattingDepth == 0) {
+ m_insideBold = false;
+ m_output << rstBoldOff;
+ }
+ break;
+ case QXmlStreamReader::Characters:
m_output << escape(reader.text().trimmed());
+ break;
+ default:
+ break;
}
}
void QtXmlToSphinx::handleArgumentTag(QXmlStreamReader& reader)
{
- QXmlStreamReader::TokenType token = reader.tokenType();
- if (token == QXmlStreamReader::StartElement || token == QXmlStreamReader::EndElement)
- m_output << "``";
- else if (token == QXmlStreamReader::Characters)
+ switch (reader.tokenType()) {
+ case QXmlStreamReader::StartElement:
+ if (m_formattingDepth++ == 0)
+ m_output << rstCode;
+ break;
+ case QXmlStreamReader::EndElement:
+ if (--m_formattingDepth == 0)
+ m_output << rstCodeOff;
+ break;
+ case QXmlStreamReader::Characters:
m_output << reader.text().trimmed();
+ break;
+ default:
+ break;
+ }
}
-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 == QLatin1String("property"))
- return functionLinkType();
- if (type == QLatin1String("typedef"))
- return classLinkType();
+ if (type == u"property")
+ return functionLinkType;
+ if (type == u"typedef")
+ return classLinkType;
return type.toString();
}
static inline QString linkSourceAttribute(const QString &type)
{
- if (type == functionLinkType() || type == classLinkType())
- return QLatin1String("raw");
- return type == QLatin1String("enum") || type == QLatin1String("page")
- ? type : QLatin1String("href");
+ if (type == functionLinkType || type == classLinkType)
+ return u"raw"_s;
+ return type == u"enum" || type == u"page"
+ ? type : u"href"_s;
}
// "See also" links may appear as nested links:
@@ -693,8 +886,8 @@ void QtXmlToSphinx::handleSeeAlsoTag(QXmlStreamReader& reader)
if (!textR.isEmpty()) {
const QString text = textR.toString();
if (m_seeAlsoContext.isNull()) {
- const QString type = text.endsWith(QLatin1String("()"))
- ? functionLinkType() : classLinkType();
+ const QString type = text.endsWith(u"()")
+ ? functionLinkType : classLinkType;
m_seeAlsoContext.reset(handleLinkStart(type, text));
}
handleLinkText(m_seeAlsoContext.data(), text);
@@ -713,12 +906,12 @@ 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)
{
- const auto lines = QStringView{snippet}.split(QLatin1Char('\n'));
+ const auto lines = QStringView{snippet}.split(u'\n');
for (const auto &line : lines) {
if (!line.trimmed().isEmpty())
str << indent << line;
@@ -744,55 +937,48 @@ void QtXmlToSphinx::handleSnippetTag(QXmlStreamReader& reader)
{
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
- const bool consecutiveSnippet = m_lastTagName == QLatin1String("snippet")
- || m_lastTagName == QLatin1String("dots") || m_lastTagName == QLatin1String("codeline");
+ const bool consecutiveSnippet = m_lastTagName == u"snippet"
+ || 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(QLatin1String("location")).toString();
- QString identifier = reader.attributes().value(QLatin1String("identifier")).toString();
+ 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();
QString errorMessage;
- const QString pythonCode =
- readFromLocations(m_parameters.codeSnippetDirs, location, identifier, &errorMessage);
+
+ const Snippet snippet = readSnippetFromLocations(location, identifier,
+ fallbackPath, &errorMessage);
if (!errorMessage.isEmpty())
warn(msgTagWarning(reader, m_context, m_lastTagName, errorMessage));
- // Fall back to C++ snippet when "path" attribute is present.
- // Also read fallback snippet when comparison is desired.
- QString fallbackCode;
- if ((pythonCode.isEmpty() || m_parameters.snippetComparison)
- && reader.attributes().hasAttribute(fallbackPathAttribute())) {
- const QString fallback = reader.attributes().value(fallbackPathAttribute()).toString();
- if (QFileInfo::exists(fallback)) {
- if (pythonCode.isEmpty())
- warn(msgFallbackWarning(reader, m_context, m_lastTagName, location, identifier, fallback));
- fallbackCode = readFromLocation(fallback, identifier, &errorMessage);
- if (!errorMessage.isEmpty())
- warn(msgTagWarning(reader, m_context, m_lastTagName, errorMessage));
- }
- }
- if (!pythonCode.isEmpty() && !fallbackCode.isEmpty() && m_parameters.snippetComparison)
- debug(msgSnippetComparison(location, identifier, pythonCode, fallbackCode));
+ if (m_parameters.snippetComparison && snippet.result == Snippet::Converted
+ && !fallbackPath.isEmpty()) {
+ const QString fallbackCode = readFromLocation(fallbackPath, identifier, &errorMessage);
+ debug(msgSnippetComparison(location, identifier, snippet.code, fallbackCode));
+ }
if (!consecutiveSnippet)
m_output << "::\n\n";
Indentation indentation(m_output);
- const QString code = pythonCode.isEmpty() ? fallbackCode : pythonCode;
- if (code.isEmpty())
+ if (snippet.result == Snippet::Error)
m_output << "<Code snippet \"" << location << ':' << identifier << "\" not found>\n";
else
- m_output << code << ensureEndl;
+ m_output << snippet.code << ensureEndl;
m_output << '\n';
}
}
+
void QtXmlToSphinx::handleDotsTag(QXmlStreamReader& reader)
{
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
- const bool consecutiveSnippet = m_lastTagName == QLatin1String("snippet")
- || m_lastTagName == QLatin1String("dots") || m_lastTagName == QLatin1String("codeline");
+ const bool consecutiveSnippet = m_lastTagName == u"snippet"
+ || m_lastTagName == u"dots" || m_lastTagName == u"codeline";
if (consecutiveSnippet) {
m_output.flush();
m_output.string()->chop(2);
@@ -800,7 +986,7 @@ void QtXmlToSphinx::handleDotsTag(QXmlStreamReader& reader)
m_output << "::\n\n";
}
pushOutputBuffer();
- int indent = reader.attributes().value(QLatin1String("indent")).toInt()
+ int indent = reader.attributes().value(u"indent"_s).toInt()
+ m_output.indentation() * m_output.tabWidth();
for (int i = 0; i < indent; ++i)
m_output << ' ';
@@ -817,12 +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_tableHasHeader = false;
+ 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();
}
@@ -834,11 +1019,11 @@ void QtXmlToSphinx::handleTermTag(QXmlStreamReader& reader)
if (token == QXmlStreamReader::StartElement) {
pushOutputBuffer();
} else if (token == QXmlStreamReader::Characters) {
- m_output << reader.text().toString().replace(QLatin1String("::"), QLatin1String("."));
+ m_output << reader.text().toString().replace(u"::"_s, u"."_s);
} else if (token == QXmlStreamReader::EndElement) {
TableCell cell;
cell.data = popOutputBuffer().trimmed();
- m_currentTable.appendRow(TableRow(1, cell));
+ m_tables.back().appendRow(TableRow(1, cell));
}
}
@@ -847,70 +1032,83 @@ 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(QLatin1String("colspan")).toShort();
- cell.rowSpan = reader.attributes().value(QLatin1String("rowspan")).toShort();
+ 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;
}
}
}
-void QtXmlToSphinx::handleRowTag(QXmlStreamReader& reader)
+void QtXmlToSphinx::handleHeaderTag(QXmlStreamReader &reader)
{
- QXmlStreamReader::TokenType token = reader.tokenType();
- if (token == QXmlStreamReader::StartElement) {
- m_tableHasHeader = reader.name() == QLatin1String("header");
- m_currentTable.appendRow({});
+ // <header> in WebXML is either a table header or a description of a
+ // C++ header with "name"/"href" attributes.
+ if (reader.tokenType() == QXmlStreamReader::StartElement
+ && !reader.attributes().hasAttribute(u"name"_s)) {
+ auto &table = m_tables.back();
+ table.setHeaderEnabled(true);
+ table.appendRow({});
}
}
+void QtXmlToSphinx::handleRowTag(QXmlStreamReader& reader)
+{
+ if (reader.tokenType() == QXmlStreamReader::StartElement)
+ m_tables.back().appendRow({});
+}
+
enum ListType { BulletList, OrderedList, EnumeratedList };
static inline ListType webXmlListType(QStringView t)
{
- if (t == QLatin1String("enum"))
+ if (t == u"enum")
return EnumeratedList;
- if (t == QLatin1String("ordered"))
+ if (t == u"ordered")
return OrderedList;
return BulletList;
}
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) {
- listType = webXmlListType(reader.attributes().value(QLatin1String("type")));
+ m_tables.push({});
+ auto &table = m_tables.back();
+ listType = webXmlListType(reader.attributes().value(u"type"_s));
if (listType == EnumeratedList) {
- m_currentTable.appendRow(TableRow{TableCell(QLatin1String("Constant")),
- TableCell(QLatin1String("Description"))});
- m_tableHasHeader = 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()) {
- const auto itemLines = QStringView{cell.data}.split(QLatin1Char('\n'));
+ for (const TableCell &cell : table.constFirst()) {
+ const auto itemLines = QStringView{cell.data}.split(u'\n');
m_output << separator << itemLines.constFirst() << '\n';
- for (int i = 1, max = itemLines.count(); i < max; ++i)
+ for (qsizetype i = 1, max = itemLines.size(); i < max; ++i)
m_output << indentLine << itemLines[i] << '\n';
}
m_output << '\n';
@@ -921,7 +1119,7 @@ void QtXmlToSphinx::handleListTag(QXmlStreamReader& reader)
break;
}
}
- m_currentTable.clear();
+ m_tables.pop();
}
}
@@ -931,7 +1129,7 @@ void QtXmlToSphinx::handleLinkTag(QXmlStreamReader& reader)
case QXmlStreamReader::StartElement: {
// <link> embedded in <see-also> means the characters of <see-also> are no link.
m_seeAlsoContext.reset();
- const QString type = fixLinkType(reader.attributes().value(QLatin1String("type")));
+ const QString type = fixLinkType(reader.attributes().value(u"type"_s));
const QString ref = reader.attributes().value(linkSourceAttribute(type)).toString();
m_linkContext.reset(handleLinkStart(type, ref));
}
@@ -952,8 +1150,8 @@ void QtXmlToSphinx::handleLinkTag(QXmlStreamReader& reader)
QtXmlToSphinxLink *QtXmlToSphinx::handleLinkStart(const QString &type, QString ref) const
{
- ref.replace(QLatin1String("::"), QLatin1String("."));
- ref.remove(QLatin1String("()"));
+ ref.replace(u"::"_s, u"."_s);
+ ref.remove(u"()"_s);
auto *result = new QtXmlToSphinxLink(ref);
if (m_insideBold)
@@ -963,25 +1161,25 @@ 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(QLatin1Char('.'));
+ const auto rawlinklist = QStringView{result->linkRef}.split(u'.');
if (rawlinklist.size() == 1 || rawlinklist.constFirst() == m_context) {
const auto lastRawLink = rawlinklist.constLast().toString();
QString context = m_generator->resolveContextForMethod(m_context, lastRawLink);
if (!result->linkRef.startsWith(context))
- result->linkRef.prepend(context + QLatin1Char('.'));
+ result->linkRef.prepend(context + u'.');
} 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 == QLatin1String("enum")) {
+ } else if (type == u"enum") {
result->type = QtXmlToSphinxLink::Attribute;
- } else if (type == QLatin1String("page")) {
+ } else if (type == u"page") {
// Module, external web page or reference
if (result->linkRef == m_parameters.moduleName)
result->type = QtXmlToSphinxLink::Module;
@@ -995,7 +1193,7 @@ QtXmlToSphinxLink *QtXmlToSphinx::handleLinkStart(const QString &type, QString r
// <link raw="Model/View Classes" href="model-view-programming.html#model-view-classes"
// type="page" page="Model/View Programming">Model/View Classes</link>
-// <link type="page" page="http://doc.qt.io/qt-5/class.html">QML types</link>
+// <link type="page" page="https://doc.qt.io/qt-5/class.html">QML types</link>
// <link raw="Qt Quick" href="qtquick-index.html" type="page" page="Qt Quick">Qt Quick</link>
// <link raw="QObject" href="qobject.html" type="class">QObject</link>
// <link raw="Qt::Window" href="qt.html#WindowType-enum" type="enum" enum="Qt::WindowType">Qt::Window</link>
@@ -1010,16 +1208,16 @@ static QString fixLinkText(const QtXmlToSphinxLink *linkContext,
}
// For the language reference documentation, strip the module name.
// Clear the link text if that matches the function/class/enumeration name.
- const int lastSep = linktext.lastIndexOf(QLatin1String("::"));
+ const int lastSep = linktext.lastIndexOf(u"::");
if (lastSep != -1)
linktext.remove(0, lastSep + 2);
else
QtXmlToSphinx::stripPythonQualifiers(&linktext);
if (linkContext->linkRef == linktext)
- return QString();
+ return {};
if ((linkContext->type & QtXmlToSphinxLink::FunctionMask) != 0
- && (linkContext->linkRef + QLatin1String("()")) == linktext) {
- return QString();
+ && (linkContext->linkRef + u"()"_s) == linktext) {
+ return {};
}
return linktext;
}
@@ -1042,36 +1240,17 @@ WebXmlTag QtXmlToSphinx::parentTag() const
// Copy images that are placed in a subdirectory "images" under the webxml files
// by qdoc to a matching subdirectory under the "rst/PySide6/<module>" directory
-static bool copyImage(const QString &href, const QString &docDataDir,
- const QString &context, const QString &outputDir,
+static bool copyImage(const QString &docDataDir, const QString &relativeSourceFile,
+ const QString &outputDir, const QString &relativeTargetFile,
const QLoggingCategory &lc, QString *errorMessage)
{
- const QChar slash = QLatin1Char('/');
- const int 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);
- if (!imageSource.exists()) {
- QTextStream(errorMessage) << "Image " << href << " does not exist in "
- << QDir::toNativeSeparators(docDataDir);
- return false;
- }
- // Determine directory from context, "Pyside2.QtGui.QPainter" ->"Pyside2/QtGui".
- // 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(QLatin1Char('.'));
- if (lastDot != -1)
- relativeTargetDir.truncate(lastDot);
- relativeTargetDir.replace(QLatin1Char('.'), slash);
- if (!imagePath.isEmpty())
- relativeTargetDir += slash + imagePath;
-
- const QString targetDir = outputDir + slash + relativeTargetDir;
- const QString targetFileName = targetDir + slash + imageFileName;
+ QString targetFileName = outputDir + u'/' + relativeTargetFile;
if (QFileInfo::exists(targetFileName))
return true;
- if (!QFileInfo::exists(targetDir)) {
+
+ QString relativeTargetDir = relativeTargetFile;
+ relativeTargetDir.truncate(qMax(relativeTargetDir.lastIndexOf(u'/'), qsizetype(0)));
+ if (!relativeTargetDir.isEmpty() && !QFileInfo::exists(outputDir + u'/' + relativeTargetDir)) {
const QDir outDir(outputDir);
if (!outDir.mkpath(relativeTargetDir)) {
QTextStream(errorMessage) << "Cannot create " << QDir::toNativeSeparators(relativeTargetDir)
@@ -1080,28 +1259,29 @@ static bool copyImage(const QString &href, const QString &docDataDir,
}
}
- QFile source(imageSource.absoluteFilePath());
+ QFile source(docDataDir + u'/' + relativeSourceFile);
if (!source.copy(targetFileName)) {
QTextStream(errorMessage) << "Cannot copy " << QDir::toNativeSeparators(source.fileName())
<< " to " << QDir::toNativeSeparators(targetFileName) << ": "
<< source.errorString();
return false;
}
- qCDebug(lc).noquote().nospace() << __FUNCTION__ << " href=\""
- << href << "\", context=\"" << context << "\", docDataDir=\""
- << docDataDir << "\", outputDir=\"" << outputDir << "\", copied \""
- << source.fileName() << "\"->\"" << targetFileName << '"';
+
+ qCDebug(lc).noquote().nospace() << __FUNCTION__ << " \"" << relativeSourceFile
+ << "\"->\"" << relativeTargetFile << '"';
return true;
}
bool QtXmlToSphinx::copyImage(const QString &href) const
{
QString errorMessage;
- const bool result =
- ::copyImage(href, m_parameters.docDataDir, m_context,
- m_parameters.outputDirectory,
- m_generator->loggingCategory(),
- &errorMessage);
+ const auto imagePaths = m_generator->resolveImage(href, m_context);
+ const bool result = ::copyImage(m_parameters.docDataDir,
+ imagePaths.source,
+ m_parameters.outputDirectory,
+ imagePaths.target,
+ m_generator->loggingCategory(),
+ &errorMessage);
if (!result)
throw Exception(errorMessage);
return result;
@@ -1111,7 +1291,7 @@ void QtXmlToSphinx::handleImageTag(QXmlStreamReader& reader)
{
if (reader.tokenType() != QXmlStreamReader::StartElement)
return;
- const QString href = reader.attributes().value(QLatin1String("href")).toString();
+ const QString href = reader.attributes().value(u"href"_s).toString();
if (copyImage(href))
m_output << ".. image:: " << href << "\n\n";
}
@@ -1120,17 +1300,17 @@ void QtXmlToSphinx::handleInlineImageTag(QXmlStreamReader& reader)
{
if (reader.tokenType() != QXmlStreamReader::StartElement)
return;
- const QString href = reader.attributes().value(QLatin1String("href")).toString();
+ const QString href = reader.attributes().value(u"href"_s).toString();
if (!copyImage(href))
return;
// Handle inline images by substitution references. Insert a unique tag
// enclosed by '|' and define it further down. Determine tag from the base
//file name with number.
QString tag = href;
- int pos = tag.lastIndexOf(QLatin1Char('/'));
+ auto pos = tag.lastIndexOf(u'/');
if (pos != -1)
tag.remove(0, pos + 1);
- pos = tag.indexOf(QLatin1Char('.'));
+ pos = tag.indexOf(u'.');
if (pos != -1)
tag.truncate(pos);
tag += QString::number(m_inlineImages.size() + 1);
@@ -1142,7 +1322,7 @@ void QtXmlToSphinx::handleRawTag(QXmlStreamReader& reader)
{
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
- QString format = reader.attributes().value(QLatin1String("format")).toString();
+ QString format = reader.attributes().value(u"format"_s).toString();
m_output << ".. raw:: " << format.toLower() << "\n\n";
} else if (token == QXmlStreamReader::Characters) {
Indentation indent(m_output);
@@ -1195,11 +1375,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);
@@ -1212,7 +1392,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());
}
@@ -1232,14 +1412,14 @@ void QtXmlToSphinx::handleAnchorTag(QXmlStreamReader& reader)
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::StartElement) {
QString anchor;
- if (reader.attributes().hasAttribute(QLatin1String("id")))
- anchor = reader.attributes().value(QLatin1String("id")).toString();
- else if (reader.attributes().hasAttribute(QLatin1String("name")))
- anchor = reader.attributes().value(QLatin1String("name")).toString();
+ if (reader.attributes().hasAttribute(u"id"_s))
+ anchor = reader.attributes().value(u"id"_s).toString();
+ else if (reader.attributes().hasAttribute(u"name"_s))
+ anchor = reader.attributes().value(u"name"_s).toString();
if (!anchor.isEmpty() && m_opened_anchor != anchor) {
m_opened_anchor = anchor;
if (!m_context.isEmpty())
- anchor.prepend(m_context + QLatin1Char('_'));
+ anchor.prepend(m_context + u'_');
m_output << rstLabel(anchor);
}
} else if (token == QXmlStreamReader::EndElement) {
@@ -1258,7 +1438,7 @@ void QtXmlToSphinx::handleQuoteFileTag(QXmlStreamReader& reader)
QXmlStreamReader::TokenType token = reader.tokenType();
if (token == QXmlStreamReader::Characters) {
QString location = reader.text().toString();
- location.prepend(m_parameters.libSourceDir + QLatin1Char('/'));
+ location.prepend(m_parameters.libSourceDir + u'/');
QString errorMessage;
QString code = readFromLocation(location, QString(), &errorMessage);
if (!errorMessage.isEmpty())
@@ -1273,51 +1453,72 @@ void QtXmlToSphinx::handleQuoteFileTag(QXmlStreamReader& reader)
}
}
+bool QtXmlToSphinx::Table::hasEmptyLeadingRow() const
+{
+ return !m_rows.isEmpty() && m_rows.constFirst().isEmpty();
+}
+
+bool QtXmlToSphinx::Table::hasEmptyTrailingRow() const
+{
+ return !m_rows.isEmpty() && m_rows.constLast().isEmpty();
+}
+
void QtXmlToSphinx::Table::normalize()
{
- if (m_normalized || isEmpty())
+ if (m_normalized)
+ return;
+
+ // Empty leading/trailing rows have been observed with nested tables
+ if (hasEmptyLeadingRow() || hasEmptyLeadingRow()) {
+ qWarning() << "QtXmlToSphinx: Table with leading/trailing empty columns found: " << *this;
+ while (hasEmptyTrailingRow())
+ m_rows.pop_back();
+ while (hasEmptyLeadingRow())
+ m_rows.pop_front();
+ }
+
+ if (isEmpty())
return;
//QDoc3 generates tables with wrong number of columns. We have to
//check and if necessary, merge the last columns.
- int maxCols = -1;
- for (const auto &row : qAsConst(m_rows)) {
- if (row.count() > maxCols)
- maxCols = row.count();
+ qsizetype maxCols = -1;
+ for (const auto &row : std::as_const(m_rows)) {
+ if (row.size() > maxCols)
+ maxCols = row.size();
}
if (maxCols <= 0)
return;
// add col spans
- for (int row = 0; row < m_rows.count(); ++row) {
- for (int col = 0; col < m_rows.at(row).count(); ++col) {
+ for (qsizetype row = 0; row < m_rows.size(); ++row) {
+ for (qsizetype col = 0; col < m_rows.at(row).size(); ++col) {
QtXmlToSphinx::TableCell& cell = m_rows[row][col];
bool mergeCols = (col >= maxCols);
if (cell.colSpan > 0) {
QtXmlToSphinx::TableCell newCell;
newCell.colSpan = -1;
- for (int i = 0, max = cell.colSpan-1; i < max; ++i) {
+ for (int i = 0, max = cell.colSpan-1; i < max; ++i)
m_rows[row].insert(col + 1, newCell);
- }
cell.colSpan = 0;
col++;
} else if (mergeCols) {
- m_rows[row][maxCols - 1].data += QLatin1Char(' ') + cell.data;
+ m_rows[row][maxCols - 1].data += u' ' + cell.data;
}
}
}
// row spans
- const int numCols = m_rows.constFirst().count();
- for (int col = 0; col < numCols; ++col) {
- for (int row = 0; row < m_rows.count(); ++row) {
- if (col < m_rows[row].count()) {
+ const qsizetype numCols = m_rows.constFirst().size();
+ for (qsizetype col = 0; col < numCols; ++col) {
+ for (qsizetype row = 0; row < m_rows.size(); ++row) {
+ if (col < m_rows[row].size()) {
QtXmlToSphinx::TableCell& cell = m_rows[row][col];
if (cell.rowSpan > 0) {
QtXmlToSphinx::TableCell newCell;
newCell.rowSpan = -1;
- int targetRow = row + 1;
- const int targetEndRow =
- std::min(targetRow + cell.rowSpan - 1, int(m_rows.count()));
+ qsizetype targetRow = row + 1;
+ const qsizetype targetEndRow =
+ std::min(targetRow + cell.rowSpan - 1, m_rows.size());
cell.rowSpan = 0;
for ( ; targetRow < targetEndRow; ++targetRow)
m_rows[targetRow].insert(col, newCell);
@@ -1337,16 +1538,17 @@ void QtXmlToSphinx::Table::format(TextStream& s) const
Q_ASSERT(isNormalized());
// calc width and height of each column and row
- const int headerColumnCount = m_rows.constFirst().count();
- QList<int> colWidths(headerColumnCount, 0);
- QList<int> rowHeights(m_rows.count(), 0);
- for (int i = 0, maxI = m_rows.count(); i < maxI; ++i) {
+ const qsizetype headerColumnCount = m_rows.constFirst().size();
+ QList<qsizetype> colWidths(headerColumnCount, 0);
+ QList<qsizetype> rowHeights(m_rows.size(), 0);
+ for (qsizetype i = 0, maxI = m_rows.size(); i < maxI; ++i) {
const QtXmlToSphinx::TableRow& row = m_rows.at(i);
- for (int j = 0, maxJ = std::min(row.count(), colWidths.size()); j < maxJ; ++j) {
- const auto rowLines = QStringView{row[j].data}.split(QLatin1Char('\n')); // cache this would be a good idea
+ for (qsizetype j = 0, maxJ = std::min(row.size(), colWidths.size()); j < maxJ; ++j) {
+ // cache this would be a good idea
+ const auto rowLines = QStringView{row[j].data}.split(u'\n');
for (const auto &str : rowLines)
- colWidths[j] = std::max(colWidths[j], int(str.size()));
- rowHeights[i] = std::max(rowHeights[i], int(rowLines.size()));
+ colWidths[j] = std::max(colWidths[j], str.size());
+ rowHeights[i] = std::max(rowHeights[i], rowLines.size());
}
}
@@ -1354,44 +1556,41 @@ void QtXmlToSphinx::Table::format(TextStream& s) const
return; // empty table (table with empty cells)
// create a horizontal line to be used later.
- QString horizontalLine = QLatin1String("+");
- for (int i = 0, max = colWidths.count(); i < max; ++i) {
- horizontalLine += QString(colWidths.at(i), QLatin1Char('-'));
- horizontalLine += QLatin1Char('+');
- }
+ QString horizontalLine = u"+"_s;
+ for (auto colWidth : colWidths)
+ horizontalLine += QString(colWidth, u'-') + u'+';
// write table rows
- for (int i = 0, maxI = m_rows.count(); i < maxI; ++i) { // for each row
+ for (qsizetype i = 0, maxI = m_rows.size(); i < maxI; ++i) { // for each row
const QtXmlToSphinx::TableRow& row = m_rows.at(i);
// print line
s << '+';
- for (int col = 0; col < headerColumnCount; ++col) {
- char c;
- if (col >= row.length() || row[col].rowSpan == -1)
+ for (qsizetype col = 0; col < headerColumnCount; ++col) {
+ 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';
// Print the table cells
- for (int rowLine = 0; rowLine < rowHeights[i]; ++rowLine) { // for each line in a row
- int j = 0;
- for (int maxJ = std::min(int(row.count()), headerColumnCount); j < maxJ; ++j) { // for each column
+ for (qsizetype rowLine = 0; rowLine < rowHeights.at(i); ++rowLine) { // for each line in a row
+ qsizetype j = 0;
+ for (qsizetype maxJ = std::min(row.size(), headerColumnCount); j < maxJ; ++j) { // for each column
const QtXmlToSphinx::TableCell& cell = row[j];
- const auto rowLines = QStringView{cell.data}.split(QLatin1Char('\n')); // FIXME: Cache this!!!
+ // FIXME: Cache this!!!
+ const auto rowLines = QStringView{cell.data}.split(u'\n');
if (!j || !cell.colSpan)
s << '|';
else
s << ' ';
- const int width = colWidths.at(j);
- if (rowLine < rowLines.count())
+ const auto width = int(colWidths.at(j));
+ if (rowLine < rowLines.size())
s << AlignedField(rowLines.at(rowLine), width);
else
s << Pad(' ', width);
@@ -1404,9 +1603,31 @@ void QtXmlToSphinx::Table::format(TextStream& s) const
s << horizontalLine << "\n\n";
}
+void QtXmlToSphinx::Table::formatDebug(QDebug &debug) const
+{
+ const auto rowCount = m_rows.size();
+ debug << "Table(" <<rowCount << " rows";
+ if (m_hasHeader)
+ debug << ", [header]";
+ if (m_normalized)
+ debug << ", [normalized]";
+ for (qsizetype r = 0; r < rowCount; ++r) {
+ const auto &row = m_rows.at(r);
+ const auto &colCount = row.size();
+ debug << ", row " << r << " [" << colCount << "]={";
+ for (qsizetype c = 0; c < colCount; ++c) {
+ if (c > 0)
+ debug << ", ";
+ debug << row.at(c);
+ }
+ debug << '}';
+ }
+ debug << ')';
+}
+
void QtXmlToSphinx::stripPythonQualifiers(QString *s)
{
- const int lastSep = s->lastIndexOf(QLatin1Char('.'));
+ const int lastSep = s->lastIndexOf(u'.');
if (lastSep != -1)
s->remove(0, lastSep + 1);
}
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
index 55d6a79b1..398c5bc97 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinx.h
@@ -1,42 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef QTXMLTOSPHINX_H
#define QTXMLTOSPHINX_H
#include <textstream.h>
-#include <QtCore/QHash>
#include <QtCore/QList>
#include <QtCore/QScopedPointer>
-#include <QtCore/QSharedPointer>
#include <QtCore/QStack>
-#include <QtCore/QTextStream>
+
+#include <memory>
QT_BEGIN_NAMESPACE
class QDebug;
@@ -67,7 +41,7 @@ public:
QString data;
TableCell(const QString& text = QString()) : data(text) {}
- TableCell(const char* text) : data(QLatin1String(text)) {}
+ TableCell(const char* text) : data(QString::fromLatin1(text)) {}
};
using TableRow = QList<TableCell>;
@@ -96,20 +70,19 @@ 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(); }
void format(TextStream& s) const;
+ void formatDebug(QDebug &debug) const;
private:
+ bool hasEmptyLeadingRow() const;
+ bool hasEmptyTrailingRow() const;
+
QList<TableRow> m_rows;
bool m_hasHeader = false;
bool m_normalized = false;
@@ -128,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);
@@ -155,6 +132,7 @@ private:
// table tagsvoid QtXmlToSphinx::handleValueTag(QXmlStreamReader& reader)
void handleTableTag(QXmlStreamReader& reader);
+ void handleHeaderTag(QXmlStreamReader& reader);
void handleRowTag(QXmlStreamReader& reader);
void handleItemTag(QXmlStreamReader& reader);
void handleRawTag(QXmlStreamReader& reader);
@@ -182,21 +160,40 @@ 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>
- bool m_tableHasHeader = false;
QString m_context;
const QtXmlToSphinxDocGeneratorInterface *m_generator;
const QtXmlToSphinxParameters &m_parameters;
+ int m_formattingDepth = 0;
bool m_insideBold = false;
bool m_insideItalic = false;
QString m_lastTagName;
QString m_opened_anchor;
QList<InlineImage> m_inlineImages;
- QString readFromLocations(const QStringList &locations, const QString &path,
- const QString &identifier, QString *errorMessage);
+ bool m_containsAutoTranslations = false;
+
+ struct Snippet
+ {
+ enum Result {
+ Converted, // C++ converted to Python
+ Resolved, // Otherwise resolved in snippet paths
+ Fallback, // Fallback from XML
+ Error
+ };
+
+ QString code;
+ Result result;
+ };
+
+ void setAutoTranslatedNote(QString *str) const;
+
+ Snippet readSnippetFromLocations(const QString &path,
+ const QString &identifier,
+ const QString &fallbackPath,
+ QString *errorMessage);
static QString readFromLocation(const QString &location, const QString &identifier,
QString *errorMessage);
void pushOutputBuffer();
@@ -213,5 +210,7 @@ inline TextStream& operator<<(TextStream& s, const QtXmlToSphinx& xmlToSphinx)
}
QDebug operator<<(QDebug d, const QtXmlToSphinxLink &l);
+QDebug operator<<(QDebug debug, const QtXmlToSphinx::Table &t);
+QDebug operator<<(QDebug debug, const QtXmlToSphinx::TableCell &c);
#endif // QTXMLTOSPHINX_H
diff --git a/sources/shiboken6/generator/qtdoc/qtxmltosphinxinterface.h b/sources/shiboken6/generator/qtdoc/qtxmltosphinxinterface.h
index d4e792d76..d4a098a12 100644
--- a/sources/shiboken6/generator/qtdoc/qtxmltosphinxinterface.h
+++ b/sources/shiboken6/generator/qtdoc/qtxmltosphinxinterface.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef QTXMLTOSPHINXINTERFACE_H
#define QTXMLTOSPHINXINTERFACE_H
@@ -40,6 +15,8 @@ struct QtXmlToSphinxParameters
QString outputDirectory;
QString libSourceDir;
QStringList codeSnippetDirs;
+ QString codeSnippetRewriteOld;
+ QString codeSnippetRewriteNew;
bool snippetComparison = false;
};
@@ -76,6 +53,15 @@ public:
virtual QtXmlToSphinxLink resolveLink(const QtXmlToSphinxLink &) const = 0;
+ // Resolve images paths relative to doc data directory/output directory.
+ struct Image
+ {
+ QString source;
+ QString target;
+ };
+
+ virtual Image resolveImage(const QString &href, const QString &context) const = 0;
+
virtual ~QtXmlToSphinxDocGeneratorInterface() = default;
};
diff --git a/sources/shiboken6/generator/qtdoc/rstformat.h b/sources/shiboken6/generator/qtdoc/rstformat.h
index d14ecc55d..8af7671fb 100644
--- a/sources/shiboken6/generator/qtdoc/rstformat.h
+++ b/sources/shiboken6/generator/qtdoc/rstformat.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef RSTFORMAT_H
#define RSTFORMAT_H
@@ -55,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)
{
@@ -116,14 +69,14 @@ inline TextStream &operator<<(TextStream &str, const escape &e)
// RST anchor string: Anything else but letters, numbers, '_' or '.' replaced by '-'
inline bool isValidRstLabelChar(QChar c)
{
- return c.isLetterOrNumber() || c == QLatin1Char('_') || c == QLatin1Char('.');
+ return c.isLetterOrNumber() || c == u'_' || c == u'.';
}
inline QString toRstLabel(QString s)
{
for (int i = 0, size = s.size(); i < size; ++i) {
if (!isValidRstLabelChar(s.at(i)))
- s[i] = QLatin1Char('-');
+ s[i] = u'-';
}
return 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 06299a2ab..97a38a08d 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.cpp
@@ -1,44 +1,27 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <memory>
+// 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 "configurablescope.h"
+#include "generatorargument.h"
+#include "generatorstrings.h"
+#include "defaultvalue.h"
+#include "generatorcontext.h"
+#include "codesnip.h"
+#include "customconversion.h"
+#include "headergenerator.h"
#include "apiextractorresult.h"
#include "ctypenames.h"
#include <exception.h>
#include "pytypenames.h"
#include "fileout.h"
#include "overloaddata.h"
+#include "pymethoddefentry.h"
#include <abstractmetaenum.h>
#include <abstractmetafield.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
+#include <abstractmetalang_helpers.h>
#include <messages.h>
#include <modifications.h>
#include <propertyspec.h>
@@ -46,81 +29,115 @@
#include <sourcelocation.h>
#include <textstream.h>
#include <typedatabase.h>
+#include <containertypeentry.h>
+#include <enumtypeentry.h>
+#include <flagstypeentry.h>
+#include <functiontypeentry.h>
+#include <namespacetypeentry.h>
+#include <primitivetypeentry.h>
+#include <smartpointertypeentry.h>
+#include <typesystemtypeentry.h>
+#include <valuetypeentry.h>
#include <parser/enumvalue.h>
+#include "qtcompat.h"
+
+#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QMetaObject>
+#include <QtCore/QMetaType>
#include <QtCore/QRegularExpression>
#include <QtCore/QTextStream>
-#include <QtCore/QDebug>
-#include <QMetaType>
#include <algorithm>
#include <cstring>
+#include <memory>
+#include <set>
-static const char CPP_ARG0[] = "cppArg0";
-const char *CppGenerator::PYTHON_TO_CPPCONVERSION_STRUCT = "Shiboken::Conversions::PythonToCppConversion";
+using namespace Qt::StringLiterals;
-static inline QString reprFunction() { return QStringLiteral("__repr__"); }
+static const char shibokenErrorsOccurred[] = "Shiboken::Errors::occurred() != nullptr";
-QString CppGenerator::m_currentErrorCode(QLatin1String("{}"));
+static constexpr auto virtualMethodStaticReturnVar = "result"_L1;
+static constexpr auto initFuncPrefix = "init_"_L1;
-static const char typeNameFunc[] = R"CPP(
-template <class T>
-static const char *typeNameOf(const T &t)
+static constexpr auto sbkObjectTypeF = "SbkObject_TypeF()"_L1;
+static const char initInheritanceFunction[] = "initInheritance";
+
+static QString mangleName(QString name)
{
- 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;
+ if (name == u"None" || name == u"False" || name == u"True" || name == u"from")
+ name += u'_';
+ return name;
}
-)CPP";
-// utility functions
-inline AbstractMetaType getTypeWithoutContainer(const AbstractMetaType &arg)
+struct sbkUnusedVariableCast
{
- if (arg.typeEntry()->isContainer()) {
- // only support containers with 1 type
- if (arg.instantiations().size() == 1)
- return arg.instantiations().constFirst();
- }
- return arg;
-}
+ explicit sbkUnusedVariableCast(QAnyStringView name) : m_name(name) {}
+
+ const QAnyStringView m_name;
+};
-// A helper for writing C++ return statements for either void ("return;")
-// or some return value ("return value;")
-class returnStatement
+TextStream &operator<<(TextStream &str, const sbkUnusedVariableCast &c)
{
-public:
- explicit returnStatement(QString s) : m_returnValue(std::move(s)) {}
+ str << "SBK_UNUSED(" << c.m_name << ")\n";
+ return str;
+}
- friend TextStream &operator<<(TextStream &s, const returnStatement &r);
+struct pyTypeGetSlot
+{
+ explicit pyTypeGetSlot(QAnyStringView funcType, QAnyStringView typeObject,
+ QAnyStringView aSlot) :
+ m_funcType(funcType), m_typeObject(typeObject), m_slot(aSlot) {}
-private:
- const QString m_returnValue;
+ const QAnyStringView m_funcType;
+ const QAnyStringView m_typeObject;
+ const QAnyStringView m_slot;
};
-TextStream &operator<<(TextStream &s, const returnStatement &r)
+TextStream &operator<<(TextStream &str, const pyTypeGetSlot &p)
+{
+ str << "reinterpret_cast<" << p.m_funcType << ">(PepType_GetSlot("
+ << p.m_typeObject << ", " << p.m_slot << "));\n";
+ return str;
+}
+
+TextStream &operator<<(TextStream &s, CppGenerator::ErrorReturn r)
{
s << "return";
- if (!r.m_returnValue.isEmpty())
- s << ' ' << r.m_returnValue;
- s << ';';
+ switch (r) {
+ case CppGenerator::ErrorReturn::Default:
+ s << " {}";
+ break;
+ case CppGenerator::ErrorReturn::Zero:
+ s << " 0";
+ break;
+ case CppGenerator::ErrorReturn::MinusOne:
+ s << " -1";
+ break;
+ case CppGenerator::ErrorReturn::Void:
+ break;
+ }
+ s << ";\n";
+ 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;
}
@@ -148,15 +165,15 @@ static bool contains(const ProtocolEntries &l, const QString &needle)
const ProtocolEntries &mappingProtocols()
{
static const ProtocolEntries result = {
- {QLatin1String("__mlen__"),
- QLatin1String("PyObject *self"),
- QLatin1String("Py_ssize_t")},
- {QLatin1String("__mgetitem__"),
- QLatin1String("PyObject *self, PyObject *_key"),
- QLatin1String("PyObject*")},
- {QLatin1String("__msetitem__"),
- QLatin1String("PyObject *self, PyObject *_key, PyObject *_value"),
- intT()}};
+ {u"__mlen__"_s,
+ u"PyObject *self"_s,
+ u"Py_ssize_t"_s},
+ {u"__mgetitem__"_s,
+ u"PyObject *self, PyObject *_key"_s,
+ u"PyObject*"_s},
+ {u"__msetitem__"_s,
+ u"PyObject *self, PyObject *_key, PyObject *_value"_s,
+ intT}};
return result;
}
@@ -165,27 +182,27 @@ const ProtocolEntries &mappingProtocols()
const ProtocolEntries &sequenceProtocols()
{
static const ProtocolEntries result = {
- {QLatin1String("__len__"),
- QLatin1String("PyObject *self"),
- QLatin1String("Py_ssize_t")},
- {QLatin1String("__getitem__"),
- QLatin1String("PyObject *self, Py_ssize_t _i"),
- QLatin1String("PyObject*")},
- {QLatin1String("__setitem__"),
- QLatin1String("PyObject *self, Py_ssize_t _i, PyObject *_value"),
- intT()},
- {QLatin1String("__getslice__"),
- QLatin1String("PyObject *self, Py_ssize_t _i1, Py_ssize_t _i2"),
- QLatin1String("PyObject*")},
- {QLatin1String("__setslice__"),
- QLatin1String("PyObject *self, Py_ssize_t _i1, Py_ssize_t _i2, PyObject *_value"),
- intT()},
- {QLatin1String("__contains__"),
- QLatin1String("PyObject *self, PyObject *_value"),
- intT()},
- {QLatin1String("__concat__"),
- QLatin1String("PyObject *self, PyObject *_other"),
- QLatin1String("PyObject*")}
+ {u"__len__"_s,
+ u"PyObject *self"_s,
+ u"Py_ssize_t"_s},
+ {u"__getitem__"_s,
+ u"PyObject *self, Py_ssize_t _i"_s,
+ u"PyObject*"_s},
+ {u"__setitem__"_s,
+ u"PyObject *self, Py_ssize_t _i, PyObject *_value"_s,
+ 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},
+ {u"__contains__"_s,
+ u"PyObject *self, PyObject *_value"_s,
+ intT},
+ {u"__concat__"_s,
+ u"PyObject *self, PyObject *_other"_s,
+ u"PyObject*"_s}
};
return result;
}
@@ -193,14 +210,14 @@ const ProtocolEntries &sequenceProtocols()
// Return name of function to create PyObject wrapping a container
static QString opaqueContainerCreationFunc(const AbstractMetaType &type)
{
- const auto *containerTypeEntry =
- static_cast<const ContainerTypeEntry *>(type.typeEntry());
- const auto *instantiationTypeEntry =
+ const auto containerTypeEntry =
+ std::static_pointer_cast<const ContainerTypeEntry>(type.typeEntry());
+ const auto instantiationTypeEntry =
type.instantiations().constFirst().typeEntry();
- QString result = u"create"_qs;
+ QString result = u"create"_s;
if (type.isConstant())
- result += u"Const"_qs;
- result += containerTypeEntry->opaqueContainerName(instantiationTypeEntry->name());
+ result += u"Const"_s;
+ result += containerTypeEntry->opaqueContainerName(type.instantiationCppSignatures());
return result;
}
@@ -215,130 +232,21 @@ static void writeOpaqueContainerCreationFuncDecl(TextStream &s, const QString &n
CppGenerator::CppGenerator() = default;
-QString CppGenerator::fileNameSuffix() const
-{
- return QLatin1String("_wrapper.cpp");
-}
-
QString CppGenerator::fileNameForContext(const GeneratorContext &context) const
{
- const AbstractMetaClass *metaClass = context.metaClass();
- if (!context.forSmartPointer()) {
- QString fileNameBase = metaClass->qualifiedCppName().toLower();
- fileNameBase.replace(QLatin1String("::"), QLatin1String("_"));
- return fileNameBase + fileNameSuffix();
- }
- const AbstractMetaType &smartPointerType = context.preciseType();
- QString fileNameBase = getFileNameBaseForSmartPointer(smartPointerType, metaClass);
- return fileNameBase + fileNameSuffix();
-}
-
-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;
-}
-
-AbstractMetaFunctionCPtr CppGenerator::boolCast(const AbstractMetaClass *metaClass) const
-{
- const auto *te = metaClass->typeEntry();
- auto mode = te->operatorBoolMode();
- if (useOperatorBoolAsNbNonZero()
- ? mode != TypeSystem::BoolCast::Disabled : mode == TypeSystem::BoolCast::Enabled) {
- const auto func = metaClass->findOperatorBool();
- if (!func.isNull())
- return func;
- }
-
- mode = te->isNullMode();
- if (useIsNullAsNbNonZero()
- ? mode != TypeSystem::BoolCast::Disabled : mode == TypeSystem::BoolCast::Enabled) {
- const auto func = metaClass->findQtIsNullMethod();
- if (!func.isNull())
- return func;
- }
- return {};
-}
-
-std::optional<AbstractMetaType>
- CppGenerator::findSmartPointerInstantiation(const TypeEntry *entry) const
-{
- for (const auto &i : instantiatedSmartPointers()) {
- if (i.instantiations().at(0).typeEntry() == entry)
- return i;
- }
- return {};
+ return fileNameForContextHelper(context, u"_wrapper.cpp"_s);
}
void CppGenerator::clearTpFuncs()
{
+ // Functions that should not be registered under a name in PyMethodDef,
+ // but under a special constant under slots.
m_tpFuncs = {
- {QLatin1String("__str__"), {}}, {QLatin1String("__str__"), {}},
- {reprFunction(), {}}, {QLatin1String("__iter__"), {}},
- {QLatin1String("__next__"), {}}
+ {u"__str__"_s, {}}, {u"__str__"_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
@@ -346,13 +254,13 @@ static const char includeQDebug[] =
"#ifndef QT_NO_VERSION_TAGGING\n"
"# define QT_NO_VERSION_TAGGING\n"
"#endif\n"
-"#include <QDebug>\n";
+"#include <QtCore/QDebug>\n";
-static QString chopType(QString s)
+QString CppGenerator::chopType(QString s)
{
- if (s.endsWith(QLatin1String("_Type")))
+ if (s.endsWith(u"_Type"))
s.chop(5);
- else if (s.endsWith(QLatin1String("_TypeF()")))
+ else if (s.endsWith(u"_TypeF()"))
s.chop(8);
return s;
}
@@ -360,133 +268,314 @@ static QString chopType(QString s)
static bool isStdSetterName(QString setterName, QString propertyName)
{
return setterName.size() == propertyName.size() + 3
- && setterName.startsWith(QLatin1String("set"))
+ && setterName.startsWith(u"set")
&& setterName.endsWith(QStringView{propertyName}.right(propertyName.size() - 1))
&& setterName.at(3) == propertyName.at(0).toUpper();
}
static QString buildPropertyString(const QPropertySpec &spec)
{
- QString text;
- text += QLatin1Char('"');
- text += spec.name();
- text += QLatin1Char(':');
+ QString text = u'"' + spec.name() + u':';
if (spec.read() != spec.name())
text += spec.read();
if (!spec.write().isEmpty()) {
- text += QLatin1Char(':');
+ text += u':';
if (!isStdSetterName(spec.write(), spec.name()))
text += spec.write();
}
- text += QLatin1Char('"');
+ text += u'"';
return text;
}
+static QString _plainName(const QString &s)
+{
+ auto cutPos = s.lastIndexOf(u"::"_s);
+ return cutPos < 0 ? s : s.right(s.length() - (cutPos + 2));
+}
+
+/**********************************************************************
+ *
+ * Decision whether to use an IntEnum/IntFlag
+ * ------------------------------------------
+ *
+ * Unfortunately, all attempts to drive this decision automagically
+ * did not work out. We therefore compile a list in with known
+ * IntEnum and IntFlag.
+ */
+
+/*
+ * This function is now unused and replaced by TypeSystem::PythonEnumType
+ */
+#if 0
+static QSet<QString> useIntSet()
+{
+ static const QSet<QString> result{
+ /* IntEnum */ u"PySide6.QtCore.QDataStream.Version"_s,
+ /* IntEnum */ u"PySide6.QtCore.QEvent.Type"_s,
+ /* IntEnum */ u"PySide6.QtCore.QLocale.FloatingPointPrecisionOption"_s,
+ /* IntFlag */ u"PySide6.QtCore.QLocale.LanguageCodeType"_s,
+ /* IntFlag */ u"PySide6.QtCore.QUrl.ComponentFormattingOption"_s,
+ // note: "QUrl::UrlFormattingOption" is set as IntFlag without flags
+ /* IntFlag */ u"PySide6.QtCore.QUrl.UrlFormattingOption"_s,
+ /* IntFlag */ u"PySide6.QtCore.Qt.AlignmentFlag"_s,
+ /* IntFlag */ u"PySide6.QtCore.Qt.FocusPolicy"_s,
+ /* IntEnum */ u"PySide6.QtCore.Qt.GestureType"_s,
+ /* IntEnum */ u"PySide6.QtCore.Qt.ItemDataRole"_s,
+ /* IntEnum */ u"PySide6.QtCore.Qt.Key"_s,
+ /* Flag */ u"PySide6.QtCore.Qt.Modifier"_s,
+ // note: "Qt::TextFlag" is set as IntFlag without flags
+ /* IntFlag */ u"PySide6.QtCore.Qt.TextFlag"_s,
+ /* IntFlag */ u"PySide6.QtCore.Qt.WindowType"_s,
+ // This is found in QtWidgets but should be in QtGui.
+ /* IntEnum */ u"PySide6.QtGui.QFileSystemModel.Roles"_s,
+ /* IntEnum */ u"PySide6.QtGui.QFont.Stretch"_s,
+ /* IntEnum */ u"PySide6.QtGui.QFont.Weight"_s,
+ /* IntEnum */ u"PySide6.QtGui.QTextDocument.ResourceType"_s,
+ /* IntEnum */ u"PySide6.QtGui.QTextFormat.FormatType"_s,
+ /* IntEnum */ u"PySide6.QtGui.QTextFormat.ObjectTypes"_s,
+ /* IntEnum */ u"PySide6.QtGui.QTextFormat.Property"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QDialog.DialogCode"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QFrame.Shadow"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QFrame.Shape"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QListWidgetItem.ItemType"_s,
+ /* IntFlag */ u"PySide6.QtWidgets.QMessageBox.StandardButton"_s,
+ // note: "QSizePolicy::PolicyFlag" is set as IntFlag without flags
+ /* IntFlag */ u"PySide6.QtWidgets.QSizePolicy.PolicyFlag"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QStyle.ComplexControl"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QStyle.ContentsType"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QStyle.ControlElement"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QStyle.PixelMetric"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QStyle.PrimitiveElement"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QStyle.StandardPixmap"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QStyle.StyleHint"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QStyle.SubElement"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QTableWidgetItem.ItemType"_s,
+ /* IntEnum */ u"PySide6.QtWidgets.QTreeWidgetItem.ItemType"_s,
+ /* IntEnum */ u"PySide6.QtCharts.QBoxSet.ValuePositions"_s,
+ /* IntEnum */ u"PySide6.QtMultimedia.QMediaPlayer.Loops"_s,
+ /* IntEnum */ u"PySide6.QtQuick.QSGGeometry.DrawingMode"_s,
+ /* IntEnum */ u"PySide6.QtWebEngineCore.QWebEngineScript.ScriptWorldId"_s,
+ // Added because it should really be used as number
+ /* IntEnum */ u"PySide6.QtCore.QMetaType.Type"_s,
+ /* IntEnum */ u"PySide6.QtSerialPort.QSerialPort.BaudRate"_s,
+ };
+ return result;
+}
+#endif
+
+static bool _shouldInheritInt(const AbstractMetaEnum &cppEnum)
+{
+ return !cppEnum.fullName().startsWith(u"PySide6."_s);
+}
+
+static QString BuildEnumFlagInfo(const AbstractMetaEnum &cppEnum)
+{
+ auto enumType = cppEnum.typeEntry();
+ QString result = _plainName(enumType->name());
+ auto flags = enumType->flags();
+ auto decision = enumType->pythonEnumType();
+ bool _int = _shouldInheritInt(cppEnum);
+ bool _flag = bool(flags);
+
+ if (decision != TypeSystem::PythonEnumType::Unspecified) {
+ _int = decision == TypeSystem::PythonEnumType::IntEnum ||
+ decision == TypeSystem::PythonEnumType::IntFlag;
+ _flag = decision == TypeSystem::PythonEnumType::Flag ||
+ decision == TypeSystem::PythonEnumType::IntFlag;
+ }
+ result += _flag ? (_int ? u":IntFlag"_s : u":Flag"_s)
+ : (_int ? u":IntEnum"_s : u":Enum"_s);
+ if (flags)
+ result += u':' + _plainName(flags->flagsName());
+ return u'"' + result + u'"';
+}
+
static void writePyGetSetDefEntry(TextStream &s, const QString &name,
const QString &getFunc, const QString &setFunc)
{
- s << "{const_cast<char *>(\"" << name << "\"), " << getFunc << ", "
- << (setFunc.isEmpty() ? QLatin1String(NULL_PTR) : setFunc) << "},\n";
+ s << "{const_cast<char *>(\"" << mangleName(name) << "\"), " << getFunc << ", "
+ << (setFunc.isEmpty() ? NULL_PTR : setFunc) << ", nullptr, nullptr},\n";
}
-/*!
- Function used to write the class generated binding code on the buffer
- \param s the output buffer
- \param metaClass the pointer to metaclass information
-*/
-void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classContext)
+static bool generateRichComparison(const GeneratorContext &c)
{
- s.setLanguage(TextStream::Language::Cpp);
- const AbstractMetaClass *metaClass = classContext.metaClass();
+ const auto metaClass = c.metaClass();
+ if (c.forSmartPointer()) {
+ auto te = std::static_pointer_cast<const SmartPointerTypeEntry>(metaClass->typeEntry());
+ return te->smartPointerType() == TypeSystem::SmartPointerType::Shared;
+ }
+
+ return !metaClass->isNamespace() && metaClass->hasComparisonOperatorOverload();
+}
+
+void CppGenerator::generateIncludes(TextStream &s, const GeneratorContext &classContext,
+ const IncludeGroupList &includes,
+ const AbstractMetaClassCList &innerClasses) const
+{
+ const auto metaClass = classContext.metaClass();
// write license comment
s << licenseComment() << '\n';
- if (!avoidProtectedHack() && !metaClass->isNamespace() && !metaClass->hasPrivateDestructor()) {
- s << "//workaround to access protected functions\n";
- s << "#define protected public\n\n";
- }
+ const bool normalClass = !classContext.forSmartPointer();
+ // 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"};
// headers
s << "// default includes\n";
s << "#include <shiboken.h>\n";
- if (usePySideExtensions()) {
+ if (wrapperDiagnostics()) {
+ s << "#include <helper.h>\n";
+ cppIncludes << "iostream";
+ }
+
+ if (normalClass && usePySideExtensions()) {
s << includeQDebug;
- s << "#include <pysidesignal.h>\n"
- << "#include <pysideproperty.h>\n"
- << "#include <pyside.h>\n"
- << "#include <pysideqenum.h>\n"
+ if (metaClass->hasToStringCapability())
+ s << "#include <QtCore/QBuffer>\n";
+ if (isQObject(metaClass)) {
+ s << "#include <pysideqobject.h>\n"
+ << "#include <pysidesignal.h>\n"
+ << "#include <pysideproperty.h>\n"
+ << "#include <signalmanager.h>\n"
+ << "#include <pysidemetafunction.h>\n";
+ }
+ s << "#include <pysideqenum.h>\n"
+ << "#include <pysideqmetatype.h>\n"
+ << "#include <pysideutils.h>\n"
<< "#include <feature_select.h>\n"
<< "QT_WARNING_DISABLE_DEPRECATED\n\n";
- }
-
- s << "#include <typeinfo>\n";
- if (usePySideExtensions() && metaClass->isQObject()) {
- s << "#include <signalmanager.h>\n";
- s << "#include <pysidemetafunction.h>\n";
}
// The multiple inheritance initialization function
// needs the 'set' class from C++ STL.
- if (getMultipleInheritingClass(metaClass) != nullptr)
- s << "#include <algorithm>\n#include <set>\n";
- if (metaClass->generateExceptionHandling())
- s << "#include <exception>\n";
- s << "#include <iterator>\n"; // For containers
-
- if (wrapperDiagnostics())
- s << "#include <helper.h>\n#include <iostream>\n";
+ if (normalClass && getMultipleInheritingClass(metaClass) != nullptr)
+ cppIncludes << "algorithm" << "set";
+ if (normalClass && metaClass->generateExceptionHandling())
+ cppIncludes << "exception";
s << "\n// module include\n" << "#include \"" << getModuleHeaderFileName() << "\"\n";
if (hasPrivateClasses())
s << "#include \"" << getPrivateModuleHeaderFileName() << "\"\n";
- QString headerfile = fileNameForContext(classContext);
- headerfile.replace(QLatin1String(".cpp"), QLatin1String(".h"));
- s << "\n// main header\n" << "#include \"" << headerfile << "\"\n";
-
- s << '\n' << "// inner classes\n";
- const AbstractMetaClassList &innerClasses = metaClass->innerClasses();
- for (AbstractMetaClass *innerClass : innerClasses) {
- GeneratorContext innerClassContext = contextForClass(innerClass);
- if (shouldGenerate(innerClass) && !innerClass->typeEntry()->isSmartPointer()) {
- QString headerfile = fileNameForContext(innerClassContext);
- headerfile.replace(QLatin1String(".cpp"), QLatin1String(".h"));
- s << "#include \"" << headerfile << "\"\n";
+ s << "\n// main header\n" << "#include \""
+ << HeaderGenerator::headerFileNameForContext(classContext) << "\"\n";
+
+ if (!innerClasses.isEmpty()) {
+ s << "\n// inner classes\n";
+ for (const auto &innerClass : innerClasses) {
+ GeneratorContext innerClassContext = contextForClass(innerClass);
+ s << "#include \""
+ << HeaderGenerator::headerFileNameForContext(innerClassContext) << "\"\n";
}
}
- AbstractMetaEnumList classEnums = metaClass->enums();
- metaClass->getEnumsFromInvisibleNamespacesToBeGenerated(&classEnums);
+ if (avoidProtectedHack())
+ s << baseWrapperIncludes(classContext);
- //Extra includes
- QList<Include> includes;
- if (!classContext.useWrapper())
- includes += metaClass->typeEntry()->extraIncludes();
- for (const AbstractMetaEnum &cppEnum : qAsConst(classEnums))
- includes.append(cppEnum.typeEntry()->extraIncludes());
- if (!includes.isEmpty()) {
- s << "\n// Extra includes\n";
- std::sort(includes.begin(), includes.end());
- for (const Include &inc : qAsConst(includes))
- s << inc.toString() << '\n';
- s << '\n';
+ for (const auto &g : includes)
+ s << g;
+
+ // C++ includes
+ std::sort(cppIncludes.begin(), cppIncludes.end());
+ s << '\n';
+ for (const auto &i : std::as_const(cppIncludes))
+ s << "#include <" << i << ">\n";
+}
+
+// Write methods definition
+void CppGenerator::writePyMethodDefs(TextStream &s, const QString &className,
+ const QString &methodsDefinitions)
+{
+ s << "static PyMethodDef " << className << "_methods[] = {\n" << indent
+ << 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()));
+ }
+ }
+}
+
+bool CppGenerator::hasHashFunction(const AbstractMetaClassCPtr &c)
+{
+ return !c->typeEntry()->hashFunction().isEmpty()
+ || c->hasHashFunction();
+}
+
+static bool needsTypeDiscoveryFunction(const AbstractMetaClassCPtr &c)
+{
+ return c->baseClass() != nullptr
+ && (c->isPolymorphic() || !c->typeEntry()->polymorphicIdValue().isEmpty());
+}
+
+static void writeAddedTypeSignatures(TextStream &s, const ComplexTypeEntryCPtr &te)
+{
+ for (const auto &e : te->addedPyMethodDefEntrys()) {
+ if (auto count = e.signatures.size()) {
+ for (qsizetype i = 0; i < count; ++i) {
+ if (count > 1)
+ s << i << ':';
+ s << e.signatures.at(i) << '\n';
+ }
+ }
}
+}
- s << "\n#include <cctype>\n#include <cstring>\n";
+/// Function used to write the class generated binding code on the buffer
+/// \param s the output buffer
+/// \param classContext the pointer to metaclass information
+void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classContext)
+{
+ if (classContext.forSmartPointer()) {
+ generateSmartPointerClass(s, classContext);
+ return;
+ }
- if (metaClass->typeEntry()->typeFlags() & ComplexTypeEntry::Deprecated)
+ s.setLanguage(TextStream::Language::Cpp);
+ AbstractMetaClassCPtr metaClass = classContext.metaClass();
+ const auto typeEntry = metaClass->typeEntry();
+
+ auto innerClasses = metaClass->innerClasses();
+ for (auto it = innerClasses.begin(); it != innerClasses.end(); ) {
+ auto innerTypeEntry = (*it)->typeEntry();
+ if (shouldGenerate(innerTypeEntry) && !innerTypeEntry->isSmartPointer())
+ ++it;
+ else
+ it = innerClasses.erase(it);
+ }
+
+ AbstractMetaEnumList classEnums = metaClass->enums();
+ metaClass->getEnumsFromInvisibleNamespacesToBeGenerated(&classEnums);
+
+ IncludeGroupList includeGroups;
+ if (!classContext.useWrapper() || !avoidProtectedHack())
+ includeGroups.append(classIncludes(metaClass));
+ generateIncludes(s, classContext, includeGroups, innerClasses);
+
+ if (typeEntry->typeFlags().testFlag(ComplexTypeEntry::Deprecated))
s << "#Deprecated\n";
// Use class base namespace
{
- const AbstractMetaClass *context = metaClass->enclosingClass();
+ AbstractMetaClassCPtr context = metaClass->enclosingClass();
while (context) {
if (context->isNamespace() && !context->enclosingClass()
- && static_cast<const NamespaceTypeEntry *>(context->typeEntry())->generateUsing()) {
+ && std::static_pointer_cast<const NamespaceTypeEntry>(context->typeEntry())->generateUsing()) {
s << "\nusing namespace " << context->qualifiedCppName() << ";\n";
break;
}
@@ -494,149 +583,109 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
}
}
- s << "\n\n" << typeNameFunc << '\n';
-
- // Create string literal for smart pointer getter method.
- if (classContext.forSmartPointer()) {
- const auto *typeEntry =
- static_cast<const SmartPointerTypeEntry *>(classContext.preciseType()
- .typeEntry());
- QString rawGetter = typeEntry->getter();
- s << "static const char * " << SMART_POINTER_GETTER << " = \"" << rawGetter << "\";";
- }
+ s << '\n';
// class inject-code native/beginning
- if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
- writeClassCodeSnips(s, metaClass->typeEntry()->codeSnips(),
+ if (!typeEntry->codeSnips().isEmpty()) {
+ writeClassCodeSnips(s, typeEntry->codeSnips(),
TypeSystem::CodeSnipPositionBeginning, TypeSystem::NativeCode,
classContext);
s << '\n';
}
// python conversion rules
- if (metaClass->typeEntry()->hasTargetConversionRule()) {
- s << "// Python Conversion\n";
- s << metaClass->typeEntry()->targetConversionRule() << '\n';
+ if (typeEntry->isValue()) {
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(typeEntry);
+ if (vte->hasTargetConversionRule()) {
+ s << "// Python Conversion\n";
+ s << vte->targetConversionRule() << '\n';
+ }
}
if (classContext.useWrapper()) {
s << "// Native ---------------------------------------------------------\n\n";
if (avoidProtectedHack() && usePySideExtensions()) {
- s << "void " << classContext.wrapperName() << "::pysideInitQtMetaTypes()\n{\n";
- Indentation indent(s);
+ s << "void " << classContext.wrapperName() << "::pysideInitQtMetaTypes()\n{\n"
+ << indent;
writeInitQtMetaTypeFunctionBody(s, classContext);
- s << "}\n\n";
+ s << outdent << "}\n\n";
}
- const auto &funcs = filterFunctions(metaClass);
int maxOverrides = 0;
writeCacheResetNative(s, classContext);
- for (const auto &func : funcs) {
- const bool notAbstract = !func->isAbstract();
- if ((func->isPrivate() && notAbstract && !func->isVisibilityModifiedToPrivate())
- || (func->isModifiedRemoved() && notAbstract))
- continue;
- if (func->functionType() == AbstractMetaFunction::ConstructorFunction && !func->isUserAdded())
+ for (const auto &func : metaClass->functions()) {
+ const auto generation = functionGeneration(func);
+ if (generation.testFlag(FunctionGenerationFlag::WrapperConstructor))
writeConstructorNative(s, classContext, func);
- else if (shouldWriteVirtualMethodNative(func))
+ else if (generation.testFlag(FunctionGenerationFlag::VirtualMethod))
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);
- s << "\n// Target ---------------------------------------------------------\n\n"
- << "extern \"C\" {\n";
+ s << openTargetExternC;
+
const auto &functionGroups = getFunctionGroups(metaClass);
for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
+ if (contains(sequenceProtocols(), it.key()) || contains(mappingProtocols(), it.key()))
+ continue;
const AbstractMetaFunctionCList &overloads = it.value();
if (overloads.isEmpty())
continue;
const auto rfunc = overloads.constFirst();
- if (contains(sequenceProtocols(), rfunc->name())
- || contains(mappingProtocols(), rfunc->name())) {
- continue;
- }
-
OverloadData overloadData(overloads, api());
if (rfunc->isConstructor()) {
- // @TODO: Implement constructor support for smart pointers, so that they can be
- // instantiated in python code.
- if (classContext.forSmartPointer())
- continue;
writeConstructorWrapper(s, overloadData, classContext);
writeSignatureInfo(signatureStream, overloadData);
}
// call operators
- else if (rfunc->name() == QLatin1String("operator()")) {
+ else if (rfunc->name() == u"operator()") {
writeMethodWrapper(s, overloadData, classContext);
writeSignatureInfo(signatureStream, overloadData);
}
else if (!rfunc->isOperatorOverload()) {
-
- if (classContext.forSmartPointer()) {
- const auto *smartPointerTypeEntry =
- static_cast<const SmartPointerTypeEntry *>(
- classContext.preciseType().typeEntry());
-
- if (smartPointerTypeEntry->getter() == rfunc->name()) {
- // Replace the return type of the raw pointer getter method with the actual
- // return type.
- QString innerTypeName =
- classContext.preciseType().getSmartPointerInnerType().cppSignature();
- QString pointerToInnerTypeName = innerTypeName + QLatin1Char('*');
- // @TODO: This possibly leaks, but there are a bunch of other places where this
- // is done, so this will be fixed in bulk with all the other cases, because the
- // ownership of the pointers is not clear at the moment.
- auto pointerToInnerType =
- AbstractMetaType::fromString(pointerToInnerTypeName);
- Q_ASSERT(pointerToInnerType.has_value());
- auto mutableRfunc = overloads.constFirst();
- qSharedPointerConstCast<AbstractMetaFunction>(mutableRfunc)->setType(pointerToInnerType.value());
- } else if (smartPointerTypeEntry->refCountMethodName().isEmpty()
- || smartPointerTypeEntry->refCountMethodName() != rfunc->name()) {
- // Skip all public methods of the smart pointer except for the raw getter and
- // the ref count method.
- continue;
- }
- }
-
writeMethodWrapper(s, overloadData, classContext);
writeSignatureInfo(signatureStream, overloadData);
// For a mixture of static and member function overloads,
// a separate PyMethodDef entry is written which is referenced
// in the PyMethodDef list and later in getattro() for handling
// the non-static case.
+ const auto defEntries = methodDefinitionEntries(overloadData);
if (OverloadData::hasStaticAndInstanceFunctions(overloads)) {
QString methDefName = cpythonMethodDefinitionName(rfunc);
- smd << "static PyMethodDef " << methDefName << " = " << indent;
- writeMethodDefinitionEntries(smd, overloadData, 1);
- smd << outdent << ";\n\n";
+ smd << "static PyMethodDef " << methDefName << " = " << indent
+ << defEntries.constFirst() << outdent << ";\n\n";
}
- writeMethodDefinition(md, overloadData);
+ 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 (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) {
- writeCopyFunction(s, classContext);
- signatureStream << fullPythonClassName(metaClass) << ".__copy__()\n";
- }
-
// Write single method definitions
s << singleMethodDefinitions;
@@ -652,77 +701,41 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
s << '\n';
s << "static const char *" << className << "_PropertyStrings[] = {\n" << indent;
- for (const auto &entry : qAsConst(sorter))
+ for (const auto &entry : std::as_const(sorter))
+ s << entry << ",\n";
+ s << NULL_PTR << " // Sentinel\n"
+ << outdent << "};\n\n";
+
+ }
+ // PYSIDE-1735: Write an EnumFlagInfo structure
+ QStringList sorter;
+ for (const auto &entry : std::as_const(classEnums))
+ sorter.append(BuildEnumFlagInfo(entry));
+ sorter.sort();
+ if (!sorter.empty()) {
+ s << "static const char *" << className << "_EnumFlagInfo[] = {\n" << indent;
+ for (const auto &entry : std::as_const(sorter))
s << entry << ",\n";
s << NULL_PTR << " // Sentinel\n"
<< outdent << "};\n\n";
}
// Write methods definition
- s << "static PyMethodDef " << className << "_methods[] = {\n" << indent
- << methodsDefinitions << '\n';
- if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) {
- s << "{\"__copy__\", reinterpret_cast<PyCFunction>(" << className << "___copy__)"
- << ", METH_NOARGS},\n";
- }
- s << '{' << NULL_PTR << ", " << NULL_PTR << "} // Sentinel\n" << outdent
- << "};\n\n";
+ writePyMethodDefs(s, className, methodsDefinitions);
// Write tp_s/getattro function
const AttroCheck attroCheck = checkAttroFunctionNeeds(metaClass);
- if (attroCheck.testFlag(AttroCheckFlag::GetattroSmartPointer)) {
- writeSmartPointerGetattroFunction(s, classContext);
- writeSmartPointerSetattroFunction(s, classContext);
- } else {
- if ((attroCheck & AttroCheckFlag::GetattroMask) != 0)
- writeGetattroFunction(s, attroCheck, classContext);
- if ((attroCheck & AttroCheckFlag::SetattroMask) != 0)
- writeSetattroFunction(s, attroCheck, classContext);
- }
-
- const auto f = boolCast(metaClass);
- if (!f.isNull()) {
- ErrorCode errorCode(-1);
- s << "static int " << cpythonBaseName(metaClass) << "___nb_bool(PyObject *self)\n"
- << "{\n" << indent;
- writeCppSelfDefinition(s, classContext);
-
- const bool allowThread = f->allowThread();
- if (allowThread)
- s << "int result;\n" << BEGIN_ALLOW_THREADS << "\nresult = ";
- else
- s << "return ";
+ if ((attroCheck & AttroCheckFlag::GetattroMask) != 0)
+ writeGetattroFunction(s, attroCheck, classContext);
+ if ((attroCheck & AttroCheckFlag::SetattroMask) != 0)
+ writeSetattroFunction(s, attroCheck, classContext);
- if (f->isOperatorBool())
- s << '*' << CPP_SELF_VAR << " ? 1 : 0;\n";
- else
- s << CPP_SELF_VAR << "->isNull() ? 0 : 1;\n";
-
- if (allowThread)
- s << END_ALLOW_THREADS << "\nreturn result;\n";
- s << outdent << "}\n\n";
- }
-
- if (supportsNumberProtocol(metaClass) && !metaClass->typeEntry()->isSmartPointer()) {
- 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;
+ if (const auto f = boolCast(metaClass) ; f.has_value())
+ writeNbBoolFunction(classContext, f.value(), s);
+ if (supportsNumberProtocol(metaClass)) {
+ const auto numberProtocolOps = numberProtocolOperators(metaClass);
+ for (const auto &overloads : numberProtocolOps) {
OverloadData overloadData(overloads, api());
writeMethodWrapper(s, overloadData, classContext);
writeSignatureInfo(signatureStream, overloadData);
@@ -737,12 +750,12 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
writeMappingMethods(s, metaClass, classContext);
}
- if (!metaClass->isNamespace() && metaClass->hasComparisonOperatorOverload()) {
+ if (generateRichComparison(classContext)) {
s << "// Rich comparison\n";
writeRichCompareFunction(s, classContext);
}
- if (shouldGenerateGetSetList(metaClass) && !classContext.forSmartPointer()) {
+ if (shouldGenerateGetSetList(metaClass)) {
const AbstractMetaFieldList &fields = metaClass->fields();
for (const AbstractMetaField &metaField : fields) {
if (metaField.canGenerateGetter())
@@ -785,13 +798,13 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
cpythonGetterFunctionName(property, metaClass), setter);
}
}
- s << '{' << NULL_PTR << "} // Sentinel\n"
+ s << "{nullptr, nullptr, nullptr, nullptr, nullptr} // Sentinel\n"
<< outdent << "};\n\n";
}
- s << "} // extern \"C\"\n\n";
+ s << closeExternC;
- if (!metaClass->typeEntry()->hashFunction().isEmpty())
+ if (hasHashFunction(metaClass))
writeHashFunction(s, classContext);
// Write tp_traverse and tp_clear functions.
@@ -801,27 +814,38 @@ void CppGenerator::generateClass(TextStream &s, const GeneratorContext &classCon
writeClassDefinition(s, metaClass, classContext);
s << '\n';
- if (metaClass->isPolymorphic() && metaClass->baseClass())
+ if (needsTypeDiscoveryFunction(metaClass)) {
writeTypeDiscoveryFunction(s, metaClass);
-
- writeFlagsNumberMethodsDefinitions(s, classEnums);
- s << '\n';
+ s << '\n';
+ }
writeConverterFunctions(s, metaClass, classContext);
+ writeAddedTypeSignatures(signatureStream, typeEntry);
writeClassRegister(s, metaClass, classContext, signatureStream);
if (metaClass->hasStaticFields())
writeStaticFieldInitialization(s, metaClass);
// class inject-code native/end
- if (!metaClass->typeEntry()->codeSnips().isEmpty()) {
- writeClassCodeSnips(s, metaClass->typeEntry()->codeSnips(),
+ 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,
+ const GeneratorContext &classContext) const
+{
+ OverloadData overloadData(overloads, api());
+ writeMethodWrapper(s, overloadData, classContext);
+ writeSignatureInfo(signatureStream, overloadData);
+ definitionStream << methodDefinitionEntries(overloadData);
+}
+
void CppGenerator::writeCacheResetNative(TextStream &s, const GeneratorContext &classContext)
{
s << "void " << classContext.wrapperName()
@@ -833,7 +857,7 @@ void CppGenerator::writeCacheResetNative(TextStream &s, const GeneratorContext &
void CppGenerator::writeConstructorNative(TextStream &s, const GeneratorContext &classContext,
const AbstractMetaFunctionCPtr &func) const
{
- const QString qualifiedName = classContext.wrapperName() + QLatin1String("::");
+ const QString qualifiedName = classContext.wrapperName() + u"::"_s;
s << functionSignature(func, qualifiedName, QString(),
OriginalTypeDescription | SkipDefaultValues);
s << " : ";
@@ -852,7 +876,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;
@@ -864,19 +888,12 @@ Shiboken::Object::destroy(wrapper, this);
)" << outdent << "}\n";
}
-static bool allArgumentsRemoved(const AbstractMetaFunctionCPtr& func)
-{
- const AbstractMetaArgumentList &arguments = func->arguments();
- return std::all_of(arguments.cbegin(), arguments.cend(),
- [](const AbstractMetaArgument &a) { return a.isModifiedRemoved(); });
-}
-
// Return type for error messages when getting invalid types from virtual
// methods implemented in Python in C++ wrappers
QString CppGenerator::getVirtualFunctionReturnTypeName(const AbstractMetaFunctionCPtr &func) const
{
if (func->type().isVoid())
- return QLatin1String("\"\"");
+ return u"\"\""_s;
if (func->isTypeModified())
return u'"' + func->modifiedTypeName() + u'"';
@@ -884,39 +901,38 @@ 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 = static_cast<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")"_qs;
+ return uR"("set")"_s;
break;
case ContainerTypeEntry::MapContainer:
case ContainerTypeEntry::MultiMapContainer:
- return uR"("dict")"_qs;
+ return uR"("dict")"_s;
break;
case ContainerTypeEntry::PairContainer:
- return uR"("tuple")"_qs;
+ return uR"("tuple")"_s;
break;
}
- return uR"("list")"_qs;
+ return uR"("list")"_s;
}
if (typeEntry->isSmartPointer())
- return QLatin1Char('"') + typeEntry->qualifiedCppName() + QLatin1Char('"');
+ return u'"' + typeEntry->qualifiedCppName() + u'"';
if (avoidProtectedHack()) {
auto metaEnum = api().findAbstractMetaEnum(func->type().typeEntry());
- if (metaEnum.has_value() && metaEnum->isProtected()) {
- return QLatin1Char('"') + protectedEnumSurrogateName(metaEnum.value())
- + QLatin1Char('"');
- }
+ if (metaEnum.has_value() && metaEnum->isProtected())
+ return u'"' + protectedEnumSurrogateName(metaEnum.value()) + u'"';
}
if (func->type().isPrimitive())
- return QLatin1Char('"') + func->type().name() + QLatin1Char('"');
+ return u'"' + func->type().name() + u'"';
- return QLatin1String("reinterpret_cast<PyTypeObject *>(Shiboken::SbkType< ")
- + typeEntry->qualifiedCppName() + QLatin1String(" >())->tp_name");
+ return u"Shiboken::SbkType< "_s
+ + typeEntry->qualifiedCppName() + u" >()->tp_name"_s;
}
// When writing an overridden method of a wrapper class, write the part
@@ -926,8 +942,8 @@ void CppGenerator::writeVirtualMethodCppCall(TextStream &s,
const QString &funcName,
const CodeSnipList &snips,
const AbstractMetaArgument *lastArg,
- const TypeEntry *retType,
- const QString &returnStatement) const
+ const TypeEntryCPtr &retType,
+ const QString &returnStatement, bool hasGil) const
{
if (!snips.isEmpty()) {
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionBeginning,
@@ -935,13 +951,17 @@ void CppGenerator::writeVirtualMethodCppCall(TextStream &s,
}
if (func->isAbstract()) {
- s << "PyErr_SetString(PyExc_NotImplementedError, \"pure virtual method '"
- << func->ownerClass()->name() << '.' << funcName
- << "()' not implemented.\");\n"
+ if (!hasGil)
+ s << "Shiboken::GilState gil;\n";
+ s << "Shiboken::Errors::setPureVirtualMethodError(\""
+ << func->ownerClass()->name() << '.' << funcName << "\");\n"
<< returnStatement << '\n';
return;
}
+ if (hasGil)
+ s << "gil.release();\n";
+
if (retType)
s << "return ";
s << "this->::" << func->implementingClass()->qualifiedCppName() << "::";
@@ -957,17 +977,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 QLatin1String("return;");
+ 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; ; ) {
@@ -975,7 +1002,7 @@ QString CppGenerator::virtualMethodReturn(TextStream &s, const ApiExtractorResul
if (!match.hasMatch())
break;
const int argId = match.capturedView(1).toInt() - 1;
- if (argId < 0 || argId > func->arguments().count()) {
+ if (argId < 0 || argId > func->arguments().size()) {
qCWarning(lcShiboken, "The expression used in return value contains an invalid index.");
break;
}
@@ -983,62 +1010,178 @@ QString CppGenerator::virtualMethodReturn(TextStream &s, const ApiExtractorResul
offset = match.capturedStart(1);
}
DefaultValue defaultReturnExpr(DefaultValue::Custom, expr);
- return QLatin1String("return ") + defaultReturnExpr.returnValue()
- + QLatin1Char(';');
+ result.statement += defaultReturnExpr.returnValue() + u';';
+ return result;
}
}
}
QString errorMessage;
const auto defaultReturnExpr = minimalConstructor(api, returnType, &errorMessage);
if (!defaultReturnExpr.has_value()) {
- QString errorMsg = QLatin1String(__FUNCTION__) + QLatin1String(": ");
- if (const AbstractMetaClass *c = func->implementingClass())
- errorMsg += c->qualifiedCppName() + QLatin1String("::");
- errorMsg += func->signature();
+ QString errorMsg = QLatin1StringView(__FUNCTION__) + u": "_s
+ + func->classQualifiedSignature();
errorMsg = msgCouldNotFindMinimalConstructor(errorMsg,
func->type().cppSignature(),
errorMessage);
- qCWarning(lcShiboken).noquote().nospace() << errorMsg;
- s << "\n#error " << errorMsg << '\n';
+ throw Exception(errorMsg);
}
- if (returnType.referenceType() == LValueReference) {
- s << "static " << returnType.typeEntry()->qualifiedCppName()
- << " result;\n";
- return QLatin1String("return result;");
+
+ 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).
+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'};
+
+ const auto &type = arg.type();
+ auto argTypeEntry = type.typeEntry();
+ // Check for primitive types convertible by Py_BuildValue()
+ if (argTypeEntry->isPrimitive() && !type.isCString()) {
+ const auto pte = basicReferencedTypeEntry(argTypeEntry);
+ auto it = formatUnits().constFind(pte->name());
+ if (it != formatUnits().constEnd())
+ return {arg.name(), it.value()};
}
- return QLatin1String("return ") + defaultReturnExpr->returnValue()
- + QLatin1Char(';');
+
+ // Rest: convert
+ StringStream ac(TextStream::Language::Cpp);
+ writeToPythonConversion(ac, type, func->ownerClass(), arg.name());
+ return {ac.toString(), u'N'};
}
-void CppGenerator::writeVirtualMethodNative(TextStream &s,
- const AbstractMetaFunctionCPtr &func,
- int cacheIndex) const
+static const char PYTHON_ARGS_ARRAY[] = "pyArgArray";
+
+void CppGenerator::writeVirtualMethodNativeVectorCallArgs(TextStream &s,
+ const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaArgumentList &arguments,
+ const QList<int> &invalidateArgs)
{
- // abbreviations
- const QString pyRetVar = QLatin1String(PYTHON_RETURN_VAR);
- const QString cppRetVar = QLatin1String(CPP_RETURN_VAR);
+ Q_ASSERT(!arguments.isEmpty());
+ s << "PyObject *" << PYTHON_ARGS_ARRAY <<'[' << arguments.size() << "] = {\n" << indent;
+ const qsizetype last = arguments.size() - 1;
+ for (qsizetype i = 0; i <= last; ++i) {
+ const AbstractMetaArgument &arg = arguments.at(i);
+ if (func->hasConversionRule(TypeSystem::TargetLangCode, arg.argumentIndex() + 1)) {
+ s << arg.name() + CONV_RULE_OUT_VAR_SUFFIX;
+ } else {
+ writeToPythonConversion(s, arg.type(), func->ownerClass(), arg.name());
+ }
+ if (i < last)
+ s << ',';
+ s << '\n';
+ }
+ s << outdent << "};\n";
- // skip metaObject function, this will be written manually ahead
- if (usePySideExtensions() && func->ownerClass() && func->ownerClass()->isQObject() &&
- ((func->name() == u"metaObject"_qs)
- || (func->name() == QLatin1String("qt_metacall"))))
+ if (!invalidateArgs.isEmpty())
+ s << '\n';
+ for (int index : invalidateArgs) {
+ 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)
+{
+ s << "Shiboken::AutoDecRef " << PYTHON_ARGS << '(';
+ if (arguments.isEmpty()) {
+ s << "PyTuple_New(0));\n";
return;
+ }
+
+ QString format;
+ QStringList argConversions;
+ for (const AbstractMetaArgument &arg : arguments) {
+ auto argPair = virtualMethodNativeArg(func, arg);
+ argConversions.append(argPair.first);
+ format += argPair.second;
+ }
+
+ s << "Py_BuildValue(\"(" << format << ")\",\n"
+ << indent << argConversions.join(u",\n"_s) << outdent << "\n));\n";
+
+ for (int index : std::as_const(invalidateArgs)) {
+ s << "bool invalidateArg" << index << " = Py_REFCNT(PyTuple_GET_ITEM(" << PYTHON_ARGS
+ << ", " << index - 1 << ")) == 1;\n";
+ }
+}
- const TypeEntry *retType = func->type().typeEntry();
+static bool isArgumentNotRemoved(const AbstractMetaArgument &a)
+{
+ return !a.isModifiedRemoved();
+}
+
+// PyObject_Vectorcall(): since 3.9
+static const char vectorCallCondition[] =
+ "#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(PYPY_VERSION) && ((defined(Py_LIMITED_API) && Py_LIMITED_API >= 0x030A0000) || !defined(Py_LIMITED_API))\n";
+static const char inverseNoArgsCallCondition[] =
+ "#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,
+ int cacheIndex) const
+{
+ TypeEntryCPtr retType = func->type().typeEntry();
const QString funcName = func->isOperatorOverload()
? pythonOperatorFunctionName(func) : func->definitionNames().constFirst();
- QString prefix = wrapperName(func->ownerClass()) + QLatin1String("::");
+ QString prefix = wrapperName(func->ownerClass()) + u"::"_s;
s << functionSignature(func, prefix, QString(), Generator::SkipDefaultValues |
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);
- if (func->isAbstract() && func->isModifiedRemoved()) {
- qCWarning(lcShiboken, "%s", qPrintable(msgPureVirtualFunctionRemoved(func.data())));
- s << returnStatement << '\n' << outdent << "}\n\n";
+ const bool isAbstract = func->isAbstract();
+ if (isAbstract && func->isModifiedRemoved()) {
+ qCWarning(lcShiboken, "%s", qPrintable(msgPureVirtualFunctionRemoved(func.get())));
+ s << returnStatement.statement << '\n' << outdent << "}\n\n";
return;
}
@@ -1063,113 +1206,93 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
<< R"(] << '\n';)" << '\n';
}
// PYSIDE-803: Build a boolean cache for unused overrides
- const bool multi_line = func->isVoid() || !snips.isEmpty() || func->isAbstract();
- s << "if (m_PyMethodCache[" << cacheIndex << "])" << (multi_line ? " {\n" : "\n");
- {
- Indentation indentation(s);
- writeVirtualMethodCppCall(s, func, funcName, snips, lastArg, retType,
- returnStatement);
- }
+ const bool multi_line = func->isVoid() || !snips.isEmpty() || isAbstract;
+ s << "if (m_PyMethodCache[" << cacheIndex << "])" << (multi_line ? " {\n" : "\n")
+ << indent;
+ writeVirtualMethodCppCall(s, func, funcName, snips, lastArg, retType,
+ returnStatement.statement, false);
+ s << outdent;
if (multi_line)
s << "}\n";
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) + QLatin1Char(':');
+ 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 << "gil.release();\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);
+ returnStatement.statement, true);
s << outdent << "}\n\n"; //WS
- writeConversionRule(s, func, TypeSystem::TargetLangCode, false);
-
- s << "Shiboken::AutoDecRef " << PYTHON_ARGS << "(";
+ if (!snips.isEmpty()) {
+ writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionPyOverride,
+ TypeSystem::ShellCode, func, false, lastArg);
+ }
- if (func->arguments().isEmpty() || allArgumentsRemoved(func)) {
- s << "PyTuple_New(0));\n";
- } else {
- QStringList argConversions;
- const AbstractMetaArgumentList &arguments = func->arguments();
- for (const AbstractMetaArgument &arg : arguments) {
- if (arg.isModifiedRemoved())
- continue;
+ writeVirtualMethodPythonOverride(s, func, snips, returnStatement);
+}
- const auto &argType = arg.type();
- const auto *argTypeEntry = argType.typeEntry();
- bool convert = argTypeEntry->isObject()
- || argTypeEntry->isValue()
- || argType.isValuePointer()
- || argType.isNativePointer()
- || argTypeEntry->isFlags()
- || argTypeEntry->isEnum()
- || argTypeEntry->isContainer()
- || argType.referenceType() == LValueReference;
-
- if (!convert && argTypeEntry->isPrimitive()) {
- const auto *pte = argTypeEntry->asPrimitive()->basicReferencedTypeEntry();
- convert = !formatUnits().contains(pte->name());
- }
+void CppGenerator::writeVirtualMethodPythonOverride(TextStream &s,
+ const AbstractMetaFunctionCPtr &func,
+ const CodeSnipList &snips,
+ const VirtualMethodReturn &returnStatement) const
+{
+ writeConversionRule(s, func, TypeSystem::TargetLangCode, false);
- StringStream ac(TextStream::Language::Cpp);
- if (!func->conversionRule(TypeSystem::TargetLangCode,
- arg.argumentIndex() + 1).isEmpty()) {
- // Has conversion rule.
- ac << arg.name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX);
+ bool invalidateReturn = false;
+ QList<int> invalidateArgs;
+ for (const FunctionModification &funcMod : func->modifications()) {
+ for (const ArgumentModification &argMod : funcMod.argument_mods()) {
+ const int index = argMod.index();
+ if (index == 0) {
+ if (argMod.targetOwnerShip() == TypeSystem::CppOwnership)
+ invalidateReturn = true;
} else {
- QString argName = arg.name();
- if (convert)
- writeToPythonConversion(ac, arg.type(), func->ownerClass(), argName);
- else
- ac << argName;
+ const int actualIndex = func->actualArgumentIndex(index - 1) + 1;
+ if (argMod.resetAfterUse() && !invalidateArgs.contains(actualIndex))
+ invalidateArgs.append(actualIndex);
}
-
- argConversions << ac.toString();
}
+ }
+ std::sort(invalidateArgs.begin(), invalidateArgs.end());
- s << "Py_BuildValue(\"(" << getFormatUnitString(func, false) << ")\",\n"
- << indent << argConversions.join(u",\n"_qs) << outdent << "\n));\n";
+ auto arguments = func->arguments();
+ auto removedEnd = std::stable_partition(arguments.begin(), arguments.end(),
+ isArgumentNotRemoved);
+ if (func->isAbstract()) { // Base function is not called, indicate unused arguments.
+ for (auto it = removedEnd; it != arguments.end(); ++it)
+ s << sbkUnusedVariableCast(it->name());
}
+ arguments.erase(removedEnd, arguments.end());
- bool invalidateReturn = false;
- QSet<int> invalidateArgs;
- for (const FunctionModification &funcMod : func->modifications()) {
- for (const ArgumentModification &argMod : funcMod.argument_mods()) {
- const int index = argMod.index();
- if (argMod.resetAfterUse() && !invalidateArgs.contains(index)) {
- invalidateArgs.insert(index);
- s << "bool invalidateArg" << index
- << " = PyTuple_GET_ITEM(" << PYTHON_ARGS << ", "
- << index - 1 << ")->ob_refcnt == 1;\n";
- } else if (index == 0 &&
- argMod.targetOwnerShip() == TypeSystem::CppOwnership) {
- invalidateReturn = true;
- }
+ // FIXME PYSIDE-7: new functions PyObject_Vectorcall() (since 3.9) and
+ // PyObject_CallNoArgs() (since 3.9, stable API since 3.10) might have
+ // become part of the stable API?
+
+ // Code snips might expect the args tuple, don't generate new code
+ const bool generateNewCall = snips.isEmpty();
+ const qsizetype argCount = arguments.size();
+ const char *newCallCondition = argCount == 0 ? noArgsCallCondition : vectorCallCondition;
+ if (generateNewCall) {
+ if (argCount > 0) {
+ s << newCallCondition;
+ writeVirtualMethodNativeVectorCallArgs(s, func, arguments, invalidateArgs);
+ s << "#else\n";
+ } else {
+ s << inverseNoArgsCallCondition;
}
}
+ writeVirtualMethodNativeArgs(s, func, arguments, invalidateArgs);
+ if (generateNewCall)
+ s << "#endif\n";
s << '\n';
if (!snips.isEmpty()) {
@@ -1182,31 +1305,54 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
TypeSystem::NativeCode, func, false, lastArg);
}
+ qsizetype returnIndirections = 0;
+
if (!func->injectedCodeCallsPythonOverride()) {
- s << "Shiboken::AutoDecRef " << pyRetVar << "(PyObject_Call("
+ if (generateNewCall) {
+ s << newCallCondition << "Shiboken::AutoDecRef " << PYTHON_RETURN_VAR << '(';
+ if (argCount > 0) {
+ s << "PyObject_Vectorcall(" << PYTHON_OVERRIDE_VAR << ", "
+ << PYTHON_ARGS_ARRAY << ", " << argCount << ", nullptr));\n";
+ for (int argIndex : std::as_const(invalidateArgs)) {
+ s << "if (invalidateArg" << argIndex << ")\n" << indent
+ << "Shiboken::Object::invalidate(" << PYTHON_ARGS_ARRAY
+ << '[' << (argIndex - 1) << "]);\n" << outdent;
+ }
+ for (qsizetype i = 0, size = arguments.size(); i < size; ++i)
+ s << "Py_DECREF(" << PYTHON_ARGS_ARRAY << '[' << i << "]);\n";
+ } else {
+ s << "PyObject_CallNoArgs(" << PYTHON_OVERRIDE_VAR << "));\n";
+ }
+ s << "#else\n";
+ }
+ s << "Shiboken::AutoDecRef " << PYTHON_RETURN_VAR << "(PyObject_Call("
<< PYTHON_OVERRIDE_VAR << ", " << PYTHON_ARGS << ", nullptr));\n";
- for (int argIndex : qAsConst(invalidateArgs)) {
+ for (int argIndex : std::as_const(invalidateArgs)) {
s << "if (invalidateArg" << argIndex << ")\n" << indent
<< "Shiboken::Object::invalidate(PyTuple_GET_ITEM(" << PYTHON_ARGS
<< ", " << (argIndex - 1) << "));\n" << outdent;
}
+ if (generateNewCall)
+ s << "#endif\n";
- s << "if (" << pyRetVar << ".isNull()) {\n" << indent
+ 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 = " << pyRetVar << "->ob_refcnt == 1;\n"
+ s << "bool invalidateArg0 = Py_REFCNT(" << PYTHON_RETURN_VAR << ") == 1;\n"
<< "if (invalidateArg0)\n" << indent
- << "Shiboken::Object::releaseOwnership(" << pyRetVar << ".object());\n" << outdent;
+ << "Shiboken::Object::releaseOwnership(" << PYTHON_RETURN_VAR
+ << ".object());\n" << outdent;
}
if (!func->isVoid()) {
- if (func->modifiedTypeName() != cPyObjectT()) {
+ if (func->modifiedTypeName() != cPyObjectT) {
s << "// Check return type\n";
@@ -1215,50 +1361,46 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
s << PYTHON_TO_CPPCONVERSION_STRUCT << ' '
<< PYTHON_TO_CPP_VAR << " =\n" << indent
<< cpythonIsConvertibleFunction(func->type())
- << pyRetVar << ");\n" << outdent
+ << PYTHON_RETURN_VAR << ");\n" << outdent
<< "if (!" << PYTHON_TO_CPP_VAR << ") {\n" << indent
- << "Shiboken::warning(PyExc_RuntimeWarning, 2,\n" << indent
- << "\"Invalid return value in function %s, expected %s, got %s.\",\n"
- << "\"" << func->ownerClass()->name() << '.' << funcName << "\",\n"
- << getVirtualFunctionReturnTypeName(func) << ",\n"
- << "Py_TYPE(" << pyRetVar << ")->tp_name);\n" << outdent
- << returnStatement << '\n' << outdent
+ << "Shiboken::Warnings::warnInvalidReturnValue(\""
+ << func->ownerClass()->name() << "\", funcName, "
+ << getVirtualFunctionReturnTypeName(func) << ", "
+ << "Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);\n"
+ << returnStatement.statement << '\n' << outdent
<< "}\n";
} else {
s << "bool typeIsValid = ";
if (func->isTypeModified()) {
- writeTypeCheck(s, func->modifiedTypeName(), pyRetVar);
+ writeTypeCheck(s, func->modifiedTypeName(), PYTHON_RETURN_VAR);
} else {
const bool numberType = isNumber(func->type().typeEntry());
- writeTypeCheck(s, func->type(), pyRetVar, numberType);
+ writeTypeCheck(s, func->type(), PYTHON_RETURN_VAR, numberType);
}
s << ";\n";
s << "if (!typeIsValid";
if (func->type().isPointerToWrapperType())
- s << " && " << pyRetVar << " != Py_None";
+ s << " && " << PYTHON_RETURN_VAR << " != Py_None";
s << ") {\n" << indent
- << "Shiboken::warning(PyExc_RuntimeWarning, 2,\n" << indent
- << "\"Invalid return value in function %s, expected %s, got %s.\",\n"
- << "\"" << func->ownerClass()->name() << '.' << funcName << "\",\n"
- << getVirtualFunctionReturnTypeName(func) << ",\n"
- << "Py_TYPE(" << pyRetVar << ")->tp_name);\n" << outdent
- << returnStatement << '\n' << outdent
+ << "Shiboken::Warnings::warnInvalidReturnValue(\""
+ << func->ownerClass()->name() << "\", funcName, "
+ << getVirtualFunctionReturnTypeName(func) << ", "
+ << "Py_TYPE(" << PYTHON_RETURN_VAR << ")->tp_name);\n"
+ << returnStatement.statement << '\n' << outdent
<< "}\n";
}
}
- if (!func->conversionRule(TypeSystem::NativeCode, 0).isEmpty()) {
- // Has conversion rule.
- writeConversionRule(s, func, TypeSystem::NativeCode, cppRetVar);
+ if (func->hasConversionRule(TypeSystem::NativeCode, 0)) {
+ writeConversionRule(s, func, TypeSystem::NativeCode, CPP_RETURN_VAR);
} else if (!func->injectedCodeHasReturnValueAttribution(TypeSystem::NativeCode)) {
- writePythonToCppTypeConversion(
- s, func->type(), pyRetVar,
- cppRetVar, func->implementingClass(), {},
- PythonToCppTypeConversionFlag::DisableOpaqueContainers);
+ returnIndirections = writePythonToCppTypeConversion(
+ s, func->type(), PYTHON_RETURN_VAR,
+ CPP_RETURN_VAR, func->implementingClass(), {});
}
}
}
@@ -1267,8 +1409,8 @@ void CppGenerator::writeVirtualMethodNative(TextStream &s,
for (const ArgumentModification &argMod : funcMod.argument_mods()) {
if (argMod.index() == 0
&& argMod.nativeOwnership() == TypeSystem::CppOwnership) {
- s << "if (Shiboken::Object::checkType(" << pyRetVar << "))\n" << indent
- << "Shiboken::Object::releaseOwnership(" << pyRetVar << ");\n"
+ s << "if (Shiboken::Object::checkType(" << PYTHON_RETURN_VAR << "))\n" << indent
+ << "Shiboken::Object::releaseOwnership(" << PYTHON_RETURN_VAR << ");\n"
<< outdent;
}
}
@@ -1284,25 +1426,49 @@ 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"::"_qs + metaEnum->enclosingClass()->qualifiedCppName();
- typeCast += u"::"_qs + metaEnum->name();
+ typeCast += getFullTypeName(metaEnum->enclosingClass());
+ typeCast += u"::"_s + metaEnum->name();
s << '(' << typeCast << ')';
}
}
- if (func->type().isWrapperPassedByReference())
- s << " *";
- s << cppRetVar << ";\n";
+
+ if (returnIndirections > 0)
+ s << QByteArray(returnIndirections, '*');
+ s << CPP_RETURN_VAR << ";\n";
}
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
{
@@ -1310,7 +1476,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"
@@ -1324,7 +1490,7 @@ void CppGenerator::writeMetaObjectMethod(TextStream &s,
<< "::qt_metacall(QMetaObject::Call call, int id, void **args)\n";
s << "{\n" << indent;
- const auto list = classContext.metaClass()->queryFunctionsByName(QLatin1String("qt_metacall"));
+ const auto list = classContext.metaClass()->queryFunctionsByName(u"qt_metacall"_s);
CodeSnipList snips;
if (list.size() == 1) {
@@ -1353,108 +1519,117 @@ 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::writeEnumConverterFunctions(TextStream &s, const AbstractMetaEnum &metaEnum) const
+static void generateDeprecatedValueWarnings(TextStream &c,
+ const AbstractMetaEnum &metaEnum,
+ bool useSurrogateName)
{
- if (metaEnum.isPrivate() || metaEnum.isAnonymous())
- return;
- writeEnumConverterFunctions(s, metaEnum.typeEntry());
+ EnumTypeEntryCPtr enumType = metaEnum.typeEntry();
+ const QString prefix = enumType->qualifiedCppName() + u"::"_s;
+ c << "switch (value) {\n";
+ const auto &deprecatedValues = metaEnum.deprecatedValues();
+ for (const auto &v : deprecatedValues) {
+ c << "case ";
+ if (useSurrogateName)
+ c << v.value().toString(); // Protected, use int representation
+ else
+ c << prefix << v.name();
+ c << ":\n" << indent
+ << "Shiboken::Warnings::warnDeprecatedEnumValue(\"" << enumType->name()
+ << "\", \"" << v.name() << "\");\nbreak;\n" << outdent;
+ }
+ if (deprecatedValues.size() < metaEnum.values().size())
+ c << "default:\n" << indent << "break;\n" << outdent;
+ c << "}\n";
}
-void CppGenerator::writeEnumConverterFunctions(TextStream &s, const TypeEntry *enumType) const
+void CppGenerator::writeEnumConverterFunctions(TextStream &s, const AbstractMetaEnum &metaEnum) const
{
- if (!enumType)
+ if (metaEnum.isPrivate() || metaEnum.isAnonymous())
return;
+ EnumTypeEntryCPtr enumType = metaEnum.typeEntry();
+ Q_ASSERT(enumType);
QString typeName = fixedCppTypeName(enumType);
QString enumPythonType = cpythonTypeNameExt(enumType);
- QString cppTypeName = getFullTypeName(enumType).trimmed();
- if (avoidProtectedHack()) {
- auto metaEnum = api().findAbstractMetaEnum(enumType);
- if (metaEnum.has_value() && metaEnum->isProtected())
- cppTypeName = protectedEnumSurrogateName(metaEnum.value());
- }
+ const bool useSurrogateName = avoidProtectedHack() && metaEnum.isProtected();
+ QString cppTypeName = useSurrogateName
+ ? protectedEnumSurrogateName(metaEnum) : getFullTypeName(enumType).trimmed();
+
StringStream c(TextStream::Language::Cpp);
- c << "*reinterpret_cast<" << cppTypeName << " *>(cppOut) =\n"
- << " ";
- if (enumType->isFlags())
- c << cppTypeName << "(QFlag(int(PySide::QFlags::getValue(reinterpret_cast<PySideQFlagsObject *>(pyIn)))))";
- else
- c << "static_cast<" << cppTypeName << ">(Shiboken::Enum::getValue(pyIn))";
- c << ";\n";
+ if (metaEnum.isDeprecated())
+ c << "Shiboken::Warnings::warnDeprecatedEnum(\"" << enumType->name() << "\");\n";
+
+ c << "const auto value = static_cast<" << cppTypeName
+ << ">(Shiboken::Enum::getValue(pyIn));\n";
+
+ // Warn about deprecated values unless it is protected+scoped (inaccessible values)
+ const bool valuesAcccessible = !useSurrogateName || metaEnum.enumKind() != EnumClass;
+ if (valuesAcccessible && metaEnum.hasDeprecatedValues())
+ 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, "_qs + enumPythonType + u')';
+ QString pyTypeCheck = u"PyObject_TypeCheck(pyIn, "_s + enumPythonType + u')';
writeIsPythonConvertibleToCppFunction(s, typeName, typeName, pyTypeCheck);
c.clear();
c << "const int castCppIn = int(*reinterpret_cast<const "
- << cppTypeName << " *>(cppIn));\n" << "return ";
- if (enumType->isFlags()) {
- c << "reinterpret_cast<PyObject *>(PySide::QFlags::newObject(castCppIn, "
- << enumPythonType << "))";
- } else {
- c << "Shiboken::Enum::newItem(" << enumPythonType << ", castCppIn)";
- }
- c << ";\n";
+ << cppTypeName << " *>(cppIn));\n" << "return "
+ << "Shiboken::Enum::newItem(" << enumPythonType << ", castCppIn);\n";
writeCppToPythonFunction(s, c.toString(), typeName, typeName);
s << '\n';
+}
- if (enumType->isFlags())
- return;
+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";
- auto flags = reinterpret_cast<const EnumTypeEntry *>(enumType)->flags();
- if (!flags)
+ const QString nameFunc = metaClass->typeEntry()->polymorphicNameFunction();
+ if (nameFunc.isEmpty() && !metaClass->hasVirtualDestructor()) {
+ c << "return Shiboken::Object::newObjectWithHeuristics("
+ << cpythonType << ", const_cast<void *>(cppIn), false);\n";
return;
+ }
- // QFlags part.
-
- writeEnumConverterFunctions(s, flags);
-
- c.clear();
- cppTypeName = getFullTypeName(flags).trimmed();
- c << "*reinterpret_cast<" << cppTypeName << " *>(cppOut) =\n"
- << " " << cppTypeName
- << "(QFlag(int(Shiboken::Enum::getValue(pyIn))));\n";
-
- QString flagsTypeName = fixedCppTypeName(flags);
- writePythonToCppFunction(s, c.toString(), typeName, flagsTypeName);
- writeIsPythonConvertibleToCppFunction(s, typeName, flagsTypeName, pyTypeCheck);
+ 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";
+}
- c.clear();
- c << "Shiboken::AutoDecRef pyLong(PyNumber_Long(pyIn));\n"
- << "*reinterpret_cast<" << cppTypeName << " *>(cppOut) =\n"
- << " " << cppTypeName
- << "(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 = QStringLiteral("PyNumber_Check(pyIn) && ") + pyTypeCheck;
- writePythonToCppFunction(s, c.toString(), QLatin1String("number"), flagsTypeName);
- writeIsPythonConvertibleToCppFunction(s, QLatin1String("number"), flagsTypeName, numberCondition);
-}
-
-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";
AbstractMetaEnumList classEnums = metaClass->enums();
+ auto typeEntry = metaClass->typeEntry();
metaClass->getEnumsFromInvisibleNamespacesToBeGenerated(&classEnums);
if (!classEnums.isEmpty())
s << "// Python to C++ enum conversion.\n";
- for (const AbstractMetaEnum &metaEnum : qAsConst(classEnums))
+ for (const AbstractMetaEnum &metaEnum : std::as_const(classEnums))
writeEnumConverterFunctions(s, metaEnum);
if (metaClass->isNamespace())
@@ -1472,106 +1647,94 @@ void CppGenerator::writeConverterFunctions(TextStream &s, const AbstractMetaClas
s << "// Python to C++ pointer conversion - returns the C++ object of the Python wrapper (keeps object identity).\n";
QString sourceTypeName = metaClass->name();
- QString targetTypeName = metaClass->name() + QLatin1String("_PTR");
+ QString targetTypeName = metaClass->name() + u"_PTR"_s;
StringStream c(TextStream::Language::Cpp);
c << "Shiboken::Conversions::pythonToCppPointer(" << cpythonType << ", pyIn, cppOut);";
writePythonToCppFunction(s, c.toString(), sourceTypeName, targetTypeName);
// "Is convertible" function for the Python object to C++ pointer conversion.
- const QString pyTypeCheck = u"PyObject_TypeCheck(pyIn, "_qs + cpythonType + u")"_qs;
+ const QString pyTypeCheck = u"PyObject_TypeCheck(pyIn, "_s + cpythonType + u")"_s;
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, pyTypeCheck, QString(), true);
s << '\n';
// 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";
- {
- Indentation indent(c);
- c << "Py_INCREF(pyOut);\nreturn pyOut;\n";
- }
- c << "}\n"
- << "bool changedTypeName = false;\n"
- << "auto tCppIn = reinterpret_cast<const " << typeName << R"( *>(cppIn);
-const char *typeName = typeid(*tCppIn).name();
-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);
// The conversions for an Object Type end here.
- if (!metaClass->typeEntry()->isValue() && !metaClass->typeEntry()->isSmartPointer()) {
+ if (!typeEntry->isValue() && !typeEntry->isSmartPointer()) {
s << '\n';
return;
}
// Always copies C++ value (not pointer, and not reference) to a new Python wrapper.
s << '\n' << "// C++ to Python copy conversion.\n";
- if (!classContext.forSmartPointer())
- targetTypeName = metaClass->name();
- else
- targetTypeName = classContext.preciseType().name();
+ targetTypeName = metaClass->name();
- sourceTypeName = targetTypeName + QLatin1String("_COPY");
+ sourceTypeName = targetTypeName + u"_COPY"_s;
c.clear();
- QString computedWrapperName;
- if (!classContext.forSmartPointer()) {
- computedWrapperName = classContext.useWrapper()
- ? classContext.wrapperName() : metaClass->qualifiedCppName();
+ const bool isUniquePointer = classContext.forSmartPointer()
+ && typeEntry->isUniquePointer();
+
+ if (isUniquePointer) {
+ c << "auto *source = reinterpret_cast<" << typeName
+ << " *>(const_cast<void *>(cppIn));\n";
} else {
- computedWrapperName = classContext.smartPointerWrapperName();
+ c << "auto *source = reinterpret_cast<const " << typeName << " *>(cppIn);\n";
}
-
c << "return Shiboken::Object::newObject(" << cpythonType
- << ", new ::" << computedWrapperName << "(*reinterpret_cast<const "
- << typeName << " *>(cppIn)), true, true);";
+ << ", new " << globalScopePrefix(classContext) << classContext.effectiveClassName() << '('
+ << (isUniquePointer ? "std::move(*source)" : "*source")
+ << "), true, true);";
writeCppToPythonFunction(s, c.toString(), sourceTypeName, targetTypeName);
s << '\n';
// Python to C++ copy conversion.
s << "// Python to C++ copy conversion.\n";
- if (!classContext.forSmartPointer())
- sourceTypeName = metaClass->name();
- else
- sourceTypeName = classContext.preciseType().name();
+ sourceTypeName = metaClass->name();
- targetTypeName = sourceTypeName + QStringLiteral("_COPY");
+ targetTypeName = sourceTypeName + "_COPY"_L1;
c.clear();
- QString pyInVariable = QLatin1String("pyIn");
- QString wrappedCPtrExpression;
- if (!classContext.forSmartPointer())
- wrappedCPtrExpression = cpythonWrapperCPtr(metaClass->typeEntry(), pyInVariable);
- else
- wrappedCPtrExpression = cpythonWrapperCPtr(classContext.preciseType(), pyInVariable);
+ QString pyInVariable = u"pyIn"_s;
+ const QString outPtr = u"reinterpret_cast<"_s + typeName + u" *>(cppOut)"_s;
+ if (!classContext.forSmartPointer()) {
+ c << '*' << outPtr << " = *"
+ << cpythonWrapperCPtr(typeEntry, pyInVariable) << ';';
+ } else {
+ 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;
+ if (resetMethod.isEmpty())
+ c << "*ptr = {};\n";
+ else
+ c << "ptr->" << resetMethod << "();\n";
+ const QString value = u'*' + cpythonWrapperCPtr(classContext.preciseType(), pyInVariable);
+ c << outdent << "else\n" << indent
+ << "*ptr = " << (isUniquePointer ? stdMove(value) : value) << ';';
+ }
- c << "*reinterpret_cast<" << typeName << " *>(cppOut) = *"
- << wrappedCPtrExpression << ';';
writePythonToCppFunction(s, c.toString(), sourceTypeName, targetTypeName);
// "Is convertible" function for the Python object to C++ value copy conversion.
- writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, pyTypeCheck);
+ QString copyTypeCheck = pyTypeCheck;
+ if (classContext.forSmartPointer())
+ copyTypeCheck.prepend(pyInVariable + u" == Py_None || "_s);
+ writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, copyTypeCheck);
s << '\n';
// User provided implicit conversions.
- auto *typeEntry = metaClass->typeEntry();
// Implicit conversions.
const AbstractMetaFunctionCList implicitConvs = implicitConversions(typeEntry);
@@ -1579,7 +1742,7 @@ return result;)";
s << "// Implicit conversions.\n";
AbstractMetaType targetType = AbstractMetaType::fromAbstractMetaClass(metaClass);
- for (const auto &conv : qAsConst(implicitConvs)) {
+ for (const auto &conv : std::as_const(implicitConvs)) {
if (conv->isModifiedRemoved())
continue;
@@ -1587,11 +1750,11 @@ return result;)";
QString toCppConv;
QString toCppPreConv;
if (conv->isConversionOperator()) {
- const AbstractMetaClass *sourceClass = conv->ownerClass();
- typeCheck = u"PyObject_TypeCheck(pyIn, "_qs
+ const auto sourceClass = conv->ownerClass();
+ typeCheck = u"PyObject_TypeCheck(pyIn, "_s
+ cpythonTypeNameExt(sourceClass->typeEntry()) + u')';
- toCppConv = QLatin1Char('*') + cpythonWrapperCPtr(sourceClass->typeEntry(),
- pyInVariable);
+ toCppConv = u'*' + cpythonWrapperCPtr(sourceClass->typeEntry(),
+ pyInVariable);
} else {
// Constructor that does implicit conversion.
const auto &firstArg = conv->arguments().constFirst();
@@ -1601,7 +1764,7 @@ return result;)";
if (sourceType.isWrapperType()) {
if (sourceType.referenceType() == LValueReference
|| !sourceType.isPointerToWrapperType()) {
- toCppConv = u" *"_qs;
+ toCppConv = u" *"_s;
}
toCppConv += cpythonWrapperCPtr(sourceType.typeEntry(), pyInVariable);
}
@@ -1621,15 +1784,15 @@ return result;)";
StringStream pc(TextStream::Language::Cpp);
pc << getFullTypeNameWithoutModifiers(sourceType) << " cppIn"
<< minimalConstructorExpression(api(), sourceType) << ";\n";
- writeToCppConversion(pc, sourceType, nullptr, pyInVariable,
- u"cppIn"_qs);
+ writeToCppConversion(pc, sourceType, pyInVariable,
+ u"cppIn"_s);
pc << ';';
toCppPreConv = pc.toString();
- toCppConv.append(QLatin1String("cppIn"));
+ toCppConv.append(u"cppIn"_s);
} else if (!sourceType.isWrapperType()) {
StringStream tcc(TextStream::Language::Cpp);
- writeToCppConversion(tcc, sourceType, metaClass, pyInVariable,
- u"/*BOZO-1061*/"_qs);
+ writeToCppConversion(tcc, sourceType, pyInVariable,
+ u"/*BOZO-1061*/"_s);
toCppConv = tcc.toString();
}
}
@@ -1639,61 +1802,61 @@ return result;)";
writePythonToCppConversionFunctions(s, sourceType, targetType, typeCheck, toCppConv, toCppPreConv);
}
- writeCustomConverterFunctions(s, typeEntry->customConversion());
+ if (typeEntry->isValue()) {
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(typeEntry);
+ writeCustomConverterFunctions(s, vte->customConversion());
+ }
}
void CppGenerator::writeCustomConverterFunctions(TextStream &s,
- const CustomConversion *customConversion) const
+ const CustomConversionPtr &customConversion) const
{
if (!customConversion)
return;
- const CustomConversion::TargetToNativeConversions &toCppConversions = customConversion->targetToNativeConversions();
+ const TargetToNativeConversions &toCppConversions = customConversion->targetToNativeConversions();
if (toCppConversions.isEmpty())
return;
- s << "// Python to C++ conversions for type '" << customConversion->ownerType()->qualifiedCppName() << "'.\n";
- for (CustomConversion::TargetToNativeConversion *toNative : toCppConversions)
- writePythonToCppConversionFunctions(s, toNative, customConversion->ownerType());
+ auto ownerType = customConversion->ownerType();
+ s << "// Python to C++ conversions for type '" << ownerType->qualifiedCppName() << "'.\n";
+ for (const auto &toNative : toCppConversions)
+ writePythonToCppConversionFunctions(s, toNative, ownerType);
s << '\n';
}
-void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass *metaClass,
+void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext) const
{
- if (metaClass->isNamespace())
+ const auto typeEntry = metaClass->typeEntry();
+ if (typeEntry->isNamespace())
return;
s << "// Register Converter\n"
- << "SbkConverter *converter = Shiboken::Conversions::createConverter(pyType,\n";
- {
- Indentation indent(s);
- QString sourceTypeName = metaClass->name();
- QString targetTypeName = sourceTypeName + QLatin1String("_PTR");
- s << pythonToCppFunctionName(sourceTypeName, targetTypeName) << ',' << '\n'
- << convertibleToCppFunctionName(sourceTypeName, targetTypeName) << ',' << '\n';
- std::swap(targetTypeName, sourceTypeName);
+ << "SbkConverter *converter = Shiboken::Conversions::createConverter(pyType,\n"
+ << indent;
+ QString sourceTypeName = metaClass->name();
+ QString targetTypeName = sourceTypeName + u"_PTR"_s;
+ s << pythonToCppFunctionName(sourceTypeName, targetTypeName) << ',' << '\n'
+ << convertibleToCppFunctionName(sourceTypeName, targetTypeName) << ',' << '\n';
+ std::swap(targetTypeName, sourceTypeName);
+ s << cppToPythonFunctionName(sourceTypeName, targetTypeName);
+ if (typeEntry->isValue() || typeEntry->isSmartPointer()) {
+ s << ',' << '\n';
+ sourceTypeName = metaClass->name() + u"_COPY"_s;
s << cppToPythonFunctionName(sourceTypeName, targetTypeName);
- if (metaClass->typeEntry()->isValue() || metaClass->typeEntry()->isSmartPointer()) {
- s << ',' << '\n';
- sourceTypeName = metaClass->name() + QLatin1String("_COPY");
- s << cppToPythonFunctionName(sourceTypeName, targetTypeName);
- }
}
- s << ");\n";
-
- s << '\n';
+ s << outdent << ");\n\n";
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)
{
- QStringList lst = fullTypeName.split(QLatin1String("::"),
+ QStringList lst = fullTypeName.split(u"::"_s,
Qt::SkipEmptyParts);
while (!lst.isEmpty()) {
- QString signature = lst.join(QLatin1String("::"));
+ QString signature = lst.join(u"::"_s);
writeConversions(signature);
lst.removeFirst();
}
@@ -1706,18 +1869,18 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass
const QString &smartPointerType = classContext.preciseType().instantiations().at(0).cppSignature();
const QString &smartPointerName = classContext.preciseType().typeEntry()->name();
- QStringList lst = smartPointerType.split(QLatin1String("::"),
+ QStringList lst = smartPointerType.split(u"::"_s,
Qt::SkipEmptyParts);
while (!lst.isEmpty()) {
- QString signature = lst.join(QLatin1String("::"));
- writeConversions(smartPointerName + u'<' + signature + u" >"_qs);
+ QString signature = lst.join(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();
@@ -1727,25 +1890,22 @@ 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 (!metaClass->typeEntry()->isValue() && !metaClass->typeEntry()->isSmartPointer())
+ 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";
- QString sourceTypeName = metaClass->name();
- QString targetTypeName = sourceTypeName + QLatin1String("_COPY");
+ 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);
QString isConv = convertibleToCppFunctionName(sourceTypeName, targetTypeName);
- writeAddPythonToCppConversion(s, QLatin1String("converter"), toCpp, isConv);
+ writeAddPythonToCppConversion(s, u"converter"_s, toCpp, isConv);
// User provided implicit conversions.
- auto *typeEntry = metaClass->typeEntry();
// Add implicit conversions.
const AbstractMetaFunctionCList implicitConvs = implicitConversions(typeEntry);
@@ -1754,7 +1914,7 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass
s << "// Add implicit conversions to type converter.\n";
AbstractMetaType targetType = AbstractMetaType::fromAbstractMetaClass(metaClass);
- for (const auto &conv : qAsConst(implicitConvs)) {
+ for (const auto &conv : std::as_const(implicitConvs)) {
if (conv->isModifiedRemoved())
continue;
AbstractMetaType sourceType;
@@ -1769,22 +1929,27 @@ void CppGenerator::writeConverterRegister(TextStream &s, const AbstractMetaClass
}
QString toCpp = pythonToCppFunctionName(sourceType, targetType);
QString isConv = convertibleToCppFunctionName(sourceType, targetType);
- writeAddPythonToCppConversion(s, QLatin1String("converter"), toCpp, isConv);
+ writeAddPythonToCppConversion(s, u"converter"_s, toCpp, isConv);
}
- writeCustomConverterRegister(s, typeEntry->customConversion(), u"converter"_qs);
+ if (typeEntry->isValue()) {
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(typeEntry);
+ writeCustomConverterRegister(s, vte->customConversion(), u"converter"_s);
+ }
}
-void CppGenerator::writeCustomConverterRegister(TextStream &s, const CustomConversion *customConversion,
+void CppGenerator::writeCustomConverterRegister(TextStream &s,
+ const CustomConversionPtr &customConversion,
const QString &converterVar)
{
if (!customConversion)
return;
- const CustomConversion::TargetToNativeConversions &toCppConversions = customConversion->targetToNativeConversions();
+ const TargetToNativeConversions &toCppConversions =
+ customConversion->targetToNativeConversions();
if (toCppConversions.isEmpty())
return;
s << "// Add user defined implicit conversions to type converter.\n";
- for (CustomConversion::TargetToNativeConversion *toNative : toCppConversions) {
+ for (const auto &toNative : toCppConversions) {
QString toCpp = pythonToCppFunctionName(toNative, customConversion->ownerType());
QString isConv = convertibleToCppFunctionName(toNative, customConversion->ownerType());
writeAddPythonToCppConversion(s, converterVar, toCpp, isConv);
@@ -1798,38 +1963,25 @@ void CppGenerator::writeContainerConverterFunctions(TextStream &s,
writePythonToCppConversionFunctions(s, containerType);
}
-void CppGenerator::writeSmartPointerConverterFunctions(TextStream &s,
- const AbstractMetaType &smartPointerType) const
+bool CppGenerator::needsArgumentErrorHandling(const OverloadData &overloadData)
{
- auto targetClass = AbstractMetaClass::findClass(api().classes(),
- smartPointerType.instantiations().at(0).typeEntry());
-
- if (targetClass) {
- const auto *smartPointerTypeEntry =
- static_cast<const SmartPointerTypeEntry *>(
- smartPointerType.typeEntry());
-
- // TODO: Missing conversion to smart pointer pointer type:
-
- s << "// Register smartpointer conversion for all derived classes\n";
- const auto classes = targetClass->typeSystemBaseClasses();
- for (auto k : classes) {
- if (smartPointerTypeEntry->matchesInstantiation(k->typeEntry())) {
- if (auto smartTargetType = findSmartPointerInstantiation(k->typeEntry())) {
- s << "// SmartPointer derived class: "
- << smartTargetType->cppSignature() << "\n";
- writePythonToCppConversionFunctions(s, smartPointerType, smartTargetType.value(), {}, {}, {});
- }
- }
- }
- }
+ if (overloadData.maxArgs() > 0)
+ return true;
+ // QObject constructors need error handling when passing properties as kwarg.
+ if (!usePySideExtensions())
+ return false;
+ auto rfunc = overloadData.referenceFunction();
+ return rfunc->functionType() == AbstractMetaFunction::ConstructorFunction
+ && isQObject(rfunc->ownerClass());
}
-void CppGenerator::writeMethodWrapperPreamble(TextStream &s,const OverloadData &overloadData,
- const GeneratorContext &context) const
+void CppGenerator::writeMethodWrapperPreamble(TextStream &s,
+ const OverloadData &overloadData,
+ const GeneratorContext &context,
+ 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();
@@ -1839,33 +1991,31 @@ 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();
else
qualifiedCppName = context.preciseType().cppSignature();
- s << qualifiedCppName << " >()))\n";
- Indentation indent(s);
- s << returnStatement(m_currentErrorCode) << '\n' << '\n';
+ s << qualifiedCppName << " >()))\n" << indent << errorReturn << outdent << '\n';
}
// Declare pointer for the underlying C++ object.
- s << "::";
- if (!context.forSmartPointer()) {
- s << (context.useWrapper() ? context.wrapperName() : ownerClass->qualifiedCppName());
- } else {
- s << context.smartPointerWrapperName();
- }
- s << " *cptr{};\n";
+ s << globalScopePrefix(context) << context.effectiveClassName() << " *cptr{};\n";
initPythonArguments = maxArgs > 0;
} else {
if (rfunc->implementingClass() &&
(!rfunc->implementingClass()->isNamespace() && overloadData.hasInstanceFunction())) {
- writeCppSelfDefinition(s, rfunc, context, overloadData.hasStaticFunction(),
- overloadData.hasClassMethod());
+ CppSelfDefinitionFlags flags;
+ if (overloadData.hasStaticFunction())
+ flags.setFlag(CppSelfDefinitionFlag::HasStaticOverload);
+ if (overloadData.hasClassMethod())
+ flags.setFlag(CppSelfDefinitionFlag::HasClassMethodOverload);
+ writeCppSelfDefinition(s, rfunc, context, errorReturn, flags);
}
if (!rfunc->isInplaceOperator() && overloadData.hasNonVoidReturnType())
s << "PyObject *" << PYTHON_RETURN_VAR << "{};\n";
@@ -1873,16 +2023,24 @@ void CppGenerator::writeMethodWrapperPreamble(TextStream &s,const OverloadData &
initPythonArguments = minArgs != maxArgs || maxArgs > 1;
}
- 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;
if (overloadData.pythonFunctionWrapperUsesListOfArguments())
s << '[' << maxArgs << ']';
- s << ";\n";
- writeUnusedVariableCast(s, QLatin1String(PYTHON_TO_CPP_VAR));
+ s << ";\n" << sbkUnusedVariableCast(PYTHON_TO_CPP_VAR);
}
if (initPythonArguments) {
@@ -1891,7 +2049,7 @@ static const char *fullName = ")" << fullPythonFunctionName(rfunc, true)
&& !overloadData.pythonFunctionWrapperUsesListOfArguments()) {
s << "(" << PYTHON_ARG << " == 0 ? 0 : 1);\n";
} else {
- writeArgumentsInitializer(s, overloadData);
+ writeArgumentsInitializer(s, overloadData, errorReturn);
}
}
}
@@ -1899,20 +2057,23 @@ static const char *fullName = ")" << fullPythonFunctionName(rfunc, true)
void CppGenerator::writeConstructorWrapper(TextStream &s, const OverloadData &overloadData,
const GeneratorContext &classContext) const
{
- ErrorCode errorCode(-1);
+ 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("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"
@@ -1923,26 +2084,22 @@ 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)) {
- writeUnusedVariableCast(s, QStringLiteral("sbkSelf"));
- writeUnusedVariableCast(s, QStringLiteral("type"));
- writeUnusedVariableCast(s, QStringLiteral("myType"));
+ s << sbkUnusedVariableCast("sbkSelf")
+ << sbkUnusedVariableCast("type")
+ << sbkUnusedVariableCast("myType");
if (needsMetaObject)
- writeUnusedVariableCast(s, QStringLiteral("metaObject"));
- s << "PyErr_SetString(PyExc_NotImplementedError,\n" << indent
- << "\"Abstract class '" << metaClass->qualifiedCppName()
- << "' cannot be instantiated since the wrapper has been disabled.\");\n" << outdent
- << returnStatement(m_currentErrorCode) << outdent
- << "\n}\n\n";
+ s << sbkUnusedVariableCast("metaObject");
+ s << "Shiboken::Errors::setInstantiateAbstractClassDisabledWrapper(\""
+ << metaClass->qualifiedCppName() << "\");\n" << errorReturn << outdent
+ << "}\n\n";
return;
}
// Refuse to instantiate Abstract C++ class (via C++ Wrapper) unless it is
// a Python-derived class for which type != myType.
s << "if (type == myType) {\n" << indent
- << "PyErr_SetString(PyExc_NotImplementedError,\n" << indent
- << "\"'" << metaClass->qualifiedCppName()
- << "' represents a C++ abstract class and cannot be instantiated\");\n" << outdent
- << returnStatement(m_currentErrorCode) << '\n' << outdent
+ << "Shiboken::Errors::setInstantiateAbstractClass(\"" << metaClass->qualifiedCppName()
+ << "\");\n" << errorReturn << outdent
<< "}\n\n";
}
@@ -1955,29 +2112,37 @@ void CppGenerator::writeConstructorWrapper(TextStream &s, const OverloadData &ov
}
// PYSIDE-1478: Switching must also happen at object creation time.
- if (usePySideExtensions())
+ if (usePySideExtensions() && !classContext.forSmartPointer())
s << "PySide::Feature::Select(self);\n";
- writeMethodWrapperPreamble(s, overloadData, classContext);
+ writeMethodWrapperPreamble(s, overloadData, classContext, errorReturn);
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);
+ writeFunctionCalls(s, overloadData, classContext, errorReturn);
s << '\n';
- s << "if (PyErr_Occurred() || !Shiboken::Object::setCppPointer(sbkSelf, Shiboken::SbkType< ::"
- << metaClass->qualifiedCppName() << " >(), cptr)) {\n";
- {
- Indentation indent(s);
- s << "delete cptr;\n";
- s << returnStatement(m_currentErrorCode) << '\n';
- }
- s << "}\n";
+ const QString typeName = classContext.forSmartPointer()
+ ? classContext.preciseType().cppSignature() : metaClass->qualifiedCppName();
+ 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
@@ -1988,24 +2153,20 @@ void CppGenerator::writeConstructorWrapper(TextStream &s, const OverloadData &ov
s << "Shiboken::Object::setHasCppWrapper(sbkSelf, true);\n";
// Need to check if a wrapper for same pointer is already registered
// Caused by bug PYSIDE-217, where deleted objects' wrappers are not released
- s << "if (Shiboken::BindingManager::instance().hasWrapper(cptr)) {\n";
- {
- Indentation indent(s);
- s << "Shiboken::BindingManager::instance().releaseWrapper("
- "Shiboken::BindingManager::instance().retrieveWrapper(cptr));\n";
- }
- s << "}\nShiboken::BindingManager::instance().registerWrapper(sbkSelf, cptr);\n";
+ s << "if (Shiboken::BindingManager::instance().hasWrapper(cptr)) {\n" << indent
+ << "Shiboken::BindingManager::instance().releaseWrapper("
+ "Shiboken::BindingManager::instance().retrieveWrapper(cptr));\n" << outdent
+ << "}\nShiboken::BindingManager::instance().registerWrapper(sbkSelf, cptr);\n";
// Create metaObject and register signal/slot
- bool errHandlerNeeded = overloadData.maxArgs() > 0;
if (needsMetaObject) {
- errHandlerNeeded = true;
s << "\n// QObject setup\n"
<< "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";
}
@@ -2022,31 +2183,27 @@ void CppGenerator::writeConstructorWrapper(TextStream &s, const OverloadData &ov
}
if (hasCodeInjectionsAtEnd) {
// FIXME: C++ arguments are not available in code injection on constructor when position = end.
- s <<"switch (overloadId) {\n";
+ s << "switch (overloadId) {\n";
for (const auto &func : overloadData.overloads()) {
- Indentation indent(s);
+ s << indent;
const CodeSnipList &injectedCodeSnips = func->injectedCodeSnips();
for (const CodeSnip &cs : injectedCodeSnips) {
if (cs.position == TypeSystem::CodeSnipPositionEnd) {
s << "case " << metaClass->functions().indexOf(func) << ':' << '\n'
- << "{\n";
- {
- Indentation indent(s);
- writeCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionEnd,
- TypeSystem::TargetLangCode, func,
- true /* usesPyArgs */, nullptr);
- }
- s << "}\nbreak;\n";
+ << "{\n" << indent;
+ writeCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionEnd,
+ TypeSystem::TargetLangCode, func,
+ true /* usesPyArgs */, nullptr);
+ s << outdent << "}\nbreak;\n";
break;
}
}
+ s << outdent;
}
s << "}\n";
}
s << "\n\nreturn 1;\n";
- if (errHandlerNeeded)
- writeErrorSection(s, overloadData);
s<< outdent << "}\n\n";
}
@@ -2059,89 +2216,71 @@ void CppGenerator::writeMethodWrapper(TextStream &s, const OverloadData &overloa
s << "static PyObject *";
s << cpythonFunctionName(rfunc) << "(PyObject *self";
+ bool hasKwdArgs = false;
if (maxArgs > 0) {
- s << ", PyObject *" << (overloadData.pythonFunctionWrapperUsesListOfArguments() ? "args" : PYTHON_ARG);
- if (overloadData.hasArgumentWithDefaultValue() || rfunc->isCallOperator())
+ s << ", PyObject *"
+ << (overloadData.pythonFunctionWrapperUsesListOfArguments() ? u"args"_s : PYTHON_ARG);
+ hasKwdArgs = overloadData.hasArgumentWithDefaultValue() || rfunc->isCallOperator();
+ if (hasKwdArgs)
s << ", PyObject *kwds";
}
s << ")\n{\n" << indent;
+ if (rfunc->ownerClass() == nullptr || overloadData.hasStaticFunction())
+ s << sbkUnusedVariableCast(PYTHON_SELF_VAR);
+ if (hasKwdArgs)
+ s << sbkUnusedVariableCast("kwds");
writeMethodWrapperPreamble(s, overloadData, classContext);
s << '\n';
- /*
- * This code is intended for shift operations only:
- * Make sure reverse <</>> operators defined in other classes (specially from other modules)
- * are called. A proper and generic solution would require an reengineering in the operator
- * system like the extended converters.
- *
- * Solves #119 - QDataStream <</>> operators not working for QPixmap
- * http://bugs.openbossa.org/show_bug.cgi?id=119
- */
- bool hasReturnValue = overloadData.hasNonVoidReturnType();
- bool callExtendedReverseOperator = hasReturnValue
- && !rfunc->isInplaceOperator()
- && !rfunc->isCallOperator()
- && rfunc->isOperatorOverload();
-
- QScopedPointer<Indentation> reverseIndent;
-
- if (callExtendedReverseOperator) {
- QString revOpName = ShibokenGenerator::pythonOperatorFunctionName(rfunc).insert(2, QLatin1Char('r'));
+ // This code is intended for shift operations only: Make sure reverse <</>>
+ // operators defined in other classes (specially from other modules)
+ // are called. A proper and generic solution would require an reengineering
+ // in the operator system like the extended converters.
+ // Solves #119 - QDataStream <</>> operators not working for QPixmap.
+ const bool hasReturnValue = overloadData.hasNonVoidReturnType();
+
+ if (hasReturnValue && rfunc->functionType() == AbstractMetaFunction::ShiftOperator
+ && rfunc->isBinaryOperator()) {
// For custom classes, operations like __radd__ and __rmul__
// will enter an infinite loop.
- if (rfunc->isBinaryOperator() && revOpName.contains(QLatin1String("shift"))) {
- s << "Shiboken::AutoDecRef attrName(Py_BuildValue(\"s\", \"" << revOpName << "\"));\n";
- s << "if (!isReverse\n";
- {
- Indentation indent(s);
- s << "&& Shiboken::Object::checkType(" << PYTHON_ARG << ")\n"
- << "&& !PyObject_TypeCheck(" << PYTHON_ARG << ", self->ob_type)\n"
- << "&& PyObject_HasAttr(" << PYTHON_ARG << ", attrName)) {\n";
-
- // This PyObject_CallMethod call will emit lots of warnings like
- // "deprecated conversion from string constant to char *" during compilation
- // due to the method name argument being declared as "char *" instead of "const char *"
- // issue 6952 http://bugs.python.org/issue6952
- s << "PyObject *revOpMethod = PyObject_GetAttr(" << PYTHON_ARG << ", attrName);\n";
- s << "if (revOpMethod && PyCallable_Check(revOpMethod)) {\n";
- {
- Indentation indent(s);
- s << PYTHON_RETURN_VAR << " = PyObject_CallFunction(revOpMethod, \"O\", self);\n"
- << "if (PyErr_Occurred() && (PyErr_ExceptionMatches(PyExc_NotImplementedError)"
- << " || PyErr_ExceptionMatches(PyExc_AttributeError))) {\n";
- {
- Indentation indent(s);
- s << "PyErr_Clear();\n"
- << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");\n"
- << PYTHON_RETURN_VAR << " = " << NULL_PTR << ";\n";
- }
- s << "}\n";
- }
- s << "}\n"
- << "Py_XDECREF(revOpMethod);\n\n";
- } //
- s << "}\n\n"
- << "// Do not enter here if other object has implemented a reverse operator.\n"
- << "if (!" << PYTHON_RETURN_VAR << ") {\n";
- reverseIndent.reset(new Indentation(s));
- } // binary shift operator
- }
-
- if (maxArgs > 0)
- writeOverloadedFunctionDecisor(s, overloadData);
-
- writeFunctionCalls(s, overloadData, classContext);
-
- if (!reverseIndent.isNull()) { // binary shift operator
- reverseIndent.reset();
- s << '\n' << "} // End of \"if (!" << PYTHON_RETURN_VAR << ")\"\n";
+ const QString pythonOp = ShibokenGenerator::pythonOperatorFunctionName(rfunc);
+ s << "static PyObject *attrName = Shiboken::PyMagicName::r"
+ << pythonOp.mid(2, pythonOp.size() -4) << "();\n" // Strip __
+ << "if (!isReverse\n" << indent
+ << "&& Shiboken::Object::checkType(" << PYTHON_ARG << ")\n"
+ << "&& !PyObject_TypeCheck(" << PYTHON_ARG << ", self->ob_type)\n"
+ << "&& PyObject_HasAttr(" << PYTHON_ARG << ", attrName)) {\n"
+ << "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 (" << shibokenErrorsOccurred
+ << " && (PyErr_ExceptionMatches(PyExc_NotImplementedError)"
+ << " || PyErr_ExceptionMatches(PyExc_AttributeError))) {\n" << indent
+ << "PyErr_Clear();\n"
+ << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");\n"
+ << PYTHON_RETURN_VAR << " = " << NULL_PTR << ";\n"
+ << outdent << "}\n"
+ << outdent << "}\n"
+ << "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 << " == nullptr) {\n" << indent;
+ if (maxArgs > 0)
+ 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, ErrorReturn::Default);
+ writeFunctionCalls(s, overloadData, classContext, ErrorReturn::Default);
}
s << '\n';
- writeFunctionReturnErrorCheckSection(s, hasReturnValue && !rfunc->isInplaceOperator());
+ writeFunctionReturnErrorCheckSection(s, ErrorReturn::Default,
+ hasReturnValue && !rfunc->isInplaceOperator());
if (hasReturnValue) {
if (rfunc->isInplaceOperator()) {
@@ -2153,24 +2292,21 @@ void CppGenerator::writeMethodWrapper(TextStream &s, const OverloadData &overloa
s << "Py_RETURN_NONE;\n";
}
- if (maxArgs > 0)
- writeErrorSection(s, overloadData);
-
s<< outdent << "}\n\n";
}
-void CppGenerator::writeArgumentsInitializer(TextStream &s, const OverloadData &overloadData)
+void CppGenerator::writeArgumentsInitializer(TextStream &s, const OverloadData &overloadData,
+ ErrorReturn errorReturn)
{
const auto rfunc = overloadData.referenceFunction();
- s << "PyTuple_GET_SIZE(args);\n";
- writeUnusedVariableCast(s, QLatin1String("numArgs"));
+ s << "PyTuple_GET_SIZE(args);\n" << sbkUnusedVariableCast("numArgs");
int minArgs = overloadData.minArgs();
int maxArgs = overloadData.maxArgs();
s << "PyObject *";
s << PYTHON_ARGS << "[] = {"
- << QString(maxArgs, QLatin1Char('0')).split(QLatin1String(""), Qt::SkipEmptyParts).join(QLatin1String(", "))
+ << QByteArrayList(maxArgs, "nullptr").join(", ")
<< "};\n\n";
if (overloadData.hasVarargs()) {
@@ -2189,47 +2325,34 @@ void CppGenerator::writeArgumentsInitializer(TextStream &s, const OverloadData &
bool usesNamedArguments = overloadData.hasArgumentWithDefaultValue();
s << "// invalid argument lengths\n";
- bool ownerClassIsQObject = rfunc->ownerClass() && rfunc->ownerClass()->isQObject() && rfunc->isConstructor();
- if (usesNamedArguments) {
- if (!ownerClassIsQObject) {
- s << "if (numArgs > " << maxArgs << ") {\n";
- {
- Indentation indent(s);
- s << "static PyObject *const too_many = "
- "Shiboken::String::createStaticString(\">\");\n"
- << "errInfo.reset(too_many);\n"
- << "Py_INCREF(errInfo.object());\n"
- << "goto " << cpythonFunctionName(rfunc) << "_TypeError;\n";
- }
- s << '}';
- }
- if (minArgs > 0) {
- if (!ownerClassIsQObject)
- s << " else ";
- s << "if (numArgs < " << minArgs << ") {\n";
- {
- Indentation indent(s);
- s << "static PyObject *const too_few = "
- "Shiboken::String::createStaticString(\"<\");\n"
- << "errInfo.reset(too_few);\n"
- << "Py_INCREF(errInfo.object());\n"
- << "goto " << cpythonFunctionName(rfunc) << "_TypeError;\n";
- }
- s << '}';
- }
+
+ // Disable argument count checks for QObject constructors to allow for
+ // passing properties as KW args.
+ 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
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n"
+ << outdent;
}
+
const QList<int> invalidArgsLength = overloadData.invalidArgumentLengths();
if (!invalidArgsLength.isEmpty()) {
- QStringList invArgsLen;
- for (int i : qAsConst(invalidArgsLength))
- invArgsLen << u"numArgs == "_qs + QString::number(i);
- if (usesNamedArguments && (!ownerClassIsQObject || minArgs > 0))
- s << " else ";
- s << "if (" << invArgsLen.join(QLatin1String(" || ")) << ")\n";
- Indentation indent(s);
- s << "goto " << cpythonFunctionName(rfunc) << "_TypeError;";
+ s << "if (";
+ for (qsizetype i = 0, size = invalidArgsLength.size(); i < size; ++i) {
+ if (i)
+ s << " || ";
+ s << "numArgs == " << invalidArgsLength.at(i);
+ }
+ s << ")\n" << indent
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n"
+ << outdent;
}
- s << "\n\n";
+ s << '\n';
QString funcName;
if (rfunc->isOperatorOverload())
@@ -2237,8 +2360,8 @@ void CppGenerator::writeArgumentsInitializer(TextStream &s, const OverloadData &
else
funcName = rfunc->name();
- QString argsVar = overloadData.hasVarargs() ? QLatin1String("nonvarargs") : QLatin1String("args");
- s << "if (!";
+ QString argsVar = overloadData.hasVarargs() ? u"nonvarargs"_s : u"args"_s;
+ s << "if (";
if (usesNamedArguments) {
s << "PyArg_ParseTuple(" << argsVar << ", \"|" << QByteArray(maxArgs, 'O')
<< ':' << funcName << '"';
@@ -2248,156 +2371,156 @@ void CppGenerator::writeArgumentsInitializer(TextStream &s, const OverloadData &
}
for (int i = 0; i < maxArgs; i++)
s << ", &(" << PYTHON_ARGS << '[' << i << "])";
- s << "))\n";
- {
- Indentation indent(s);
- s << returnStatement(m_currentErrorCode) << '\n';
- }
- s << '\n';
+ s << ") == 0)\n" << indent << errorReturn << outdent << '\n';
}
void CppGenerator::writeCppSelfConversion(TextStream &s, const GeneratorContext &context,
const QString &className, bool useWrapperClass)
{
- static const QString pythonSelfVar = QLatin1String("self");
+ if (context.forSmartPointer()) {
+ writeSmartPointerCppSelfConversion(s, context);
+ return;
+ }
+
if (useWrapperClass)
s << "static_cast<" << className << " *>(";
- if (!context.forSmartPointer())
- s << cpythonWrapperCPtr(context.metaClass(), pythonSelfVar);
- else
- s << cpythonWrapperCPtr(context.preciseType(), pythonSelfVar);
+ s << cpythonWrapperCPtr(context.metaClass(), PYTHON_SELF_VAR);
if (useWrapperClass)
s << ')';
}
+void CppGenerator::writeCppSelfVarDef(TextStream &s,
+ CppSelfDefinitionFlags flags)
+{
+ if (flags.testFlag(CppGenerator::CppSelfAsReference))
+ s << "auto &" << CPP_SELF_VAR << " = *";
+ else
+ s << "auto *" << CPP_SELF_VAR << " = ";
+}
+
void CppGenerator::writeCppSelfDefinition(TextStream &s,
const GeneratorContext &context,
- bool hasStaticOverload,
- bool hasClassMethodOverload,
- bool cppSelfAsReference) const
+ ErrorReturn errorReturn,
+ CppSelfDefinitionFlags flags)
{
- Q_ASSERT(!(cppSelfAsReference && hasStaticOverload));
+ Q_ASSERT(!(flags.testFlag(CppSelfAsReference) && flags.testFlag(HasStaticOverload)));
+ if (context.forSmartPointer()) {
+ writeSmartPointerCppSelfDefinition(s, context, errorReturn, flags);
+ 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.
const bool useWrapperClass = avoidProtectedHack()
&& cppWrapper.testFlag(AbstractMetaClass::CppProtectedHackWrapper);
Q_ASSERT(!useWrapperClass || context.useWrapper());
- QString className;
- if (!context.forSmartPointer()) {
- className = useWrapperClass
- ? context.wrapperName()
- : (QLatin1String("::") + metaClass->qualifiedCppName());
- } else {
- className = context.smartPointerWrapperName();
- }
+ const QString className = useWrapperClass
+ ? context.wrapperName() : getFullTypeName(metaClass);
- writeInvalidPyObjectCheck(s, QLatin1String("self"));
+ writeInvalidPyObjectCheck(s, PYTHON_SELF_VAR, errorReturn);
- if (cppSelfAsReference) {
- s << "auto &" << CPP_SELF_VAR << " = *";
+ if (flags.testFlag(CppSelfAsReference)) {
+ writeCppSelfVarDef(s, flags);
writeCppSelfConversion(s, context, className, useWrapperClass);
s << ";\n";
return;
}
- if (!hasStaticOverload) {
- if (!hasClassMethodOverload) {
+ if (!flags.testFlag(HasStaticOverload)) {
+ if (!flags.testFlag(HasClassMethodOverload)) {
// PYSIDE-131: The single case of a class method for now: tr().
- s << "auto " << CPP_SELF_VAR << " = ";
+ writeCppSelfVarDef(s, flags);
writeCppSelfConversion(s, context, className, useWrapperClass);
- s << ";\n";
- writeUnusedVariableCast(s, QLatin1String(CPP_SELF_VAR));
+ s << ";\n" << sbkUnusedVariableCast(CPP_SELF_VAR);
}
return;
}
- s << className << " *" << CPP_SELF_VAR << " = nullptr;\n";
- writeUnusedVariableCast(s, QLatin1String(CPP_SELF_VAR));
+ s << className << " *" << CPP_SELF_VAR << " = nullptr;\n"
+ << sbkUnusedVariableCast(CPP_SELF_VAR);
// Checks if the underlying C++ object is valid.
- s << "if (self)\n";
- {
- Indentation indent(s);
- s << CPP_SELF_VAR << " = ";
- writeCppSelfConversion(s, context, className, useWrapperClass);
- s << ";\n";
- }
+ s << "if (self)\n" << indent
+ << CPP_SELF_VAR << " = ";
+ writeCppSelfConversion(s, context, className, useWrapperClass);
+ s << ";\n"<< outdent;
}
void CppGenerator::writeCppSelfDefinition(TextStream &s,
const AbstractMetaFunctionCPtr &func,
const GeneratorContext &context,
- bool hasStaticOverload,
- bool hasClassMethodOverload) const
+ ErrorReturn errorReturn,
+ CppSelfDefinitionFlags flags)
{
if (!func->ownerClass() || func->isConstructor())
return;
if (func->isOperatorOverload() && func->isBinaryOperator()) {
QString checkFunc = cpythonCheckFunction(func->ownerClass()->typeEntry());
- s << "bool isReverse = " << checkFunc << PYTHON_ARG << ")\n";
- {
- Indentation indent1(s, 4);
- s << "&& !" << checkFunc << "self);\n";
- }
- s << "if (isReverse)\n";
- Indentation indent(s);
- s << "std::swap(self, " << PYTHON_ARG << ");\n";
+ s << "bool isReverse = " << checkFunc << PYTHON_ARG << ")\n"
+ << " && !" << checkFunc << "self);\n"
+ << "if (isReverse)\n" << indent
+ << "std::swap(self, " << PYTHON_ARG << ");\n" << outdent;
}
- writeCppSelfDefinition(s, context, hasStaticOverload, hasClassMethodOverload);
+ writeCppSelfDefinition(s, context, errorReturn, flags);
}
-void CppGenerator::writeErrorSection(TextStream &s, const OverloadData &overloadData)
+QString CppGenerator::returnErrorWrongArguments(const OverloadData &overloadData,
+ ErrorReturn errorReturn)
{
const auto rfunc = overloadData.referenceFunction();
- s << '\n' << cpythonFunctionName(rfunc) << "_TypeError:\n";
- Indentation indentation(s);
QString argsVar = overloadData.pythonFunctionWrapperUsesListOfArguments()
- ? QLatin1String("args") : QLatin1String(PYTHON_ARG);
- s << "Shiboken::setErrorAboutWrongArguments(" << argsVar << ", fullName, errInfo);\n"
- << "return " << m_currentErrorCode << ";\n";
+ ? u"args"_s : PYTHON_ARG;
+ 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, bool hasReturnValue)
+void CppGenerator::writeFunctionReturnErrorCheckSection(TextStream &s,
+ ErrorReturn errorReturn,
+ bool hasReturnValue)
{
- s << "if (PyErr_Occurred()";
+ s << "if (" << shibokenErrorsOccurred;
if (hasReturnValue)
- s << " || !" << PYTHON_RETURN_VAR;
- s << ") {\n";
- {
- Indentation indent(s);
- if (hasReturnValue)
- s << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");\n";
- s << returnStatement(m_currentErrorCode) << '\n';
- }
- s << "}\n";
+ s << " || " << PYTHON_RETURN_VAR << " == nullptr";
+ s << ") {\n" << indent;
+ if (hasReturnValue)
+ s << "Py_XDECREF(" << PYTHON_RETURN_VAR << ");\n";
+ s << errorReturn << outdent << "}\n";
}
-void CppGenerator::writeInvalidPyObjectCheck(TextStream &s, const QString &pyObj)
+void CppGenerator::writeInvalidPyObjectCheck(TextStream &s, const QString &pyObj,
+ ErrorReturn errorReturn)
{
- s << "if (!Shiboken::Object::isValid(" << pyObj << "))\n";
- Indentation indent(s);
- s << returnStatement(m_currentErrorCode) << '\n';
+ s << "if (!Shiboken::Object::isValid(" << pyObj << "))\n"
+ << indent << errorReturn << outdent;
}
static QString pythonToCppConverterForArgumentName(const QString &argumentName)
{
- static const QRegularExpression pyArgsRegex(QLatin1String(PYTHON_ARGS)
- + QLatin1String(R"((\[\d+[-]?\d*\]))"));
+ static const QRegularExpression pyArgsRegex(PYTHON_ARGS
+ + uR"((\[\d+[-]?\d*\]))"_s);
Q_ASSERT(pyArgsRegex.isValid());
const QRegularExpressionMatch match = pyArgsRegex.match(argumentName);
- QString result = QLatin1String(PYTHON_TO_CPP_VAR);
+ QString result = PYTHON_TO_CPP_VAR;
if (match.hasMatch())
result += match.captured(1);
return result;
}
void CppGenerator::writeTypeCheck(TextStream &s, const QString &customType,
- const QString &argumentName) const
+ const QString &argumentName)
{
QString errorMessage;
const auto metaTypeOpt = AbstractMetaType::fromString(customType, &errorMessage);
@@ -2409,7 +2532,7 @@ void CppGenerator::writeTypeCheck(TextStream &s, const QString &customType,
void CppGenerator::writeTypeCheck(TextStream &s, const AbstractMetaType &argType,
const QString &argumentName, bool isNumber,
- bool rejectNull) const
+ bool rejectNull)
{
// TODO-CONVERTER: merge this with the code below.
QString typeCheck = cpythonIsConvertibleFunction(argType);
@@ -2419,16 +2542,16 @@ void CppGenerator::writeTypeCheck(TextStream &s, const AbstractMetaType &argType
// TODO-CONVERTER -----------------------------------------------------------------------
if (!argType.typeEntry()->isCustom()) {
typeCheck = u'(' + pythonToCppConverterForArgumentName(argumentName)
- + u" = "_qs + typeCheck + u"))"_qs;
- if (!isNumber && argType.typeEntry()->isCppPrimitive()) {
+ + u" = "_s + typeCheck + u"))"_s;
+ if (!isNumber && isCppPrimitive(argType.typeEntry())) {
typeCheck.prepend(cpythonCheckFunction(argType) + u'('
- + argumentName + u") && "_qs);
+ + argumentName + u") && "_s);
}
}
// TODO-CONVERTER -----------------------------------------------------------------------
if (rejectNull)
- typeCheck = u'(' + argumentName + u" != Py_None && "_qs + typeCheck + u')';
+ typeCheck = u'(' + argumentName + u" != Py_None && "_s + typeCheck + u')';
s << typeCheck;
}
@@ -2449,7 +2572,7 @@ static void checkTypeViability(const AbstractMetaFunctionCPtr &func,
|| type.isCString()
|| isRemoved
|| modified
- || !func->conversionRule(TypeSystem::All, argIdx).isEmpty()
+ || func->hasConversionRule(TypeSystem::All, argIdx)
|| func->hasInjectedCode())
return;
QString message;
@@ -2473,15 +2596,15 @@ static void checkTypeViability(const AbstractMetaFunctionCPtr &func)
if (func->isUserAdded())
return;
checkTypeViability(func, func->type(), 0);
- for (int i = 0; i < func->arguments().count(); ++i)
- checkTypeViability(func, func->arguments().at(i).type(), i + 1);
+ for (qsizetype i = 0; i < func->arguments().size(); ++i)
+ checkTypeViability(func, func->arguments().at(i).type(), int(i + 1));
}
void CppGenerator::writeTypeCheck(TextStream &s,
- const QSharedPointer<OverloadDataNode> &overloadData,
- const QString &argumentName) const
+ const std::shared_ptr<OverloadDataNode> &overloadData,
+ const QString &argumentName)
{
- QSet<const TypeEntry *> numericTypes;
+ QSet<TypeEntryCPtr> numericTypes;
const OverloadDataList &siblings = overloadData->parent()->children();
for (const auto &sibling : siblings) {
for (const auto &func : sibling->overloads()) {
@@ -2499,26 +2622,30 @@ void CppGenerator::writeTypeCheck(TextStream &s,
AbstractMetaType argType = overloadData->modifiedArgType();
if (auto viewOn = argType.viewOn())
argType = *viewOn;
- bool numberType = numericTypes.count() == 1 || ShibokenGenerator::isPyInt(argType);
+ const bool numberType = numericTypes.size() == 1 || ShibokenGenerator::isPyInt(argType);
bool rejectNull =
shouldRejectNullPointerArgument(overloadData->referenceFunction(), overloadData->argPos());
writeTypeCheck(s, argType, argumentName, numberType, rejectNull);
}
-void CppGenerator::writeArgumentConversion(TextStream &s,
- const AbstractMetaType &argType,
- const QString &argName, const QString &pyArgName,
- const AbstractMetaClass *context,
- const QString &defaultValue,
- bool castArgumentAsUnused) const
+qsizetype CppGenerator::writeArgumentConversion(TextStream &s,
+ const AbstractMetaType &argType,
+ const QString &argName,
+ const QString &pyArgName,
+ ErrorReturn errorReturn,
+ const AbstractMetaClassCPtr &context,
+ const QString &defaultValue,
+ bool castArgumentAsUnused) const
{
+ qsizetype result = 0;
if (argType.typeEntry()->isCustom() || argType.typeEntry()->isVarargs())
- return;
+ return result;
if (argType.isWrapperType())
- writeInvalidPyObjectCheck(s, pyArgName);
- writePythonToCppTypeConversion(s, argType, pyArgName, argName, context, defaultValue);
+ writeInvalidPyObjectCheck(s, pyArgName, errorReturn);
+ result = writePythonToCppTypeConversion(s, argType, pyArgName, argName, context, defaultValue);
if (castArgumentAsUnused)
- writeUnusedVariableCast(s, argName);
+ s << sbkUnusedVariableCast(argName);
+ return result;
}
AbstractMetaType
@@ -2538,15 +2665,14 @@ static inline QString arrayHandleType(const AbstractMetaTypeList &nestedArrayTyp
{
switch (nestedArrayTypes.size()) {
case 1:
- return QStringLiteral("Shiboken::Conversions::ArrayHandle<")
- + nestedArrayTypes.constLast().minimalSignature()
- + QLatin1Char('>');
+ 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())
- + QLatin1Char('>');
+ + u'>';
}
return QString();
}
@@ -2579,71 +2705,52 @@ static void writeMinimalConstructorExpression(TextStream &s,
s << '(' << defaultValue << ')';
}
-void CppGenerator::writePythonToCppTypeConversion(TextStream &s,
+qsizetype CppGenerator::writePythonToCppTypeConversion(TextStream &s,
const AbstractMetaType &type,
const QString &pyIn,
const QString &cppOut,
- const AbstractMetaClass *context,
- const QString &defaultValue,
- PythonToCppTypeConversionFlags flags) const
+ const AbstractMetaClassCPtr &context,
+ const QString &defaultValue) const
{
- const TypeEntry *typeEntry = type.typeEntry();
+ TypeEntryCPtr typeEntry = type.typeEntry();
if (typeEntry->isCustom() || typeEntry->isVarargs())
- return;
+ return 0;
+
+ const auto arg = GeneratorArgument::fromMetaType(type);
+ const bool isPrimitive = arg.type == GeneratorArgument::Type::Primitive;
- QString cppOutAux = cppOut + QLatin1String("_local");
-
- const bool isPrimitive = typeEntry->isPrimitive();
- const bool isEnum = typeEntry->isEnum();
- const bool isFlags = typeEntry->isFlags();
- const bool treatAsPointer = type.valueTypeWithCopyConstructorOnlyPassed();
- const bool maybeOpaqueContainer =
- !flags.testFlag(PythonToCppTypeConversionFlag::DisableOpaqueContainers)
- && type.generateOpaqueContainer();
- bool isPointerOrObjectType = (type.isObjectType() || type.isPointer())
- && !type.isUserPrimitive() && !type.isExtendedCppPrimitive()
- && !isEnum && !isFlags;
- const bool isNotContainerEnumOrFlags = !typeEntry->isContainer()
- && !isEnum && !isFlags;
- const bool mayHaveImplicitConversion = type.referenceType() == LValueReference
- && !type.isUserPrimitive()
- && !type.isExtendedCppPrimitive()
- && isNotContainerEnumOrFlags
- && !(treatAsPointer || isPointerOrObjectType);
-
- // For implicit conversions or containers, either value or pointer conversion
- // may occur. An implicit conversion uses value conversion whereas the object
- // itself uses pointer conversion. For containers, the PyList/container
- // conversion is by value whereas opaque containers use pointer conversion.
- const bool valueOrPointer = mayHaveImplicitConversion || maybeOpaqueContainer;
-
- const AbstractMetaTypeList &nestedArrayTypes = type.nestedArrayTypes();
- const bool isCppPrimitiveArray = !nestedArrayTypes.isEmpty()
- && nestedArrayTypes.constLast().isCppPrimitive();
- QString typeName = isCppPrimitiveArray
- ? arrayHandleType(nestedArrayTypes)
- : getFullTypeNameWithoutModifiers(type);
+ QString cppOutAux = cppOut + u"_local"_s;
+
+ QString typeName = arg.type == GeneratorArgument::Type::CppPrimitiveArray
+ ? arrayHandleType(type.nestedArrayTypes())
+ : getFullTypeNameWithoutModifiers(type);
bool isProtectedEnum = false;
- if (isEnum && avoidProtectedHack()) {
+ if (arg.type == GeneratorArgument::Type::Enum && avoidProtectedHack()) {
auto metaEnum = api().findAbstractMetaEnum(type.typeEntry());
if (metaEnum.has_value() && metaEnum->isProtected()) {
- typeName = wrapperName(context) + QLatin1String("::")
+ typeName = wrapperName(context) + u"::"_s
+ metaEnum.value().name();
isProtectedEnum = true;
}
}
s << typeName;
- if (isCppPrimitiveArray) {
+ switch (arg.conversion) {
+ case GeneratorArgument::Conversion::CppPrimitiveArray:
s << ' ' << cppOut;
- } else if (valueOrPointer) {
+ break;
+ case GeneratorArgument::Conversion::ValueOrPointer: {
// Generate either value conversion for &cppOutAux or pointer
// conversion for &cppOut
s << ' ' << cppOutAux;
- writeMinimalConstructorExpression(s, api(), type, isPrimitive, defaultValue);
+ // No default value for containers which can also be passed by pointer.
+ if (arg.type != GeneratorArgument::Type::Container || type.indirections() == 0)
+ writeMinimalConstructorExpression(s, api(), type, isPrimitive, defaultValue);
s << ";\n" << typeName << " *" << cppOut << " = &" << cppOutAux;
- } else if (treatAsPointer || isPointerOrObjectType) {
+ }
+ break;
+ case GeneratorArgument::Conversion::Pointer: {
s << " *" << cppOut;
if (!defaultValue.isEmpty()) {
const bool needsConstCast = !isNullPtr(defaultValue)
@@ -2656,7 +2763,9 @@ void CppGenerator::writePythonToCppTypeConversion(TextStream &s,
if (needsConstCast)
s << ')';
}
- } else {
+ }
+ break;
+ case GeneratorArgument::Conversion::Default:
s << ' ' << cppOut;
if (isProtectedEnum && avoidProtectedHack()) {
s << " = ";
@@ -2664,19 +2773,22 @@ void CppGenerator::writePythonToCppTypeConversion(TextStream &s,
s << "{}";
else
s << defaultValue;
- } else if (type.isUserPrimitive() || isEnum || isFlags) {
+ } else if (type.isUserPrimitive()
+ || 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;
}
s << ";\n";
QString pythonToCppFunc = pythonToCppConverterForArgumentName(pyIn);
- QString pythonToCppCall = pythonToCppFunc + u'(' + pyIn + u", &"_qs
+ QString pythonToCppCall = pythonToCppFunc + u'(' + pyIn + u", &"_s
+ cppOut + u')';
- if (!valueOrPointer) {
+ if (arg.conversion != GeneratorArgument::Conversion::ValueOrPointer) {
// pythonToCppFunc may be 0 when less parameters are passed and
// the defaultValue takes effect.
if (!defaultValue.isEmpty())
@@ -2684,7 +2796,7 @@ void CppGenerator::writePythonToCppTypeConversion(TextStream &s,
s << pythonToCppCall << ";\n";
if (!defaultValue.isEmpty())
s << outdent;
- return;
+ return arg.indirections;
}
// pythonToCppFunc may be 0 when less parameters are passed and
@@ -2701,6 +2813,8 @@ void CppGenerator::writePythonToCppTypeConversion(TextStream &s,
s << '\n';
else
s << "}\n" << outdent;
+
+ return arg.indirections;
}
static void addConversionRuleCodeSnippet(CodeSnipList &snippetList, QString &rule,
@@ -2712,10 +2826,10 @@ static void addConversionRuleCodeSnippet(CodeSnipList &snippetList, QString &rul
if (rule.isEmpty())
return;
if (snippetLanguage == TypeSystem::TargetLangCode) {
- rule.replace(QLatin1String("%in"), inputName);
- rule.replace(QLatin1String("%out"), outputName + QLatin1String("_out"));
+ rule.replace(u"%in"_s, inputName);
+ rule.replace(u"%out"_s, outputName + u"_out"_s);
} else {
- rule.replace(QLatin1String("%out"), outputName);
+ rule.replace(u"%out"_s, outputName);
}
CodeSnip snip(snippetLanguage);
snip.position = (snippetLanguage == TypeSystem::NativeCode) ? TypeSystem::CodeSnipPositionAny : TypeSystem::CodeSnipPositionBeginning;
@@ -2758,17 +2872,19 @@ 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();
const AbstractMetaFunctionCList &functionOverloads = overloadData.overloads();
- for (int i = 0; i < functionOverloads.count(); i++) {
+ for (qsizetype i = 0; i < functionOverloads.size(); ++i) {
const auto func = functionOverloads.at(i);
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';
}
@@ -2778,18 +2894,16 @@ void CppGenerator::writeOverloadedFunctionDecisor(TextStream &s, const OverloadD
// Ensure that the direct overload that called this reverse
// is called.
if (rfunc->isOperatorOverload() && !rfunc->isCallOperator()) {
- s << "if (isReverse && overloadId == -1) {\n";
- {
- Indentation indent(s);
- s << "PyErr_SetString(PyExc_NotImplementedError, \"reverse operator not implemented.\");\n"
- << "return {};\n";
- }
- s << "}\n\n";
+ s << "if (isReverse && overloadId == -1) {\n" << indent
+ << "Shiboken::Errors::setReverseOperatorNotImplemented();\n"
+ << "return {};\n" << outdent
+ << "}\n\n";
}
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,
@@ -2851,21 +2965,17 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
if (hasDefaultCall) {
isFirst = false;
int numArgs = node->argPos() + 1;
- s << "if (numArgs == " << numArgs << ") {\n";
- {
- Indentation indent(s);
- auto func = referenceFunction;
- for (const auto &child : children) {
- const auto defValFunc = child->getFunctionWithDefaultValue();
- if (!defValFunc.isNull()) {
- func = defValFunc;
- break;
- }
+ s << "if (numArgs == " << numArgs << ") {\n" << indent;
+ auto func = referenceFunction;
+ for (const auto &child : children) {
+ const auto defValFunc = child->getFunctionWithDefaultValue();
+ if (defValFunc) {
+ func = defValFunc;
+ break;
}
- s << "overloadId = " << overloadData.functionNumber(func)
- << "; // " << func->minimalSignature() << '\n';
}
- s << '}';
+ s << "overloadId = " << overloadData.functionNumber(func)
+ << "; // " << func->minimalSignature() << '\n' << outdent << '}';
}
for (auto child : children) {
@@ -2879,27 +2989,26 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
QString pyArgName = (usePyArgs && maxArgs > 1)
? pythonArgsAt(child->argPos())
- : QLatin1String(PYTHON_ARG);
+ : PYTHON_ARG;
auto od = child;
int startArg = od->argPos();
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());
StringStream tck(TextStream::Language::Cpp);
auto func = od->referenceFunction();
- if (func->isConstructor() && func->arguments().count() == 1) {
- const AbstractMetaClass *ownerClass = func->ownerClass();
- const ComplexTypeEntry *baseContainerType = ownerClass->typeEntry()->baseContainerType();
+ if (func->isConstructor() && func->arguments().size() == 1) {
+ AbstractMetaClassCPtr ownerClass = func->ownerClass();
+ ComplexTypeEntryCPtr baseContainerType = ownerClass->typeEntry()->baseContainerType();
if (baseContainerType && baseContainerType == func->arguments().constFirst().type().typeEntry()
&& ownerClass->isCopyable()) {
- tck << '!' << cpythonCheckFunction(ownerClass->typeEntry()) << pyArgName << ")\n";
- Indentation indent(s);
- tck << "&& ";
+ tck << '!' << cpythonCheckFunction(ownerClass->typeEntry())
+ << pyArgName << ")\n" << indent << "&& " << outdent;
}
}
writeTypeCheck(tck, od, pyArgName);
@@ -2925,16 +3034,16 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
int numArgs = args.size() - OverloadData::numberOfRemovedArguments(refFunc);
if (isVarargs)
--numArgs;
- QString check = (isVarargs ? u"numArgs >= "_qs : u"numArgs == "_qs)
+ QString check = (isVarargs ? u"numArgs >= "_s : u"numArgs == "_s)
+ QString::number(numArgs);
typeChecks.prepend(check);
} else if (usePyArgs && sequenceArgCount > 0) {
- typeChecks.prepend(u"numArgs >= "_qs + QString::number(startArg + sequenceArgCount));
+ typeChecks.prepend(u"numArgs >= "_s + QString::number(startArg + sequenceArgCount));
} else if (refFunc->isOperatorOverload() && !refFunc->isCallOperator()) {
QString check;
if (!refFunc->isReverseOperator())
- check.append(QLatin1Char('!'));
- check.append(QLatin1String("isReverse"));
+ check.append(u'!');
+ check.append(u"isReverse"_s);
typeChecks.prepend(check);
}
@@ -2947,88 +3056,87 @@ void CppGenerator::writeOverloadedFunctionDecisorEngine(TextStream &s,
if (typeChecks.isEmpty()) {
s << "true";
} else {
- Indentation indent(s);
- s << typeChecks.join(QLatin1String("\n&& "));
+ s << indent << typeChecks.join(u"\n&& "_s) << outdent;
}
- s << ") {\n";
- {
- Indentation indent(s);
- writeOverloadedFunctionDecisorEngine(s, overloadData, child.data());
- }
- s << "}";
+ s << ") {\n" << indent;
+ writeOverloadedFunctionDecisorEngine(s, overloadData, child.get());
+ s << outdent << '}';
}
s << '\n';
}
void CppGenerator::writeFunctionCalls(TextStream &s, const OverloadData &overloadData,
- const GeneratorContext &context) const
+ const GeneratorContext &context,
+ ErrorReturn errorReturn) const
{
const AbstractMetaFunctionCList &overloads = overloadData.overloads();
s << "// Call function/method\n"
- << (overloads.count() > 1 ? "switch (overloadId) " : "") << "{\n";
- {
- Indentation indent(s);
- if (overloads.count() == 1) {
- writeSingleFunctionCall(s, overloadData, overloads.constFirst(), context);
- } else {
- for (int i = 0; i < overloads.count(); i++) {
- const auto func = overloads.at(i);
- s << "case " << i << ": // " << func->signature() << "\n{\n";
- {
- Indentation indent(s);
- writeSingleFunctionCall(s, overloadData, func, context);
- if (func->attributes().testFlag(AbstractMetaFunction::Deprecated)) {
- s << "PyErr_WarnEx(PyExc_DeprecationWarning, \"";
- if (auto cls = context.metaClass())
- s << cls->name() << '.';
- s << func->signature() << " is deprecated\", 1);\n";
- }
- s << "break;\n";
- }
- s << "}\n";
- }
+ << (overloads.size() > 1 ? "switch (overloadId) " : "") << "{\n" << indent;
+ if (overloads.size() == 1) {
+ writeSingleFunctionCall(s, overloadData, overloads.constFirst(), context,
+ errorReturn);
+ } else {
+ for (qsizetype i = 0; i < overloads.size(); ++i) {
+ const auto func = overloads.at(i);
+ s << "case " << i << ": // " << func->signature() << "\n{\n" << indent;
+ writeSingleFunctionCall(s, overloadData, func, context, errorReturn);
+ s << "break;\n" << outdent << "}\n";
}
}
- s << "}\n";
+ s << outdent << "}\n";
+}
+
+static void writeDeprecationWarning(TextStream &s,
+ const GeneratorContext &context,
+ const AbstractMetaFunctionCPtr &func,
+ CppGenerator::ErrorReturn errorReturn)
+{
+ s << "Shiboken::Warnings::warnDeprecated(\"";
+ 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 (" << shibokenErrorsOccurred << ")\n"
+ << indent << errorReturn << outdent;
}
void CppGenerator::writeSingleFunctionCall(TextStream &s,
const OverloadData &overloadData,
const AbstractMetaFunctionCPtr &func,
- const GeneratorContext &context) const
+ const GeneratorContext &context,
+ ErrorReturn errorReturn) const
{
- if (func->isDeprecated()) {
- s << "Shiboken::warning(PyExc_DeprecationWarning, 1, \"Function: '"
- << func->signature().replace(QLatin1String("::"), QLatin1String("."))
- << "' is marked as deprecated, please check the documentation for more information.\");\n";
- }
+ if (func->isDeprecated())
+ writeDeprecationWarning(s, context, func, errorReturn);
if (func->functionType() == AbstractMetaFunction::EmptyFunction) {
- s << "PyErr_Format(PyExc_TypeError, \"%s is a private method.\", \""
- << func->signature().replace(QLatin1String("::"), QLatin1String("."))
- << "\");\n"
- << returnStatement(m_currentErrorCode) << '\n';
+ s << "Shiboken::Errors::setPrivateMethod(\""
+ << func->signature().replace(u"::"_s, u"."_s) << "\");\n"
+ << errorReturn;
return;
}
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;
int removedArgs = 0;
- for (int argIdx = 0; argIdx < func->arguments().count(); ++argIdx) {
- bool hasConversionRule = !func->conversionRule(TypeSystem::NativeCode, argIdx + 1).isEmpty();
+
+ const auto argCount = func->arguments().size();
+ QList<qsizetype> indirections(argCount, 0);
+ for (qsizetype argIdx = 0; argIdx < argCount; ++argIdx) {
+ const bool hasConversionRule =
+ func->hasConversionRule(TypeSystem::NativeCode, int(argIdx + 1));
const AbstractMetaArgument &arg = func->arguments().at(argIdx);
if (arg.isModifiedRemoved()) {
if (!arg.defaultValueExpression().isEmpty()) {
- const QString cppArgRemoved = QLatin1String(CPP_ARG_REMOVED)
- + QString::number(argIdx);
+ const QString cppArgRemoved = CPP_ARG_REMOVED(argIdx);
s << getFullTypeName(arg.type()) << ' ' << cppArgRemoved;
- s << " = " << guessScopeForDefaultValue(func, arg) << ";\n";
- writeUnusedVariableCast(s, cppArgRemoved);
+ s << " = " << arg.defaultValueExpression() << ";\n"
+ << sbkUnusedVariableCast(cppArgRemoved);
} else if (!injectCodeCallsFunc && !func->isUserAdded() && !hasConversionRule) {
// When an argument is removed from a method signature and no other means of calling
// the method are provided (as with code injection) the generator must abort.
@@ -3047,22 +3155,22 @@ void CppGenerator::writeSingleFunctionCall(TextStream &s,
continue;
auto argType = getArgumentType(func, argIdx);
int argPos = argIdx - removedArgs;
- QString argName = QLatin1String(CPP_ARG) + QString::number(argPos);
- QString pyArgName = usePyArgs ? pythonArgsAt(argPos) : QLatin1String(PYTHON_ARG);
- QString defaultValue = guessScopeForDefaultValue(func, arg);
- writeArgumentConversion(s, argType, argName, pyArgName,
- func->implementingClass(), defaultValue,
- func->isUserAdded());
+ QString pyArgName = usePyArgs ? pythonArgsAt(argPos) : PYTHON_ARG;
+ indirections[argIdx] =
+ writeArgumentConversion(s, argType, CPP_ARG_N(argPos), pyArgName, errorReturn,
+ func->implementingClass(), arg.defaultValueExpression(),
+ func->isUserAdded());
}
s << '\n';
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);
+ func->arguments().size() - numRemovedArgs, indirections, errorReturn);
+
if (!func->isConstructor())
writeNoneReturn(s, func, overloadData.hasNonVoidReturnType());
s << outdent << "}\n";
@@ -3072,34 +3180,34 @@ QString CppGenerator::cppToPythonFunctionName(const QString &sourceTypeName, QSt
{
if (targetTypeName.isEmpty())
targetTypeName = sourceTypeName;
- return sourceTypeName + QLatin1String("_CppToPython_") + targetTypeName;
+ return sourceTypeName + u"_CppToPython_"_s + targetTypeName;
}
QString CppGenerator::pythonToCppFunctionName(const QString &sourceTypeName, const QString &targetTypeName)
{
- return sourceTypeName + QLatin1String("_PythonToCpp_") + targetTypeName;
+ return sourceTypeName + u"_PythonToCpp_"_s + targetTypeName;
}
QString CppGenerator::pythonToCppFunctionName(const AbstractMetaType &sourceType, const AbstractMetaType &targetType)
{
return pythonToCppFunctionName(fixedCppTypeName(sourceType), fixedCppTypeName(targetType));
}
-QString CppGenerator::pythonToCppFunctionName(const CustomConversion::TargetToNativeConversion *toNative,
- const TypeEntry *targetType)
+QString CppGenerator::pythonToCppFunctionName(const TargetToNativeConversion &toNative,
+ const TypeEntryCPtr &targetType)
{
return pythonToCppFunctionName(fixedCppTypeName(toNative), fixedCppTypeName(targetType));
}
QString CppGenerator::convertibleToCppFunctionName(const QString &sourceTypeName, const QString &targetTypeName)
{
- return QLatin1String("is_") + sourceTypeName + QLatin1String("_PythonToCpp_")
- + targetTypeName + QLatin1String("_Convertible");
+ return u"is_"_s + sourceTypeName + u"_PythonToCpp_"_s
+ + targetTypeName + u"_Convertible"_s;
}
QString CppGenerator::convertibleToCppFunctionName(const AbstractMetaType &sourceType, const AbstractMetaType &targetType)
{
return convertibleToCppFunctionName(fixedCppTypeName(sourceType), fixedCppTypeName(targetType));
}
-QString CppGenerator::convertibleToCppFunctionName(const CustomConversion::TargetToNativeConversion *toNative,
- const TypeEntry *targetType)
+QString CppGenerator::convertibleToCppFunctionName(const TargetToNativeConversion &toNative,
+ const TypeEntryCPtr &targetType)
{
return convertibleToCppFunctionName(fixedCppTypeName(toNative), fixedCppTypeName(targetType));
}
@@ -3109,9 +3217,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";
}
@@ -3134,53 +3243,66 @@ static void replaceCppToPythonVariables(QString &code, const QString &typeName,
bool constRef = false)
{
CodeSnipAbstract::prependCode(&code, writeCppInRef(typeName, constRef));
- code.replace(QLatin1String("%INTYPE"), typeName);
- code.replace(QLatin1String("%OUTTYPE"), QLatin1String("PyObject *"));
- code.replace(QLatin1String("%in"), QLatin1String("cppInRef"));
- code.replace(QLatin1String("%out"), QLatin1String("pyOut"));
+ code.replace(u"%INTYPE"_s, typeName);
+ code.replace(u"%OUTTYPE"_s, u"PyObject *"_s);
+ code.replace(u"%in"_s, u"cppInRef"_s);
+ code.replace(u"%out"_s, u"pyOut"_s);
}
-void CppGenerator::writeCppToPythonFunction(TextStream &s, const CustomConversion *customConversion) const
+void CppGenerator::writeCppToPythonFunction(TextStream &s,
+ const CustomConversionPtr &customConversion) const
{
QString code = customConversion->nativeToTargetConversion();
- auto *ownerType = customConversion->ownerType();
+ auto ownerType = customConversion->ownerType();
const bool constRef = !ownerType->isPrimitive(); // PyCapsule needs a non-const ref
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
{
- const CustomConversion *customConversion = containerType.typeEntry()->customConversion();
- if (!customConversion) {
+ Q_ASSERT(containerType.typeEntry()->isContainer());
+ 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 '"
<< containerType.typeEntry()->qualifiedCppName()
<< "' - no conversion rule was defined for it in the type system.";
throw Exception(m);
}
- if (!containerType.typeEntry()->isContainer()) {
- writeCppToPythonFunction(s, customConversion);
- return;
- }
+ const auto customConversion = cte->customConversion();
QString code = customConversion->nativeToTargetConversion();
- for (int i = 0; i < containerType.instantiations().count(); ++i) {
+ for (qsizetype i = 0; i < containerType.instantiations().size(); ++i) {
const AbstractMetaType &type = containerType.instantiations().at(i);
QString typeName = getFullTypeName(type);
if (type.isConstant())
- typeName = QLatin1String("const ") + typeName;
- code.replace(u"%INTYPE_"_qs + QString::number(i), typeName);
+ typeName = u"const "_s + typeName;
+ 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";
}
@@ -3198,16 +3320,15 @@ void CppGenerator::writeIsPythonConvertibleToCppFunction(TextStream &s,
s << "static PythonToCppFunc " << convertibleToCppFunctionName(sourceTypeName, targetTypeName);
s << "(PyObject *pyIn)\n{\n" << indent;
if (acceptNoneAsCppNull) {
- s << "if (pyIn == Py_None)\n";
- Indentation indent(s);
- s << "return Shiboken::Conversions::nonePythonToCppNullPtr;\n";
- }
- s << "if (" << condition << ")\n";
- {
- Indentation indent(s);
- s << "return " << pythonToCppFuncName << ";\n";
+ s << "if (pyIn == Py_None)\n" << indent
+ << "return Shiboken::Conversions::nonePythonToCppNullPtr;\n" << outdent;
+ } else {
+ if (!condition.contains(u"pyIn"))
+ s << sbkUnusedVariableCast("pyIn");
}
- s << "return {};\n" << outdent << "}\n";
+ s << "if (" << condition << ")\n" << indent
+ << "return " << pythonToCppFuncName << ";\n" << outdent
+ << "return {};\n" << outdent << "}\n";
}
void CppGenerator::writePythonToCppConversionFunctions(TextStream &s,
@@ -3222,95 +3343,97 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s,
// Python to C++ conversion function.
StringStream c(TextStream::Language::Cpp);
if (conversion.isEmpty())
- conversion = QLatin1Char('*') + cpythonWrapperCPtr(sourceType, QLatin1String("pyIn"));
+ conversion = u'*' + cpythonWrapperCPtr(sourceType, u"pyIn"_s);
if (!preConversion.isEmpty())
c << preConversion << '\n';
const QString fullTypeName = targetType.isSmartPointer()
? targetType.cppSignature()
: getFullTypeName(targetType.typeEntry());
c << "*reinterpret_cast<" << fullTypeName << " *>(cppOut) = "
- << fullTypeName << '(' << conversion << ");";
+ << fullTypeName << '('
+ << (sourceType.isUniquePointer() ? stdMove(conversion) : conversion)
+ << ");";
QString sourceTypeName = fixedCppTypeName(sourceType);
QString targetTypeName = fixedCppTypeName(targetType);
writePythonToCppFunction(s, c.toString(), sourceTypeName, targetTypeName);
// Python to C++ convertible check function.
if (typeCheck.isEmpty())
- typeCheck = u"PyObject_TypeCheck(pyIn, "_qs + sourcePyType + u')';
+ typeCheck = u"PyObject_TypeCheck(pyIn, "_s + sourcePyType + u')';
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, typeCheck);
s << '\n';
}
void CppGenerator::writePythonToCppConversionFunctions(TextStream &s,
- const CustomConversion::TargetToNativeConversion *toNative,
- const TypeEntry *targetType) const
+ const TargetToNativeConversion &toNative,
+ const TypeEntryCPtr &targetType) const
{
// Python to C++ conversion function.
- QString code = toNative->conversion();
+ QString code = toNative.conversion();
QString inType;
- if (toNative->sourceType())
- inType = cpythonTypeNameExt(toNative->sourceType());
+ if (toNative.sourceType())
+ inType = cpythonTypeNameExt(toNative.sourceType());
else
- inType = u'(' + toNative->sourceTypeName() + u"_TypeF())"_qs;
- code.replace(QLatin1String("%INTYPE"), inType);
- code.replace(QLatin1String("%OUTTYPE"), targetType->qualifiedCppName());
- code.replace(QLatin1String("%in"), QLatin1String("pyIn"));
- code.replace(QLatin1String("%out"),
- QLatin1String("*reinterpret_cast<") + getFullTypeName(targetType) + QLatin1String(" *>(cppOut)"));
+ inType = u'(' + toNative.sourceTypeName() + u"_TypeF())"_s;
+ code.replace(u"%INTYPE"_s, inType);
+ code.replace(u"%OUTTYPE"_s, targetType->qualifiedCppName());
+ code.replace(u"%in"_s, u"pyIn"_s);
+ code.replace(u"%out"_s,
+ u"*reinterpret_cast<"_s + getFullTypeName(targetType) + u" *>(cppOut)"_s);
QString sourceTypeName = fixedCppTypeName(toNative);
QString targetTypeName = fixedCppTypeName(targetType);
writePythonToCppFunction(s, code, sourceTypeName, targetTypeName);
// Python to C++ convertible check function.
- QString typeCheck = toNative->sourceTypeCheck();
+ QString typeCheck = toNative.sourceTypeCheck();
if (typeCheck.isEmpty()) {
- QString pyTypeName = toNative->sourceTypeName();
- if (pyTypeName == QLatin1String("Py_None") || pyTypeName == QLatin1String("PyNone"))
- typeCheck = QLatin1String("%in == Py_None");
- else if (pyTypeName == QLatin1String("SbkEnumType"))
- typeCheck = QLatin1String("Shiboken::isShibokenEnum(%in)");
- else if (pyTypeName == QLatin1String("SbkObject"))
- typeCheck = QLatin1String("Shiboken::Object::checkType(%in)");
+ QString pyTypeName = toNative.sourceTypeName();
+ if (pyTypeName == u"Py_None" || pyTypeName == u"PyNone")
+ typeCheck = u"%in == Py_None"_s;
+ else if (pyTypeName == u"SbkObject")
+ typeCheck = u"Shiboken::Object::checkType(%in)"_s;
}
if (typeCheck.isEmpty()) {
- if (!toNative->sourceType() || toNative->sourceType()->isPrimitive()) {
+ if (!toNative.sourceType() || toNative.sourceType()->isPrimitive()) {
QString m;
QTextStream(&m) << "User added implicit conversion for C++ type '" << targetType->qualifiedCppName()
<< "' must provide either an input type check function or a non primitive type entry.";
throw Exception(m);
}
- typeCheck = u"PyObject_TypeCheck(%in, "_qs
- + cpythonTypeNameExt(toNative->sourceType()) + u')';
+ typeCheck = u"PyObject_TypeCheck(%in, "_s
+ + cpythonTypeNameExt(toNative.sourceType()) + u')';
}
- typeCheck.replace(QLatin1String("%in"), QLatin1String("pyIn"));
- processCodeSnip(typeCheck);
+ typeCheck.replace(u"%in"_s, u"pyIn"_s);
+ processCodeSnip(typeCheck, targetType->qualifiedCppName());
writeIsPythonConvertibleToCppFunction(s, sourceTypeName, targetTypeName, typeCheck);
}
void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, const AbstractMetaType &containerType) const
{
- const CustomConversion *customConversion = containerType.typeEntry()->customConversion();
- if (!customConversion) {
- //qFatal
- return;
- }
- const CustomConversion::TargetToNativeConversions &toCppConversions = customConversion->targetToNativeConversions();
- if (toCppConversions.isEmpty()) {
- //qFatal
- return;
- }
+ Q_ASSERT(containerType.typeEntry()->isContainer());
+ const auto cte = std::static_pointer_cast<const ContainerTypeEntry>(containerType.typeEntry());
+ const auto customConversion = cte->customConversion();
+ 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();
- const QString line = QLatin1String("auto &cppOutRef = *reinterpret_cast<")
- + cppTypeName + QLatin1String(" *>(cppOut);");
+ QString code = conv.conversion();
+ const QString line = u"auto &cppOutRef = *reinterpret_cast<"_s
+ + cppTypeName + u" *>(cppOut);"_s;
CodeSnipAbstract::prependCode(&code, line);
- for (int i = 0; i < containerType.instantiations().count(); ++i) {
+ for (qsizetype i = 0; i < containerType.instantiations().size(); ++i) {
const AbstractMetaType &type = containerType.instantiations().at(i);
QString typeName = getFullTypeName(type);
// Containers of opaque containers are not handled here.
- if (type.shouldDereferenceArgument() && !type.generateOpaqueContainer()) {
+ const auto generatorArg = GeneratorArgument::fromMetaType(type);
+ if (generatorArg.indirections > 0 && !type.generateOpaqueContainer()) {
for (int pos = 0; ; ) {
const QRegularExpressionMatch match = convertToCppRegEx().match(code, pos);
if (!match.hasMatch())
@@ -3318,26 +3441,27 @@ void CppGenerator::writePythonToCppConversionFunctions(TextStream &s, const Abst
pos = match.capturedEnd();
const QString varName = match.captured(1);
QString rightCode = code.mid(pos);
- rightCode.replace(varName, QLatin1Char('*') + varName);
+ rightCode.replace(varName, u'*' + varName);
code.replace(pos, code.size() - pos, rightCode);
}
- typeName.append(QLatin1String(" *"));
+ typeName.append(u" *"_s);
}
- code.replace(u"%OUTTYPE_"_qs + QString::number(i), typeName);
+ code.replace(u"%OUTTYPE_"_s + QString::number(i), typeName);
}
- code.replace(QLatin1String("%OUTTYPE"), cppTypeName);
- code.replace(QLatin1String("%in"), QLatin1String("pyIn"));
- code.replace(QLatin1String("%out"), QLatin1String("cppOutRef"));
+ code.replace(u"%OUTTYPE"_s, cppTypeName);
+ 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);
if (typeCheck.isEmpty())
- typeCheck = QLatin1String("false");
+ typeCheck = u"false"_s;
else
- typeCheck = typeCheck + QLatin1String("pyIn)");
- writeIsPythonConvertibleToCppFunction(s, typeName, typeName, typeCheck);
+ typeCheck = typeCheck + u"pyIn)"_s;
+ writeIsPythonConvertibleToCppFunction(s, sourceTypeName, typeName, typeCheck);
s << '\n';
}
@@ -3369,139 +3493,168 @@ void CppGenerator::writeSetPythonToCppPointerConversion(TextStream &s,
converterVar, pythonToCppFunc, isConvertibleFunc);
}
-void CppGenerator::writeNamedArgumentResolution(TextStream &s, const AbstractMetaFunctionCPtr &func,
- bool usePyArgs, const OverloadData &overloadData) const
+// PYSIDE-1986: Some QObject derived classes, (QVBoxLayout) do not have default
+// arguments, which breaks setting properties by named arguments. Force the
+// handling code to be generated nevertheless for applicable widget classes,
+// so that the mechanism of falling through to the error handling to set
+// the properties works nevertheless.
+static bool forceQObjectNamedArguments(const AbstractMetaFunctionCPtr &func)
+{
+ if (func->functionType() != AbstractMetaFunction::ConstructorFunction)
+ return false;
+ const auto owner = func->ownerClass();
+ Q_ASSERT(owner);
+ 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,
+ ErrorReturn errorReturn)
{
const AbstractMetaArgumentList &args = OverloadData::getArgumentsWithDefaultValues(func);
- if (args.isEmpty()) {
+ const bool hasDefaultArguments = !args.isEmpty();
+ const bool force = !hasDefaultArguments && usePySideExtensions()
+ && forceQObjectNamedArguments(func);
+ 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";
- {
- Indentation indent(s);
- s << "errInfo.reset(kwds);\n"
- << "Py_INCREF(errInfo.object());\n"
- << "goto " << cpythonFunctionName(func) << "_TypeError;\n";
- }
- s << "}\n";
+ s << "if (kwds != nullptr && PyDict_Size(kwds) > 0) {\n" << indent
+ << "errInfo.reset(kwds);\n"
+ << "Py_INCREF(errInfo.object());\n"
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n"
+ << outdent << "}\n";
}
return;
}
// PySide-535: Allow for empty dict instead of nullptr in PyPy
- s << "if (kwds && PyDict_Size(kwds) > 0) {\n";
- {
- Indentation indent(s);
- s << "PyObject *value{};\n"
- << "PyObject *kwds_dup = PyDict_Copy(kwds);\n";
- for (const AbstractMetaArgument &arg : args) {
- const int pyArgIndex = arg.argumentIndex()
- - OverloadData::numberOfRemovedArguments(func, arg.argumentIndex());
- QString pyArgName = usePyArgs ? pythonArgsAt(pyArgIndex) : QLatin1String(PYTHON_ARG);
- QString pyKeyName = QLatin1String("key_") + arg.name();
- s << "static PyObject *const " << pyKeyName
- << " = Shiboken::String::createStaticString(\"" << arg.name() << "\");\n"
- << "if (PyDict_Contains(kwds, " << pyKeyName << ")) {\n";
- {
- Indentation indent(s);
- s << "value = PyDict_GetItem(kwds, " << pyKeyName << ");\n"
- << "if (value && " << pyArgName << ") {\n";
- {
- Indentation indent(s);
- s << "errInfo.reset(" << pyKeyName << ");\n"
- << "Py_INCREF(errInfo.object());\n"
- << "goto " << cpythonFunctionName(func) << "_TypeError;\n";
- }
- s << "}\nif (value) {\n";
- {
- Indentation indent(s);
- s << pyArgName << " = value;\nif (!";
- const auto &type = arg.modifiedType();
- writeTypeCheck(s, type, pyArgName, isNumber(type.typeEntry()), {});
- s << ")\n";
- {
- Indentation indent(s);
- s << "goto " << cpythonFunctionName(func) << "_TypeError;\n";
- }
- }
- s << "}\nPyDict_DelItem(kwds_dup, " << pyKeyName << ");\n";
- }
- s << "}\n";
- }
- // PYSIDE-1305: Handle keyword args correctly.
- // Normal functions handle their parameters immediately.
- // For constructors that are QObject, we need to delay that
- // until extra keyword signals and properties are handled.
- s << "if (PyDict_Size(kwds_dup) > 0) {\n";
- {
- Indentation indent(s);
- s << "errInfo.reset(kwds_dup);\n";
- if (!(func->isConstructor() && func->ownerClass()->isQObject()))
- s << "goto " << cpythonFunctionName(func) << "_TypeError;\n";
- else
- s << "// fall through to handle extra keyword signals and properties\n";
- }
- s << "}\n";
- }
- s << "}\n";
+ s << "if (kwds && PyDict_Size(kwds) > 0) {\n" << indent;
+ if (!force)
+ s << "PyObject *value{};\n";
+ s << "Shiboken::AutoDecRef kwds_dup(PyDict_Copy(kwds));\n";
+ for (const AbstractMetaArgument &arg : args) {
+ const int pyArgIndex = arg.argumentIndex()
+ - OverloadData::numberOfRemovedArguments(func, arg.argumentIndex());
+ QString pyArgName = usePyArgs ? pythonArgsAt(pyArgIndex)
+ : PYTHON_ARG;
+ QString pyKeyName = u"key_"_s + arg.name();
+ s << "static PyObject *const " << pyKeyName
+ << " = Shiboken::String::createStaticString(\"" << arg.name() << "\");\n"
+ << "if (PyDict_Contains(kwds, " << pyKeyName << ") != 0) {\n" << indent
+ << "value = PyDict_GetItem(kwds, " << pyKeyName << ");\n"
+ << "if (value != nullptr && " << pyArgName << " != nullptr ) {\n"
+ << indent << "errInfo.reset(" << pyKeyName << ");\n"
+ << "Py_INCREF(errInfo.object());\n"
+ << "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
+ << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n"
+ << outdent << outdent
+ << "}\nPyDict_DelItem(kwds_dup, " << pyKeyName << ");\n"
+ << outdent << "}\n";
+ }
+ // PYSIDE-1305: Handle keyword args correctly.
+ // Normal functions handle their parameters immediately.
+ // For constructors that are QObject, we need to delay that
+ // 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() && isQObject(func->ownerClass())))
+ s << "return " << returnErrorWrongArguments(overloadData, errorReturn) << ";\n";
+ else
+ s << "// fall through to handle extra keyword signals and properties\n";
+ s << outdent << "}\n"
+ << outdent << "}\n";
}
QString CppGenerator::argumentNameFromIndex(const ApiExtractorResult &api,
- const AbstractMetaFunctionCPtr &func, int argIndex,
- const AbstractMetaClass **wrappedClass,
- QString *errorMessage)
-{
- if (errorMessage != nullptr)
- errorMessage->clear();
- *wrappedClass = nullptr;
- QString pyArgName;
- if (argIndex == -1) {
- pyArgName = QLatin1String("self");
- *wrappedClass = func->implementingClass();
- } else if (argIndex == 0) {
- const auto funcType = func->type();
- AbstractMetaType returnType = getTypeWithoutContainer(funcType);
- if (!returnType.isVoid()) {
- pyArgName = QLatin1String(PYTHON_RETURN_VAR);
- *wrappedClass = AbstractMetaClass::findClass(api.classes(), returnType.typeEntry());
- if (*wrappedClass == nullptr && errorMessage != nullptr)
- *errorMessage = msgClassNotFound(returnType.typeEntry());
- } else {
- if (errorMessage != nullptr) {
- QTextStream str(errorMessage);
- str << "Invalid Argument index (0, return value) on function modification: "
- << funcType.name() << ' ';
- if (const AbstractMetaClass *declaringClass = func->declaringClass())
- str << declaringClass->name() << "::";
- str << func->name() << "()";
- }
- }
+ const AbstractMetaFunctionCPtr &func, int argIndex)
+{
+ switch (argIndex) {
+ case -1:
+ return PYTHON_SELF_VAR;
+ case 0:
+ return PYTHON_RETURN_VAR;
+ case 1: { // Single argument?
+ OverloadData data(getFunctionGroups(func->implementingClass()).value(func->name()), api);
+ if (!data.pythonFunctionWrapperUsesListOfArguments())
+ return PYTHON_ARG;
+ break;
+ }
+ }
+ return pythonArgsAt(argIndex - 1);
+}
+
+AbstractMetaClassCPtr
+CppGenerator::argumentClassFromIndex(const ApiExtractorResult &api,
+ const AbstractMetaFunctionCPtr &func, int argIndex)
+{
+ if (argIndex == -1)
+ return func->implementingClass();
+
+ AbstractMetaType type;
+ if (argIndex == 0) {
+ type = func->type();
} else {
- int realIndex = argIndex - 1 - OverloadData::numberOfRemovedArguments(func, argIndex - 1);
- AbstractMetaType argType = getTypeWithoutContainer(func->arguments().at(realIndex).type());
- *wrappedClass = AbstractMetaClass::findClass(api.classes(), argType.typeEntry());
- if (*wrappedClass == nullptr && errorMessage != nullptr)
- *errorMessage = msgClassNotFound(argType.typeEntry());
- if (argIndex == 1
- && !func->isConstructor()
- && OverloadData::isSingleArgument(getFunctionGroups(func->implementingClass()).value(func->name())))
- pyArgName = QLatin1String(PYTHON_ARG);
- else
- pyArgName = pythonArgsAt(argIndex - 1);
+ const int arg = argIndex - 1;
+ const int realIndex = arg - OverloadData::numberOfRemovedArguments(func, arg);
+ type = func->arguments().at(realIndex).type();
}
- return pyArgName;
+
+ if (type.typeEntry()->isContainer()) {
+ // only support containers with 1 type
+ if (type.instantiations().size() == 1)
+ type = type.instantiations().constFirst();
+ }
+
+ auto te = type.typeEntry();
+ if (type.isVoid() || !te->isComplex())
+ throw Exception(msgInvalidArgumentModification(func, argIndex));
+ const auto result = AbstractMetaClass::findClass(api.classes(), te);
+ if (!result)
+ throw Exception(msgClassNotFound(te));
+ return result;
}
+const char tryBlock[] = R"(
+PyObject *errorType{};
+PyObject *errorString{};
+try {
+)";
+
const char defaultExceptionHandling[] = R"(} catch (const std::exception &e) {
- PyErr_SetString(PyExc_RuntimeError, e.what());
+ errorType = PyExc_RuntimeError;
+ errorString = Shiboken::String::fromCString(e.what());
} catch (...) {
- PyErr_SetString(PyExc_RuntimeError, "An unknown exception was caught");
+ errorType = PyExc_RuntimeError;
+ errorString = Shiboken::Messages::unknownException();
}
)";
+const char propagateException[] = R"(
+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) const
+ int maxArgs,
+ const QList<qsizetype> &argumentIndirections,
+ ErrorReturn errorReturn) const
{
s << "// " << func->minimalSignature() << (func->isReverseOperator() ? " [reverse operator]": "") << '\n';
if (func->isConstructor()) {
@@ -3518,14 +3671,10 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
}
if (func->isAbstract()) {
- s << "if (Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject *>(self))) {\n";
- {
- Indentation indent(s);
- s << "PyErr_SetString(PyExc_NotImplementedError, \"pure virtual method '";
- s << func->ownerClass()->name() << '.' << func->name() << "()' not implemented.\");\n";
- s << returnStatement(m_currentErrorCode) << '\n';
- }
- s << "}\n";
+ s << "if (Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject *>(self))) {\n"
+ << indent << "Shiboken::Errors::setPureVirtualMethodError(\""
+ << func->ownerClass()->name() << '.' << func->name() << "\");\n"
+ << errorReturn << outdent << "}\n";
}
// Used to provide contextual information to custom code writer function.
@@ -3554,14 +3703,16 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
writeConversionRule(s, func, TypeSystem::NativeCode, usesPyArgs);
+ bool generateExceptionHandling = false;
+
if (!func->isUserAdded()) {
QStringList userArgs;
if (func->functionType() != AbstractMetaFunction::CopyConstructorFunction) {
int removedArgs = 0;
for (int i = 0; i < maxArgs + removedArgs; i++) {
const AbstractMetaArgument &arg = func->arguments().at(i);
- bool hasConversionRule = !func->conversionRule(TypeSystem::NativeCode,
- arg.argumentIndex() + 1).isEmpty();
+ const bool hasConversionRule =
+ func->hasConversionRule(TypeSystem::NativeCode, arg.argumentIndex() + 1);
if (arg.isModifiedRemoved()) {
// If some argument with default value is removed from a
// method signature, the said value must be explicitly
@@ -3570,22 +3721,26 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
// If have conversion rules I will use this for removed args
if (hasConversionRule)
- userArgs << arg.name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX);
+ userArgs << arg.name() + CONV_RULE_OUT_VAR_SUFFIX;
else if (!arg.defaultValueExpression().isEmpty())
- userArgs.append(QLatin1String(CPP_ARG_REMOVED) + QString::number(i));
+ userArgs.append(CPP_ARG_REMOVED(i));
} else {
if (hasConversionRule) {
- userArgs.append(arg.name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX));
+ userArgs.append(arg.name() + CONV_RULE_OUT_VAR_SUFFIX);
} else {
const int idx = arg.argumentIndex() - removedArgs;
- const bool deRef = arg.type().shouldDereferenceArgument();
- QString argName;
- if (deRef)
- argName += QLatin1Char('*');
- argName += QLatin1String(CPP_ARG) + QString::number(idx);
+ const auto deRef = argumentIndirections.at(i);
+ QString argName = AbstractMetaType::dereferencePrefix(deRef)
+ + CPP_ARG_N(idx);
userArgs.append(argName);
}
}
+ // "Pass unique ptr by value" pattern: Apply std::move()
+ auto type = arg.type();
+ 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
@@ -3595,19 +3750,19 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
QStringList otherArgs;
bool otherArgsModified = false;
bool argsClear = true;
- for (int i = func->arguments().size() - 1; i >= maxArgs + removedArgs; i--) {
+ for (auto i = func->arguments().size() - 1; i >= maxArgs + removedArgs; i--) {
const AbstractMetaArgument &arg = func->arguments().at(i);
const bool defValModified = arg.hasModifiedDefaultValueExpression();
- bool hasConversionRule = !func->conversionRule(TypeSystem::NativeCode,
- arg.argumentIndex() + 1).isEmpty();
+ const bool hasConversionRule =
+ func->hasConversionRule(TypeSystem::NativeCode, arg.argumentIndex() + 1);
if (argsClear && !defValModified && !hasConversionRule)
continue;
argsClear = false;
otherArgsModified |= defValModified || hasConversionRule || arg.isModifiedRemoved();
if (hasConversionRule)
- otherArgs.prepend(arg.name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX));
+ otherArgs.prepend(arg.name() + CONV_RULE_OUT_VAR_SUFFIX);
else
- otherArgs.prepend(QLatin1String(CPP_ARG_REMOVED) + QString::number(i));
+ otherArgs.prepend(CPP_ARG_REMOVED(i));
}
if (otherArgsModified)
userArgs << otherArgs;
@@ -3618,16 +3773,14 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
StringStream uva(TextStream::Language::Cpp);
if (func->isOperatorOverload() && !func->isCallOperator()) {
- QString firstArg(QLatin1Char('('));
+ QString firstArg(u'(');
if (!func->isPointerOperator()) // no de-reference operator
- firstArg += QLatin1Char('*');
- firstArg += QLatin1String(CPP_SELF_VAR);
- firstArg += QLatin1Char(')');
- QString secondArg = QLatin1String(CPP_ARG0);
- if (!func->isUnaryOperator()
- && func->arguments().constFirst().type().shouldDereferenceArgument()) {
- AbstractMetaType::dereference(&secondArg);
- }
+ firstArg += u'*';
+ firstArg += CPP_SELF_VAR;
+ firstArg += u')';
+ QString secondArg = CPP_ARG0;
+ if (!func->isUnaryOperator())
+ AbstractMetaType::applyDereference(&secondArg, argumentIndirections.at(0));
if (func->isUnaryOperator())
std::swap(firstArg, secondArg);
@@ -3640,7 +3793,7 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
std::swap(firstArg, secondArg);
// Emulate operator+=/-= (__iadd__, __isub__) by using ++/--
- if (((op == QLatin1String("++")) || (op == QLatin1String("--"))) && !func->isReverseOperator()) {
+ if (((op == u"++") || (op == u"--")) && !func->isReverseOperator()) {
s << "\nfor (int i = 0; i < " << secondArg
<< "; ++i, " << op << firstArg << ");\n";
mc << firstArg;
@@ -3655,31 +3808,23 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
isCtor = true;
const auto owner = func->ownerClass();
Q_ASSERT(owner == context.metaClass());
- QString className = context.useWrapper()
- ? context.wrapperName() : owner->qualifiedCppName();
-
- if (func->functionType() == AbstractMetaFunction::CopyConstructorFunction && maxArgs == 1) {
- mc << "new ::" << className << "(*" << CPP_ARG0 << ')';
+ if (func->functionType() == AbstractMetaFunction::CopyConstructorFunction
+ && maxArgs == 1) {
+ mc << "new " << globalScopePrefix(context) << context.effectiveClassName()
+ << "(*" << CPP_ARG0 << ')';
} else {
- QString ctorCall = className + QLatin1Char('(') + userArgs.join(QLatin1String(", ")) + QLatin1Char(')');
- if (usePySideExtensions() && owner->isQObject()) {
+ const QString ctorCall = context.effectiveClassName() + u'('
+ + userArgs.join(u", "_s) + u')';
+ if (usePySideExtensions() && isQObject(owner)) {
s << "void *addr = PySide::nextQObjectMemoryAddr();\n";
- uva << "if (addr) {\n";
- {
- Indentation indent(uva);
-
- uva << "cptr = new (addr) ::" << ctorCall << ";\n"
- << "PySide::setNextQObjectMemoryAddr(0);"
- << '\n';
- }
- uva << "} else {\n";
- {
- Indentation indent(uva);
- uva << "cptr = new ::" << ctorCall << ";\n";
- }
- uva << "}\n";
+ uva << "if (addr != nullptr) {\n" << indent
+ << "cptr = new (addr) " << globalScopePrefix(context) << ctorCall
+ << ";\nPySide::setNextQObjectMemoryAddr(nullptr);\n" << outdent
+ << "} else {\n" << indent
+ << "cptr = new " << globalScopePrefix(context) << ctorCall << ";\n"
+ << outdent << "}\n";
} else {
- mc << "new ::" << ctorCall;
+ mc << "new " << globalScopePrefix(context) << ctorCall;
}
}
} else {
@@ -3693,21 +3838,22 @@ 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()
- ? QLatin1String(CPP_SELF_VAR)
- : QLatin1String("reinterpret_cast<") + methodCallClassName
- + QLatin1String(" *>(") + QLatin1String(CPP_SELF_VAR) + QLatin1Char(')');
+ ? cppSelfVar
+ : u"reinterpret_cast<"_s + methodCallClassName
+ + 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()
- ? QLatin1String(CPP_SELF_VAR)
- : QLatin1String("reinterpret_cast<") + wrapperName(ownerClass)
- + QLatin1String(" *>(") + QLatin1String(CPP_SELF_VAR) + QLatin1Char(')');
+ ? cppSelfVar
+ : u"reinterpret_cast<"_s + wrapperName(ownerClass)
+ + u" *>("_s + cppSelfVar + u')';
mc << wrapperName(ownerClass);
mc << " *>(" << selfWrapCast << ")->";
}
@@ -3716,7 +3862,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 {
@@ -3732,26 +3878,26 @@ 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()) :
- QLatin1String("::")
- + methodCallClassName) << "::";
+ m_gsp + methodCallClassName) << "::";
mc << func->originalName() << "_protected";
}
} else {
mc << func->originalName();
}
- mc << '(' << userArgs.join(QLatin1String(", ")) << ')';
+ mc << '(' << userArgs.join(u", "_s) << ')';
if (!func->isAbstract() && func->isVirtual()) {
if (!avoidProtectedHack() || !func->isProtected()) {
QString virtualCall = mc;
QString normalCall = virtualCall;
- virtualCall.replace(QLatin1String("%CLASS_NAME"),
+ virtualCall.replace(u"%CLASS_NAME"_s,
methodCallClassName);
- normalCall.remove(QLatin1String("::%CLASS_NAME::"));
+ normalCall.remove(u"::%CLASS_NAME::"_s);
mc.clear();
mc << "Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject *>(self))\n"
<< " ? " << virtualCall << '\n'
@@ -3763,9 +3909,9 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
if (!injectedCodeCallsCppFunction(context, func)) {
const bool allowThread = func->allowThread();
- const bool generateExceptionHandling = func->generateExceptionHandling();
+ generateExceptionHandling = func->generateExceptionHandling();
if (generateExceptionHandling) {
- s << "try {\n" << indent;
+ s << tryBlock << indent;
if (allowThread) {
s << "Shiboken::ThreadStateSaver threadSaver;\n"
<< "threadSaver.save();\n";
@@ -3785,13 +3931,13 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
if (metaEnum.has_value()) {
QString enumName;
if (metaEnum->isProtected()) {
- enumName = context.wrapperName() + QLatin1String("::")
+ enumName = context.wrapperName() + u"::"_s
+ metaEnum.value().name();
} else {
enumName = func->type().cppSignature();
}
- const QString methodCall = enumName + QLatin1Char('(')
- + mc.toString() + QLatin1Char(')');
+ const QString methodCall = enumName + u'('
+ + mc.toString() + u')';
mc.clear();
mc << methodCall;
s << enumName;
@@ -3803,9 +3949,9 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
s << func->type().cppSignature();
if (func->type().isObjectTypeUsedAsValueType()) {
s << '*';
- methodCall = QLatin1String("new ")
+ methodCall = u"new "_s
+ func->type().typeEntry()->qualifiedCppName()
- + QLatin1Char('(') + mc.toString() + QLatin1Char(')');
+ + u'(' + mc.toString() + u')';
}
}
s << " " << CPP_RETURN_VAR << " = " << methodCall << ";\n";
@@ -3815,13 +3961,14 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
if (allowThread) {
s << (generateExceptionHandling
- ? "threadSaver.restore();" : END_ALLOW_THREADS) << '\n';
+ ? u"threadSaver.restore();"_s : END_ALLOW_THREADS) << '\n';
}
// Convert result
const auto funcType = func->type();
- if (!func->conversionRule(TypeSystem::TargetLangCode, 0).isEmpty()) {
- writeConversionRule(s, func, TypeSystem::TargetLangCode, QLatin1String(PYTHON_RETURN_VAR));
+ if (func->hasConversionRule(TypeSystem::TargetLangCode, 0)) {
+ writeConversionRule(s, func, TypeSystem::TargetLangCode,
+ PYTHON_RETURN_VAR);
} else if (!isCtor && !func->isInplaceOperator() && !func->isVoid()
&& !func->injectedCodeHasReturnValueAttribution(TypeSystem::TargetLangCode)) {
if (func->type().isObjectTypeUsedAsValueType()) {
@@ -3835,7 +3982,8 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
<< "(&" << CPP_RETURN_VAR << ");\n";
} else {
s << PYTHON_RETURN_VAR << " = ";
- writeToPythonConversion(s, funcType, func->ownerClass(), QLatin1String(CPP_RETURN_VAR));
+ writeToPythonConversion(s, funcType, func->ownerClass(),
+ CPP_RETURN_VAR);
}
s << ";\n";
}
@@ -3843,8 +3991,8 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
if (generateExceptionHandling) { // "catch" code
s << outdent << defaultExceptionHandling;
}
- }
- }
+ } // !injected code calls C++ function
+ } // !userAdded
if (func->hasInjectedCode() && !func->isConstructor())
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionEnd,
@@ -3871,25 +4019,11 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
if (!ownership_mods.isEmpty()) {
s << '\n' << "// Ownership transferences.\n";
- for (const ArgumentModification &arg_mod : qAsConst(ownership_mods)) {
- const AbstractMetaClass *wrappedClass = nullptr;
- QString errorMessage;
- QString pyArgName = argumentNameFromIndex(api(), func, arg_mod.index(),
- &wrappedClass, &errorMessage);
- if (!wrappedClass) {
- QString message;
- QTextStream str(&message);
- str << "Invalid ownership modification for argument " << arg_mod.index()
- << " (" << pyArgName << ") of ";
- if (const AbstractMetaClass *declaringClass = func->declaringClass())
- str << declaringClass->name() << "::";
- str << func->name() << "(): " << errorMessage;
- qCWarning(lcShiboken, "%s", qPrintable(message));
- s << "#error " << message << '\n';
- break;
- }
+ for (const ArgumentModification &arg_mod : std::as_const(ownership_mods)) {
+ const int argIndex = arg_mod.index();
+ const QString pyArgName = argumentNameFromIndex(api(), func, argIndex);
- if (arg_mod.index() == 0 || arg_mod.owner().index == 0)
+ if (argIndex == 0 || arg_mod.owner().index == 0)
hasReturnPolicy = true;
// The default ownership does nothing. This is useful to avoid automatic heuristically
@@ -3901,11 +4035,9 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
s << "Shiboken::Object::";
if (ownership == TypeSystem::TargetLangOwnership) {
s << "getOwnership(" << pyArgName << ");";
- } else if (wrappedClass->hasVirtualDestructor()) {
- if (arg_mod.index() == 0)
- s << "releaseOwnership(" << PYTHON_RETURN_VAR << ");";
- else
- s << "releaseOwnership(" << pyArgName << ");";
+ } else if (auto ac = argumentClassFromIndex(api(), func, argIndex);
+ ac && ac->hasVirtualDestructor()) {
+ s << "releaseOwnership(" << pyArgName << ");";
} else {
s << "invalidate(" << pyArgName << ");";
}
@@ -3913,7 +4045,7 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
}
} else if (!refcount_mods.isEmpty()) {
- for (const ArgumentModification &arg_mod : qAsConst(refcount_mods)) {
+ for (const ArgumentModification &arg_mod : std::as_const(refcount_mods)) {
ReferenceCount refCount = arg_mod.referenceCounts().constFirst();
if (refCount.action != ReferenceCount::Set
&& refCount.action != ReferenceCount::Remove
@@ -3921,28 +4053,9 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
qCWarning(lcShiboken) << "\"set\", \"add\" and \"remove\" are the only values supported by Shiboken for action attribute of reference-count tag.";
continue;
}
- const AbstractMetaClass *wrappedClass = nullptr;
-
- QString pyArgName;
- if (refCount.action == ReferenceCount::Remove) {
- pyArgName = QLatin1String("Py_None");
- } else {
- QString errorMessage;
- pyArgName = argumentNameFromIndex(api(), func, arg_mod.index(),
- &wrappedClass, &errorMessage);
- if (pyArgName.isEmpty()) {
- QString message;
- QTextStream str(&message);
- str << "Invalid reference count modification for argument "
- << arg_mod.index() << " of ";
- if (const AbstractMetaClass *declaringClass = func->declaringClass())
- str << declaringClass->name() << "::";
- str << func->name() << "(): " << errorMessage;
- qCWarning(lcShiboken, "%s", qPrintable(message));
- s << "#error " << message << "\n\n";
- break;
- }
- }
+ const int argIndex = arg_mod.index();
+ const QString pyArgName = refCount.action == ReferenceCount::Remove
+ ? u"Py_None"_s : argumentNameFromIndex(api(), func, argIndex);
if (refCount.action == ReferenceCount::Add || refCount.action == ReferenceCount::Set)
s << "Shiboken::Object::keepReference(";
@@ -3952,25 +4065,28 @@ void CppGenerator::writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr
s << "reinterpret_cast<SbkObject *>(self), \"";
QString varName = arg_mod.referenceCounts().constFirst().varName;
if (varName.isEmpty())
- varName = func->minimalSignature() + QString::number(arg_mod.index());
+ varName = func->minimalSignature() + QString::number(argIndex);
s << varName << "\", " << pyArgName
<< (refCount.action == ReferenceCount::Add ? ", true" : "")
<< ");\n";
- if (arg_mod.index() == 0)
+ if (argIndex == 0)
hasReturnPolicy = true;
}
}
writeParentChildManagement(s, func, usesPyArgs, !hasReturnPolicy);
+
+ if (generateExceptionHandling)
+ s << propagateException;
}
-QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClass *metaClass)
+QStringList CppGenerator::getAncestorMultipleInheritance(const AbstractMetaClassCPtr &metaClass)
{
QStringList result;
- const AbstractMetaClassList &baseClases = metaClass->typeSystemBaseClasses();
+ 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";
@@ -3983,256 +4099,203 @@ 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 (int 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";
- {
- Indentation indent(s);
- s << "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";
-
- 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";
- }
- s << "}\nreturn mi_offsets;\n" << outdent << "}\n";
-}
-
-void CppGenerator::writeSpecialCastFunction(TextStream &s, const AbstractMetaClass *metaClass)
+ << "{\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 << "*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 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 AbstractMetaClassList &allAncestors = metaClass->allTypeSystemAncestors();
- for (const AbstractMetaClass *baseClass : allAncestors) {
+ const auto &allAncestors = metaClass->allTypeSystemAncestors();
+ for (const auto &baseClass : allAncestors) {
if (!firstClass)
s << "else ";
- s << "if (desiredType == " << cpythonTypeNameExt(baseClass->typeEntry()) << ")\n";
- Indentation indent(s);
- s << "return static_cast< ::" << baseClass->qualifiedCppName() << " *>(me);\n";
+ s << "if (desiredType == " << cpythonTypeNameExt(baseClass->typeEntry())
+ << ")\n" << indent
+ << "return static_cast< " << getFullTypeName(baseClass) << " *>(me);\n"
+ << outdent;
firstClass = false;
}
s << "return me;\n" << outdent << "}\n\n";
}
void CppGenerator::writePrimitiveConverterInitialization(TextStream &s,
- const CustomConversion *customConversion)
+ const CustomConversionPtr &customConversion)
{
- const TypeEntry *type = customConversion->ownerType();
+ TypeEntryCPtr type = customConversion->ownerType();
QString converter = converterObject(type);
s << "// Register converter for type '" << type->qualifiedTargetLangName() << "'.\n"
<< 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);
}
-void CppGenerator::writeEnumConverterInitialization(TextStream &s, const AbstractMetaEnum &metaEnum)
+static void registerConverterInScopes(TextStream &s, QStringView signature,
+ QAnyStringView varName = converterVar)
{
- if (metaEnum.isPrivate() || metaEnum.isAnonymous())
- return;
- writeEnumConverterInitialization(s, metaEnum.typeEntry());
+ while (true) {
+ s << registerConverterName(signature, varName);
+ const auto qualifierPos = signature.indexOf("::"_L1);
+ if (qualifierPos == -1)
+ break;
+ signature = signature.sliced(qualifierPos + 2);
+ }
}
-void CppGenerator::writeEnumConverterInitialization(TextStream &s, const TypeEntry *enumType)
+void CppGenerator::writeEnumConverterInitialization(TextStream &s, const AbstractMetaEnum &metaEnum)
{
- if (!enumType)
+ if (metaEnum.isPrivate() || metaEnum.isAnonymous())
return;
- QString enumFlagName = enumType->isFlags() ? QLatin1String("flag") : QLatin1String("enum");
- QString enumPythonType = cpythonTypeNameExt(enumType);
+ EnumTypeEntryCPtr enumType = metaEnum.typeEntry();
+ Q_ASSERT(enumType);
- const FlagsTypeEntry *flags = nullptr;
- if (enumType->isFlags())
- flags = static_cast<const FlagsTypeEntry *>(enumType);
+ static const char enumPythonVar[] = "EType";
- s << "// Register converter for " << enumFlagName << " '" << enumType->qualifiedCppName()
- << "'.\n{\n";
- {
- Indentation indent(s);
- QString typeName = fixedCppTypeName(enumType);
- s << "SbkConverter *converter = Shiboken::Conversions::createConverter("
- << enumPythonType << ',' << '\n';
- {
- Indentation indent(s);
- s << cppToPythonFunctionName(typeName, typeName) << ");\n";
- }
+ s << "// Register converter for enum '" << enumType->qualifiedCppName()
+ << "'.\n{\n" << indent;
- if (flags) {
- QString enumTypeName = fixedCppTypeName(flags->originator());
- QString toCpp = pythonToCppFunctionName(enumTypeName, typeName);
- QString isConv = convertibleToCppFunctionName(enumTypeName, typeName);
- writeAddPythonToCppConversion(s, QLatin1String("converter"), toCpp, isConv);
- }
+ const QString typeName = fixedCppTypeName(enumType);
+ s << "SbkConverter *converter = Shiboken::Conversions::createConverter("
+ << enumPythonVar << ',' << '\n' << indent
+ << cppToPythonFunctionName(typeName, typeName) << ");\n" << outdent;
- QString toCpp = pythonToCppFunctionName(typeName, typeName);
- QString isConv = convertibleToCppFunctionName(typeName, typeName);
- writeAddPythonToCppConversion(s, QLatin1String("converter"), toCpp, isConv);
+ const QString toCpp = pythonToCppFunctionName(typeName, typeName);
+ const QString isConv = convertibleToCppFunctionName(typeName, typeName);
+ writeAddPythonToCppConversion(s, u"converter"_s, toCpp, isConv);
+ s << "Shiboken::Enum::setTypeConverter(" << enumPythonVar
+ << ", converter);\n";
- if (flags) {
- QString toCpp = pythonToCppFunctionName(QLatin1String("number"), typeName);
- QString isConv = convertibleToCppFunctionName(QLatin1String("number"), typeName);
- writeAddPythonToCppConversion(s, QLatin1String("converter"), toCpp, isConv);
- }
+ 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 << "Shiboken::Enum::setTypeConverter(" << enumPythonType
- << ", converter, " << (enumType->isFlags() ? "true" : "false") << ");\n";
-
- QString signature = enumType->qualifiedCppName();
- // Replace "QFlags<Class::Option>" by "Class::Options"
- if (flags && signature.startsWith(QLatin1String("QFlags<")) && signature.endsWith(QLatin1Char('>'))) {
- signature.chop(1);
- signature.remove(0, 7);
- const int lastQualifierPos = signature.lastIndexOf(QLatin1String("::"));
- if (lastQualifierPos != -1) {
- signature.replace(lastQualifierPos + 2, signature.size() - lastQualifierPos - 2,
- flags->flagsName());
- } else {
- signature = flags->flagsName();
- }
- }
-
- while (true) {
- s << "Shiboken::Conversions::registerConverterName(converter, \""
- << signature << "\");\n";
- const int qualifierPos = signature.indexOf(QLatin1String("::"));
- if (qualifierPos != -1)
- signature.remove(0, qualifierPos + 2);
- else
- break;
- }
- if (flags) {
- // 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";
- }
-
- }
- s << "}\n";
-
- if (!flags)
- writeEnumConverterInitialization(s, static_cast<const EnumTypeEntry *>(enumType)->flags());
+ s << outdent << "}\n";
}
-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";
+ s << '&' << targetTypeName << "_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";
- }
- 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 QString typeName = fixedCppTypeName(type);
+ s << ", " << cppToPythonFunctionName(typeName, targetTypeName) << ");\n";
- auto klass = AbstractMetaClass::findClass(api().classes(), type.instantiations().at(0).typeEntry());
- if (!klass)
- return;
+ 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);
+ }
- const auto classes = klass->typeSystemBaseClasses();
- if (classes.isEmpty())
- return;
+ 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);
+ }
- s << "// Register SmartPointer converter for type '" << cppSignature << "'." << '\n'
- << "///////////////////////////////////////////////////////////////////////////////////////\n\n";
-
- for (auto k : classes) {
- auto smartTargetType = findSmartPointerInstantiation(k->typeEntry());
- if (smartTargetType.has_value()) {
- s << "// Convert to SmartPointer derived class: ["
- << smartTargetType->cppSignature() << "]\n";
- const QString converter = u"Shiboken::Conversions::getConverter(\""_qs
- + smartTargetType->cppSignature() + u"\")"_qs;
- writeConversionRegister(type, fixedCppTypeName(smartTargetType.value()), 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, const TypeEntry *externalType,
+void CppGenerator::writeExtendedConverterInitialization(TextStream &s,
+ const TypeEntryCPtr &externalType,
const AbstractMetaClassCList &conversions)
{
s << "// Extended implicit conversions for " << externalType->qualifiedTargetLangName()
<< ".\n";
- for (const AbstractMetaClass *sourceClass : conversions) {
- const QString converterVar = cppApiVariableName(externalType->targetLangPackage()) + QLatin1Char('[')
- + 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()) + QLatin1String("_mi_init");
+ 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))
@@ -4242,7 +4305,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()
@@ -4251,18 +4314,18 @@ 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))
return true;
}
- const ComplexTypeEntry *baseType = metaClass->typeEntry()->baseContainerType();
+ ComplexTypeEntryCPtr baseType = metaClass->typeEntry()->baseContainerType();
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())
@@ -4280,63 +4343,57 @@ 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_flags;
QString tp_init;
QString tp_new;
QString tp_dealloc;
QString tp_hash;
QString tp_call;
const QString className = chopType(cpythonTypeName(metaClass));
- QString baseClassName;
AbstractMetaFunctionCList ctors;
- const auto &allCtors = metaClass->queryFunctions(FunctionQueryOption::Constructors);
+ const auto &allCtors = metaClass->queryFunctions(FunctionQueryOption::AnyConstructor);
for (const auto &f : allCtors) {
- if (!f->isPrivate() && !f->isModifiedRemoved() && !classContext.forSmartPointer())
+ if (!f->isPrivate() && !f->isModifiedRemoved()
+ && f->functionType() != AbstractMetaFunction::MoveConstructorFunction) {
ctors.append(f);
+ }
}
- if (!metaClass->baseClass())
- baseClassName = QLatin1String("SbkObject_TypeF()");
-
bool onlyPrivCtor = !metaClass->hasNonPrivateConstructor();
const bool isQApp = usePySideExtensions()
- && metaClass->inheritsFrom(u"QCoreApplication"_qs);
+ && inheritsFrom(metaClass, u"QCoreApplication"_s);
- tp_flags = QLatin1String("Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE");
+ QString tp_flags = u"Py_TPFLAGS_DEFAULT"_s;
+ if (!metaClass->attributes().testFlag(AbstractMetaClass::FinalCppClass))
+ tp_flags += u"|Py_TPFLAGS_BASETYPE"_s;
if (metaClass->isNamespace() || metaClass->hasPrivateDestructor()) {
tp_dealloc = metaClass->hasPrivateDestructor() ?
- QLatin1String("SbkDeallocWrapperWithPrivateDtor") :
- QLatin1String("Sbk_object_dealloc /* PYSIDE-832: Prevent replacement of \"0\" with subtype_dealloc. */");
+ u"SbkDeallocWrapperWithPrivateDtor"_s :
+ u"Sbk_object_dealloc /* PYSIDE-832: Prevent replacement of \"0\" with subtype_dealloc. */"_s;
tp_init.clear();
} else {
tp_dealloc = isQApp
- ? QLatin1String("&SbkDeallocQAppWrapper") : QLatin1String("&SbkDeallocWrapper");
+ ? u"&SbkDeallocQAppWrapper"_s : u"&SbkDeallocWrapper"_s;
if (!onlyPrivCtor && !ctors.isEmpty())
tp_init = cpythonFunctionName(ctors.constFirst());
}
@@ -4348,53 +4405,59 @@ void CppGenerator::writeClassDefinition(TextStream &s,
? cpythonSetattroFunctionName(metaClass) : QString();
if (metaClass->hasPrivateDestructor() || onlyPrivCtor) {
- // tp_flags = QLatin1String("Py_TPFLAGS_DEFAULT");
+ // tp_flags = u"Py_TPFLAGS_DEFAULT"_s;
// This is not generally possible, because PySide does not care about
// privacy the same way. This worked before the heap types were used,
// because inheritance is not really checked for static types.
- // Instead, we check this at runtime, see SbkObjectTypeTpNew.
- if (metaClass->fullName().startsWith(QLatin1String("PySide6.Qt"))) {
+ // Instead, we check this at runtime, see SbkObjectType_tp_new.
+ if (metaClass->fullName().startsWith(u"PySide6.Qt")) {
// PYSIDE-595: No idea how to do non-inheritance correctly.
// Since that is only relevant in shiboken, I used a shortcut for
// PySide.
- tp_new = QLatin1String("SbkObjectTpNew");
+ tp_new = u"SbkObject_tp_new"_s;
}
else {
- tp_new = QLatin1String("SbkDummyNew /* PYSIDE-595: Prevent replacement "
- "of \"0\" with base->tp_new. */");
+ tp_new = u"SbkDummyNew /* PYSIDE-595: Prevent replacement "
+ "of \"0\" with base->tp_new. */"_s;
}
}
else if (isQApp) {
- tp_new = QLatin1String("SbkQAppTpNew"); // PYSIDE-571: need singleton app
+ tp_new = u"SbkQApp_tp_new"_s; // PYSIDE-571: need singleton app
}
else {
- tp_new = QLatin1String("SbkObjectTpNew");
+ tp_new = u"SbkObject_tp_new"_s;
}
- tp_flags.append(QLatin1String("|Py_TPFLAGS_HAVE_GC"));
+ tp_flags.append(u"|Py_TPFLAGS_HAVE_GC"_s);
QString tp_richcompare;
- if (!metaClass->isNamespace() && metaClass->hasComparisonOperatorOverload())
- tp_richcompare = cpythonBaseName(metaClass) + QLatin1String("_richcompare");
+ 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);
@@ -4405,39 +4468,33 @@ void CppGenerator::writeClassDefinition(TextStream &s,
s << "// Class Definition -----------------------------------------------\n"
"extern \"C\" {\n";
- if (!metaClass->typeEntry()->hashFunction().isEmpty())
- tp_hash = QLatin1Char('&') + cpythonBaseName(metaClass) + QLatin1String("_HashFunc");
-
- const auto callOp = metaClass->findFunction(QLatin1String("operator()"));
- if (!callOp.isNull() && !callOp->isModifiedRemoved())
- tp_call = QLatin1Char('&') + cpythonFunctionName(callOp);
+ if (hasHashFunction(metaClass))
+ tp_hash = u'&' + cpythonBaseName(metaClass) + u"_HashFunc"_s;
- QString computedClassTargetFullName;
- if (!classContext.forSmartPointer())
- computedClassTargetFullName = getClassTargetFullName(metaClass);
- else
- computedClassTargetFullName = getClassTargetFullName(classContext.preciseType());
+ const auto callOp = metaClass->findFunction("operator()");
+ if (callOp && !callOp->isModifiedRemoved())
+ tp_call = u'&' + cpythonFunctionName(callOp);
- const QString typePtr = QLatin1String("_") + className
- + QLatin1String("_Type");
+ const QString typePtr = u"_"_s + className
+ + u"_Type"_s;
s << "static PyTypeObject *" << typePtr << " = nullptr;\n"
<< "static PyTypeObject *" << className << "_TypeF(void)\n"
<< "{\n" << indent << "return " << typePtr << ";\n" << outdent
<< "}\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(QLatin1String("__str__")))
+ << pyTypeSlotEntry("Py_tp_str", m_tpFuncs.value(u"__str__"_s))
<< pyTypeSlotEntry("Py_tp_getattro", tp_getattro)
<< pyTypeSlotEntry("Py_tp_setattro", tp_setattro)
- << pyTypeSlotEntry("Py_tp_traverse", className + QLatin1String("_traverse"))
- << pyTypeSlotEntry("Py_tp_clear", className + QLatin1String("_clear"))
+ << pyTypeSlotEntry("Py_tp_traverse", className + u"_traverse"_s)
+ << pyTypeSlotEntry("Py_tp_clear", className + u"_clear"_s)
<< pyTypeSlotEntry("Py_tp_richcompare", tp_richcompare)
- << pyTypeSlotEntry("Py_tp_iter", m_tpFuncs.value(QLatin1String("__iter__")))
- << pyTypeSlotEntry("Py_tp_iternext", m_tpFuncs.value(QLatin1String("__next__")))
- << pyTypeSlotEntry("Py_tp_methods", className + QLatin1String("_methods"))
+ << pyTypeSlotEntry("Py_tp_iter", m_tpFuncs.value(u"__iter__"_s))
+ << pyTypeSlotEntry("Py_tp_iternext", m_tpFuncs.value(u"__next__"_s))
+ << pyTypeSlotEntry("Py_tp_methods", className + u"_methods"_s)
<< pyTypeSlotEntry("Py_tp_getset", tp_getset)
<< pyTypeSlotEntry("Py_tp_init", tp_init)
<< pyTypeSlotEntry("Py_tp_new", tp_new);
@@ -4450,61 +4507,58 @@ 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);
}
s << "{0, " << NULL_PTR << "}\n" << outdent << "};\n";
- int packageLevel = packageName().count(QLatin1Char('.')) + 1;
+ int packageLevel = packageName().count(u'.') + 1;
s << "static PyType_Spec " << className << "_spec = {\n" << indent
- << '"' << packageLevel << ':' << computedClassTargetFullName << "\",\n"
+ << '"' << packageLevel << ':' << getClassTargetFullName(metaClass) << "\",\n"
<< "sizeof(SbkObject),\n0,\n" << tp_flags << ",\n"
<< className << "_slots\n" << outdent
<< "};\n\n} //extern \"C\"\n";
}
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);
- s << m.returnType << ' ' << funcName << '(' << m.arguments << ")\n{\n";
- writeInvalidPyObjectCheck(s, QLatin1String("self"));
+ s << m.returnType << ' ' << funcName << '(' << m.arguments << ")\n{\n" << indent;
- writeCppSelfDefinition(s, func, context);
+ writeCppSelfDefinition(s, func, context, ErrorReturn::Default);
const AbstractMetaArgument *lastArg = func->arguments().isEmpty()
? nullptr : &func->arguments().constLast();
writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionAny,
TypeSystem::TargetLangCode, func, false, lastArg);
- s<< "}\n\n";
+ s << outdent << "}\n\n";
}
}
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);
CodeSnipList snips = func->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode);
s << seq.returnType << ' ' << funcName << '(' << seq.arguments << ")\n{\n" << indent;
- writeInvalidPyObjectCheck(s, QLatin1String("self"));
- writeCppSelfDefinition(s, func, context);
+ writeCppSelfDefinition(s, func, context, ErrorReturn::Default);
const AbstractMetaArgument *lastArg = func->arguments().isEmpty() ? nullptr : &func->arguments().constLast();
writeCodeSnips(s, snips,TypeSystem::CodeSnipPositionAny,
@@ -4520,26 +4574,26 @@ void CppGenerator::writeSequenceMethods(TextStream &s,
static const QHash<QString, QString> &sqFuncs()
{
static const QHash<QString, QString> result = {
- {QLatin1String("__concat__"), QLatin1String("sq_concat")},
- {QLatin1String("__contains__"), QLatin1String("sq_contains")},
- {QLatin1String("__getitem__"), QLatin1String("sq_item")},
- {QLatin1String("__getslice__"), QLatin1String("sq_slice")},
- {QLatin1String("__len__"), QLatin1String("sq_length")},
- {QLatin1String("__setitem__"), QLatin1String("sq_ass_item")},
- {QLatin1String("__setslice__"), QLatin1String("sq_ass_slice")}
+ {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()) {
- funcs.insert(seq.name, QLatin1Char('&') + cpythonFunctionName(func));
+ if (func) {
+ funcs.insert(seq.name, u'&' + cpythonFunctionName(func));
hasFunctions = true;
}
}
@@ -4548,46 +4602,42 @@ void CppGenerator::writeTypeAsSequenceDefinition(TextStream &s,
//use default implementation
if (!hasFunctions) {
- funcs[QLatin1String("__len__")] = baseName + QLatin1String("__len__");
- funcs[QLatin1String("__getitem__")] = baseName + QLatin1String("__getitem__");
- funcs[QLatin1String("__setitem__")] = baseName + QLatin1String("__setitem__");
+ funcs[u"__len__"_s] = baseName + u"__len__"_s;
+ funcs[u"__getitem__"_s] = baseName + u"__getitem__"_s;
+ funcs[u"__setitem__"_s] = baseName + u"__setitem__"_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{
- {QLatin1String("__mlen__"), QLatin1String("mp_length")},
- {QLatin1String("__mgetitem__"), QLatin1String("mp_subscript")},
- {QLatin1String("__msetitem__"), QLatin1String("mp_ass_subscript")},
+ {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()) {
- const QString entry = QLatin1String("reinterpret_cast<void *>(&")
- + cpythonFunctionName(func) + QLatin1Char(')');
+ if (func) {
+ const QString entry = u"reinterpret_cast<void *>(&"_s
+ + cpythonFunctionName(func) + u')';
funcs.insert(m.name, entry);
- } else {
- funcs.insert(m.name, QLatin1String(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());
}
}
@@ -4595,106 +4645,103 @@ void CppGenerator::writeTypeAsMappingDefinition(TextStream &s,
static const QHash<QString, QString> &nbFuncs()
{
static const QHash<QString, QString> result = {
- {QLatin1String("__add__"), QLatin1String("nb_add")},
- {QLatin1String("__sub__"), QLatin1String("nb_subtract")},
- {QLatin1String("__mul__"), QLatin1String("nb_multiply")},
- {QLatin1String("__div__"), QLatin1String("nb_divide")},
- {QLatin1String("__mod__"), QLatin1String("nb_remainder")},
- {QLatin1String("__neg__"), QLatin1String("nb_negative")},
- {QLatin1String("__pos__"), QLatin1String("nb_positive")},
- {QLatin1String("__invert__"), QLatin1String("nb_invert")},
- {QLatin1String("__lshift__"), QLatin1String("nb_lshift")},
- {QLatin1String("__rshift__"), QLatin1String("nb_rshift")},
- {QLatin1String("__and__"), QLatin1String("nb_and")},
- {QLatin1String("__xor__"), QLatin1String("nb_xor")},
- {QLatin1String("__or__"), QLatin1String("nb_or")},
- {QLatin1String("__iadd__"), QLatin1String("nb_inplace_add")},
- {QLatin1String("__isub__"), QLatin1String("nb_inplace_subtract")},
- {QLatin1String("__imul__"), QLatin1String("nb_inplace_multiply")},
- {QLatin1String("__idiv__"), QLatin1String("nb_inplace_divide")},
- {QLatin1String("__imod__"), QLatin1String("nb_inplace_remainder")},
- {QLatin1String("__ilshift__"), QLatin1String("nb_inplace_lshift")},
- {QLatin1String("__irshift__"), QLatin1String("nb_inplace_rshift")},
- {QLatin1String("__iand__"), QLatin1String("nb_inplace_and")},
- {QLatin1String("__ixor__"), QLatin1String("nb_inplace_xor")},
- {QLatin1String("__ior__"), QLatin1String("nb_inplace_or")},
- {boolT(), QLatin1String("nb_nonzero")}
+ {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 + QLatin1String("___nb_bool"));
+ 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 == QLatin1String("__div__") || nbName == QLatin1String("__idiv__"))
- continue; // excludeFromPy3K
const auto nbIt = nb.constFind(nbName);
- if (nbIt != nb.constEnd()) {
- const QString fixednbName = nbName == boolT()
- ? QLatin1String("nb_bool") : it.value();
- s << "{Py_" << fixednbName << ", reinterpret_cast<void *>("
- << nbIt.value() << ")},\n";
- }
- }
-
- auto nbIt = nb.constFind(QLatin1String("__div__"));
- if (nbIt != nb.constEnd())
- s << "{Py_nb_true_divide, reinterpret_cast<void *>(" << nbIt.value() << ")},\n";
-
- nbIt = nb.constFind(QLatin1String("__idiv__"));
- 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;
- writeCppSelfDefinition(s, context, false, false, true);
+ 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())
conversionCode = cpythonToPythonConversionFunction(metaClass);
@@ -4703,19 +4750,21 @@ void CppGenerator::writeCopyFunction(TextStream &s, const GeneratorContext &cont
s << "PyObject *" << PYTHON_RETURN_VAR << " = " << conversionCode
<< CPP_SELF_VAR << ");\n";
- writeFunctionReturnErrorCheckSection(s);
+ 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);
@@ -4729,9 +4778,8 @@ QString CppGenerator::cppFieldAccess(const AbstractMetaField &metaField,
void CppGenerator::writeGetterFunction(TextStream &s,
const AbstractMetaField &metaField,
- const GeneratorContext &context) const
+ const GeneratorContext &context)
{
- ErrorCode errorCode(QString::fromLatin1(NULL_PTR));
writeGetterFunctionStart(s, cpythonGetterFunctionName(metaField));
writeCppSelfDefinition(s, context);
@@ -4760,41 +4808,38 @@ void CppGenerator::writeGetterFunction(TextStream &s,
if (fieldType.isCppIntegralPrimitive() || fieldType.isEnum()) {
s << getFullTypeNameWithoutModifiers(fieldType) << " cppOut_local = " << cppField << ";\n";
- cppField = QLatin1String("cppOut_local");
+ cppField = u"cppOut_local"_s;
}
s << "PyObject *pyOut = {};\n";
if (newWrapperSameObject) {
// Special case colocated field with same address (first field in a struct)
s << "if (reinterpret_cast<void *>("
- << cppField
- << ") == reinterpret_cast<void *>("
- << CPP_SELF_VAR << ")) {\n";
- {
- Indentation indent(s);
- s << "pyOut = reinterpret_cast<PyObject *>(Shiboken::Object::findColocatedChild("
- << "reinterpret_cast<SbkObject *>(self), "
- << cpythonTypeNameExt(fieldType)
- << "));\n";
- s << "if (pyOut) {\n";
- {
- Indentation indent(s);
- s << "Py_IncRef(pyOut);\n"
- << "return pyOut;\n";
- }
- s << "}\n";
- }
+ << cppField << ") == reinterpret_cast<void *>("
+ << CPP_SELF_VAR << ")) {\n" << indent
+ << "pyOut = reinterpret_cast<PyObject *>(Shiboken::Object::findColocatedChild("
+ << "reinterpret_cast<SbkObject *>(self), "
+ << cpythonTypeNameExt(fieldType) << "));\n"
+ << "if (pyOut != nullptr) {\n" << indent
+ << "Py_IncRef(pyOut);\n"
+ << "return pyOut;\n"
+ << outdent << "}\n";
// Check if field wrapper has already been created.
- s << "} else if (Shiboken::BindingManager::instance().hasWrapper(" << cppField << ")) {" << "\n";
- {
- Indentation indent(s);
- s << "pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper("
- << cppField << "));" << "\n"
- << "Py_IncRef(pyOut);" << "\n"
- << "return pyOut;" << "\n";
- }
- s << "}\n";
- // Create and register new wrapper
+ s << outdent << "} else if (Shiboken::BindingManager::instance().hasWrapper("
+ << cppField << ")) {" << "\n" << indent
+ << "pyOut = reinterpret_cast<PyObject *>(Shiboken::BindingManager::instance().retrieveWrapper("
+ << cppField << "));" << "\n"
+ << "Py_IncRef(pyOut);" << "\n"
+ << "return pyOut;" << "\n"
+ << outdent << "}\n";
+ // 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"
@@ -4807,57 +4852,52 @@ 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)
{
- ErrorCode errorCode(0);
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";
- {
- Indentation indent(s);
- s << "Py_XDECREF(pyResult);\nreturn {};\n";
- }
- s << "}\nreturn pyResult;\n" << outdent << "}\n\n";
+ 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);
+ writeCppSelfDefinition(s, context, ErrorReturn::Zero);
s << "if (pyIn == " << NULL_PTR << ") {\n" << indent
- << "PyErr_SetString(PyExc_TypeError, \"'"
- << name << "' may not be deleted\");\n"
+ << "Shiboken::Errors::setInvalidTypeDeletion(\"" << name << "\");\n"
<< "return -1;\n"
<< outdent << "}\n";
s << PYTHON_TO_CPPCONVERSION_STRUCT << ' ' << PYTHON_TO_CPP_VAR << ";\n"
<< "if (!";
- writeTypeCheck(s, type, QLatin1String("pyIn"), isNumber(type.typeEntry()));
+ writeTypeCheck(s, type, u"pyIn"_s, isNumber(type.typeEntry()));
s << ") {\n" << indent
- << "PyErr_SetString(PyExc_TypeError, \"wrong type attributed to '"
- << name << "', '" << type.name() << "' or convertible type expected\");\n"
+ << "Shiboken::Errors::setSetterTypeError(\"" << name << "\", \""
+ << type.name() << "\");\n"
<< "return -1;\n"
<< outdent << "}\n\n";
}
void CppGenerator::writeSetterFunction(TextStream &s,
const AbstractMetaField &metaField,
- const GeneratorContext &context) const
+ const GeneratorContext &context)
{
- ErrorCode errorCode(0);
-
const AbstractMetaType &fieldType = metaField.type();
writeSetterFunctionPreamble(s, metaField.name(), cpythonSetterFunctionName(metaField),
fieldType, context);
@@ -4888,215 +4928,193 @@ 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)
{
- ErrorCode errorCode(0);
- 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";
- {
- Indentation indent(s);
- s << "return -1;\n";
- }
- s << CPP_SELF_VAR << "->" << property.write() << "(cppOut);\n"
+ << "if (" << shibokenErrorsOccurred << ")\n" << indent
+ << "return -1;\n" << outdent
+ << CPP_SELF_VAR << "->" << property.write() << "(cppOut);\n"
<< "return 0;\n" << outdent << "}\n\n";
}
-void CppGenerator::writeRichCompareFunction(TextStream &s,
- const GeneratorContext &context) const
+void CppGenerator::writeRichCompareFunctionHeader(TextStream &s,
+ const QString &baseName,
+ const GeneratorContext &context)
{
- const AbstractMetaClass *metaClass = context.metaClass();
- QString baseName = cpythonBaseName(metaClass);
s << "static PyObject * ";
s << baseName << "_richcompare(PyObject *self, PyObject *" << PYTHON_ARG
<< ", int op)\n{\n" << indent;
- writeCppSelfDefinition(s, context, false, false, true);
- writeUnusedVariableCast(s, QLatin1String(CPP_SELF_VAR));
- s << "PyObject *" << PYTHON_RETURN_VAR << "{};\n"
- << PYTHON_TO_CPPCONVERSION_STRUCT << ' ' << PYTHON_TO_CPP_VAR << ";\n";
- writeUnusedVariableCast(s, QLatin1String(PYTHON_TO_CPP_VAR));
- s << '\n';
+ writeCppSelfDefinition(s, context, ErrorReturn::Default, CppSelfDefinitionFlag::CppSelfAsReference);
+ s << sbkUnusedVariableCast(CPP_SELF_VAR)
+ << "PyObject *" << PYTHON_RETURN_VAR << "{};\n"
+ << PYTHON_TO_CPPCONVERSION_STRUCT << ' ' << PYTHON_TO_CPP_VAR << ";\n"
+ << sbkUnusedVariableCast(PYTHON_TO_CPP_VAR) << '\n';
+}
- s << "switch (op) {\n";
- {
- Indentation indent(s);
- const QList<AbstractMetaFunctionCList> &groupedFuncs =
- filterGroupedOperatorFunctions(metaClass, OperatorQueryOption::ComparisonOp);
- for (const AbstractMetaFunctionCList &overloads : groupedFuncs) {
- const auto rfunc = overloads[0];
+void CppGenerator::writeRichCompareFunction(TextStream &s,
+ const GeneratorContext &context) const
+{
+ const auto metaClass = context.metaClass();
+ QString baseName = cpythonBaseName(metaClass);
+ writeRichCompareFunctionHeader(s, baseName, context);
- QString operatorId = ShibokenGenerator::pythonRichCompareOperatorId(rfunc);
- s << "case " << operatorId << ':' << '\n';
+ s << "switch (op) {\n" << indent;
+ const QList<AbstractMetaFunctionCList> &groupedFuncs =
+ filterGroupedOperatorFunctions(metaClass, OperatorQueryOption::ComparisonOp);
+ for (const AbstractMetaFunctionCList &overloads : groupedFuncs) {
+ const auto rfunc = overloads[0];
- Indentation indent(s);
+ const auto op = rfunc->comparisonOperatorType().value();
+ s << "case " << AbstractMetaFunction::pythonRichCompareOpCode(op)
+ << ":\n" << indent;
- QString op = rfunc->originalName();
- op = op.right(op.size() - QLatin1String("operator").size());
+ int alternativeNumericTypes = 0;
+ for (const auto &func : overloads) {
+ if (!func->isStatic() &&
+ ShibokenGenerator::isNumber(func->arguments().at(0).type().typeEntry()))
+ alternativeNumericTypes++;
+ }
- int alternativeNumericTypes = 0;
- for (const auto &func : overloads) {
- if (!func->isStatic() &&
- ShibokenGenerator::isNumber(func->arguments().at(0).type().typeEntry()))
- alternativeNumericTypes++;
+ bool first = true;
+ OverloadData overloadData(overloads, api());
+ const OverloadDataList &nextOverloads = overloadData.children();
+ for (const auto &od : nextOverloads) {
+ const auto func = od->referenceFunction();
+ if (func->isStatic())
+ continue;
+ auto argType = getArgumentType(func, 0);
+ if (!first) {
+ s << " else ";
+ } else {
+ first = false;
}
-
- bool first = true;
- OverloadData overloadData(overloads, api());
- const OverloadDataList &nextOverloads = overloadData.children();
- for (const auto &od : nextOverloads) {
- const auto func = od->referenceFunction();
- if (func->isStatic())
- continue;
- auto argType = getArgumentType(func, 0);
- if (!first) {
- s << " else ";
- } else {
- first = false;
+ s << "if (";
+ writeTypeCheck(s, argType, PYTHON_ARG,
+ alternativeNumericTypes == 1 || isPyInt(argType));
+ s << ") {\n" << indent
+ << "// " << func->signature() << '\n';
+ writeArgumentConversion(s, argType, CPP_ARG0,
+ PYTHON_ARG, ErrorReturn::Default,
+ metaClass,
+ QString(), func->isUserAdded());
+ // If the function is user added, use the inject code
+ bool generateOperatorCode = true;
+ if (func->isUserAdded()) {
+ CodeSnipList snips = func->injectedCodeSnips();
+ if (!snips.isEmpty()) {
+ writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionAny,
+ TypeSystem::TargetLangCode, func,
+ false /* uses PyArgs */, &func->arguments().constLast());
+ generateOperatorCode = false;
}
- s << "if (";
- writeTypeCheck(s, argType, QLatin1String(PYTHON_ARG), alternativeNumericTypes == 1 || isPyInt(argType));
- s << ") {\n";
- {
- Indentation indent(s);
- s << "// " << func->signature() << '\n';
- writeArgumentConversion(s, argType, QLatin1String(CPP_ARG0),
- QLatin1String(PYTHON_ARG), metaClass,
- QString(), func->isUserAdded());
-
- // If the function is user added, use the inject code
- bool generateOperatorCode = true;
- if (func->isUserAdded()) {
- CodeSnipList snips = func->injectedCodeSnips();
- if (!snips.isEmpty()) {
- writeCodeSnips(s, snips, TypeSystem::CodeSnipPositionAny,
- TypeSystem::TargetLangCode, func,
- false /* uses PyArgs */, &func->arguments().constLast());
- generateOperatorCode = false;
- }
- }
- if (generateOperatorCode) {
- if (!func->isVoid())
- s << func->type().cppSignature() << " " << CPP_RETURN_VAR << " = ";
- // expression
- if (func->isPointerOperator())
- s << '&';
- s << CPP_SELF_VAR << ' ' << op << '(';
- if (argType.shouldDereferenceArgument())
- s << '*';
- s << CPP_ARG0 << ");\n"
- << PYTHON_RETURN_VAR << " = ";
- if (!func->isVoid())
- writeToPythonConversion(s, func->type(), metaClass, QLatin1String(CPP_RETURN_VAR));
- else
- s << "Py_None;\n" << "Py_INCREF(Py_None)";
- s << ";\n";
- }
- }
- s << '}';
}
-
- s << " else {\n";
- if (operatorId == QLatin1String("Py_EQ") || operatorId == QLatin1String("Py_NE")) {
- Indentation indent(s);
- s << PYTHON_RETURN_VAR << " = "
- << (operatorId == QLatin1String("Py_EQ") ? "Py_False" : "Py_True") << ";\n"
- << "Py_INCREF(" << PYTHON_RETURN_VAR << ");\n";
- } else {
- Indentation indent(s);
- s << "goto " << baseName << "_RichComparison_TypeError;\n";
+ if (generateOperatorCode) {
+ if (!func->isVoid())
+ s << func->type().cppSignature() << " " << CPP_RETURN_VAR << " = ";
+ // expression
+ if (func->isPointerOperator())
+ s << '&';
+ s << CPP_SELF_VAR << ' '
+ << AbstractMetaFunction::cppComparisonOperator(op) << " (";
+ auto generatorArg = GeneratorArgument::fromMetaType(argType);
+ if (generatorArg.indirections != 0)
+ s << QByteArray(generatorArg.indirections, '*');
+ s << CPP_ARG0 << ");\n"
+ << PYTHON_RETURN_VAR << " = ";
+ if (!func->isVoid()) {
+ writeToPythonConversion(s, func->type(), metaClass,
+ CPP_RETURN_VAR);
+ } else {
+ s << "Py_None;\n" << "Py_INCREF(Py_None)";
+ }
+ s << ";\n";
}
- s << "}\n\n";
-
- s << "break;\n";
+ s << outdent << '}';
}
- s << "default:\n";
- {
- Indentation indent(s);
- s << "// PYSIDE-74: By default, we redirect to object's tp_richcompare (which is `==`, `!=`).\n"
- << "return FallbackRichCompare(self, " << PYTHON_ARG << ", op);\n"
- << "goto " << baseName << "_RichComparison_TypeError;\n";
+
+ s << " else {\n";
+ if (op == AbstractMetaFunction::OperatorEqual ||
+ op == AbstractMetaFunction::OperatorNotEqual) {
+ s << indent << PYTHON_RETURN_VAR << " = "
+ << (op == AbstractMetaFunction::OperatorEqual ? "Py_False" : "Py_True") << ";\n"
+ << "Py_INCREF(" << PYTHON_RETURN_VAR << ");\n" << outdent;
+ } else {
+ s << indent << "return Shiboken::returnFromRichCompare("
+ << PYTHON_RETURN_VAR << ");\n" << outdent;
}
- }
- s << "}\n\n";
+ s << "}\n\n";
- s << "if (" << PYTHON_RETURN_VAR << " && !PyErr_Occurred())\n";
- {
- Indentation indent(s);
- s << "return " << PYTHON_RETURN_VAR << ";\n";
+ s << "break;\n" << outdent;
}
- s << baseName << "_RichComparison_TypeError:\n"
- << "PyErr_SetString(PyExc_NotImplementedError, \"operator not implemented.\");\n"
- << returnStatement(m_currentErrorCode) << '\n' << '\n'
- << outdent << "}\n\n";
+ s << "default:\n" << indent
+ << richCompareComment
+ << "return FallbackRichCompare(self, " << PYTHON_ARG << ", op);\n"
+ << outdent << outdent << "}\n\n"
+ << "return Shiboken::returnFromRichCompare(" << PYTHON_RETURN_VAR << ");\n" << outdent
+ << "}\n\n";
}
-QString CppGenerator::methodDefinitionParameters(const OverloadData &overloadData) const
+// Return a flag combination for PyMethodDef
+QByteArrayList CppGenerator::methodDefinitionParameters(const OverloadData &overloadData) const
{
const bool usePyArgs = overloadData.pythonFunctionWrapperUsesListOfArguments();
- const auto func = overloadData.referenceFunction();
int min = overloadData.minArgs();
int max = overloadData.maxArgs();
- QString result;
- QTextStream s(&result);
- s << "reinterpret_cast<PyCFunction>("
- << cpythonFunctionName(func) << "), ";
+ QByteArrayList result;
if ((min == max) && (max < 2) && !usePyArgs) {
- if (max == 0)
- s << "METH_NOARGS";
- else
- s << "METH_O";
+ result.append(max == 0 ? QByteArrayLiteral("METH_NOARGS")
+ : QByteArrayLiteral("METH_O"));
} else {
- s << "METH_VARARGS";
+ result.append(QByteArrayLiteral("METH_VARARGS"));
if (overloadData.hasArgumentWithDefaultValue())
- s << "|METH_KEYWORDS";
+ result.append(QByteArrayLiteral("METH_KEYWORDS"));
}
// METH_STATIC causes a crash when used for global functions (also from
// invisible namespaces).
- auto ownerClass = func->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())
- s << "|METH_STATIC";
+ result.append(QByteArrayLiteral("METH_STATIC"));
if (overloadData.hasClassMethod())
- s << "|METH_CLASS";
+ result.append(QByteArrayLiteral("METH_CLASS"));
}
return result;
}
-void CppGenerator::writeMethodDefinitionEntries(TextStream &s,
- const OverloadData &overloadData,
- qsizetype maxEntries) const
+QList<PyMethodDefEntry>
+ CppGenerator::methodDefinitionEntries(const OverloadData &overloadData) const
{
+
const QStringList names = overloadData.referenceFunction()->definitionNames();
- const QString parameters = methodDefinitionParameters(overloadData);
- const qsizetype count = maxEntries > 0
- ? qMin(names.size(), maxEntries) : names.size();
- for (qsizetype i = 0; i < count; ++i) {
- if (i)
- s << ",\n";
- s << "{\"" << names.at(i) << "\", " << parameters << '}';
- }
+ const QString funcName = cpythonFunctionName(overloadData.referenceFunction());
+ const QByteArrayList parameters = methodDefinitionParameters(overloadData);
+
+ QList<PyMethodDefEntry> result;
+ result.reserve(names.size());
+ for (const auto &name : names)
+ result.append({name, funcName, parameters, {}});
+ return result;
}
-void CppGenerator::writeMethodDefinition(TextStream &s,
- const OverloadData &overloadData) const
+QString CppGenerator::pythonSignature(const AbstractMetaType &type) const
{
- const auto func = overloadData.referenceFunction();
- if (m_tpFuncs.contains(func->name()))
- return;
-
- if (OverloadData::hasStaticAndInstanceFunctions(overloadData.overloads())) {
- s << cpythonMethodDefinitionName(func);
- } else {
- writeMethodDefinitionEntries(s, overloadData);
+ 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();
}
- s << ',' << '\n';
+ return type.pythonSignature();
}
// Format the type signature of a function parameter
@@ -5110,17 +5128,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();
@@ -5134,12 +5157,6 @@ QString CppGenerator::signatureParameter(const AbstractMetaArgument &arg) const
if (size > 1)
s << ']';
- if (!arg.defaultValueExpression().isEmpty()) {
- s << '=';
- QString e = arg.defaultValueExpression();
- e.replace(QLatin1String("::"), QLatin1String("."));
- s << e;
- }
return result;
}
@@ -5156,181 +5173,213 @@ 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 << QLatin1String("self");
+ args << PYTHON_SELF_VAR;
const auto &arguments = f->arguments();
for (qsizetype i = 0, size = arguments.size(); i < size; ++i) {
- QString t = f->pyiTypeReplaced(i + 1);
- if (t.isEmpty()) {
- t = signatureParameter(arguments.at(i));
- } else {
- t.prepend(u':');
- t.prepend(arguments.at(i).name());
+ 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(arg);
+ } else {
+ t.prepend(u':');
+ t.prepend(arg.name());
+ }
+ QString defaultValue = arg.defaultValueExpression();
+ if (!defaultValue.isEmpty())
+ t += u'=' + defaultValue.replace(u"::"_s, u"."_s);
+ args.append(t);
}
- args.append(t);
}
// mark the multiple signatures as such, to make it easier to generate different code
if (multiple)
s << idx-- << ':';
- s << funcName << '(' << args.join(QLatin1Char(',')) << ')';
- if (!f->isVoid()) {
- QString t = f->pyiTypeReplaced(0);
- if (t.isEmpty())
- t = f->type().pythonSignature();
- s << "->" << t;
- }
+ s << funcName << '(' << args.join(u',') << ')';
+
+ QString returnType = f->pyiTypeReplaced(0); // pyi or modified type
+ if (returnType.isEmpty() && !f->isVoid())
+ returnType = pythonSignature(f->type());
+ if (!returnType.isEmpty())
+ s << "->" << returnType;
+
s << '\n';
}
}
-void CppGenerator::writeEnumsInitialization(TextStream &s, AbstractMetaEnumList &enums) const
+void CppGenerator::writeEnumsInitialization(TextStream &s, AbstractMetaEnumList &enums)
{
if (enums.isEmpty())
return;
- s << "// Initialization of enums.\n\n";
- for (const AbstractMetaEnum &cppEnum : qAsConst(enums)) {
+ bool preambleWritten = false;
+ bool etypeUsed = false;
+
+ for (const AbstractMetaEnum &cppEnum : std::as_const(enums)) {
if (cppEnum.isPrivate())
continue;
- writeEnumInitialization(s, cppEnum);
+ if (!preambleWritten) {
+ s << "// Initialization of enums.\n"
+ << "Shiboken::AutoDecRef tpDict{};\n"
+ << "PyTypeObject *EType{};\n\n";
+ preambleWritten = true;
+ }
+ 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 == QLatin1String("None")
- || name == QLatin1String("False")
- || name == QLatin1String("True"))
- name += QLatin1Char('_');
- 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) const
+bool CppGenerator::writeEnumInitialization(TextStream &s, const AbstractMetaEnum &cppEnum)
{
- const AbstractMetaClass *enclosingClass = cppEnum.targetLangEnclosingClass();
- bool hasUpperEnclosingClass = enclosingClass && enclosingClass->targetLangEnclosingClass() != nullptr;
- const EnumTypeEntry *enumTypeEntry = cppEnum.typeEntry();
+ const auto enclosingClass = cppEnum.targetLangEnclosingClass();
+ const bool hasUpperEnclosingClass = enclosingClass
+ && enclosingClass->targetLangEnclosingClass();
+ EnumTypeEntryCPtr enumTypeEntry = cppEnum.typeEntry();
QString enclosingObjectVariable;
if (enclosingClass)
enclosingObjectVariable = cpythonTypeName(enclosingClass);
else if (hasUpperEnclosingClass)
- enclosingObjectVariable = QLatin1String("enclosingClass");
+ enclosingObjectVariable = u"enclosingClass"_s;
else
- enclosingObjectVariable = QLatin1String("module");
+ enclosingObjectVariable = u"module"_s;
s << "// Initialization of ";
s << (cppEnum.isAnonymous() ? "anonymous enum identified by enum value" : "enum");
s << " '" << cppEnum.name() << "'.\n";
- QString enumVarTypeObj;
- if (!cppEnum.isAnonymous()) {
- int packageLevel = packageName().count(QLatin1Char('.')) + 1;
- FlagsTypeEntry *flags = enumTypeEntry->flags();
- if (flags) {
- // 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(QLatin1Char('.')) + 1);
- s << cpythonTypeNameExt(flags) << " = PySide::QFlags::create(\""
- << packageLevel << ':' << fullPath << flags->flagsName() << "\", "
- << cpythonEnumName(cppEnum) << "_number_slots);\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();
- enumVarTypeObj = cpythonTypeNameExt(enumTypeEntry);
-
- s << enumVarTypeObj << " = Shiboken::Enum::"
- << ((enclosingClass || hasUpperEnclosingClass) ? "createScopedEnum" : "createGlobalEnum")
- << '(' << enclosingObjectVariable << ',' << '\n';
- {
- Indentation indent(s);
- s << '"' << cppEnum.name() << "\",\n"
- << '"' << packageLevel << ':' << getClassTargetFullName(cppEnum) << "\",\n"
- << '"' << cppEnum.qualifiedCppName() << '"';
- if (flags)
- s << ",\n" << cpythonTypeNameExt(flags);
- s << ");\n";
- }
- s << "if (!" << cpythonTypeNameExt(cppEnum.typeEntry()) << ")\n";
- {
- Indentation indent(s);
- s << returnStatement(m_currentErrorCode) << "\n\n";
+ 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;
}
- 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 = QLatin1String("(long) ");
- if (cppEnum.enclosingClass())
- enumValueText += cppEnum.enclosingClass()->qualifiedCppName() + QLatin1String("::");
- // Fully qualify the value which is required for C++ 11 enum classes.
- if (!cppEnum.isAnonymous())
- enumValueText += cppEnum.name() + QLatin1String("::");
- enumValueText += enumValue.name();
- } 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;
+ }
- const QString mangledName = mangleName(enumValue.name());
- switch (cppEnum.enumKind()) {
- case AnonymousEnum:
+ // 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 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";
- {
- Indentation indent(s);
- s << "PyObject *anonEnumItem = PyLong_FromLong(" << enumValueText << ");\n"
- << "if (PyDict_SetItemString(reinterpret_cast<PyTypeObject *>("
- << enclosingObjectVariable
- << ")->tp_dict, \"" << mangledName << "\", anonEnumItem) < 0)\n";
- {
- Indentation indent(s);
- s << returnStatement(m_currentErrorCode) << '\n';
- }
- s << "Py_DECREF(anonEnumItem);\n";
- }
- s << "}\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";
- {
- Indentation indent(s);
- s << returnStatement(m_currentErrorCode) << '\n';
- }
+ 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 << '(' << enumVarTypeObj << ',' << '\n';
- Indentation indent(s);
- s << enclosingObjectVariable << ", \"" << mangledName << "\", "
- << enumValueText << "))\n"
- << returnStatement(m_currentErrorCode) << '\n';
- }
- break;
- case EnumClass: {
- s << "if (!Shiboken::Enum::createScopedEnumItem("
- << enumVarTypeObj << ',' << '\n';
- Indentation indent(s);
- s << enumVarTypeObj<< ", \"" << mangledName << "\", "
- << enumValueText << "))\n"
- << returnStatement(m_currentErrorCode) << '\n';
- }
- break;
}
}
+ 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"
+ << cpythonTypeNameExtSet(cppEnum.typeEntry()->flags()) << " =\n"
+ << indent << "EType;\n" << outdent;
+ }
writeEnumConverterInitialization(s, cppEnum);
s << "// End of '" << cppEnum.name() << "' enum";
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();
@@ -5352,155 +5401,31 @@ 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)
-{
- FlagsTypeEntry *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)
-{
- FlagsTypeEntry *flagsEntry = cppEnum.typeEntry()->flags();
- if (!flagsEntry)
- 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, QLatin1String("and"), QLatin1String("&"));
- writeFlagsBinaryOperator(s, cppEnum, QLatin1String("or"), QLatin1String("|"));
- writeFlagsBinaryOperator(s, cppEnum, QLatin1String("xor"), QLatin1String("^"));
-
- writeFlagsUnaryOperator(s, cppEnum, QLatin1String("invert"), QLatin1String("~"));
- 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)
-{
- FlagsTypeEntry *flagsEntry = cppEnum.typeEntry()->flags();
- Q_ASSERT(flagsEntry);
-
- 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, QLatin1String("cppResult"));
- s << ";\n" << outdent << "}\n\n";
-}
-
-void CppGenerator::writeFlagsUnaryOperator(TextStream &s, const AbstractMetaEnum &cppEnum,
- const QString &pyOpName,
- const QString &cppOpName, bool boolResult)
-{
- FlagsTypeEntry *flagsEntry = cppEnum.typeEntry()->flags();
- Q_ASSERT(flagsEntry);
-
- s << "PyObject *" << cpythonEnumName(cppEnum) << "___" << pyOpName
- << "__(PyObject *self, PyObject *" << PYTHON_ARG << ")\n{\n" << indent;
-
- 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, QLatin1String("cppResult"));
- 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.
if (metaClass->isNamespace())
initFunctionName += moduleName();
initFunctionName += metaClass->qualifiedCppName();
- initFunctionName.replace(QLatin1String("::"), QLatin1String("_"));
+ initFunctionName.replace(u"::"_s, u"_"_s);
return initFunctionName;
}
-QString CppGenerator::getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClass *metaClass)
+QString
+ CppGenerator::getSimpleClassStaticFieldsInitFunctionName(const AbstractMetaClassCPtr &metaClass)
{
- return QLatin1String("init_") + getSimpleClassInitFunctionName(metaClass)
- + QLatin1String("StaticFields");
+ return u"init_"_s + getSimpleClassInitFunctionName(metaClass)
+ + u"StaticFields"_s;
}
QString CppGenerator::getInitFunctionName(const GeneratorContext &context)
{
- return !context.forSmartPointer()
- ? getSimpleClassInitFunctionName(context.metaClass())
- : getFilteredCppSignatureString(context.preciseType().cppSignature());
+ return getSimpleClassInitFunctionName(context.metaClass());
}
void CppGenerator::writeSignatureStrings(TextStream &s,
@@ -5514,7 +5439,7 @@ void CppGenerator::writeSignatureStrings(TextStream &s,
const auto lines = QStringView{signatures}.split(u'\n', Qt::SkipEmptyParts);
for (auto line : lines) {
// must anything be escaped?
- if (line.contains(QLatin1Char('"')) || line.contains(QLatin1Char('\\')))
+ if (line.contains(u'"') || line.contains(u'\\'))
s << "R\"CPP(" << line << ")CPP\",\n";
else
s << '"' << line << "\",\n";
@@ -5523,13 +5448,13 @@ 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 {};
if (classContext.forSmartPointer())
- return classContext.smartPointerWrapperName();
+ return classContext.effectiveClassName();
const bool isValue = metaClass->typeEntry()->isValue();
const bool hasProtectedDestructor = metaClass->hasProtectedDestructor();
if (((avoidProtectedHack() && hasProtectedDestructor) || isValue)
@@ -5541,128 +5466,162 @@ 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
{
- const ComplexTypeEntry *classTypeEntry = metaClass->typeEntry();
+ ComplexTypeEntryCPtr classTypeEntry = metaClass->typeEntry();
- const AbstractMetaClass *enc = metaClass->targetLangEnclosingClass();
- QString enclosingObjectVariable = enc ? QLatin1String("enclosingClass") : QLatin1String("module");
+ AbstractMetaClassCPtr enc = metaClass->targetLangEnclosingClass();
+ QString enclosingObjectVariable = enc ? u"enclosingClass"_s : u"module"_s;
QString pyTypeName = cpythonTypeName(metaClass);
QString initFunctionName = getInitFunctionName(classContext);
// 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) + QLatin1String("_Type_bases");
- const AbstractMetaClassList baseClasses = metaClass->typeSystemBaseClasses();
- if (metaClass->baseClassNames().size() > 1) {
- s << "PyObject *" << pyTypeBasesVariable
- << " = PyTuple_Pack(" << baseClasses.size() << ',' << '\n';
- Indentation indent(s);
- for (int i = 0, size = baseClasses.size(); i < size; ++i) {
- if (i)
- s << ",\n";
- s << "reinterpret_cast<PyObject *>("
- << cpythonTypeNameExt(baseClasses.at(i)->typeEntry()) << ')';
- }
- s << ");\n\n";
+ QString pyTypeBasesVariable = chopType(pyTypeName) + u"_Type_bases"_s;
+ 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 = QLatin1String("_") + chopType(pyTypeName)
- + QLatin1String("_Type");
+ const QString typePtr = u"_"_s + chopType(pyTypeName)
+ + u"_Type"_s;
- s << typePtr << " = Shiboken::ObjectType::introduceWrapperType(\n";
- {
- Indentation indent(s);
- // 1:enclosingObject
- s << enclosingObjectVariable << ",\n";
- QString typeName;
- if (!classContext.forSmartPointer())
- typeName = metaClass->name();
- else
- typeName = classContext.preciseType().cppSignature();
+ s << typePtr << " = Shiboken::ObjectType::introduceWrapperType(\n" << indent;
+ // 1:enclosingObject
+ s << enclosingObjectVariable << ",\n";
- // 2:typeName
- s << "\"" << typeName << "\",\n";
+ // 2:typeName
+ s << "\"" << metaClass->name() << "\",\n";
- // 3:originalName
- s << "\"";
- if (!classContext.forSmartPointer()) {
- s << metaClass->qualifiedCppName();
- if (classTypeEntry->isObject())
- s << '*';
- } else {
- s << classContext.preciseType().cppSignature();
- }
+ // 3:originalName
+ s << "\"";
+ if (!classContext.forSmartPointer()) {
+ s << metaClass->qualifiedCppName();
+ if (classTypeEntry->isObject())
+ s << '*';
+ } else {
+ s << classContext.preciseType().cppSignature();
+ }
- s << "\",\n";
- // 4:typeSpec
- s << '&' << chopType(pyTypeName) << "_spec,\n";
+ s << "\",\n";
+ // 4:typeSpec
+ s << '&' << chopType(pyTypeName) << "_spec,\n";
- // 5:cppObjDtor
- QString dtorClassName = destructorClassName(metaClass, classContext);
- 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";
- }
+ // 5:cppObjDtor
+ QString dtorClassName = destructorClassName(metaClass, classContext);
+ if (dtorClassName.isEmpty())
+ s << "nullptr,\n";
+ else
+ s << "&Shiboken::callCppDestructor< " << globalScopePrefix(classContext)
+ << dtorClassName << " >,\n";
+
+ // 7:baseTypes
+ s << pyTypeBasesVariable << ".object()," << '\n';
+
+ // 8:wrapperflags
+ QByteArrayList wrapperFlags;
+ if (enc)
+ 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
+ s << wrapperFlags.join(" | ");
- // 7:baseTypes
- if (metaClass->baseClassNames().size() > 1)
- s << pyTypeBasesVariable << ',' << '\n';
- else
- s << "0,\n";
-
- // 8:wrapperflags
- QByteArrayList wrapperFlags;
- if (enc)
- wrapperFlags.append(QByteArrayLiteral("Shiboken::ObjectType::WrapperFlags::InnerClass"));
- if (metaClass->deleteInMainThread())
- wrapperFlags.append(QByteArrayLiteral("Shiboken::ObjectType::WrapperFlags::DeleteInMainThread"));
- if (wrapperFlags.isEmpty())
- s << '0';
- else
- s << wrapperFlags.join(" | ");
- }
- s << ");\nauto *pyType = " << pyTypeName << "; // references " << typePtr << "\n"
+ s << outdent << ");\nauto *pyType = " << pyTypeName << "; // references "
+ << typePtr << "\n"
<< "InitSignatureStrings(pyType, " << initFunctionName << "_SignatureStrings);\n";
- if (usePySideExtensions())
+ 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);
s << '\n';
+ if (classContext.forSmartPointer())
+ writeSmartPointerConverterInitialization(s, classContext.preciseType());
+
// class inject-code target/beginning
if (!classTypeEntry->codeSnips().isEmpty()) {
writeClassCodeSnips(s, classTypeEntry->codeSnips(),
@@ -5672,7 +5631,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) {
@@ -5688,15 +5647,19 @@ void CppGenerator::writeClassRegister(TextStream &s,
}
// Set typediscovery struct or fill the struct of another one
- if (metaClass->isPolymorphic() && metaClass->baseClass()) {
- s << "Shiboken::ObjectType::setTypeDiscoveryFunctionV2(" << cpythonTypeName(metaClass)
- << ", &" << cpythonBaseName(metaClass) << "_typeDiscovery);\n\n";
+ if (needsTypeDiscoveryFunction(metaClass)) {
+ s << "Shiboken::ObjectType::setTypeDiscoveryFunctionV2(\n" << indent
+ << cpythonTypeName(metaClass)
+ << ", &" << cpythonBaseName(metaClass) << "_typeDiscovery);" << outdent << "\n\n";
}
AbstractMetaEnumList classEnums = metaClass->enums();
metaClass->getEnumsFromInvisibleNamespacesToBeGenerated(&classEnums);
- ErrorCode errorCode(QString::fromLatin1(""));
+ if (!classContext.forSmartPointer() && !classEnums.isEmpty())
+ s << "// Pass the ..._EnumFlagInfo to the class.\n"
+ << "SbkObjectType_SetEnumFlagInfo(pyType, " << chopType(pyTypeName)
+ << "_EnumFlagInfo);\n\n";
writeEnumsInitialization(s, classEnums);
if (metaClass->hasSignals())
@@ -5717,25 +5680,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()
@@ -5744,12 +5722,59 @@ void CppGenerator::writeStaticFieldInitialization(TextStream &s, const AbstractM
s << ");\n";
}
}
- s << '\n' << outdent << "}\n";
+ s << "return type;\n" << outdent << "}\n";
+}
+
+enum class QtRegisterMetaType
+{
+ None, Pointer, Value
+};
+
+static bool hasQtMetaTypeRegistrationSpec(const AbstractMetaClassCPtr &c)
+{
+ return c->typeEntry()->qtMetaTypeRegistration() !=
+ TypeSystem::QtMetaTypeRegistration::Unspecified;
+}
+
+// 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 AbstractMetaClassCPtr &c)
+{
+ if (c->isNamespace())
+ return QtRegisterMetaType::None;
+
+ // Specified in type system?
+ const bool isObject = c->isObjectType();
+ switch (c->typeEntry()->qtMetaTypeRegistration()) {
+ case TypeSystem::QtMetaTypeRegistration::Disabled:
+ return QtRegisterMetaType::None;
+ case TypeSystem::QtMetaTypeRegistration::Enabled:
+ case TypeSystem::QtMetaTypeRegistration::BaseEnabled:
+ return isObject ? QtRegisterMetaType::Pointer : QtRegisterMetaType::Value;
+ case TypeSystem::QtMetaTypeRegistration::Unspecified:
+ break;
+ }
+
+ // Is there a "base" specification in some base class, meaning only the
+ // base class is to be registered?
+ if (auto base = recurseClassHierarchy(c, hasQtMetaTypeRegistrationSpec)) {
+ const auto baseSpec = base->typeEntry()->qtMetaTypeRegistration();
+ if (baseSpec == TypeSystem::QtMetaTypeRegistration::BaseEnabled)
+ return QtRegisterMetaType::None;
+ }
+
+ // Default.
+ if (isObject)
+ return isQObject(c) ? QtRegisterMetaType::None : QtRegisterMetaType::Pointer;
+
+ return !c->isAbstract() && c->isDefaultConstructible()
+ ? QtRegisterMetaType::Value : QtRegisterMetaType::None;
}
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())
@@ -5757,10 +5782,10 @@ 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() + QLatin1String("::") + nameVariants.constLast());
+ nameVariants << (enclosingClass->name() + u"::"_s + nameVariants.constLast());
enclosingClass = enclosingClass->enclosingClass();
}
@@ -5770,69 +5795,74 @@ void CppGenerator::writeInitQtMetaTypeFunctionBody(TextStream &s, const Generato
else
className = context.preciseType().cppSignature();
- if (!metaClass->isNamespace() && !metaClass->isAbstract()) {
- // Qt metatypes are registered only on their first use, so we do this now.
- bool canBeValue = false;
- if (!metaClass->isObjectType()) {
- // check if there's a empty ctor
- for (const auto &func : metaClass->functions()) {
- if (func->isConstructor() && !func->arguments().count()) {
- canBeValue = true;
- break;
- }
- }
- }
-
- if (canBeValue) {
- for (const QString &name : qAsConst(nameVariants)) {
- s << "qRegisterMetaType< ::" << className << " >(\"" << name << "\");\n";
- }
- }
+ // Register meta types for signal/slot connections to work
+ // Qt metatypes are registered only on their first use, so we do this now.
+ switch (qtMetaTypeRegistration(metaClass)) {
+ case QtRegisterMetaType::None:
+ break;
+ case QtRegisterMetaType::Pointer:
+ s << "qRegisterMetaType< " << m_gsp << className << " *>();\n";
+ break;
+ case QtRegisterMetaType::Value:
+ for (const QString &name : std::as_const(nameVariants))
+ s << "qRegisterMetaType< " << m_gsp << className << " >(\"" << name << "\");\n";
+ break;
}
for (const AbstractMetaEnum &metaEnum : metaClass->enums()) {
if (!metaEnum.isPrivate() && !metaEnum.isAnonymous()) {
- for (const QString &name : qAsConst(nameVariants)) {
- s << "qRegisterMetaType< ::"
+ for (const QString &name : std::as_const(nameVariants)) {
+ 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;
+ << "_typeDiscovery(void *cptr, PyTypeObject *instanceType)\n{\n" << indent
+ << sbkUnusedVariableCast("cptr")
+ << sbkUnusedVariableCast("instanceType");
if (!polymorphicExpr.isEmpty()) {
- polymorphicExpr = polymorphicExpr.replace(QLatin1String("%1"),
- QLatin1String(" reinterpret_cast< ::")
- + metaClass->qualifiedCppName()
- + QLatin1String(" *>(cptr)"));
- s << " if (" << polymorphicExpr << ")\n";
- {
- Indentation indent(s);
- s << "return cptr;\n";
- }
+ replacePolymorphicIdPlaceHolders(metaClass, &polymorphicExpr);
+ s << "if (" << polymorphicExpr << ")\n" << indent
+ << "return cptr;\n" << outdent;
} else if (metaClass->isPolymorphic()) {
- const AbstractMetaClassList &ancestors = metaClass->allTypeSystemAncestors();
- for (AbstractMetaClass *ancestor : ancestors) {
- if (ancestor->baseClass())
+ const auto &ancestors = metaClass->allTypeSystemAncestors();
+ for (const auto &ancestor : ancestors) {
+ if (ancestor->baseClass() && !ancestor->typeEntry()->isPolymorphicBase())
continue;
if (ancestor->isPolymorphic()) {
- s << "if (instanceType == Shiboken::SbkType< ::"
- << ancestor->qualifiedCppName() << " >())\n";
- Indentation indent(s);
- s << "return dynamic_cast< ::" << metaClass->qualifiedCppName()
- << " *>(reinterpret_cast< ::"<< ancestor->qualifiedCppName() << " *>(cptr));\n";
+ s << "if (instanceType == Shiboken::SbkType< " << m_gsp
+ << ancestor->qualifiedCppName() << " >())\n" << indent
+ << "return dynamic_cast< " << getFullTypeName(metaClass)
+ << " *>(reinterpret_cast< "<< getFullTypeName(ancestor)
+ << " *>(cptr));\n" << outdent;
} else {
qCWarning(lcShiboken).noquote().nospace()
<< metaClass->qualifiedCppName() << " inherits from a non polymorphic type ("
@@ -5845,7 +5875,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;
@@ -5855,7 +5886,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";
@@ -5865,7 +5896,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.
@@ -5875,62 +5906,36 @@ 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, QLatin1String("self")) << ";\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";
}
if (attroCheck.testFlag(AttroCheckFlag::SetattroQObject)) {
s << "Shiboken::AutoDecRef pp(reinterpret_cast<PyObject *>(PySide::Property::getObject(self, name)));\n"
- << "if (!pp.isNull())\n";
- Indentation indent(s);
- s << "return PySide::Property::setValue(reinterpret_cast<PySideProperty *>(pp.object()), self, value);\n";
+ << "if (!pp.isNull())\n" << indent
+ << "return PySide::Property::setValue(reinterpret_cast<PySideProperty *>(pp.object()), self, value);\n"
+ << outdent;
}
if (attroCheck.testFlag(AttroCheckFlag::SetattroUser)) {
auto func = AbstractMetaClass::queryFirstFunction(metaClass->functions(),
FunctionQueryOption::SetAttroFunction);
Q_ASSERT(func);
- s << "{\n";
- {
- Indentation indent(s);
- s << "auto " << CPP_SELF_VAR << " = "
- << cpythonWrapperCPtr(metaClass, QLatin1String("self")) << ";\n";
- writeClassCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionAny,
- TypeSystem::TargetLangCode, context);
- }
- s << "}\n";
+ s << "{\n" << indent
+ << "auto " << CPP_SELF_VAR << " = "
+ << cpythonWrapperCPtr(metaClass, PYTHON_SELF_VAR) << ";\n";
+ writeClassCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionAny,
+ TypeSystem::TargetLangCode, context);
+ s << outdent << "}\n";
}
writeSetattroDefaultReturn(s);
}
-void CppGenerator::writeSmartPointerSetattroFunction(TextStream &s,
- const GeneratorContext &context) const
-{
- Q_ASSERT(context.forSmartPointer());
- writeSetattroDefinition(s, context.metaClass());
- s << "// Try to find the 'name' attribute, by retrieving the PyObject for the corresponding C++ object held by the smart pointer.\n"
- << "PyObject *rawObj = PyObject_CallMethod(self, "
- << SMART_POINTER_GETTER << ", 0);\n";
- s << "if (rawObj) {\n";
- {
- Indentation indent(s);
- s << "int hasAttribute = PyObject_HasAttr(rawObj, name);\n"
- << "if (hasAttribute) {\n";
- {
- Indentation indent(s);
- s << "return PyObject_GenericSetAttr(rawObj, name, value);\n";
- }
- s << "}\nPy_DECREF(rawObj);\n";
- }
- s << "}\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;
@@ -5940,11 +5945,11 @@ 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 = QLatin1String("PySide::getMetaDataFromQObject(")
- + cpythonWrapperCPtr(qobjectClass, QLatin1String("self"))
- + QLatin1String(", self, name)");
+ result = u"PySide::getHiddenDataFromQObject("_s
+ + cpythonWrapperCPtr(qobjectClass, PYTHON_SELF_VAR)
+ + u", self, name)"_s;
}
return result;
}
@@ -5953,68 +5958,49 @@ 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()
- ? qObjectGetAttroFunction() : QLatin1String("PyObject_GenericGetAttr(self, name)");
+ const QString getattrFunc = usePySideExtensions() && isQObject(metaClass)
+ ? qObjectGetAttroFunction() : u"PyObject_GenericGetAttr(self, name)"_s;
if (attroCheck.testFlag(AttroCheckFlag::GetattroOverloads)) {
s << "// Search the method in the instance dict\n"
- << "if (auto ob_dict = reinterpret_cast<SbkObject *>(self)->ob_dict) {\n";
- {
- Indentation indent(s);
- s << "if (auto meth = PyDict_GetItem(ob_dict, name)) {\n";
- {
- Indentation indent(s);
- s << "Py_INCREF(meth);\n"
- << "return meth;\n";
- }
- s << "}\n";
- }
- s << "}\n"
+ << "auto *ob_dict = SbkObject_GetDict_NoRef(self);\n";
+ s << "if (auto *meth = PyDict_GetItem(ob_dict, name)) {\n" << indent
+ << "Py_INCREF(meth);\nreturn meth;\n" << outdent << "}\n"
<< "// Search the method in the type dict\n"
- << "if (Shiboken::Object::isUserType(self)) {\n";
- {
- Indentation indent(s);
- // 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";
- {
- Indentation indent(s);
- // PYSIDE-1523: PyFunction_Check is not accepting compiled functions.
- s << "if (strcmp(Py_TYPE(meth)->tp_name, \"compiled_function\") == 0)\n";
- {
- Indentation indent(s);
- s << "return Py_TYPE(meth)->tp_descr_get(meth, self, nullptr);\n";
- }
- s << "return PyFunction_Check(meth) ? PyMethod_New(meth, self)\n"
- << " : " << getattrFunc << ";\n";
- }
- s << "}\n";
- }
- s << "}\n";
+ << "if (Shiboken::Object::isUserType(self)) {\n" << indent;
+ // PYSIDE-772: Perform optimized name mangling.
+ s << "Shiboken::AutoDecRef tmp(_Pep_PrivateMangle(self, name));\n"
+ << "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
+ << "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";
const auto &funcs = getMethodsWithBothStaticAndNonStaticMethods(metaClass);
for (const auto &func : funcs) {
QString defName = cpythonMethodDefinitionName(func);
- s << "static PyMethodDef non_static_" << defName << " = {\n";
- {
- Indentation indent(s);
- s << defName << ".ml_name,\n"
- << defName << ".ml_meth,\n"
- << defName << ".ml_flags & (~METH_STATIC),\n"
- << defName << ".ml_doc,\n";
- }
- s << "};\n"
+ s << "static PyMethodDef non_static_" << defName << " = {\n" << indent
+ << defName << ".ml_name,\n"
+ << defName << ".ml_meth,\n"
+ << defName << ".ml_flags & (~METH_STATIC),\n"
+ << defName << ".ml_doc,\n" << outdent
+ << "};\n"
<< "if (Shiboken::String::compare(name, \""
- << func->definitionNames().constFirst() << "\") == 0)\n";
- Indentation indent(s);
- s << "return PyCFunction_NewEx(&non_static_" << defName << ", self, 0);\n";
+ << func->definitionNames().constFirst() << "\") == 0)\n" << indent
+ << "return PyCFunction_NewEx(&non_static_" << defName << ", self, 0);\n"
+ << outdent;
}
}
@@ -6022,93 +6008,108 @@ void CppGenerator::writeGetattroFunction(TextStream &s, AttroCheck attroCheck,
auto func = AbstractMetaClass::queryFirstFunction(metaClass->functions(),
FunctionQueryOption::GetAttroFunction);
Q_ASSERT(func);
- s << "{\n";
- {
- Indentation indent(s);
- s << "auto " << CPP_SELF_VAR << " = "
- << cpythonWrapperCPtr(metaClass, QLatin1String("self")) << ";\n";
- writeClassCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionAny,
- TypeSystem::TargetLangCode, context);
- }
- s << "}\n";
+ s << "{\n" << indent
+ << "auto " << CPP_SELF_VAR << " = "
+ << cpythonWrapperCPtr(metaClass, PYTHON_SELF_VAR) << ";\n";
+ writeClassCodeSnips(s, func->injectedCodeSnips(), TypeSystem::CodeSnipPositionAny,
+ TypeSystem::TargetLangCode, context);
+ s << outdent << "}\n";
}
s << "return " << getattrFunc << ";\n" << outdent << "}\n\n";
}
-void CppGenerator::writeSmartPointerGetattroFunction(TextStream &s, const GeneratorContext &context)
+void CppGenerator::writeNbBoolExpression(TextStream &s, const BoolCastFunction &f,
+ bool invert)
{
- Q_ASSERT(context.forSmartPointer());
- const AbstractMetaClass *metaClass = context.metaClass();
- writeGetattroDefinition(s, metaClass);
- s << "PyObject *tmp = PyObject_GenericGetAttr(self, name);\n"
- << "if (tmp)\n";
- {
- Indentation indent(s);
- s << "return tmp;\n";
- }
- s << "if (!PyErr_ExceptionMatches(PyExc_AttributeError))\n";
- {
- Indentation indent(s);
- s << "return nullptr;\n";
+ if (f.function->isOperatorBool()) {
+ if (invert)
+ s << '!';
+ s << '*' << CPP_SELF_VAR;
+ return;
}
- s << "PyErr_Clear();\n";
+ if (invert != f.invert)
+ s << '!';
+ s << CPP_SELF_VAR << "->" << f.function->name() << "()";
+}
- // This generates the code which dispatches access to member functions
- // and fields from the smart pointer to its pointee.
- s << "// Try to find the 'name' attribute, by retrieving the PyObject for "
- "the corresponding C++ object held by the smart pointer.\n"
- << "if (auto rawObj = PyObject_CallMethod(self, "
- << SMART_POINTER_GETTER << ", 0)) {\n";
- {
- Indentation indent(s);
- s << "if (auto attribute = PyObject_GetAttr(rawObj, name))\n";
- {
- Indentation indent(s);
- s << "tmp = attribute;\n";
- }
- s << "Py_DECREF(rawObj);\n";
- }
- s << "}\n"
- << "if (!tmp) {\n";
- {
- Indentation indent(s);
- s << R"(PyTypeObject *tp = Py_TYPE(self);
-PyErr_Format(PyExc_AttributeError,
- "'%.50s' object has no attribute '%.400s'",
- tp->tp_name, Shiboken::String::toCString(name));
-)";
- }
- s << "}\n"
- << "return tmp;\n" << outdent << "}\n\n";
+void CppGenerator::writeNbBoolFunction(const GeneratorContext &context,
+ const BoolCastFunction &f,
+ TextStream &s)
+{
+ s << "static int " << cpythonBaseName(context.metaClass()) << "___nb_bool(PyObject *self)\n"
+ << "{\n" << indent;
+ writeCppSelfDefinition(s, context, ErrorReturn::MinusOne);
+
+ const bool allowThread = f.function->allowThread();
+ if (allowThread)
+ s << "int result;\n" << BEGIN_ALLOW_THREADS << "\nresult = ";
+ else
+ s << "return ";
+
+ writeNbBoolExpression(s, f);
+ s << " ? 1 : 0;\n";
+
+ if (allowThread)
+ s << END_ALLOW_THREADS << "\nreturn result;\n";
+ s << outdent << "}\n\n";
}
// Write declaration and invocation of the init function for the module init
// function.
-void CppGenerator::writeInitFunc(TextStream &declStr, TextStream &callStr,
- const QString &initFunctionName,
- const TypeEntry *enclosingEntry)
-{
- const bool hasParent =
- enclosingEntry && enclosingEntry->type() != TypeEntry::TypeSystemType;
- declStr << "void init_" << initFunctionName << "(PyObject *"
- << (hasParent ? "enclosingClass" : "module") << ");\n";
- callStr << "init_" << initFunctionName;
- if (hasParent) {
- callStr << "(reinterpret_cast<PyTypeObject *>("
- << cpythonTypeNameExt(enclosingEntry) << ")->tp_dict);\n";
+static void writeInitFuncDecl(TextStream &declStr,
+ const QString &functionName)
+{
+ declStr << "PyTypeObject *" << functionName << "(PyObject *enclosing);\n";
+}
+
+// Write declaration and invocation of the init function for the module init
+// function.
+void CppGenerator::writeInitFuncCall(TextStream &callStr,
+ const QString &functionName,
+ const TypeEntryCPtr &enclosingEntry,
+ const QString &pythonName, bool lazy)
+{
+ const bool hasParent = enclosingEntry && enclosingEntry->type() != TypeEntry::TypeSystemType;
+ 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);
@@ -6117,8 +6118,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())
@@ -6130,34 +6131,69 @@ bool CppGenerator::finishGeneration()
writeMethodWrapper(s_globalFunctionImpl, overloadData, classContext);
writeSignatureInfo(signatureStream, overloadData);
- writeMethodDefinition(s_globalFunctionDef, overloadData);
+ s_globalFunctionDef << methodDefinitionEntries(overloadData);
}
AbstractMetaClassCList classesWithStaticFields;
- for (auto cls : api().classes()){
- if (shouldGenerate(cls)) {
- writeInitFunc(s_classInitDecl, s_classPythonDefines,
- getSimpleClassInitFunctionName(cls),
- cls->typeEntry()->targetLangEnclosingEntry());
+ 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';
+ }
+ const QString initFunc = initFuncPrefix + getSimpleClassInitFunctionName(cls);
+ writeInitFuncDecl(s_classInitDecl, initFunc);
+ writeInitFuncCall(s_classPythonDefines, initFunc,
+ 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.
- const auto &smartPtrs = instantiatedSmartPointers();
- for (const AbstractMetaType &metaType : smartPtrs) {
- GeneratorContext context = contextForSmartPointer(nullptr, metaType);
- writeInitFunc(s_classInitDecl, s_classPythonDefines,
- getInitFunctionName(context),
- metaType.typeEntry()->targetLangEnclosingEntry());
+ for (const auto &smp : api().instantiatedSmartPointers()) {
+ GeneratorContext context = contextForSmartPointer(smp.specialized, smp.type);
+ const auto enclosingClass = context.metaClass()->enclosingClass();
+ auto enclosingTypeEntry = targetLangEnclosingEntry(smp.specialized->typeEntry());
+
+ const QString initFunc = initFuncPrefix + getInitFunctionName(context);
+ writeInitFuncDecl(s_classInitDecl, initFunc);
+ writeInitFuncCall(s_classPythonDefines,
+ initFunc, 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.insert(inst.typeEntry()->include());
+ }
+
+ const ExtendedConverterData extendedConverters = getExtendedConverters();
+ for (auto it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) {
+ TypeEntryCPtr te = it.key();
+ includes.insert(te->include());
+ for (const auto &metaClass : it.value())
+ includes.insert(metaClass->typeEntry()->include());
+ }
+
+ const QList<CustomConversionPtr> &typeConversions = getPrimitiveCustomConversions();
+ for (const auto &c : typeConversions) {
+ if (auto te = c->ownerType())
+ includes.insert(te->include());
}
- QString moduleFileName(outputDirectory() + QLatin1Char('/') + subDirectoryForPackage(packageName()));
- moduleFileName += QLatin1Char('/') + moduleName().toLower() + QLatin1String("_module_wrapper.cpp");
+ QString moduleFileName(outputDirectory() + u'/' + subDirectoryForPackage(packageName()));
+ moduleFileName += u'/' + moduleName().toLower() + u"_module_wrapper.cpp"_s;
FileOut file(moduleFileName);
@@ -6172,67 +6208,77 @@ bool CppGenerator::finishGeneration()
#include <signature.h>
)";
- if (!instantiatedContainers().isEmpty())
+ if (!api().instantiatedContainers().isEmpty())
s << "#include <sbkcontainer.h>\n#include <sbkstaticstrings.h>\n";
if (usePySideExtensions()) {
s << includeQDebug;
- s << R"(#include <pyside.h>
+ s << R"(#include <pysidecleanup.h>
#include <pysideqenum.h>
#include <feature_select.h>
+#include <pysidestaticstrings.h>
)";
}
s << "#include \"" << getModuleHeaderFileName() << '"' << "\n\n";
- for (const Include &include : qAsConst(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)
+ s << nsp->typeEntry()->include();
+ }
TypeDatabase *typeDb = TypeDatabase::instance();
- const TypeSystemTypeEntry *moduleEntry = typeDb->defaultTypeSystemType();
+ TypeSystemTypeEntryCPtr moduleEntry = typeDb->defaultTypeSystemType();
Q_ASSERT(moduleEntry);
s << '\n';
// Extra includes
QList<Include> extraIncludes = moduleEntry->extraIncludes();
- for (const AbstractMetaEnum &cppEnum : qAsConst(globalEnums))
+ for (const AbstractMetaEnum &cppEnum : std::as_const(globalEnums))
extraIncludes.append(cppEnum.typeEntry()->extraIncludes());
if (!extraIncludes.isEmpty()) {
s << "// Extra includes\n";
std::sort(extraIncludes.begin(), extraIncludes.end());
- for (const Include &inc : qAsConst(extraIncludes))
+ for (const Include &inc : std::as_const(extraIncludes))
s << inc;
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
- << "for (int i = 0, imax = SBK_" << moduleName()
- << "_IDX_COUNT; i < imax; i++) {\n" << indent
- << "PyObject *pyType = reinterpret_cast<PyObject *>(" << cppApiVariableName() << "[i]);\n"
- << "Shiboken::AutoDecRef attrName(Py_BuildValue(\"s\", \"staticMetaObject\"));\n"
- << "if (pyType && PyObject_HasAttr(pyType, attrName))\n" << indent
+ << "static PyObject *attrName = Shiboken::PyName::qtStaticMetaObject();\n"
+ << "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 "
@@ -6240,7 +6286,7 @@ bool CppGenerator::finishGeneration()
<< s_globalFunctionImpl.toString() << '\n'
<< "static PyMethodDef " << moduleName() << "_methods[] = {\n" << indent
<< s_globalFunctionDef.toString()
- << "{0} // Sentinel\n" << outdent << "};\n\n"
+ << METHOD_DEF_SENTINEL << outdent << "};\n\n"
<< "// Classes initialization functions "
<< "------------------------------------------------------------\n"
<< s_classInitDecl.toString() << '\n';
@@ -6250,12 +6296,8 @@ bool CppGenerator::finishGeneration()
s << "// Enum definitions "
<< "------------------------------------------------------------\n";
- for (const AbstractMetaEnum &cppEnum : qAsConst(globalEnums)) {
- if (cppEnum.isAnonymous() || cppEnum.isPrivate())
- continue;
+ for (const AbstractMetaEnum &cppEnum : std::as_const(globalEnums))
writeEnumConverterFunctions(s, cppEnum);
- s << '\n';
- }
if (convImpl.size() > 0) {
s << "// Enum converters "
@@ -6265,7 +6307,6 @@ bool CppGenerator::finishGeneration()
<< "} // namespace Shiboken\n\n";
}
- writeFlagsNumberMethodsDefinitions(s, globalEnums);
s << '\n';
}
@@ -6273,20 +6314,19 @@ 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";
}
s << "\n// Module initialization "
<< "------------------------------------------------------------\n";
- ExtendedConverterData extendedConverters = getExtendedConverters();
if (!extendedConverters.isEmpty()) {
s << '\n' << "// Extended Converters.\n\n";
for (ExtendedConverterData::const_iterator it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) {
- const TypeEntry *externalType = it.key();
+ 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);
@@ -6294,10 +6334,9 @@ bool CppGenerator::finishGeneration()
}
}
- const QList<const CustomConversion *> &typeConversions = getPrimitiveCustomConversions();
if (!typeConversions.isEmpty()) {
s << "\n// Primitive Type converters.\n\n";
- for (const CustomConversion *conversion : typeConversions) {
+ for (const auto &conversion : typeConversions) {
s << "// C++ to Python conversion for primitive type '" << conversion->ownerType()->qualifiedCppName() << "'.\n";
writeCppToPythonFunction(s, conversion);
writeCustomConverterFunctions(s, conversion);
@@ -6306,31 +6345,23 @@ bool CppGenerator::finishGeneration()
}
QHash<AbstractMetaType, OpaqueContainerData> opaqueContainers;
- const auto &containers = instantiatedContainers();
+ 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';
}
- // Implicit smart pointers conversions
- const auto smartPointersList = instantiatedSmartPointers();
- if (!smartPointersList.isEmpty()) {
- s << "// SmartPointers converters.\n\n";
- for (const AbstractMetaType &smartPointer : smartPointersList) {
- s << "// C++ to Python conversion for smart pointer type '" << smartPointer.cppSignature() << "'.\n";
- writeSmartPointerConverterFunctions(s, smartPointer);
- }
- s << '\n';
- }
-
s << "static struct PyModuleDef moduledef = {\n"
<< " /* m_base */ PyModuleDef_HEAD_INIT,\n"
<< " /* m_name */ \"" << moduleName() << "\",\n"
@@ -6345,6 +6376,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_"
@@ -6353,10 +6386,9 @@ bool CppGenerator::finishGeneration()
s << "if (" << globalModuleVar << " != nullptr)\n"
<< indent << "return " << globalModuleVar << ";\n" << outdent;
- ErrorCode errorCode(QLatin1String("nullptr"));
// 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
@@ -6370,11 +6402,32 @@ bool CppGenerator::finishGeneration()
<< "}\n\n";
}
- int maxTypeIndex = getMaxTypeIndex() + instantiatedSmartPointers().size();
+ 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"
@@ -6384,13 +6437,18 @@ 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()) {
s << '\n';
- for (const CustomConversion *conversion : typeConversions) {
+ for (const auto &conversion : typeConversions) {
writePrimitiveConverterInitialization(s, conversion);
s << '\n';
}
@@ -6399,7 +6457,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,
@@ -6418,14 +6476,6 @@ bool CppGenerator::finishGeneration()
s << '\n';
}
- if (!smartPointersList.isEmpty()) {
- s << '\n';
- for (const AbstractMetaType &smartPointer : smartPointersList) {
- writeSmartPointerConverterInitialization(s, smartPointer);
- s << '\n';
- }
- }
-
if (!extendedConverters.isEmpty()) {
s << '\n';
for (ExtendedConverterData::const_iterator it = extendedConverters.cbegin(), end = extendedConverters.cend(); it != end; ++it) {
@@ -6437,21 +6487,14 @@ bool CppGenerator::finishGeneration()
writeEnumsInitialization(s, globalEnums);
s << "// Register primitive types converters.\n";
- const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
- for (const PrimitiveTypeEntry *pte : primitiveTypeList) {
- if (!pte->generateCode() || !pte->isCppPrimitive())
+ const PrimitiveTypeEntryCList &primitiveTypeList = primitiveTypes();
+ for (const auto &pte : primitiveTypeList) {
+ if (!pte->generateCode() || !isCppPrimitive(pte))
continue;
if (!pte->referencesType())
continue;
- const TypeEntry *referencedType = pte->basicReferencedTypeEntry();
- QString converter = converterObject(referencedType);
- QStringList cppSignature = pte->qualifiedCppName().split(QLatin1String("::"), Qt::SkipEmptyParts);
- while (!cppSignature.isEmpty()) {
- QString signature = cppSignature.join(QLatin1String("::"));
- s << "Shiboken::Conversions::registerConverterName("
- << converter << ", \"" << signature << "\");\n";
- cppSignature.removeFirst();
- }
+ TypeEntryCPtr referencedType = basicReferencedTypeEntry(pte);
+ registerConverterInScopes(s, pte->qualifiedCppName(), converterObject(referencedType));
}
s << '\n';
@@ -6463,27 +6506,29 @@ bool CppGenerator::finishGeneration()
// of the previously registered types (PYSIDE-1529).
if (!classesWithStaticFields.isEmpty()) {
s << "\n// Static field initialization\n";
- for (auto cls : qAsConst(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 : qAsConst(globalEnums))
+ 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";
}
@@ -6491,7 +6536,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";
@@ -6508,12 +6553,35 @@ static ArgumentOwner getArgumentOwner(const AbstractMetaFunctionCPtr &func, int
return argOwner;
}
+// Whether to enable parent ownership heuristic for a function and its argument.
+// Both must belong to the same class hierarchy and have the same
+// type entry enabling parent management.
+static bool useParentHeuristics(const ApiExtractorResult &api,
+ const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaType &argType)
+{
+ if (!ComplexTypeEntry::isParentManagementEnabled()) // FIXME PYSIDE 7: Remove this
+ return true;
+ const auto owner = func->ownerClass();
+ if (!owner)
+ return false;
+ auto ownerEntry = parentManagementEntry(owner);
+ if (!ownerEntry)
+ return false;
+ auto argTypeEntry = argType.typeEntry();
+ if (!argTypeEntry->isComplex())
+ return false;
+ const auto argClass = AbstractMetaClass::findClass(api.classes(), argTypeEntry);
+ return argClass && parentManagementEntry(argClass) == ownerEntry;
+}
+
bool CppGenerator::writeParentChildManagement(TextStream &s, const AbstractMetaFunctionCPtr &func,
int argIndex,
bool usePyArgs, bool useHeuristicPolicy) const
{
- const int numArgs = func->arguments().count();
+ const int numArgs = func->arguments().size();
bool ctorHeuristicEnabled = func->isConstructor() && useCtorHeuristic() && useHeuristicPolicy;
+ bool heuristicTriggered = false;
ArgumentOwner argOwner = getArgumentOwner(func, argIndex);
ArgumentOwner::Action action = argOwner.action;
@@ -6521,10 +6589,12 @@ bool CppGenerator::writeParentChildManagement(TextStream &s, const AbstractMetaF
int childIndex = argIndex;
if (ctorHeuristicEnabled && argIndex > 0 && argIndex <= numArgs) {
const AbstractMetaArgument &arg = func->arguments().at(argIndex-1);
- if (arg.name() == QLatin1String("parent") && arg.type().isObjectType()) {
+ if (arg.name() == u"parent" && arg.type().isObjectType()
+ && useParentHeuristics(api(), func, arg.type())) {
action = ArgumentOwner::Add;
parentIndex = argIndex;
childIndex = -1;
+ heuristicTriggered = true;
}
}
@@ -6536,28 +6606,32 @@ bool CppGenerator::writeParentChildManagement(TextStream &s, const AbstractMetaF
<< "Argument index for parent tag out of bounds: " << func->signature();
if (action == ArgumentOwner::Remove) {
- parentVariable = QLatin1String("Py_None");
+ parentVariable = u"Py_None"_s;
} else {
if (parentIndex == 0) {
- parentVariable = QLatin1String(PYTHON_RETURN_VAR);
+ parentVariable = PYTHON_RETURN_VAR;
} else if (parentIndex == -1) {
- parentVariable = QLatin1String("self");
+ parentVariable = PYTHON_SELF_VAR;
} else {
parentVariable = usePyArgs
- ? pythonArgsAt(parentIndex - 1) : QLatin1String(PYTHON_ARG);
+ ? pythonArgsAt(parentIndex - 1) : PYTHON_ARG;
}
}
if (childIndex == 0) {
- childVariable = QLatin1String(PYTHON_RETURN_VAR);
+ childVariable = PYTHON_RETURN_VAR;
} else if (childIndex == -1) {
- childVariable = QLatin1String("self");
+ childVariable = PYTHON_SELF_VAR;
} else {
childVariable = usePyArgs
- ? pythonArgsAt(childIndex - 1) : QLatin1String(PYTHON_ARG);
+ ? pythonArgsAt(childIndex - 1) : PYTHON_ARG;
}
- s << "Shiboken::Object::setParent(" << parentVariable << ", " << childVariable << ");\n";
+ s << "// Ownership transferences";
+ if (heuristicTriggered)
+ s << " (constructor heuristics)";
+ s << ".\nShiboken::Object::setParent(" << parentVariable << ", "
+ << childVariable << ");\n";
return true;
}
@@ -6568,7 +6642,7 @@ void CppGenerator::writeParentChildManagement(TextStream &s, const AbstractMetaF
bool usesPyArgs,
bool useHeuristicForReturn) const
{
- const int numArgs = func->arguments().count();
+ const int numArgs = func->arguments().size();
// -1 = return value
// 0 = self
@@ -6588,27 +6662,40 @@ void CppGenerator::writeReturnValueHeuristics(TextStream &s, const AbstractMetaF
|| type.isVoid()
|| func->isStatic()
|| func->isConstructor()
- || func->isTypeModified()) {
+ || func->isTypeModified()
+ || !useParentHeuristics(api(), func, type)
+ // Something like parent(), parentWidget(): No child relationship here.
+ || (func->maybeAccessor() && func->name().startsWith(u"parent"))) {
return;
}
ArgumentOwner argOwner = getArgumentOwner(func, ArgumentOwner::ReturnIndex);
if (argOwner.action == ArgumentOwner::Invalid || argOwner.index != ArgumentOwner::ThisIndex) {
- if (type.isPointerToWrapperType())
- s << "Shiboken::Object::setParent(self, " << PYTHON_RETURN_VAR << ");\n";
+ if (type.isPointerToWrapperType()) {
+ s << "// Ownership transferences (return value heuristics).\n"
+ << "Shiboken::Object::setParent(self, " << PYTHON_RETURN_VAR << ");\n";
+ }
}
}
-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" << indent;
+ << "_HashFunc(PyObject *self)\n{\n" << indent;
writeCppSelfDefinition(s, context);
- s << "return " << hashType << '('
- << metaClass->typeEntry()->hashFunction() << '(';
- if (!metaClass->isObjectType())
+
+ bool deref = true;
+ QString name = metaClass->typeEntry()->hashFunction();
+ if (name.isEmpty())
+ name = metaClass->hashFunction();
+ else
+ deref = !metaClass->isObjectType();
+ Q_ASSERT(!name.isEmpty());
+
+ s << "return " << hashType << '(' << name << '(';
+ if (deref)
s << '*';
s << CPP_SELF_VAR << "));\n"
<< outdent << "}\n\n";
@@ -6617,21 +6704,22 @@ void CppGenerator::writeHashFunction(TextStream &s, const GeneratorContext &cont
void CppGenerator::writeDefaultSequenceMethods(TextStream &s,
const GeneratorContext &context) const
{
- const AbstractMetaClass *metaClass = context.metaClass();
- ErrorCode errorCode(0);
+ const auto metaClass = context.metaClass();
+ ErrorReturn errorReturn = ErrorReturn::Zero;
// __len__
- s << "Py_ssize_t " << cpythonBaseName(metaClass->typeEntry())
+ const QString namePrefix = cpythonBaseName(metaClass->typeEntry());
+ s << "Py_ssize_t " << namePrefix
<< "__len__(PyObject *self)\n{\n" << indent;
- writeCppSelfDefinition(s, context);
+ writeCppSelfDefinition(s, context, errorReturn);
s << "return " << CPP_SELF_VAR << "->size();\n"
<< outdent << "}\n";
// __getitem__
- s << "PyObject *" << cpythonBaseName(metaClass->typeEntry())
+ s << "PyObject *" << namePrefix
<< "__getitem__(PyObject *self, Py_ssize_t _i)\n{\n" << indent;
- writeCppSelfDefinition(s, context);
- writeIndexError(s, QLatin1String("index out of bounds"));
+ writeCppSelfDefinition(s, context, errorReturn);
+ writeIndexError(s, u"index out of bounds"_s, errorReturn);
s << metaClass->qualifiedCppName() << "::const_iterator _item = "
<< CPP_SELF_VAR << "->begin();\n"
@@ -6648,29 +6736,25 @@ void CppGenerator::writeDefaultSequenceMethods(TextStream &s,
const AbstractMetaType &itemType = instantiations.constFirst();
s << "return ";
- writeToPythonConversion(s, itemType, metaClass, QLatin1String("*_item"));
+ writeToPythonConversion(s, itemType, metaClass, u"*_item"_s);
s << ";\n" << outdent << "}\n";
// __setitem__
- ErrorCode errorCode2(-1);
- s << "int " << cpythonBaseName(metaClass->typeEntry())
+ s << "int " << namePrefix
<< "__setitem__(PyObject *self, Py_ssize_t _i, PyObject *pyArg)\n{\n"
<< indent;
- writeCppSelfDefinition(s, context);
- writeIndexError(s, QLatin1String("list assignment index out of range"));
+ errorReturn = ErrorReturn::MinusOne;
+ writeCppSelfDefinition(s, context, errorReturn);
+ writeIndexError(s, u"list assignment index out of range"_s, errorReturn);
s << PYTHON_TO_CPPCONVERSION_STRUCT << ' ' << PYTHON_TO_CPP_VAR << ";\n"
<< "if (!";
- writeTypeCheck(s, itemType, QLatin1String("pyArg"), isNumber(itemType.typeEntry()));
- s << ") {\n";
- {
- Indentation indent(s);
- s << "PyErr_SetString(PyExc_TypeError, \"attributed value with wrong type, '"
- << itemType.name() << "' or other convertible type expected\");\n"
- << "return -1;\n";
- }
- s << "}\n";
- writeArgumentConversion(s, itemType, QLatin1String("cppValue"), QLatin1String("pyArg"), metaClass);
+ writeTypeCheck(s, itemType, u"pyArg"_s, isNumber(itemType.typeEntry()));
+ s << ") {\n" << indent
+ << "Shiboken::Errors::setSequenceTypeError(\"" << itemType.name() << "\");\n"
+ << "return -1;\n" << outdent << "}\n";
+ writeArgumentConversion(s, itemType, u"cppValue"_s,
+ u"pyArg"_s, errorReturn, metaClass);
s << metaClass->qualifiedCppName() << "::iterator _item = "
<< CPP_SELF_VAR << "->begin();\n"
@@ -6679,25 +6763,28 @@ void CppGenerator::writeDefaultSequenceMethods(TextStream &s,
s << "return {};\n" << outdent << "}\n";
}
-void CppGenerator::writeIndexError(TextStream &s, const QString &errorMsg)
+void CppGenerator::writeIndexError(TextStream &s, const QString &errorMsg,
+ ErrorReturn errorReturn)
{
- s << "if (_i < 0 || _i >= (Py_ssize_t) " << CPP_SELF_VAR << "->size()) {\n";
- {
- Indentation indent(s);
- s << "PyErr_SetString(PyExc_IndexError, \"" << errorMsg << "\");\n"
- << returnStatement(m_currentErrorCode) << '\n';
- }
- s << "}\n";
+ s << "if (_i < 0 || _i >= (Py_ssize_t) " << CPP_SELF_VAR << "->size()) {\n"
+ << indent << "PyErr_SetString(PyExc_IndexError, \"" << errorMsg << "\");\n"
+ << 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);
@@ -6708,27 +6795,25 @@ dbg << )";
s << CPP_SELF_VAR << R"(;
buffer.close();
QByteArray str = buffer.data();
-int idx = str.indexOf('(');
+const auto idx = str.indexOf('(');
+auto *typeName = Py_TYPE(self)->tp_name;
if (idx >= 0)
-)";
- {
- Indentation indent(s);
- s << "str.replace(0, idx, Py_TYPE(self)->tp_name);\n";
- }
- s << "str = str.trimmed();\n"
- << "PyObject *mod = PyDict_GetItem(Py_TYPE(self)->tp_dict, Shiboken::PyMagicName::module());\n";
+)" << indent << "str.replace(0, idx, typeName);\n" << outdent
+ << "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 && !strchr(str, '.'))\n";
- {
- Indentation indent(s);
- s << "return Shiboken::String::fromFormat(\"<%s.%s at %p>\", Shiboken::String::toCString(mod), str.constData(), self);\n";
- }
- s << "else\n";
- {
- Indentation indent(s);
- s << "return Shiboken::String::fromFormat(\"<%s at %p>\", str.constData(), self);\n";
- }
- s << outdent << "}\n} // extern C\n\n";
+ 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";
+ 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 3e3e5a21d..5920c9a3a 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator.h
+++ b/sources/shiboken6/generator/shiboken/cppgenerator.h
@@ -1,42 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CPPGENERATOR_H
#define CPPGENERATOR_H
#include "shibokengenerator.h"
-#include "abstractmetalang_enums.h"
+#include "include.h"
+#include "modifications_typedefs.h"
#include <QtCore/QFlags>
-#include <QtCore/QSharedPointer>
+#include <QtCore/QSet>
+#include <QtCore/QHash>
+
+#include <memory>
+#include <utility>
class OverloadDataNode;
class OverloadDataRootNode;
+struct PyMethodDefEntry;
/**
* The CppGenerator generate the implementations of C++ bindings classes.
@@ -44,55 +25,90 @@ class OverloadDataRootNode;
class CppGenerator : public ShibokenGenerator
{
public:
- enum class PythonToCppTypeConversionFlag {
- DisableOpaqueContainers = 0x1
+ enum class ErrorReturn {
+ Default, // "{}"
+ Zero,
+ MinusOne,
+ Void
+ };
+
+ enum CppSelfDefinitionFlag {
+ HasStaticOverload = 0x1,
+ HasClassMethodOverload = 0x2,
+ CppSelfAsReference = 0x4
};
- Q_DECLARE_FLAGS(PythonToCppTypeConversionFlags, PythonToCppTypeConversionFlag)
+ Q_DECLARE_FLAGS(CppSelfDefinitionFlags, CppSelfDefinitionFlag)
CppGenerator();
const char *name() const override { return "Source generator"; }
protected:
- QString fileNameSuffix() const override;
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:
- static void writeInitFunc(TextStream &declStr, TextStream &callStr,
- const QString &initFunctionName,
- const TypeEntry *enclosingEntry = nullptr);
+ struct VirtualMethodReturn
+ {
+ QString statement;
+ bool needsReference = false;
+ };
+
+
+ void generateSmartPointerClass(TextStream &s, const GeneratorContext &classContext);
+ void generateIncludes(TextStream &s, const GeneratorContext &classContext,
+ const IncludeGroupList &includes = {},
+ const AbstractMetaClassCList &innerClasses = {}) const;
+ static void writeInitFuncCall(TextStream &callStr,
+ const QString &functionName,
+ 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;
- void writeVirtualMethodNative(TextStream &s, const AbstractMetaFunctionCPtr &func,
+ static std::pair<QString, QChar> virtualMethodNativeArg(const AbstractMetaFunctionCPtr &func,
+ const AbstractMetaArgument &arg);
+ 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 CodeSnipList &snips,
- const AbstractMetaArgument *lastArg, const TypeEntry *retType,
- const QString &returnStatement) const;
- static QString virtualMethodReturn(TextStream &s, const ApiExtractorResult &api,
- const AbstractMetaFunctionCPtr &func,
- const FunctionModificationList &functionModifications);
+ const QString &funcName, const QList<CodeSnip> &snips,
+ const AbstractMetaArgument *lastArg, const TypeEntryCPtr &retType,
+ const QString &returnStatement, bool hasGil) const;
+
+ 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 writeEnumConverterFunctions(TextStream &s, const TypeEntry *enumType) 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 CustomConversion *customConversion) const;
- void writeConverterRegister(TextStream &s, const AbstractMetaClass *metaClass,
+ const CustomConversionPtr &customConversion) const;
+ void writeConverterRegister(TextStream &s, const AbstractMetaClassCPtr &metaClass,
const GeneratorContext &classContext) const;
- static void writeCustomConverterRegister(TextStream &s, const CustomConversion *customConversion,
+ static void writeCustomConverterRegister(TextStream &s,
+ const CustomConversionPtr &customConversion,
const QString &converterVar);
void writeContainerConverterFunctions(TextStream &s,
@@ -109,60 +125,100 @@ 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;
- void writeMethodWrapperPreamble(TextStream &s, const OverloadData &overloadData,
- const GeneratorContext &context) 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;
- static void writeArgumentsInitializer(TextStream &s, const OverloadData &overloadData);
+ void writeMethodWrapper(TextStream &s, TextStream &definitionStream,
+ TextStream &signatureStream,
+ const AbstractMetaFunctionCList &overloads,
+ const GeneratorContext &classContext) const;
+ static void writeArgumentsInitializer(TextStream &s, const OverloadData &overloadData,
+ ErrorReturn errorReturn = ErrorReturn::Default);
static void writeCppSelfConversion(TextStream &s,
const GeneratorContext &context,
const QString &className,
bool useWrapperClass);
- void writeCppSelfDefinition(TextStream &s,
- const AbstractMetaFunctionCPtr &func,
- const GeneratorContext &context,
- bool hasStaticOverload = false,
- bool hasClassMethodOverload = false) const;
- void writeCppSelfDefinition(TextStream &s,
- const GeneratorContext &context,
- bool hasStaticOverload = false,
- bool hasClassMethodOverload = false,
- bool cppSelfAsReference = false) const;
-
- static void writeErrorSection(TextStream &s, const OverloadData &overloadData) ;
- static void writeFunctionReturnErrorCheckSection(TextStream &s, bool hasReturnValue = true);
+ 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 = {});
+ 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 = {});
- /// Writes the check section for the validity of wrapped C++ objects.
- static void writeInvalidPyObjectCheck(TextStream &s, const QString &pyObj);
+ static void writeErrorSection(TextStream &s,
+ const OverloadData &overloadData,
+ ErrorReturn errorReturn);
- void writeTypeCheck(TextStream &s, const AbstractMetaType &argType,
- const QString &argumentName,
- bool isNumber = false, bool rejectNull = false) const;
- void writeTypeCheck(TextStream &s, const QString &customType,
- const QString &argumentName) const;
- void writeTypeCheck(TextStream& s, const QSharedPointer<OverloadDataNode> &overloadData,
- const QString &argumentName) const;
+ static QString returnErrorWrongArguments(const OverloadData &overloadData,
+ ErrorReturn errorReturn);
- static void writeTypeDiscoveryFunction(TextStream &s, const AbstractMetaClass *metaClass);
+ static void writeFunctionReturnErrorCheckSection(TextStream &s,
+ ErrorReturn errorReturn,
+ bool hasReturnValue = true);
- void writeSetattroDefinition(TextStream &s, const AbstractMetaClass *metaClass) const;
+ /// Writes the check section for the validity of wrapped C++ objects.
+ static void writeInvalidPyObjectCheck(TextStream &s, const QString &pyObj,
+ ErrorReturn errorReturn);
+
+ static void writeTypeCheck(TextStream &s, const AbstractMetaType &argType,
+ const QString &argumentName,
+ bool isNumber = false, bool rejectNull = false);
+ static void writeTypeCheck(TextStream &s, const QString &customType,
+ const QString &argumentName);
+ static void writeTypeCheck(TextStream& s, const std::shared_ptr<OverloadDataNode> &overloadData,
+ const QString &argumentName);
+
+ static void replacePolymorphicIdPlaceHolders(const AbstractMetaClassCPtr &metaClass,
+ QString *id);
+ static void writeTypeDiscoveryFunction(TextStream &s,
+ const AbstractMetaClassCPtr &metaClass);
+
+ 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 writeSmartPointerGetattroFunction(TextStream &s, const GeneratorContext &context);
+ static void writeGetattroDefinition(TextStream &s, const AbstractMetaClassCPtr &metaClass);
+ static void writeSmartPointerGetattroFunction(TextStream &s,
+ const GeneratorContext &context,
+ const BoolCastFunctionOptional &boolCast);
void writeGetattroFunction(TextStream &s, AttroCheck attroCheck,
const GeneratorContext &context) const;
QString qObjectGetAttroFunction() const;
+ 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.
* If implicit conversions, and thus new object allocation, are needed,
@@ -175,11 +231,12 @@ private:
* \param defaultValue an optional default value to be used instead of the conversion result
* \param castArgumentAsUnused if true the converted argument is cast as unused to avoid compiler warnings
*/
- void writeArgumentConversion(TextStream &s, const AbstractMetaType &argType,
- const QString &argName, const QString &pyArgName,
- const AbstractMetaClass *context = nullptr,
- const QString &defaultValue = QString(),
- bool castArgumentAsUnused = false) const;
+ qsizetype writeArgumentConversion(TextStream &s, const AbstractMetaType &argType,
+ const QString &argName, const QString &pyArgName,
+ ErrorReturn errorReturn,
+ const AbstractMetaClassCPtr &context = {},
+ const QString &defaultValue = QString(),
+ bool castArgumentAsUnused = false) const;
/**
* Returns the AbstractMetaType for a function argument.
@@ -192,13 +249,15 @@ private:
static AbstractMetaType
getArgumentType(const AbstractMetaFunctionCPtr &func, int index);
- void writePythonToCppTypeConversion(TextStream &s,
+ /// Writes the Python to C++ Conversion for function arguments and return
+ /// values of virtual methods for wrappers.
+ /// \return The number of indirections in case of return types
+ qsizetype writePythonToCppTypeConversion(TextStream &s,
const AbstractMetaType &type,
const QString &pyIn,
const QString &cppOut,
- const AbstractMetaClass *context = nullptr,
- const QString &defaultValue = {},
- PythonToCppTypeConversionFlags = {}) const;
+ const AbstractMetaClassCPtr &context = {},
+ const QString &defaultValue = {}) const;
/// Writes the conversion rule for arguments of regular and virtual methods.
void writeConversionRule(TextStream &s, const AbstractMetaFunctionCPtr &func,
@@ -225,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,
@@ -234,13 +294,15 @@ private:
/// Writes calls to all the possible method/function overloads.
void writeFunctionCalls(TextStream &s,
const OverloadData &overloadData,
- const GeneratorContext &context) const;
+ const GeneratorContext &context,
+ ErrorReturn errorReturn) const;
/// Writes the call to a single function usually from a collection of overloads.
void writeSingleFunctionCall(TextStream &s,
const OverloadData &overloadData,
const AbstractMetaFunctionCPtr &func,
- const GeneratorContext &context) const;
+ const GeneratorContext &context,
+ ErrorReturn errorReturn) const;
/// Returns the name of a C++ to Python conversion function.
static QString cppToPythonFunctionName(const QString &sourceTypeName, QString targetTypeName = QString());
@@ -248,18 +310,22 @@ private:
/// Returns the name of a Python to C++ conversion function.
static QString pythonToCppFunctionName(const QString &sourceTypeName, const QString &targetTypeName);
static QString pythonToCppFunctionName(const AbstractMetaType &sourceType, const AbstractMetaType &targetType);
- static QString pythonToCppFunctionName(const CustomConversion::TargetToNativeConversion *toNative, const TypeEntry *targetType);
+ static QString pythonToCppFunctionName(const TargetToNativeConversion &toNative,
+ const TypeEntryCPtr &targetType);
/// Returns the name of a Python to C++ convertible check function.
static QString convertibleToCppFunctionName(const QString &sourceTypeName, const QString &targetTypeName);
static QString convertibleToCppFunctionName(const AbstractMetaType &sourceType, const AbstractMetaType &targetType);
- static QString convertibleToCppFunctionName(const CustomConversion::TargetToNativeConversion *toNative, const TypeEntry *targetType);
+ static QString convertibleToCppFunctionName(const TargetToNativeConversion &toNative,
+ const TypeEntryCPtr &targetType);
/// Writes a C++ to Python conversion function.
void writeCppToPythonFunction(TextStream &s, const QString &code, const QString &sourceTypeName,
QString targetTypeName = QString()) const;
- void writeCppToPythonFunction(TextStream &s, const CustomConversion *customConversion) 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,
@@ -282,13 +348,17 @@ private:
const QString &preConversion = QString()) const;
/// Writes a pair of Python to C++ conversion and check functions for implicit conversions.
void writePythonToCppConversionFunctions(TextStream &s,
- const CustomConversion::TargetToNativeConversion *toNative,
- const TypeEntry *targetType) const;
+ const TargetToNativeConversion &toNative,
+ const TypeEntryCPtr &targetType) const;
/// Writes a pair of Python to C++ conversion and check functions for instantiated container types.
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);
@@ -297,120 +367,125 @@ 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,
- const AbstractMetaClass **wrappedClass,
- QString *errorMessage = nullptr);
+ 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 AbstractMetaClassCPtr
+ argumentClassFromIndex(const ApiExtractorResult &api,
+ const AbstractMetaFunctionCPtr &func, int argIndex);
+
void writeMethodCall(TextStream &s, const AbstractMetaFunctionCPtr &func,
const GeneratorContext &context, bool usesPyArgs,
- int maxArgs) const;
+ int maxArgs, const QList<qsizetype> &argumentIndirections,
+ 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);
- QString methodDefinitionParameters(const OverloadData &overloadData) const;
- void writeMethodDefinitionEntries(TextStream &s,
- const OverloadData &overloadData,
- qsizetype maxEntries = -1) const;
- void writeMethodDefinition(TextStream &s,
- const OverloadData &overloadData) const;
+ 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;
+ 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,
+ const GeneratorContext &context);
+ void writeRichCompareFunction(TextStream &s, const GeneratorContext &context) const;
+ void writeSmartPointerRichCompareFunction(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;
+ static void writeEnumsInitialization(TextStream &s, AbstractMetaEnumList &enums);
+ static bool writeEnumInitialization(TextStream &s, const AbstractMetaEnum &metaEnum);
- void writeRichCompareFunction(TextStream &s, const GeneratorContext &context) const;
+ static void writeSignalInitialization(TextStream &s, const AbstractMetaClassCPtr &metaClass);
- void writeEnumsInitialization(TextStream &s, AbstractMetaEnumList &enums) const;
- void writeEnumInitialization(TextStream &s, const AbstractMetaEnum &metaEnum) const;
-
- 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);
+ /// 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 CustomConversion *customConversion);
- static void writeEnumConverterInitialization(TextStream &s, const TypeEntry *enumType);
+ const CustomConversionPtr &customConversion);
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 void writeExtendedConverterInitialization(TextStream &s, const TypeEntry *externalType,
+
+ static QString typeInitStruct(const TypeEntryCPtr &te);
+ static void writeExtendedConverterInitialization(TextStream &s,
+ const TypeEntryCPtr &externalType,
const AbstractMetaClassCList &conversions);
void writeParentChildManagement(TextStream &s, const AbstractMetaFunctionCPtr &func,
@@ -429,66 +504,62 @@ 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;
/// Helper function for writeStdListWrapperMethods.
- static void writeIndexError(TextStream &s, const QString &errorMsg);
-
- QString writeReprFunction(TextStream &s, const GeneratorContext &context,
- uint indirections) const;
-
- AbstractMetaFunctionCPtr boolCast(const AbstractMetaClass *metaClass) const;
- bool hasBoolCast(const AbstractMetaClass *metaClass) const
- { return !boolCast(metaClass).isNull(); }
-
- std::optional<AbstractMetaType>
- findSmartPointerInstantiation(const TypeEntry *entry) const;
+ static void writeIndexError(TextStream &s, const QString &errorMsg,
+ ErrorReturn errorReturn);
+
+ 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(); }
void clearTpFuncs();
+ static QString chopType(QString s);
QHash<QString, QString> m_tpFuncs;
-
- static QString m_currentErrorCode;
- static const char *PYTHON_TO_CPPCONVERSION_STRUCT;
-
- /// Helper class to set and restore the current error code.
- class ErrorCode {
- public:
- explicit ErrorCode(QString errorCode) {
- m_savedErrorCode = CppGenerator::m_currentErrorCode;
- CppGenerator::m_currentErrorCode = errorCode;
- }
- explicit ErrorCode(int errorCode) {
- m_savedErrorCode = CppGenerator::m_currentErrorCode;
- CppGenerator::m_currentErrorCode = QString::number(errorCode);
- }
- ~ErrorCode() {
- CppGenerator::m_currentErrorCode = m_savedErrorCode;
- }
- private:
- QString m_savedErrorCode;
- };
+ QHash<QString, QString> m_nbFuncs;
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(CppGenerator::PythonToCppTypeConversionFlags)
+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 eab57bcc0..00e0cabea 100644
--- a/sources/shiboken6/generator/shiboken/cppgenerator_container.cpp
+++ b/sources/shiboken6/generator/shiboken/cppgenerator_container.cpp
@@ -1,41 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 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 <abstractmetalang.h>
#include "apiextractorresult.h"
#include "ctypenames.h"
+#include "containertypeentry.h"
#include "textstream.h"
+#include "typedatabase.h"
#include <QtCore/QDebug>
#include <algorithm>
+using namespace Qt::StringLiterals;
+
// Write a PyMethodDef entry, allowing for registering C++ functions
// under different names for Python.
static void writeMethod(TextStream &s, const QString &privateObjType,
@@ -75,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 {
@@ -102,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 = static_cast<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"_qs;
- const QString cppArg = u"cppArg"_qs;
-
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
@@ -141,48 +123,79 @@ 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
- << "PyErr_SetString(PyExc_TypeError, \"Wrong type passed to container conversion.\");\n"
+ << "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";
- const QString privateObjType = u"ShibokenSequenceContainerPrivate<"_qs
+ 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 methods = result.name + u"_methods"_qs;
+ 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");
}
+ writeNoArgsMethod(s, privateObjType, "data");
+ writeNoArgsMethod(s, privateObjType, "constData");
s << "{nullptr, nullptr, 0, nullptr} // Sentinel\n"
<< outdent << "};\n\n";
// slots
- const QString slotsList = result.name + u"_slots"_qs;
+ 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());
@@ -192,54 +205,62 @@ CppGenerator::OpaqueContainerData
s << "{0, nullptr}\n" << outdent << "};\n\n";
// spec
- const QString specName = result.name + u"_spec"_qs;
- const QString name = moduleName() + u'.' + result.name;
+ const QString specName = result.name + u"_spec"_s;
+ 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"
<< slotsList << outdent << "\n};\n\n";
// type creation function that sets a key in the type dict.
- const QString typeCreationFName = u"create"_qs + result.name + u"Type"_qs;
+ const QString typeCreationFName = u"create"_s + result.name + u"Type"_s;
s << "static inline PyTypeObject *" << typeCreationFName << "()\n{\n" << indent
- << "static auto *name = Shiboken::PyMagicName::opaque_container();\n"
- << "static auto *opaque_entry = Py_BuildValue(\"{O:O}\", name, Py_True);\n"
- << "static auto *result = SbkType_FromSpecAddDict(&" << specName << ", opaque_entry);\n"
+ << "auto *result = reinterpret_cast<PyTypeObject *>(SbkType_FromSpec(&"
+ << specName << "));\nPy_INCREF(Py_True);\n"
+ << "Shiboken::AutoDecRef tpDict(PepType_GetDict(result));\n"
+ << "PyDict_SetItem(tpDict.object(), "
+ "Shiboken::PyMagicName::opaque_container(), Py_True);\n"
<< "return result;\n" << outdent << "}\n\n";
- // typeF() function
- const QString typeFName = result.name + u"_TypeF"_qs;
+ // _TypeF() function
+ const QString typeFName = result.name + u"_TypeF"_s;
s << "static PyTypeObject *" << typeFName << "()\n{\n" << indent
<< "static PyTypeObject *type = " << typeCreationFName
<< "();\nreturn type;\n" << outdent << "}\n\n";
// creation functions from C++ references
- writeContainerCreationFunc(s, u"create"_qs + result.name, typeFName,
- containerType.cppSignature());
- writeContainerCreationFunc(s, u"createConst"_qs + result.name, typeFName,
- containerType.cppSignature(), true);
+ ContainerCreationFlags flags;
+ if (kind == ContainerTypeEntry::SpanContainer)
+ flags.setFlag(ContainerCreationFlag::Allocate);
+
+ writeContainerCreationFunc(s, u"create"_s + result.name, typeFName,
+ containerType.cppSignature(), flags);
+ flags.setFlag(ContainerCreationFlag::Const);
+ writeContainerCreationFunc(s, u"createConst"_s + result.name, typeFName,
+ containerType.cppSignature(), flags);
// Check function
- result.checkFunctionName = result.name + u"_Check"_qs;
- s << "extern \"C\" int " << result.checkFunctionName << "(PyObject *" << pyArg
- << ")\n{\n" << indent << "return " << pyArg << " != nullptr && "
- << pyArg << " != Py_None && " << pyArg << "->ob_type == "
+ result.checkFunctionName = result.name + u"_Check"_s;
+ 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"_qs + result.name;
+ 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"_qs + result.name + u"PythonToCppConvertible"_qs;
+ 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..44b76f181
--- /dev/null
+++ b/sources/shiboken6/generator/shiboken/cppgenerator_smartpointer.cpp
@@ -0,0 +1,476 @@
+// 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);
+ // Implicit smart pointers conversions
+ writeSmartPointerConverterFunctions(s, classContext.preciseType());
+ 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 abac261d5..f665b30ff 100644
--- a/sources/shiboken6/generator/shiboken/ctypenames.h
+++ b/sources/shiboken6/generator/shiboken/ctypenames.h
@@ -1,56 +1,31 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CTYPENAMES_H
#define CTYPENAMES_H
#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/generatorargument.cpp b/sources/shiboken6/generator/shiboken/generatorargument.cpp
new file mode 100644
index 000000000..e81ad0797
--- /dev/null
+++ b/sources/shiboken6/generator/shiboken/generatorargument.cpp
@@ -0,0 +1,110 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "generatorargument.h"
+#include <abstractmetatype.h>
+#include <messages.h>
+#include <typesystem.h>
+
+#include <QtCore/QDebug>
+#include <QtCore/QSet>
+
+static bool isCppPrimitiveString(const AbstractMetaType &type)
+{
+ return type.referenceType() == NoReference && type.indirections() == 1
+ && AbstractMetaType::cppSignedCharTypes().contains(type.name());
+}
+
+GeneratorArgument GeneratorArgument::fromMetaType(const AbstractMetaType &type)
+{
+ GeneratorArgument result;
+
+ const auto typeEntry = type.typeEntry();
+ if (typeEntry->isCustom() || typeEntry->isVarargs())
+ return result;
+
+ result.indirections = -type.indirectionsV().size();
+ if (isCppPrimitiveString(type)
+ || type.isVoidPointer()
+ || type.typeUsagePattern() == AbstractMetaType::NativePointerAsArrayPattern) {
+ result.indirections += 1;
+ }
+
+ if (typeEntry->isEnum()) {
+ result.type = Type::Enum;
+ } else if (typeEntry->isFlags()) {
+ result.type = Type::Flags;
+ } else if (typeEntry->isContainer()) {
+ result.type = Type::Container;
+ } else {
+ if (typeEntry->isPrimitive())
+ result.type = Type::Primitive;
+
+ const AbstractMetaTypeList &nestedArrayTypes = type.nestedArrayTypes();
+ if (!nestedArrayTypes.isEmpty()) {
+ if (nestedArrayTypes.constLast().isCppPrimitive()) {
+ result.type = Type::CppPrimitiveArray;
+ } else {
+ static QSet<QString> warnedTypes;
+ const QString &signature = type.cppSignature();
+ if (!warnedTypes.contains(signature)) {
+ warnedTypes.insert(signature);
+ qWarning("%s", qPrintable(msgUnknownArrayPointerConversion(signature)));
+ }
+ result.indirections -= 1;
+ }
+ }
+ }
+
+ if (result.type == Type::Other || result.type == Type::Primitive) {
+ if (type.valueTypeWithCopyConstructorOnlyPassed()) {
+ result.flags.setFlag(Flag::TreatAsPointer);
+ } else if ((type.isObjectType() || type.isPointer())
+ && !type.isUserPrimitive() && !type.isExtendedCppPrimitive()) {
+ result.flags.setFlag(Flag::PointerOrObjectType);
+ } else if (type.referenceType() == LValueReference
+ && !type.isUserPrimitive()
+ && !type.isExtendedCppPrimitive()) {
+ result.flags.setFlag(Flag::MayHaveImplicitConversion);
+ }
+ }
+
+ // For implicit conversions or containers, either value or pointer conversion
+ // may occur. An implicit conversion uses value conversion whereas the object
+ // itself uses pointer conversion. For containers, the PyList/container
+ // conversion is by value whereas opaque containers use pointer conversion.
+ // For a container passed by pointer, a local variable is also needed.
+ if (result.flags.testFlag(Flag::MayHaveImplicitConversion)
+ || type.generateOpaqueContainer()
+ || (result.type == Type::Container && result.indirections != 0)) {
+ result.flags.setFlag(Flag::ValueOrPointer);
+ }
+
+ if (result.type == Type::CppPrimitiveArray) {
+ result.conversion = Conversion::CppPrimitiveArray;
+ } else if (result.flags.testFlag(Flag::ValueOrPointer)) {
+ result.conversion = Conversion::ValueOrPointer;
+ ++result.indirections;
+ } else if (result.flags.testAnyFlags(Flag::TreatAsPointer | Flag::PointerOrObjectType)) {
+ result.conversion = Conversion::Pointer;
+ ++result.indirections;
+ }
+
+ return result;
+}
+
+QDebug operator<<(QDebug debug, const GeneratorArgument &a)
+{
+ QDebugStateSaver saver(debug);
+ debug.noquote();
+ debug.nospace();
+ debug << "GeneratorArgument(" << a.type;
+ if (a.conversion != GeneratorArgument::Conversion::Default)
+ debug << ", conversion=" << a.conversion;
+ if (a.flags)
+ debug << ", flags(" << a.flags;
+ if (a.indirections != 0)
+ debug << ", indirections=" << a.indirections;
+ debug << ')';
+ return debug;
+}
diff --git a/sources/shiboken6/generator/shiboken/generatorargument.h b/sources/shiboken6/generator/shiboken/generatorargument.h
new file mode 100644
index 000000000..385ad0f63
--- /dev/null
+++ b/sources/shiboken6/generator/shiboken/generatorargument.h
@@ -0,0 +1,60 @@
+// 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 GENERATORARGUMENT_H
+#define GENERATORARGUMENT_H
+
+#include <QtCore/QFlags>
+#include <QtCore/qobjectdefs.h>
+
+QT_FORWARD_DECLARE_CLASS(QDebug)
+
+class AbstractMetaType;
+
+/// A struct containing information on how the generator processes a function argument.
+struct GeneratorArgument
+{
+ Q_GADGET
+
+public:
+ enum class Type {
+ Other,
+ Primitive,
+ Enum,
+ Flags,
+ Container,
+ CppPrimitiveArray
+ };
+ Q_ENUM(Type)
+
+ enum class Conversion {
+ Default,
+ CppPrimitiveArray, // Similar to Default except default values
+ Pointer,
+ ValueOrPointer
+ };
+ Q_ENUM(Conversion)
+
+ enum class Flag {
+ TreatAsPointer = 0x1,
+ PointerOrObjectType = 0x2,
+ MayHaveImplicitConversion = 0x4,
+ ValueOrPointer = 0x8,
+ };
+ Q_ENUM(Flag)
+ Q_DECLARE_FLAGS(Flags, Flag)
+
+ static GeneratorArgument fromMetaType(const AbstractMetaType &type);
+
+ Flags flags;
+ /// Indirections from generated "cppArg<n>" variable to function argument.
+ qsizetype indirections = 0;
+ Type type = Type::Other;
+ Conversion conversion = Conversion::Default;
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(GeneratorArgument::Flags)
+
+QDebug operator<<(QDebug debug, const GeneratorArgument &a);
+
+#endif // GENERATORARGUMENT_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 0f3dd9fba..7cec9c38e 100644
--- a/sources/shiboken6/generator/shiboken/headergenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/headergenerator.cpp
@@ -1,76 +1,106 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "headergenerator.h"
+#include "configurablescope.h"
+#include "generatorcontext.h"
#include <apiextractorresult.h>
+#include <abstractmetaargument.h>
#include <abstractmetaenum.h>
#include <abstractmetafield.h>
#include <abstractmetafunction.h>
#include <abstractmetalang.h>
#include <abstractmetalang_helpers.h>
-#include <modifications.h>
+#include <codesnip.h>
+#include <clangparser/compilersupport.h>
+#include <exception.h>
#include <typedatabase.h>
#include <reporthandler.h>
#include <textstream.h>
#include <fileout.h>
-#include "parser/codemodel.h"
+#include "containertypeentry.h"
+#include "enumtypeentry.h"
+#include "flagstypeentry.h"
+#include <messages.h>
+#include "namespacetypeentry.h"
+#include "primitivetypeentry.h"
+#include "typedefentry.h"
+#include "typesystemtypeentry.h"
+
+#include "qtcompat.h"
#include <algorithm>
+#include <set>
#include <QtCore/QDir>
#include <QtCore/QTextStream>
#include <QtCore/QVariant>
#include <QtCore/QDebug>
-QString HeaderGenerator::fileNameSuffix() const
+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.
+// Simply search for the text "// C++11: need to declare (unimplemented) destructor".
+// The protected hack is the definition "#define protected public".
+// For most compilers, this "hack" is enabled, because the problem of private
+// destructors simply vanishes.
+//
+// If one does not want to use this hack, then a new problem arises:
+// C++11 requires that a destructor is declared in a wrapper class when it is
+// private in the base class. There is no implementation allowed!
+//
+// Unfortunately, MSVC in recent versions supports C++11, and due to restrictive
+// rules, it is impossible to use the hack with this compiler.
+// More unfortunate: Clang, when C++11 is enabled, also enforces a declaration
+// of a private destructor, but it falsely then creates a linker error!
+//
+// Originally, we wanted to remove the protected hack. But due to the Clang
+// problem, we gave up on removal of the protected hack and use it always
+// when we can. This might change again when the Clang problem is solved.
+
+static bool alwaysGenerateDestructorDeclaration()
{
- return QLatin1String("_wrapper.h");
+ return clang::compiler() == Compiler::Msvc;
}
+const char *HeaderGenerator::protectedHackDefine = R"(// Workaround to access protected functions
+#ifndef protected
+# define protected public
+#endif
+
+)";
+
QString HeaderGenerator::fileNameForContext(const GeneratorContext &context) const
{
- const AbstractMetaClass *metaClass = context.metaClass();
- if (!context.forSmartPointer()) {
- QString fileNameBase = metaClass->qualifiedCppName().toLower();
- fileNameBase.replace(QLatin1String("::"), QLatin1String("_"));
- return fileNameBase + fileNameSuffix();
- }
- QString fileNameBase = getFileNameBaseForSmartPointer(context.preciseType(), metaClass);
- return fileNameBase + fileNameSuffix();
+ 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()) {
@@ -79,145 +109,178 @@ 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;
- if (!classContext.forSmartPointer()) {
- wrapperName = classContext.useWrapper()
- ? classContext.wrapperName() : metaClass->qualifiedCppName();
- } else {
- wrapperName = classContext.smartPointerWrapperName();
- }
- QString outerHeaderGuard = getFilteredCppSignatureString(wrapperName).toUpper();
- QString innerHeaderGuard;
+ QString wrapperName = classContext.effectiveClassName();
+ 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';
- if (classContext.useWrapper() && !typeEntry->extraIncludes().isEmpty()) {
- s << "\n// Extra includes\n";
- for (const Include &inc : typeEntry->extraIncludes())
- s << inc.toString() << '\n';
+ // Includes
+ s << metaClass->typeEntry()->include() << '\n';
+ for (auto &inst : metaClass->templateBaseClassInstantiations())
+ s << inst.typeEntry()->include();
+
+ 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";
- const auto &funcs = filterFunctions(metaClass);
- int maxOverrides = 0;
- for (const auto &func : funcs) {
- if (!func->attributes().testFlag(AbstractMetaFunction::FinalCppMethod)) {
- writeFunction(s, func);
- // PYSIDE-803: Build a boolean cache for unused overrides.
- if (shouldWriteVirtualMethodNative(func))
- maxOverrides++;
- }
- }
- if (!maxOverrides)
- maxOverrides = 1;
-
- //destructor
- // PYSIDE-504: When C++ 11 is used, then the destructor must always be declared.
- // See abstractmetalang.cpp, determineCppWrapper() and generator.h for further
- // reference.
- if (!avoidProtectedHack() || !metaClass->hasPrivateDestructor() || alwaysGenerateDestructor) {
- 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";
+}
+
+void HeaderGenerator::writeWrapperClassDeclaration(TextStream &s,
+ const QString &wrapperName,
+ const GeneratorContext &classContext) const
+{
+ const AbstractMetaClassCPtr metaClass = classContext.metaClass();
+ const auto typeEntry = metaClass->typeEntry();
+ InheritedOverloadSet inheritedOverloads;
+
+ // 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';
+ }
- writeClassCodeSnips(s, metaClass->typeEntry()->codeSnips(),
- TypeSystem::CodeSnipPositionDeclaration, TypeSystem::NativeCode,
- classContext);
+ 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 ((!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
- && usePySideExtensions() && metaClass->isQObject()) {
- s << outdent << "public:\n" << indent <<
-R"(int qt_metacall(QMetaObject::Call call, int id, void **args) override;
+ 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 : qAsConst(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";
-
- 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";
-
- // 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);
- if (!classContext.forSmartPointer()) {
- wrapperName = classContext.useWrapper()
- ? classContext.wrapperName() : metaClass->qualifiedCppName();
- } else {
- wrapperName = classContext.smartPointerWrapperName();
- }
- innerHeaderGuard = getFilteredCppSignatureString(wrapperName).toUpper();
+ if (usePySideExtensions())
+ s << "static void pysideInitQtMetaTypes();\n";
+
+ s << "void resetPyMethodCache();\n"
+ << outdent << "private:\n" << indent;
+
+ 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
@@ -227,8 +290,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,58 +309,52 @@ void HeaderGenerator::writeMemberFunctionWrapper(TextStream &s,
if (i > 0)
s << ", ";
const AbstractMetaArgument &arg = arguments.at(i);
- const TypeEntry *enumTypeEntry = nullptr;
- if (arg.type().isFlags())
- enumTypeEntry = static_cast<const FlagsTypeEntry *>(arg.type().typeEntry())->originator();
- else if (arg.type().isEnum())
- enumTypeEntry = arg.type().typeEntry();
- if (enumTypeEntry)
- s << arg.type().cppSignature() << '(' << arg.name() << ')';
- else
+ const auto &type = arg.type();
+ TypeEntryCPtr enumTypeEntry;
+ if (type.isFlags())
+ enumTypeEntry = std::static_pointer_cast<const FlagsTypeEntry>(type.typeEntry())->originator();
+ else if (type.isEnum())
+ enumTypeEntry = type.typeEntry();
+ if (enumTypeEntry) {
+ s << type.cppSignature() << '(' << arg.name() << ')';
+ } else if (type.passByValue() && type.isUniquePointer()) {
+ s << stdMove(arg.name());
+ } else {
s << arg.name();
+ }
}
s << "); }\n";
}
-void HeaderGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func)
+void HeaderGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func,
+ InheritedOverloadSet *inheritedOverloads,
+ FunctionGeneration generation) const
{
// do not write copy ctors here.
- if (!func->isPrivate() && func->functionType() == AbstractMetaFunction::CopyConstructorFunction) {
+ if (generation.testFlag(FunctionGenerationFlag::WrapperSpecialCopyConstructor)) {
writeCopyCtor(s, func->ownerClass());
return;
}
- if (func->isUserAdded())
- return;
- if (avoidProtectedHack() && func->isProtected() && !func->isConstructor()
- && !func->isOperatorOverload()) {
- writeMemberFunctionWrapper(s, func, QLatin1String("_protected"));
- }
+ if (generation.testFlag(FunctionGenerationFlag::ProtectedWrapper))
+ writeMemberFunctionWrapper(s, func, u"_protected"_s);
- // pure virtual functions need a default implementation
- const bool notAbstract = !func->isAbstract();
- if ((func->isPrivate() && notAbstract && !func->isVisibilityModifiedToPrivate())
- || (func->isModifiedRemoved() && notAbstract))
+ if (generation.testFlag(FunctionGenerationFlag::WrapperConstructor)) {
+ Options option = func->hasSignatureModifications()
+ ? Generator::OriginalTypeDescription : Generator::NoOption;
+ s << functionSignature(func, {}, {}, option) << ";\n";
return;
+ }
- if (avoidProtectedHack() && func->ownerClass()->hasPrivateDestructor()
- && (func->isAbstract() || func->isVirtual()))
- return;
-
- if (func->isConstructor() || func->isAbstract() || func->isVirtual()) {
- Options virtualOption = Generator::OriginalTypeDescription;
-
- const bool virtualFunc = func->isVirtual() || func->isAbstract();
- if (!virtualFunc && !func->hasSignatureModifications())
- virtualOption = Generator::NoOption;
-
- s << functionSignature(func, QString(), QString(), virtualOption);
+ const bool isVirtual = generation.testFlag(FunctionGenerationFlag::VirtualMethod);
+ if (isVirtual) {
+ s << functionSignature(func, {}, {}, Generator::OriginalTypeDescription)
+ << " override;\n";
+ }
- if (virtualFunc)
- s << " override";
- s << ";\n";
- // Check if this method hide other methods in base classes
+ // Check if this method hide other methods in base classes
+ if (isVirtual) {
for (const auto &f : func->ownerClass()->functions()) {
if (f != func
&& !f->isConstructor()
@@ -308,7 +363,7 @@ void HeaderGenerator::writeFunction(TextStream &s, const AbstractMetaFunctionCPt
&& !f->isAbstract()
&& !f->isStatic()
&& f->name() == func->name()) {
- m_inheritedOverloads << f;
+ inheritedOverloads->insert(f);
}
}
@@ -318,28 +373,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) {
@@ -349,19 +390,20 @@ static const AbstractMetaClass *
return nullptr;
}
-void HeaderGenerator::writeTypeIndexValueLine(TextStream &s, const ApiExtractorResult &api,
- const TypeEntry *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 = static_cast<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);
@@ -371,20 +413,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 = static_cast<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())
@@ -392,16 +435,16 @@ 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, metaClass->typeEntry());
+ collectTypeEntryTypeIndexes(api, typeEntry, indexValues);
}
// Format the typedefs for the typedef entries to be generated
static void formatTypeDefEntries(TextStream &s)
{
- QList<const TypedefEntry *> entries;
+ QList<TypedefEntryCPtr> entries;
const auto typeDbEntries = TypeDatabase::instance()->typedefEntries();
for (auto it = typeDbEntries.cbegin(), end = typeDbEntries.cend(); it != end; ++it) {
if (it.value()->generateCode() != 0)
@@ -410,76 +453,262 @@ static void formatTypeDefEntries(TextStream &s)
if (entries.isEmpty())
return;
s << "\n// typedef entries\n";
- for (const auto e : entries) {
+ for (const auto &e : entries) {
const QString name = e->qualifiedCppName();
// Fixme: simplify by using nested namespaces in C++ 17.
const auto components = QStringView{name}.split(u"::");
- const int nameSpaceCount = components.size() - 1;
- for (int n = 0; n < nameSpaceCount; ++n)
+ const auto nameSpaceCount = components.size() - 1;
+ for (qsizetype n = 0; n < nameSpaceCount; ++n)
s << "namespace " << components.at(n) << " {\n";
s << "using " << components.constLast() << " = " << e->sourceType() << ";\n";
- for (int n = 0; n < nameSpaceCount; ++n)
+ for (qsizetype n = 0; n < nameSpaceCount; ++n)
s << "}\n";
}
s << '\n';
}
+// 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 AbstractMetaClassCPtr &c)
+{
+ if (c->isNamespace() || !c->enums().isEmpty()
+ || !c->innerClasses().isEmpty() || c->isTypeDef()) {
+ return false;
+ }
+ if (auto encl = c->enclosingClass())
+ return encl->isNamespace();
+ return true;
+}
-bool HeaderGenerator::finishGeneration()
+static void writeForwardDeclaration(TextStream &s, const AbstractMetaClassCPtr &c)
{
- // Generate the main header for this module.
- // This header should be included by binding modules
- // extendind on top of this one.
- QSet<Include> includes;
- QSet<Include> privateIncludes;
- StringStream macrosStream(TextStream::Language::Cpp);
+ Q_ASSERT(!c->isNamespace());
+ const bool isStruct = c->attributes().testFlag(AbstractMetaClass::Struct);
+ s << (isStruct ? "struct " : "class ");
+ // Do not use name as this can be modified/renamed for target lang.
+ const QString qualifiedCppName = c->qualifiedCppName();
+ const auto lastQualifier = qualifiedCppName.lastIndexOf(u':');
+ if (lastQualifier != -1)
+ s << QStringView{qualifiedCppName}.mid(lastQualifier + 1);
+ else
+ s << qualifiedCppName;
+ s << ";\n";
+}
- const auto snips = TypeDatabase::instance()->defaultTypeSystemType()->codeSnips();
- if (!snips.isEmpty()) {
- writeCodeSnips(macrosStream, snips, TypeSystem::CodeSnipPositionDeclaration,
- TypeSystem::TargetLangCode);
+// Helpers for writing out namespaces hierarchically when writing class
+// forward declarations to the module header. Ensure inline namespaces
+// are marked as such (else clang complains) and namespaces are ordered.
+struct NameSpace {
+ AbstractMetaClassCPtr nameSpace;
+ AbstractMetaClassCList classes;
+};
+
+static bool operator<(const NameSpace &n1, const NameSpace &n2)
+{
+ return n1.nameSpace->name() < n2.nameSpace->name();
+}
+
+using NameSpaces = QList<NameSpace>;
+
+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)
+ return i;
}
+ return -1;
+}
- macrosStream << "// Type indices\nenum : int {\n";
- AbstractMetaClassCList classList = api().classes();
+static void writeNamespaceForwardDeclarationRecursion(TextStream &s, qsizetype idx,
+ const NameSpaces &nameSpaces)
+{
+ auto &root = nameSpaces.at(idx);
+ s << '\n';
+ if (root.nameSpace->isInlineNamespace())
+ s << "inline ";
+ s << "namespace " << root.nameSpace->name() << " {\n" << indent;
+ for (const auto &c : root.classes)
+ writeForwardDeclaration(s, c);
+
+ for (qsizetype i = 0, count = nameSpaces.size(); i < count; ++i) {
+ if (i != idx && nameSpaces.at(i).nameSpace->enclosingClass() == root.nameSpace)
+ writeNamespaceForwardDeclarationRecursion(s, i, nameSpaces);
+ }
+ s << outdent << "}\n";
+}
- std::sort(classList.begin(), classList.end(), [](const AbstractMetaClass *a, const AbstractMetaClass *b) {
- return a->typeEntry()->sbkIndex() < b->typeEntry()->sbkIndex();
- });
+static void writeForwardDeclarations(TextStream &s,
+ const AbstractMetaClassCList &classList)
+{
+ NameSpaces nameSpaces;
+
+ 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;
+ enclNsp = enclNsp->enclosingClass()) {
+ idx = indexOf(nameSpaces, enclNsp);
+ if (idx == -1)
+ nameSpaces.append(NameSpace{enclNsp, {}});
+ }
+ }
+ } else {
+ writeForwardDeclaration(s, c);
+ }
+ }
+
+ std::sort(nameSpaces.begin(), nameSpaces.end());
+
+ // Recursively write out namespaces starting at the root elements.
+ for (qsizetype i = 0, count = nameSpaces.size(); i < count; ++i) {
+ const auto &nsp = nameSpaces.at(i);
+ if (nsp.nameSpace->enclosingClass() == nullptr)
+ writeNamespaceForwardDeclarationRecursion(s, i, nameSpaces);
+ }
+
+ if (!typeSystemEntry->namespaceEnd().isEmpty())
+ s << typeSystemEntry->namespaceEnd() << '\n';
+}
- for (const AbstractMetaClass *metaClass : classList)
- writeTypeIndexValueLines(macrosStream, api(), metaClass);
+// 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;
+};
+
+HeaderGenerator::IndexValues
+ HeaderGenerator::collectTypeIndexes(const AbstractMetaClassCList &classList)
+{
+ IndexValues result;
+
+ 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;
- const AbstractMetaTypeList &instantiatedSmartPtrs = instantiatedSmartPointers();
- for (const AbstractMetaType &metaType : instantiatedSmartPtrs) {
- QString indexName = getTypeIndexVariableName(metaType);
- _writeTypeIndexValue(macrosStream, indexName, smartPointerCountIndex);
- macrosStream << ", // " << metaType.cppSignature() << '\n';
+ for (const auto &smp : api().instantiatedSmartPointers()) {
+ QString indexName = getTypeIndexVariableName(smp.type);
+ result.append({indexName, smartPointerCountIndex, smp.type.cppSignature()});
// Add a the same value for const pointees (shared_ptr<const Foo>).
- const auto ptrName = metaType.typeEntry()->entryName();
- int pos = indexName.indexOf(ptrName, 0, Qt::CaseInsensitive);
+ const auto ptrName = smp.type.typeEntry()->entryName();
+ const auto pos = indexName.indexOf(ptrName, 0, Qt::CaseInsensitive);
if (pos >= 0) {
- indexName.insert(pos + ptrName.size() + 1, QLatin1String("CONST"));
- _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;
+}
+
+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() != nullptr)
+ result.append({getTypeIndexVariableName(ptype), pCount++, {}});
+ }
+
+ for (const AbstractMetaType &container : api().instantiatedContainers()) {
+ result.append({getTypeIndexVariableName(container),
+ pCount++, container.cppSignature()});
+ }
+
+ // Because on win32 the compiler will not accept a zero length array.
+ if (pCount == 0)
+ pCount++;
+ result.append({"SBK_"_L1 + moduleName() + "_CONVERTERS_IDX_COUNT"_L1,
+ pCount, {}});
+ return result;
+}
- _writeTypeIndexValue(macrosStream,
- QLatin1String("SBK_") + moduleName() + QLatin1String("_IDX_COUNT"),
- getMaxTypeIndex() + smartPointerCount);
- macrosStream << "\n};\n";
+// 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 PyTypeObject **" << cppApiVariableName() << ";\n\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";
@@ -487,33 +716,16 @@ bool HeaderGenerator::finishGeneration()
// TODO-CONVERTER ------------------------------------------------------------------------------
// Using a counter would not do, a fix must be made to APIExtractor's getTypeIndex().
- macrosStream << "// Converter indices\nenum : int {\n";
- const PrimitiveTypeEntryList &primitives = primitiveTypes();
- int pCount = 0;
- for (const PrimitiveTypeEntry *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++);
- }
-
- const AbstractMetaTypeList &containers = instantiatedContainers();
- for (const AbstractMetaType &container : containers) {
- _writeTypeIndexValue(macrosStream, getTypeIndexVariableName(container), pCount);
- macrosStream << ", // " << container.cppSignature() << '\n';
- pCount++;
- }
+ const auto converterIndexes = collectConverterIndexes();
+ macrosStream << "// Converter indices\nenum [[deprecated]] : int {\n";
+ for (const auto &ci : converterIndexes)
+ macrosStream << typeIndexUpper(ci);
+ macrosStream << "};\n\n";
- // 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";
+ macrosStream << "// Converter indices\nenum : int {\n";
+ for (const auto &ci : converterIndexes)
+ macrosStream << ci;
+ macrosStream << "};\n";
formatTypeDefEntries(macrosStream);
@@ -521,36 +733,46 @@ bool HeaderGenerator::finishGeneration()
macrosStream << "// Macros for type check\n";
- StringStream typeFunctions(TextStream::Language::Cpp);
- StringStream privateTypeFunctions(TextStream::Language::Cpp);
- if (usePySideExtensions()) {
- typeFunctions << "QT_WARNING_PUSH\n";
- typeFunctions << "QT_WARNING_DISABLE_DEPRECATED\n";
- }
+ TextStream typeFunctions(&parameters.typeFunctions, TextStream::Language::Cpp);
+ TextStream privateTypeFunctions(&privateParameters.typeFunctions, TextStream::Language::Cpp);
+
for (const AbstractMetaEnum &cppEnum : api().globalEnums()) {
if (!cppEnum.isAnonymous()) {
- includes << 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) {
- if (!shouldGenerate(metaClass))
+ for (const auto &metaClass : classList) {
+ const auto classType = metaClass->typeEntry();
+ if (!shouldGenerate(classType))
continue;
- //Includes
- const TypeEntry *classType = metaClass->typeEntry();
+ // Includes
const bool isPrivate = classType->isPrivate();
- auto &includeList = isPrivate ? privateIncludes : includes;
- includeList << classType->include();
+ 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;
- EnumTypeEntry *enumType = cppEnum.typeEntry();
- includeList << enumType->include();
+ if (const auto inc = cppEnum.typeEntry()->include(); inc != classInclude)
+ par.includes.insert(inc);
writeProtectedEnumSurrogate(protEnumsSurrogates, cppEnum);
writeSbkTypeFunction(typeFunctionsStr, cppEnum);
}
@@ -559,19 +781,16 @@ bool HeaderGenerator::finishGeneration()
writeSbkTypeFunction(typeFunctionsStr, metaClass);
}
- for (const AbstractMetaType &metaType : instantiatedSmartPtrs) {
- const TypeEntry *classType = metaType.typeEntry();
- includes << classType->include();
- writeSbkTypeFunction(typeFunctions, metaType);
+ for (const auto &smp : api().instantiatedSmartPointers()) {
+ parameters.includes.insert(smp.type.typeEntry()->include());
+ writeSbkTypeFunction(typeFunctions, smp.type);
}
- if (usePySideExtensions())
- typeFunctions << "QT_WARNING_POP\n";
- const QString moduleHeaderDir = outputDirectory() + QLatin1Char('/')
- + subDirectoryForPackage(packageName()) + QLatin1Char('/');
+ const QString moduleHeaderDir = outputDirectory() + u'/'
+ + subDirectoryForPackage(packageName()) + u'/';
const QString moduleHeaderFileName(moduleHeaderDir + getModuleHeaderFileName());
- QString includeShield(QLatin1String("SBK_") + moduleName().toUpper() + QLatin1String("_PYTHON_H"));
+ QString includeShield(u"SBK_"_s + moduleName().toUpper() + u"_PYTHON_H"_s);
FileOut file(moduleHeaderFileName);
TextStream &s = file.stream;
@@ -588,34 +807,40 @@ bool HeaderGenerator::finishGeneration()
}
s << "#include <sbkpython.h>\n";
+ s << "#include <sbkmodule.h>\n";
s << "#include <sbkconverter.h>\n";
QStringList requiredTargetImports = TypeDatabase::instance()->requiredTargetImports();
if (!requiredTargetImports.isEmpty()) {
s << "// Module Includes\n";
- for (const QString &requiredModule : qAsConst(requiredTargetImports))
+ for (const QString &requiredModule : std::as_const(requiredTargetImports))
s << "#include <" << getModuleHeaderFileName(requiredModule) << ">\n";
s<< '\n';
}
s << "// Bound library includes\n";
- for (const Include &include : qAsConst(includes))
+ for (const Include &include : parameters.includes)
s << include;
+ s << parameters.conditionalIncludes;
- if (!primitiveTypes().isEmpty()) {
- s << "// Conversion Includes - Primitive Types\n";
- const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
- for (const PrimitiveTypeEntry *ptype : primitiveTypeList)
- s << ptype->include();
- s<< '\n';
- }
+ if (leanHeaders()) {
+ writeForwardDeclarations(s, parameters.forwardDeclarations);
+ } else {
+ if (!primitiveTypes().isEmpty()) {
+ s << "// Conversion Includes - Primitive Types\n";
+ const auto &primitiveTypeList = primitiveTypes();
+ for (const auto &ptype : primitiveTypeList)
+ s << ptype->include();
+ s<< '\n';
+ }
- if (!containerTypes().isEmpty()) {
- s << "// Conversion Includes - Container Types\n";
- const ContainerTypeEntryList &containerTypeList = containerTypes();
- for (const ContainerTypeEntry *ctype : containerTypeList)
- s << ctype->include();
- s<< '\n';
+ if (!containerTypes().isEmpty()) {
+ s << "// Conversion Includes - Container Types\n";
+ const ContainerTypeEntryCList &containerTypeList = containerTypes();
+ for (const auto &ctype : containerTypeList)
+ s << ctype->include();
+ s<< '\n';
+ }
}
s << macrosStream.toString() << '\n';
@@ -625,25 +850,21 @@ bool HeaderGenerator::finishGeneration()
<< protEnumsSurrogates.toString() << '\n';
}
- s << "namespace Shiboken\n{\n\n"
- << "// PyType functions, to get the PyObjectType for a type T\n"
- << typeFunctions.toString() << '\n'
- << "} // namespace Shiboken\n\n"
- << "#endif // " << includeShield << "\n\n";
+ writeTypeFunctions(s, parameters.typeFunctions);
+
+ s << "#endif // " << includeShield << "\n\n";
file.done();
- if (hasPrivateClasses()) {
- writePrivateHeader(moduleHeaderDir, includeShield,
- privateIncludes, privateTypeFunctions.toString());
- }
+ if (hasPrivateClasses())
+ writePrivateHeader(moduleHeaderDir, includeShield, privateParameters);
+
return true;
}
void HeaderGenerator::writePrivateHeader(const QString &moduleHeaderDir,
const QString &publicIncludeShield,
- const QSet<Include> &privateIncludes,
- const QString &privateTypeFunctions)
+ const ModuleHeaderParameters &parameters)
{
// Write includes and type functions of private classes
@@ -651,63 +872,90 @@ 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";
ps << "#ifndef " << privateIncludeShield << '\n';
ps << "#define " << privateIncludeShield << "\n\n";
- for (const Include &include : qAsConst(privateIncludes))
+ for (const Include &include : parameters.includes)
ps << include;
+ ps << parameters.conditionalIncludes;
ps << '\n';
+ if (leanHeaders())
+ writeForwardDeclarations(ps, parameters.forwardDeclarations);
+
+ writeTypeFunctions(ps, parameters.typeFunctions);
+
+ ps << "#endif\n";
+ privateFile.done();
+}
+
+void HeaderGenerator::writeTypeFunctions(TextStream &s, const QString &typeFunctions)
+{
+ if (typeFunctions.isEmpty())
+ return;
+
if (usePySideExtensions())
- ps << "QT_WARNING_PUSH\nQT_WARNING_DISABLE_DEPRECATED\n";
+ s << "QT_WARNING_PUSH\nQT_WARNING_DISABLE_DEPRECATED\n";
- ps << "namespace Shiboken\n{\n\n"
+ s << "namespace Shiboken\n{\n\n"
<< "// PyType functions, to get the PyObjectType for a type T\n"
- << privateTypeFunctions << '\n'
+ << typeFunctions << '\n'
<< "} // namespace Shiboken\n\n";
if (usePySideExtensions())
- ps << "QT_WARNING_POP\n";
-
- ps << "#endif\n";
- privateFile.done();
+ 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();
+ const auto te = cppEnum.typeEntry();
+ ConfigurableScope configScope(s, te);
+ s << "template<> inline PyTypeObject *SbkType< " << m_gsp << enumName << " >() ";
+ s << "{ return " << cpythonTypeNameExt(te) << "; }\n";
- s << "template<> inline PyTypeObject *SbkType< ::" << enumName << " >() ";
- s << "{ return " << cpythonTypeNameExt(cppEnum.typeEntry()) << "; }\n";
-
- FlagsTypeEntry *flag = cppEnum.typeEntry()->flags();
+ const auto flag = cppEnum.typeEntry()->flags();
if (flag) {
- s << "template<> inline PyTypeObject *SbkType< ::" << flag->name() << " >() "
+ 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 3d64158e7..03b98e743 100644
--- a/sources/shiboken6/generator/shiboken/headergenerator.h
+++ b/sources/shiboken6/generator/shiboken/headergenerator.h
@@ -1,39 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef HEADERGENERATOR_H
#define HEADERGENERATOR_H
#include "shibokengenerator.h"
+#include "include.h"
+#include "modifications_typedefs.h"
+#include <QtCore/QList>
#include <QtCore/QSet>
+struct IndexValue;
class AbstractMetaFunction;
+struct ModuleHeaderParameters;
/**
* The HeaderGenerator generate the declarations of C++ bindings classes.
@@ -41,36 +21,54 @@ class AbstractMetaFunction;
class HeaderGenerator : public ShibokenGenerator
{
public:
- OptionDescriptions options() const override { return OptionDescriptions(); }
-
const char *name() const override { return "Header generator"; }
+ static const char *protectedHackDefine;
+
protected:
- QString fileNameSuffix() const override;
QString fileNameForContext(const GeneratorContext &context) const override;
void generateClass(TextStream &s, const GeneratorContext &classContext) override;
bool finishGeneration() override;
private:
- void writeCopyCtor(TextStream &s, const AbstractMetaClass *metaClass) const;
- void writeFunction(TextStream &s, const AbstractMetaFunctionCPtr &func);
- 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 TypeEntry *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 QSet<Include> &privateIncludes,
- const QString &privateTypeFunctions);
+ const ModuleHeaderParameters &parameters);
+ 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 fe45965fa..c28fcdc1a 100644
--- a/sources/shiboken6/generator/shiboken/overloaddata.cpp
+++ b/sources/shiboken6/generator/shiboken/overloaddata.cpp
@@ -1,42 +1,23 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 <abstractmetafunction.h>
#include <apiextractorresult.h>
#include <abstractmetalang.h>
#include <dotview.h>
#include <reporthandler.h>
-#include <typesystem.h>
+#include <complextypeentry.h>
+#include <containertypeentry.h>
+#include <primitivetypeentry.h>
#include <graph.h>
#include "overloaddata.h"
+#include "messages.h"
#include "ctypenames.h"
#include "pytypenames.h"
#include "textstream.h"
+#include "exception.h"
+
+#include "qtcompat.h"
#include <QtCore/QDir>
#include <QtCore/QFile>
@@ -45,21 +26,23 @@
#include <algorithm>
#include <utility>
+using namespace Qt::StringLiterals;
+
static QString getTypeName(const AbstractMetaType &type)
{
- const TypeEntry *typeEntry = type.typeEntry();
+ TypeEntryCPtr typeEntry = type.typeEntry();
if (typeEntry->isPrimitive())
- typeEntry = typeEntry->asPrimitive()->basicReferencedTypeEntry();
+ typeEntry = basicReferencedTypeEntry(typeEntry);
QString typeName = typeEntry->name();
if (typeEntry->isContainer()) {
QStringList types;
for (const auto &cType : type.instantiations()) {
- const TypeEntry *typeEntry = cType.typeEntry();
+ TypeEntryCPtr typeEntry = cType.typeEntry();
if (typeEntry->isPrimitive())
- typeEntry = typeEntry->asPrimitive()->basicReferencedTypeEntry();
+ typeEntry = basicReferencedTypeEntry(typeEntry);
types << typeEntry->name();
}
- typeName += QLatin1Char('<') + types.join(QLatin1Char(',')) + QLatin1String(" >");
+ typeName += u'<' + types.join(u',') + u" >"_s;
}
return typeName;
}
@@ -71,7 +54,7 @@ static bool typesAreEqual(const AbstractMetaType &typeA, const AbstractMetaType
if (typeA.instantiations().size() != typeB.instantiations().size())
return false;
- for (int i = 0; i < typeA.instantiations().size(); ++i) {
+ for (qsizetype i = 0; i < typeA.instantiations().size(); ++i) {
if (!typesAreEqual(typeA.instantiations().at(i), typeB.instantiations().at(i)))
return false;
}
@@ -105,33 +88,8 @@ static QString getImplicitConversionTypeName(const AbstractMetaType &containerTy
for (const auto &otherType : containerType.instantiations())
types << (otherType == instantiation ? impConv : getTypeName(otherType));
- return containerType.typeEntry()->qualifiedCppName() + QLatin1Char('<')
- + types.join(QLatin1String(", ")) + QLatin1String(" >");
-}
-
-// overloaddata.cpp
-static QString msgCyclicDependency(const QString &funcName, const QString &graphName,
- const AbstractMetaFunctionCList &cyclic,
- const AbstractMetaFunctionCList &involvedConversions)
-{
- QString result;
- QTextStream str(&result);
- str << "Cyclic dependency found on overloaddata for \"" << funcName
- << "\" method! The graph boy saved the graph at \"" << QDir::toNativeSeparators(graphName)
- << "\". Cyclic functions:";
- for (const auto &c : cyclic)
- str << ' ' << c->signature();
- if (const int count = involvedConversions.size()) {
- str << " Implicit conversions (" << count << "): ";
- for (int i = 0; i < count; ++i) {
- if (i)
- str << ", \"";
- str << involvedConversions.at(i)->signature() << '"';
- if (const AbstractMetaClass *c = involvedConversions.at(i)->implementingClass())
- str << '(' << c->name() << ')';
- }
- }
- return result;
+ return containerType.typeEntry()->qualifiedCppName() + u'<'
+ + types.join(u", "_s) + u" >"_s;
}
static inline int overloadNumber(const OverloadDataNodePtr &o)
@@ -167,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;
@@ -176,13 +135,13 @@ 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 : qAsConst(m_children))
+ for (const auto &ov : std::as_const(m_children))
ov->sortNextOverloads(api);
if (m_children.size() <= 1 || sortByOverloadNumberModification(m_children))
@@ -193,7 +152,7 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
// with graph sorting using integers.
OverloadGraph graph;
- for (const auto &ov : qAsConst(m_children)) {
+ for (const auto &ov : std::as_const(m_children)) {
const QString typeName = getTypeName(ov->modifiedArgType());
auto it = typeToOverloads.find(typeName);
if (it == typeToOverloads.end()) {
@@ -203,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()) {
@@ -224,7 +183,7 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
// as Point must come before the PointF instantiation, or else list<Point> will never
// be called. In the case of primitive types, list<double> must come before list<int>.
if (instantiation.isPrimitive() && (signedIntegerPrimitives.contains(instantiation.name()))) {
- for (const QString &primitive : qAsConst(nonIntegerPrimitives))
+ for (const QString &primitive : std::as_const(nonIntegerPrimitives))
graph.addNode(getImplicitConversionTypeName(ov->argType(), instantiation, nullptr, primitive));
} else {
const auto &funcs = api.implicitConversions(instantiation);
@@ -237,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) {
@@ -248,13 +207,13 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
}
if (checkPySequence && checkPyObject)
- graph.addEdge(cPySequenceT(), cPyObjectT());
+ graph.addEdge(cPySequenceT, cPyObjectT);
QStringList classesWithIntegerImplicitConversion;
AbstractMetaFunctionCList involvedConversions;
- for (const auto &ov : qAsConst(m_children)) {
+ for (const auto &ov : std::as_const(m_children)) {
const AbstractMetaType &targetType = ov->argType();
const QString targetTypeEntryName = getTypeName(ov->modifiedArgType());
@@ -267,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))
@@ -282,10 +241,12 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
// Process inheritance relationships
if (targetType.isValue() || targetType.isObject()) {
- auto metaClass = AbstractMetaClass::findClass(api.classes(),
- targetType.typeEntry());
- const AbstractMetaClassList &ancestors = metaClass->allTypeSystemAncestors();
- for (const AbstractMetaClass *ancestor : ancestors) {
+ const auto te = targetType.typeEntry();
+ auto metaClass = AbstractMetaClass::findClass(api.classes(), te);
+ if (!metaClass)
+ throw Exception(msgArgumentClassNotFound(m_overloads.constFirst(), te));
+ const auto &ancestors = metaClass->allTypeSystemAncestors();
+ for (const auto &ancestor : ancestors) {
QString ancestorTypeName = ancestor->typeEntry()->name();
if (!graph.hasNode(ancestorTypeName))
continue;
@@ -302,7 +263,7 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
graph.addEdge(convertible, targetTypeEntryName);
if (instantiation.isPrimitive() && (signedIntegerPrimitives.contains(instantiation.name()))) {
- for (const QString &primitive : qAsConst(nonIntegerPrimitives)) {
+ for (const QString &primitive : std::as_const(nonIntegerPrimitives)) {
QString convertibleTypeName =
getImplicitConversionTypeName(ov->argType(), instantiation, nullptr, primitive);
// Avoid cyclic dependency.
@@ -327,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()) {
@@ -359,25 +320,36 @@ 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 : qAsConst(m_children)) {
+ for (const auto &ov : std::as_const(m_children)) {
const AbstractMetaType &targetType = ov->argType();
if (!targetType.isEnum())
continue;
QString targetTypeEntryName = getTypeName(targetType);
// Enum values must precede types implicitly convertible from "int" or "unsigned int".
- for (const QString &implicitFromInt : qAsConst(classesWithIntegerImplicitConversion))
+ for (const QString &implicitFromInt : std::as_const(classesWithIntegerImplicitConversion))
graph.addEdge(targetTypeEntryName, implicitFromInt);
}
// Special case for double(int i) (not tracked by m_generator->implicitConversions
- for (const QString &signedIntegerName : qAsConst(signedIntegerPrimitives)) {
+ for (const QString &signedIntegerName : std::as_const(signedIntegerPrimitives)) {
if (graph.hasNode(signedIntegerName)) {
- for (const QString &nonIntegerName : qAsConst(nonIntegerPrimitives)) {
+ for (const QString &nonIntegerName : std::as_const(nonIntegerPrimitives)) {
if (graph.hasNode(nonIntegerName))
graph.addEdge(nonIntegerName, signedIntegerName);
}
@@ -389,10 +361,10 @@ void OverloadDataRootNode::sortNextOverloads(const ApiExtractorResult &api)
if (!unmappedResult.isValid()) {
QString funcName = referenceFunction()->name();
if (auto owner = referenceFunction()->ownerClass())
- funcName.prepend(owner->name() + QLatin1Char('.'));
+ funcName.prepend(owner->name() + u'.');
// Dump overload graph
- QString graphName = QDir::tempPath() + QLatin1Char('/') + funcName + QLatin1String(".dot");
+ QString graphName = QDir::tempPath() + u'/' + funcName + u".dot"_s;
graph.dumpDot(graphName, [] (const QString &n) { return n; });
AbstractMetaFunctionCList cyclic;
for (const auto &typeName : unmappedResult.cyclic) {
@@ -420,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;
@@ -502,7 +473,7 @@ OverloadDataNode *OverloadDataRootNode::addOverloadDataNode(const AbstractMetaFu
{
OverloadDataNodePtr overloadData;
if (!func->isOperatorOverload()) {
- for (const auto &tmp : qAsConst(m_children)) {
+ for (const auto &tmp : std::as_const(m_children)) {
// TODO: 'const char *', 'char *' and 'char' will have the same TypeEntry?
// If an argument have a type replacement, then we should create a new overloaddata
@@ -514,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
@@ -643,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;
@@ -651,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);
}
@@ -680,10 +651,10 @@ bool OverloadDataRootNode::isFinalOccurrence(const AbstractMetaFunctionCPtr &fun
AbstractMetaFunctionCPtr OverloadDataRootNode::getFunctionWithDefaultValue() const
{
- const int argpos = argPos();
+ const qsizetype argpos = argPos();
for (const auto &func : m_overloads) {
- int removedArgs = 0;
- for (int i = 0; i <= argpos + removedArgs; i++) {
+ qsizetype removedArgs = 0;
+ for (qsizetype i = 0; i <= argpos + removedArgs; i++) {
if (func->arguments().at(i).isModifiedRemoved())
removedArgs++;
}
@@ -700,7 +671,7 @@ QList<int> OverloadData::invalidArgumentLengths() const
for (const auto &func : m_overloads) {
const AbstractMetaArgumentList args = func->arguments();
int offset = 0;
- for (int i = 0; i < args.size(); ++i) {
+ for (qsizetype i = 0; i < args.size(); ++i) {
if (func->arguments().at(i).isModifiedRemoved()) {
offset++;
} else {
@@ -730,26 +701,14 @@ int OverloadData::numberOfRemovedArguments(const AbstractMetaFunctionCPtr &func,
{
Q_ASSERT(finalArgPos >= 0);
int removed = 0;
- const int size = func->arguments().size();
- for (int i = 0; i < qMin(size, finalArgPos + removed); ++i) {
+ const auto size = func->arguments().size();
+ for (qsizetype i = 0; i < qMin(size, qsizetype(finalArgPos + removed)); ++i) {
if (func->arguments().at(i).isModifiedRemoved())
++removed;
}
return removed;
}
-bool OverloadData::isSingleArgument(const AbstractMetaFunctionCList &overloads)
-{
- bool singleArgument = true;
- for (const auto &func : overloads) {
- if (func->arguments().size() - numberOfRemovedArguments(func) != 1) {
- singleArgument = false;
- break;
- }
- }
- return singleArgument;
-}
-
void OverloadData::dumpGraph(const QString &filename) const
{
QFile file(filename);
@@ -774,9 +733,9 @@ bool OverloadData::showGraph() const
static inline QString toHtml(QString s)
{
- s.replace(QLatin1Char('<'), QLatin1String("&lt;"));
- s.replace(QLatin1Char('>'), QLatin1String("&gt;"));
- s.replace(QLatin1Char('&'), QLatin1String("&amp;"));
+ s.replace(u'<', u"&lt;"_s);
+ s.replace(u'>', u"&gt;"_s);
+ s.replace(u'&', u"&amp;"_s);
return s;
}
@@ -855,7 +814,7 @@ void OverloadDataRootNode::dumpRootGraph(QTextStream &s, int minArgs, int maxArg
void OverloadDataNode::dumpNodeGraph(QTextStream &s) const
{
- QString argId = QLatin1String("arg_") + QString::number(quintptr(this));
+ QString argId = u"arg_"_s + QString::number(quintptr(this));
s << argId << ";\n";
s << " \"" << argId << "\" [shape=\"plaintext\" style=\"filled,bold\" margin=\"0\" fontname=\"freemono\" fillcolor=\"white\" penwidth=1 ";
@@ -986,7 +945,7 @@ void OverloadDataRootNode::formatOverloads(QDebug &d) const
if (count < 2)
return;
d << "=(";
- for (int i = 0; i < count; ++i) {
+ for (qsizetype i = 0; i < count; ++i) {
if (i)
d << '\n';
d << m_overloads.at(i)->signature();
@@ -1000,7 +959,7 @@ void OverloadDataRootNode::formatNextOverloadData(QDebug &d) const
d << ", next[" << count << ']';
if (d.verbosity() >= 3) {
d << "=(";
- for (int i = 0; i < count; ++i) {
+ for (qsizetype i = 0; i < count; ++i) {
if (i)
d << '\n';
m_children.at(i)->formatDebug(d);
diff --git a/sources/shiboken6/generator/shiboken/overloaddata.h b/sources/shiboken6/generator/shiboken/overloaddata.h
index cbf2470f6..875a5a8b5 100644
--- a/sources/shiboken6/generator/shiboken/overloaddata.h
+++ b/sources/shiboken6/generator/shiboken/overloaddata.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OVERLOADDATA_H
#define OVERLOADDATA_H
@@ -34,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
@@ -70,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;
@@ -177,8 +153,6 @@ public:
static int numberOfRemovedArguments(const AbstractMetaFunctionCPtr &func);
static int numberOfRemovedArguments(const AbstractMetaFunctionCPtr &func, int finalArgPos);
- /// Returns true if all overloads have no more than one argument.
- static bool isSingleArgument(const AbstractMetaFunctionCList &overloads);
void dumpGraph(const QString &filename) const;
QString dumpGraph() const;
diff --git a/sources/shiboken6/generator/shiboken/pytypenames.h b/sources/shiboken6/generator/shiboken/pytypenames.h
index caeb6f671..6c7658ff6 100644
--- a/sources/shiboken6/generator/shiboken/pytypenames.h
+++ b/sources/shiboken6/generator/shiboken/pytypenames.h
@@ -1,55 +1,29 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef PYTYPENAMES_H
#define PYTYPENAMES_H
#include <QtCore/QString>
-static inline QString pyBoolT() { return QStringLiteral("PyBool"); }
-static inline QString pyFloatT() { return QStringLiteral("PyFloat"); }
-static inline QString pyIntT() { return QStringLiteral("PyLong"); }
-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 8f3017832..67fd9c994 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.cpp
@@ -1,33 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "shibokengenerator.h"
+#include "generatorstrings.h"
+#include "generatorargument.h"
+#include "defaultvalue.h"
+#include "generatorcontext.h"
#include "apiextractorresult.h"
+#include "codesnip.h"
+#include "customconversion.h"
#include "ctypenames.h"
#include <abstractmetabuilder.h>
#include <abstractmetaenum.h>
@@ -40,53 +21,96 @@
#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>
+#include <flagstypeentry.h>
+#include <namespacetypeentry.h>
+#include <primitivetypeentry.h>
+#include <pythontypeentry.h>
+#include <smartpointertypeentry.h>
+#include <valuetypeentry.h>
+
#include <iostream>
+#include "qtcompat.h"
+
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtCore/QRegularExpression>
+
+#include <algorithm>
#include <limits>
#include <memory>
+#include <utility>
+
+using namespace Qt::StringLiterals;
-static const char AVOID_PROTECTED_HACK[] = "avoid-protected-hack";
-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";
-
-const char *CPP_ARG = "cppArg";
-const char *CPP_ARG_REMOVED = "removed_cppArg";
-const char *CPP_RETURN_VAR = "cppResult";
-const char *CPP_SELF_VAR = "cppSelf";
-const char *NULL_PTR = "nullptr";
-const char *PYTHON_ARG = "pyArg";
-const char *PYTHON_ARGS = "pyArgs";
-const char *PYTHON_OVERRIDE_VAR = "pyOverride";
-const char *PYTHON_RETURN_VAR = "pyResult";
-const char *PYTHON_TO_CPP_VAR = "pythonToCpp";
-const char *SMART_POINTER_GETTER = "kSmartPointerGetter";
-
-const char *CONV_RULE_OUT_VAR_SUFFIX = "_out";
-const char *BEGIN_ALLOW_THREADS =
- "PyThreadState *_save = PyEval_SaveThread(); // Py_BEGIN_ALLOW_THREADS";
-const char *END_ALLOW_THREADS = "PyEval_RestoreThread(_save); // Py_END_ALLOW_THREADS";
+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)
@@ -102,14 +126,18 @@ const ShibokenGenerator::TypeSystemConverterRegExps &
ShibokenGenerator::typeSystemConvRegExps()
{
static const TypeSystemConverterRegExps result = {
- QRegularExpression(QLatin1String(CHECKTYPE_REGEX)),
- QRegularExpression(QLatin1String(ISCONVERTIBLE_REGEX)),
- QRegularExpression(QLatin1String(CONVERTTOCPP_REGEX)),
- QRegularExpression(QLatin1String(CONVERTTOPYTHON_REGEX))
+ QRegularExpression(QLatin1StringView(CHECKTYPE_REGEX)),
+ QRegularExpression(QLatin1StringView(ISCONVERTIBLE_REGEX)),
+ QRegularExpression(QLatin1StringView(CONVERTTOCPP_REGEX)),
+ QRegularExpression(QLatin1StringView(CONVERTTOPYTHON_REGEX))
};
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;
@@ -118,64 +146,65 @@ ShibokenGenerator::~ShibokenGenerator() = default;
static const QHash<QString, QString> &primitiveTypesCorrespondences()
{
static const QHash<QString, QString> result = {
- {QLatin1String("bool"), pyBoolT()},
- {QLatin1String("char"), sbkCharT()},
- {QLatin1String("signed char"), sbkCharT()},
- {QLatin1String("unsigned char"), sbkCharT()},
- {intT(), pyIntT()},
- {QLatin1String("signed int"), pyIntT()},
- {QLatin1String("uint"), pyIntT()},
- {QLatin1String("unsigned int"), pyIntT()},
- {shortT(), pyIntT()},
- {QLatin1String("ushort"), pyIntT()},
- {QLatin1String("signed short"), pyIntT()},
- {QLatin1String("signed short int"), pyIntT()},
- {unsignedShortT(), pyIntT()},
- {QLatin1String("unsigned short int"), pyIntT()},
- {longT(), pyIntT()},
- {doubleT(), pyFloatT()},
- {floatT(), pyFloatT()},
- {QLatin1String("unsigned long"), pyLongT()},
- {QLatin1String("signed long"), pyLongT()},
- {QLatin1String("ulong"), pyLongT()},
- {QLatin1String("unsigned long int"), pyLongT()},
- {QLatin1String("long long"), pyLongT()},
- {QLatin1String("__int64"), pyLongT()},
- {QLatin1String("unsigned long long"), pyLongT()},
- {QLatin1String("unsigned __int64"), pyLongT()},
- {QLatin1String("size_t"), 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;
}
-// Format units for C++->Python->C++ conversion
-const QHash<QString, QString> &ShibokenGenerator::formatUnits()
-{
- static const QHash<QString, QString> result = {
- {QLatin1String("char"), QLatin1String("b")},
- {QLatin1String("unsigned char"), QLatin1String("B")},
- {intT(), QLatin1String("i")},
- {QLatin1String("unsigned int"), QLatin1String("I")},
- {shortT(), QLatin1String("h")},
- {unsignedShortT(), QLatin1String("H")},
- {longT(), QLatin1String("l")},
- {unsignedLongLongT(), QLatin1String("k")},
- {longLongT(), QLatin1String("L")},
- {QLatin1String("__int64"), QLatin1String("L")},
- {unsignedLongLongT(), QLatin1String("K")},
- {QLatin1String("unsigned __int64"), QLatin1String("K")},
- {doubleT(), QLatin1String("d")},
- {floatT(), QLatin1String("f")},
+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'},
+ {u"unsigned int"_s, u'I'},
+ {shortT, u'h'},
+ {unsignedShortT, u'H'},
+ {longT, u'l'},
+ {unsignedLongLongT, u'k'},
+ {longLongT, u'L'},
+ {u"__int64"_s, u'L'},
+ {unsignedLongLongT, u'K'},
+ {u"unsigned __int64"_s, u'K'},
+ {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())
- return translateTypeForWrapperMethod(*cType.arrayElementType(), context, options) + QLatin1String("[]");
+ if (cType.isArray()) {
+ return translateTypeForWrapperMethod(*cType.arrayElementType(), context, options)
+ + u"[]"_s;
+ }
if (avoidProtectedHack() && cType.isEnum()) {
auto metaEnum = api().findAbstractMetaEnum(cType.typeEntry());
@@ -186,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)
@@ -194,20 +223,88 @@ bool ShibokenGenerator::shouldGenerateCppWrapper(const AbstractMetaClass *metaCl
&& wrapper.testFlag(AbstractMetaClass::CppProtectedHackWrapper));
}
-bool ShibokenGenerator::shouldWriteVirtualMethodNative(const AbstractMetaFunctionCPtr &func) const
+bool ShibokenGenerator::shouldGenerateMetaObjectFunctions(const AbstractMetaClassCPtr &metaClass)
{
- // PYSIDE-803: Extracted this because it is used multiple times.
- const AbstractMetaClass *metaClass = func->ownerClass();
- return (!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
- && ((func->isVirtual() || func->isAbstract())
- && !func->attributes().testFlag(AbstractMetaFunction::FinalCppMethod));
+ return usePySideExtensions()
+ && (!avoidProtectedHack() || !metaClass->hasPrivateDestructor())
+ && !metaClass->typeEntry()->typeFlags()
+ .testFlag(ComplexTypeEntry::DisableQtMetaObjectFunctions)
+ && isQObject(metaClass);
+}
+
+ShibokenGenerator::FunctionGeneration ShibokenGenerator::functionGeneration(
+ const AbstractMetaFunctionCPtr &func)
+{
+ FunctionGeneration result;
+
+ const auto functionType = func->functionType();
+ switch (functionType) {
+ case AbstractMetaFunction::ConversionOperator:
+ case AbstractMetaFunction::AssignmentOperatorFunction:
+ case AbstractMetaFunction::MoveAssignmentOperatorFunction:
+ case AbstractMetaFunction::DestructorFunction:
+ case AbstractMetaFunction::SignalFunction:
+ case AbstractMetaFunction::GetAttroFunction:
+ case AbstractMetaFunction::SetAttroFunction:
+ return result;
+ default:
+ if (func->isUserAdded() || func->usesRValueReferences() || !func->isWhiteListed())
+ return result;
+ break;
+ }
+
+ const bool notModifiedRemoved = !func->isModifiedRemoved();
+ const bool isPrivate = func->isPrivate() && !func->isVisibilityModifiedToPrivate();
+ switch (functionType) {
+ case AbstractMetaFunction::ConstructorFunction:
+ if (!isPrivate && notModifiedRemoved)
+ result.setFlag(FunctionGenerationFlag::WrapperConstructor);
+ return result;
+ case AbstractMetaFunction::CopyConstructorFunction:
+ if (!isPrivate && notModifiedRemoved)
+ result.setFlag(FunctionGenerationFlag::WrapperSpecialCopyConstructor);
+ return result;
+ case AbstractMetaFunction::NormalFunction:
+ case AbstractMetaFunction::SlotFunction:
+ if (avoidProtectedHack() && func->isProtected())
+ result.setFlag(FunctionGenerationFlag::ProtectedWrapper);
+ break;
+ default:
+ break;
+ }
+
+ // Check on virtuals (including operators).
+ const bool isAbstract = func->isAbstract();
+ if (!(isAbstract || func->isVirtual())
+ || func->cppAttributes().testFlag(FunctionAttribute::Final)
+ || func->isModifiedFinal()) {
+ return result;
+ }
+
+ // MetaObject virtuals only need to be declared; CppGenerator creates a
+ // special implementation.
+ if (functionType == AbstractMetaFunction::NormalFunction
+ && usePySideExtensions() && isQObject(func->ownerClass())) {
+ const QString &name = func->name();
+ if (name == u"metaObject"_s || name == u"qt_metacall") {
+ result.setFlag(FunctionGenerationFlag::QMetaObjectMethod);
+ return result;
+ }
+ }
+
+ // Pure virtual functions need a default implementation even if private.
+ if (isAbstract || (notModifiedRemoved && !isPrivate))
+ result.setFlag(FunctionGenerationFlag::VirtualMethod);
+
+ return result;
}
-AbstractMetaFunctionCList ShibokenGenerator::implicitConversions(const TypeEntry *t) const
+AbstractMetaFunctionCList ShibokenGenerator::implicitConversions(const TypeEntryCPtr &t) const
{
- if (!generateImplicitConversions())
+ if (!generateImplicitConversions() || !t->isValue())
return {};
- auto *customConversion = t->customConversion();
+ auto vte = std::static_pointer_cast<const ValueTypeEntry>(t);
+ auto customConversion = vte->customConversion();
if (customConversion && customConversion->replaceOriginalTargetToNativeConversions())
return {};
@@ -220,28 +317,64 @@ 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();
if (metaClass->enclosingClass()) // is a inner class
- result.replace(QLatin1String("::"), QLatin1String("_"));
- return result + QLatin1String("Wrapper");
+ result.replace(u"::"_s, u"_"_s);
+ 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() + QLatin1Char('.'));
+ fullClassName.prepend(enclosing->name() + u'.');
enclosing = enclosing->enclosingClass();
}
- fullClassName.prepend(packageName() + QLatin1Char('.'));
+ 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;
@@ -254,24 +387,29 @@ QString ShibokenGenerator::fullPythonFunctionName(const AbstractMetaFunctionCPtr
if (func->isConstructor()) {
funcName = fullClassName;
if (forceFunc)
- funcName.append(QLatin1String(".__init__"));
+ funcName.append(u".__init__"_s);
}
else {
- funcName.prepend(fullClassName + QLatin1Char('.'));
+ funcName.prepend(fullClassName + u'.');
}
}
else {
- funcName = packageName() + QLatin1Char('.') + func->name();
+ funcName = packageName() + u'.' + func->name();
}
return funcName;
}
+bool ShibokenGenerator::wrapperDiagnostics()
+{
+ return m_options.wrapperDiagnostics;
+}
+
QString ShibokenGenerator::protectedEnumSurrogateName(const AbstractMetaEnum &metaEnum)
{
QString result = metaEnum.fullName();
- result.replace(QLatin1Char('.'), QLatin1Char('_'));
- result.replace(QLatin1String("::"), QLatin1String("_"));
- return result + QLatin1String("_Surrogate");
+ result.replace(u'.', u'_');
+ result.replace(u"::"_s, u"_"_s);
+ return result + u"_Surrogate"_s;
}
QString ShibokenGenerator::cpythonFunctionName(const AbstractMetaFunctionCPtr &func)
@@ -283,16 +421,16 @@ QString ShibokenGenerator::cpythonFunctionName(const AbstractMetaFunctionCPtr &f
if (func->implementingClass()) {
result = cpythonBaseName(func->implementingClass()->typeEntry());
if (func->isConstructor()) {
- result += QLatin1String("_Init");
+ result += u"_Init"_s;
} else {
- result += QLatin1String("Func_");
+ result += u"Func_"_s;
if (func->isOperatorOverload())
result += ShibokenGenerator::pythonOperatorFunctionName(func);
else
result += func->name();
}
} else {
- result = QLatin1String("Sbk") + moduleName() + QLatin1String("Module_") + func->name();
+ result = u"Sbk"_s + moduleName() + u"Module_"_s + func->name();
}
return result;
@@ -301,37 +439,37 @@ QString ShibokenGenerator::cpythonFunctionName(const AbstractMetaFunctionCPtr &f
QString ShibokenGenerator::cpythonMethodDefinitionName(const AbstractMetaFunctionCPtr &func)
{
if (!func->ownerClass())
- return QString();
- return cpythonBaseName(func->ownerClass()->typeEntry()) + QLatin1String("Method_")
+ 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) + QLatin1String("_getsetlist");
+ return cpythonBaseName(metaClass) + u"_getsetlist"_s;
}
-QString ShibokenGenerator::cpythonSetattroFunctionName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonSetattroFunctionName(const AbstractMetaClassCPtr &metaClass)
{
- return cpythonBaseName(metaClass) + QLatin1String("_setattro");
+ return cpythonBaseName(metaClass) + u"_setattro"_s;
}
-QString ShibokenGenerator::cpythonGetattroFunctionName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonGetattroFunctionName(const AbstractMetaClassCPtr &metaClass)
{
- return cpythonBaseName(metaClass) + QLatin1String("_getattro");
+ 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)
@@ -345,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);
}
@@ -359,85 +497,15 @@ QString ShibokenGenerator::cpythonSetterFunctionName(const QPropertySpec &proper
static QString cpythonEnumFlagsName(const QString &moduleName,
const QString &qualifiedCppName)
{
- QString result = QLatin1String("Sbk") + moduleName + QLatin1Char('_') + qualifiedCppName;
- result.replace(QLatin1String("::"), QLatin1String("_"));
+ QString result = u"Sbk"_s + moduleName + u'_' + qualifiedCppName;
+ result.replace(u"::"_s, u"_"_s);
return result;
}
-/*
- * This function uses some heuristics to find out the scope for a given
- * argument default value since they must be fully qualified when used outside the class:
- * class A {
- * enum Enum { e1, e1 };
- * void foo(Enum e = e1);
- * }
- * should be qualified to:
- * A::Enum cppArg0 = A::Enum::e1;
- *
- * New situations may arise in the future and
- * this method should be updated, do it with care.
- */
-QString ShibokenGenerator::guessScopeForDefaultValue(const AbstractMetaFunctionCPtr &func,
- const AbstractMetaArgument &arg) const
-{
- QString value = arg.defaultValueExpression();
-
- if (value.isEmpty() || value == u"{}" || value == u"nullptr" || value == u"NULL"
- || arg.hasModifiedDefaultValueExpression()
- || arg.type().isPointer()) {
- return value;
- }
-
- static const QRegularExpression enumValueRegEx(QStringLiteral("^([A-Za-z_]\\w*)?$"));
- Q_ASSERT(enumValueRegEx.isValid());
- // Do not qualify macros by class name, eg QSGGeometry(..., int t = GL_UNSIGNED_SHORT);
- static const QRegularExpression macroRegEx(QStringLiteral("^[A-Z_][A-Z0-9_]*$"));
- Q_ASSERT(macroRegEx.isValid());
- if (arg.type().isPrimitive() && macroRegEx.match(value).hasMatch())
- return value;
-
- QString prefix;
- if (arg.type().isEnum() || arg.type().isFlags()) {
- // handled by AbstractMetaBuilder::fixEnumDefault()
- } else if (arg.type().typeEntry()->isValue()) {
- auto metaClass = AbstractMetaClass::findClass(api().classes(),
- arg.type().typeEntry());
- if (enumValueRegEx.match(value).hasMatch())
- prefix = AbstractMetaBuilder::resolveScopePrefix(metaClass, value);
- } else if (arg.type().isPrimitive() && arg.type().name() == intT()) {
- if (enumValueRegEx.match(value).hasMatch() && func->implementingClass())
- prefix = AbstractMetaBuilder::resolveScopePrefix(func->implementingClass(), value);
- } else if (arg.type().isPrimitive()) {
- static const QRegularExpression unknowArgumentRegEx(QStringLiteral("^(?:[A-Za-z_][\\w:]*\\()?([A-Za-z_]\\w*)(?:\\))?$")); // [PrimitiveType(] DESIREDNAME [)]
- Q_ASSERT(unknowArgumentRegEx.isValid());
- const QRegularExpressionMatch match = unknowArgumentRegEx.match(value);
- if (match.hasMatch() && func->implementingClass()) {
- for (const AbstractMetaField &field : func->implementingClass()->fields()) {
- if (match.captured(1).trimmed() == field.name()) {
- QString fieldName = field.name();
- if (field.isStatic()) {
- prefix = AbstractMetaBuilder::resolveScopePrefix(func->implementingClass(), value);
- fieldName.prepend(prefix);
- prefix.clear();
- } else {
- fieldName.prepend(QLatin1String(CPP_SELF_VAR) + QLatin1String("->"));
- }
- value.replace(match.captured(1), fieldName);
- break;
- }
- }
- }
- }
-
- if (!prefix.isEmpty())
- value.prepend(prefix);
- return value;
-}
-
-QString ShibokenGenerator::cpythonEnumName(const EnumTypeEntry *enumEntry)
+QString ShibokenGenerator::cpythonEnumName(const EnumTypeEntryCPtr &enumEntry)
{
QString p = enumEntry->targetLangPackage();
- p.replace(QLatin1Char('.'), QLatin1Char('_'));
+ p.replace(u'.', u'_');
return cpythonEnumFlagsName(p, enumEntry->qualifiedCppName());
}
@@ -446,27 +514,25 @@ QString ShibokenGenerator::cpythonEnumName(const AbstractMetaEnum &metaEnum)
return cpythonEnumName(metaEnum.typeEntry());
}
-QString ShibokenGenerator::cpythonFlagsName(const FlagsTypeEntry *flagsEntry)
+QString ShibokenGenerator::cpythonFlagsName(const FlagsTypeEntryCPtr &flagsEntry)
{
QString p = flagsEntry->targetLangPackage();
- p.replace(QLatin1Char('.'), QLatin1Char('_'));
+ p.replace(u'.', u'_');
return cpythonEnumFlagsName(p, flagsEntry->originalName());
}
QString ShibokenGenerator::cpythonFlagsName(const AbstractMetaEnum *metaEnum)
{
- const FlagsTypeEntry *flags = metaEnum->typeEntry()->flags();
- if (!flags)
- return QString();
- return cpythonFlagsName(flags);
+ const auto flags = metaEnum->typeEntry()->flags();
+ return flags ? cpythonFlagsName(flags) : QString{};
}
-QString ShibokenGenerator::cpythonSpecialCastFunctionName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonSpecialCastFunctionName(const AbstractMetaClassCPtr &metaClass)
{
- return cpythonBaseName(metaClass->typeEntry()) + QLatin1String("SpecialCastFunction");
+ 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);
@@ -476,46 +542,47 @@ QString ShibokenGenerator::cpythonWrapperCPtr(const AbstractMetaType &metaType,
const QString &argName)
{
if (!metaType.isWrapperType())
- return QString();
- return QLatin1String("reinterpret_cast< ::") + metaType.cppSignature()
- + QLatin1String(" *>(Shiboken::Conversions::cppPointer(") + cpythonTypeNameExt(metaType)
- + QLatin1String(", reinterpret_cast<SbkObject *>(") + argName + QLatin1String(")))");
+ return {};
+ return u"reinterpret_cast< ::"_s + metaType.cppSignature()
+ + u" *>(Shiboken::Conversions::cppPointer("_s + cpythonTypeNameExt(metaType)
+ + u", reinterpret_cast<SbkObject *>("_s + argName + u")))"_s;
}
-QString ShibokenGenerator::cpythonWrapperCPtr(const TypeEntry *type,
+QString ShibokenGenerator::cpythonWrapperCPtr(const TypeEntryCPtr &type,
const QString &argName)
{
if (!type->isWrapperType())
return QString();
- return QLatin1String("reinterpret_cast< ::") + type->qualifiedCppName()
- + QLatin1String(" *>(Shiboken::Conversions::cppPointer(") + cpythonTypeNameExt(type)
- + QLatin1String(", reinterpret_cast<SbkObject *>(") + argName + QLatin1String(")))");
+ 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,
int argIndex)
{
- if (argIndex < 0 || argIndex >= func->arguments().count())
+ if (argIndex < 0 || argIndex >= func->arguments().size())
return false;
const AbstractMetaArgument &arg = func->arguments().at(argIndex);
@@ -537,187 +604,152 @@ bool ShibokenGenerator::shouldRejectNullPointerArgument(const AbstractMetaFuncti
return false;
}
-QString ShibokenGenerator::getFormatUnitString(const AbstractMetaFunctionCPtr &func, bool incRef)
-{
- QString result;
- const char objType = (incRef ? 'O' : 'N');
- const AbstractMetaArgumentList &arguments = func->arguments();
- for (const AbstractMetaArgument &arg : arguments) {
- if (arg.isModifiedRemoved())
- continue;
-
- const auto &type = arg.type();
- if (arg.isTypeModified()) {
- result += QLatin1Char(objType);
- } else if (arg.type().isObject()
- || type.isValue()
- || type.isValuePointer()
- || type.isNativePointer()
- || type.isEnum()
- || type.isFlags()
- || type.isContainer()
- || type.isSmartPointer()
- || type.referenceType() == LValueReference) {
- result += QLatin1Char(objType);
- } else if (type.isPrimitive()) {
- const auto *ptype = type.typeEntry()->asPrimitive()->basicReferencedTypeEntry();
- const auto it = formatUnits().constFind(ptype->name());
- if (it != formatUnits().cend())
- result += it.value();
- else
- result += QLatin1Char(objType);
- } else if (type.isCString()) {
- result += QLatin1Char('z');
- } else {
- qCWarning(lcShiboken).noquote().nospace()
- << "Method: " << func->ownerClass()->qualifiedCppName()
- << "::" << func->signature() << " => Arg:"
- << arg.name() << "index: " << arg.argumentIndex()
- << " - cannot be handled properly. Use an inject-code to fix it!";
- result += QLatin1Char('?');
- }
- }
- return result;
-}
-
QString ShibokenGenerator::cpythonBaseName(const AbstractMetaType &type)
{
if (type.isCString())
- return QLatin1String("PyString");
+ return u"PyString"_s;
return cpythonBaseName(type.typeEntry());
}
-QString ShibokenGenerator::cpythonBaseName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonBaseName(const AbstractMetaClassCPtr &metaClass)
{
return cpythonBaseName(metaClass->typeEntry());
}
-QString ShibokenGenerator::cpythonBaseName(const TypeEntry *type)
+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;
if (type->isWrapperType() || type->isNamespace()) { // && type->referenceType() == NoReference) {
- baseName = QLatin1String("Sbk_") + type->name();
+ baseName = u"Sbk_"_s + type->name();
} else if (type->isPrimitive()) {
- const auto *ptype = type->asPrimitive()->basicReferencedTypeEntry();
+ const auto ptype = basicReferencedTypeEntry(type);
baseName = ptype->hasTargetLangApiType()
? ptype->targetLangApiName() : pythonPrimitiveTypeName(ptype->name());
} else if (type->isEnum()) {
- baseName = cpythonEnumName(static_cast<const EnumTypeEntry *>(type));
+ baseName = cpythonEnumName(std::static_pointer_cast<const EnumTypeEntry>(type));
} else if (type->isFlags()) {
- baseName = cpythonFlagsName(static_cast<const FlagsTypeEntry *>(type));
+ baseName = cpythonFlagsName(std::static_pointer_cast<const FlagsTypeEntry>(type));
} else if (type->isContainer()) {
- const auto *ctype = static_cast<const ContainerTypeEntry *>(type);
- switch (ctype->containerKind()) {
- case ContainerTypeEntry::ListContainer:
- //baseName = "PyList";
- //break;
- case ContainerTypeEntry::PairContainer:
- //baseName = "PyTuple";
- baseName = cPySequenceT();
- break;
- case ContainerTypeEntry::SetContainer:
- baseName = QLatin1String("PySet");
- break;
- case ContainerTypeEntry::MapContainer:
- case ContainerTypeEntry::MultiMapContainer:
- baseName = QLatin1String("PyDict");
- 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(QLatin1String("::"), QLatin1String("_"));
+ return baseName.replace(u"::"_s, u"_"_s);
}
-QString ShibokenGenerator::cpythonTypeName(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonTypeName(const AbstractMetaClassCPtr &metaClass)
{
return cpythonTypeName(metaClass->typeEntry());
}
-QString ShibokenGenerator::cpythonTypeName(const TypeEntry *type)
-{
- return cpythonBaseName(type) + QLatin1String("_TypeF()");
-}
-
-QString ShibokenGenerator::cpythonTypeNameExt(const TypeEntry *type)
+QString ShibokenGenerator::cpythonTypeName(const TypeEntryCPtr &type)
{
- return cppApiVariableName(type->targetLangPackage()) + QLatin1Char('[')
- + getTypeIndexVariableName(type) + QLatin1Char(']');
+ return cpythonBaseName(type) + u"_TypeF()"_s;
}
QString ShibokenGenerator::converterObject(const AbstractMetaType &type)
{
if (type.isCString())
- return QLatin1String("Shiboken::Conversions::PrimitiveTypeConverter<const char *>()");
+ return u"Shiboken::Conversions::PrimitiveTypeConverter<const char *>()"_s;
if (type.isVoidPointer())
- return QLatin1String("Shiboken::Conversions::PrimitiveTypeConverter<void *>()");
+ 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()
- + QLatin1String(">(") + QString::number(nestedArrayTypes.size())
- + QLatin1Char(')');
+ + u">("_s + QString::number(nestedArrayTypes.size())
+ + u')';
}
auto typeEntry = type.typeEntry();
if (typeEntry->isContainer() || typeEntry->isSmartPointer()) {
return convertersVariableName(typeEntry->targetLangPackage())
- + QLatin1Char('[') + getTypeIndexVariableName(type) + QLatin1Char(']');
+ + u'[' + getTypeIndexVariableName(type) + u']';
}
return converterObject(typeEntry);
}
-QString ShibokenGenerator::converterObject(const TypeEntry *type)
+QString ShibokenGenerator::converterObject(const TypeEntryCPtr &type)
{
- if (type->isExtendedCppPrimitive())
+ if (isExtendedCppPrimitive(type))
return QString::fromLatin1("Shiboken::Conversions::PrimitiveTypeConverter<%1>()")
.arg(type->qualifiedCppName());
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 */
- const auto *pte = dynamic_cast<const PrimitiveTypeEntry *>(type);
+ 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 = pte->basicReferencedTypeEntry();
- if (pte->isPrimitive() && !pte->isCppPrimitive() && !pte->customConversion()) {
- return u"Shiboken::Conversions::PrimitiveTypeConverter<"_qs
- + pte->qualifiedCppName() + u">()"_qs;
+ pte = basicReferencedTypeEntry(pte);
+ if (pte->isPrimitive() && !isCppPrimitive(pte) && !pte->customConversion()) {
+ return u"Shiboken::Conversions::PrimitiveTypeConverter<"_s
+ + pte->qualifiedCppName() + u">()"_s;
}
return convertersVariableName(type->targetLangPackage())
- + QLatin1Char('[') + getTypeIndexVariableName(type) + QLatin1Char(']');
+ + 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()) + QLatin1Char('[')
- + getTypeIndexVariableName(type) + QLatin1Char(']');
+ return cppApiVariableName(type.typeEntry()->targetLangPackage()) + u'['
+ + getTypeIndexVariableName(type) + "].type"_L1;
}
-static inline QString unknownOperator() { return QStringLiteral("__UNKNOWN_OPERATOR__"); }
+QString ShibokenGenerator::cpythonTypeNameExt(const TypeEntryCPtr &type)
+{
+ return "Shiboken::Module::get("_L1 + cppApiVariableName(type->targetLangPackage())
+ + u'[' + getTypeIndexVariableName(type) + "])"_L1;
+}
+
+QString ShibokenGenerator::cpythonTypeNameExt(const AbstractMetaType &type)
+{
+ return u"Shiboken::Module::get("_s + cppApiVariableName(type.typeEntry()->targetLangPackage())
+ + u'[' + getTypeIndexVariableName(type) + "])"_L1;
+}
-QString ShibokenGenerator::fixedCppTypeName(const CustomConversion::TargetToNativeConversion *toNative)
+QString ShibokenGenerator::fixedCppTypeName(const TargetToNativeConversion &toNative)
{
- if (toNative->sourceType())
- return fixedCppTypeName(toNative->sourceType());
- return toNative->sourceTypeName();
+ if (toNative.sourceType())
+ return fixedCppTypeName(toNative.sourceType());
+ return toNative.sourceTypeName();
}
QString ShibokenGenerator::fixedCppTypeName(const AbstractMetaType &type)
{
@@ -726,22 +758,22 @@ QString ShibokenGenerator::fixedCppTypeName(const AbstractMetaType &type)
static QString _fixedCppTypeName(QString typeName)
{
- typeName.remove(QLatin1Char(' '));
- typeName.replace(QLatin1Char('.'), QLatin1Char('_'));
- typeName.replace(QLatin1Char(','), QLatin1Char('_'));
- typeName.replace(QLatin1Char('<'), QLatin1Char('_'));
- typeName.replace(QLatin1Char('>'), QLatin1Char('_'));
- typeName.replace(QLatin1String("::"), QLatin1String("_"));
- typeName.replace(QLatin1String("*"), QLatin1String("PTR"));
- typeName.replace(QLatin1String("&"), QLatin1String("REF"));
+ typeName.remove(u' ');
+ typeName.replace(u'.', u'_');
+ typeName.replace(u',', u'_');
+ typeName.replace(u'<', u'_');
+ typeName.replace(u'>', u'_');
+ typeName.replace(u"::"_s, u"_"_s);
+ typeName.replace(u"*"_s, u"PTR"_s);
+ typeName.replace(u"&"_s, u"REF"_s);
return typeName;
}
-QString ShibokenGenerator::fixedCppTypeName(const TypeEntry *type, QString typeName)
+QString ShibokenGenerator::fixedCppTypeName(const TypeEntryCPtr &type, QString typeName)
{
if (typeName.isEmpty())
typeName = type->qualifiedCppName();
if (!type->generateCode()) {
- typeName.prepend(QLatin1Char('_'));
+ typeName.prepend(u'_');
typeName.prepend(type->targetLangPackage());
}
return _fixedCppTypeName(typeName);
@@ -752,114 +784,52 @@ QString ShibokenGenerator::pythonPrimitiveTypeName(const QString &cppTypeName)
const auto &mapping = primitiveTypesCorrespondences();
const auto it = mapping.constFind(cppTypeName);
if (it == mapping.cend())
- throw Exception(u"Primitive type not found: "_qs + cppTypeName);
+ throw Exception(u"Primitive type not found: "_s + cppTypeName);
return it.value();
}
-static const QHash<QString, QString> &pythonOperators()
-{
- static const QHash<QString, QString> result = {
- // call operator
- {QLatin1String("operator()"), QLatin1String("call")},
- // Arithmetic operators
- {QLatin1String("operator+"), QLatin1String("add")},
- {QLatin1String("operator-"), QLatin1String("sub")},
- {QLatin1String("operator*"), QLatin1String("mul")},
- {QLatin1String("operator/"), QLatin1String("div")},
- {QLatin1String("operator%"), QLatin1String("mod")},
- // Inplace arithmetic operators
- {QLatin1String("operator+="), QLatin1String("iadd")},
- {QLatin1String("operator-="), QLatin1String("isub")},
- {QLatin1String("operator++"), QLatin1String("iadd")},
- {QLatin1String("operator--"), QLatin1String("isub")},
- {QLatin1String("operator*="), QLatin1String("imul")},
- {QLatin1String("operator/="), QLatin1String("idiv")},
- {QLatin1String("operator%="), QLatin1String("imod")},
- // Bitwise operators
- {QLatin1String("operator&"), QLatin1String("and")},
- {QLatin1String("operator^"), QLatin1String("xor")},
- {QLatin1String("operator|"), QLatin1String("or")},
- {QLatin1String("operator<<"), QLatin1String("lshift")},
- {QLatin1String("operator>>"), QLatin1String("rshift")},
- {QLatin1String("operator~"), QLatin1String("invert")},
- // Inplace bitwise operators
- {QLatin1String("operator&="), QLatin1String("iand")},
- {QLatin1String("operator^="), QLatin1String("ixor")},
- {QLatin1String("operator|="), QLatin1String("ior")},
- {QLatin1String("operator<<="), QLatin1String("ilshift")},
- {QLatin1String("operator>>="), QLatin1String("irshift")},
- // Comparison operators
- {QLatin1String("operator=="), QLatin1String("eq")},
- {QLatin1String("operator!="), QLatin1String("ne")},
- {QLatin1String("operator<"), QLatin1String("lt")},
- {QLatin1String("operator>"), QLatin1String("gt")},
- {QLatin1String("operator<="), QLatin1String("le")},
- {QLatin1String("operator>="), QLatin1String("ge")},
- };
- return result;
-}
-
-QString ShibokenGenerator::pythonOperatorFunctionName(const QString &cppOpFuncName)
-{
- QString value = pythonOperators().value(cppOpFuncName);
- if (value.isEmpty())
- return unknownOperator();
- value.prepend(QLatin1String("__"));
- value.append(QLatin1String("__"));
- return value;
-}
-
QString ShibokenGenerator::pythonOperatorFunctionName(const AbstractMetaFunctionCPtr &func)
{
- QString op = pythonOperatorFunctionName(func->originalName());
- if (op == unknownOperator())
- qCWarning(lcShiboken).noquote().nospace() << msgUnknownOperator(func.data());
+ QString op = Generator::pythonOperatorFunctionName(func->originalName());
+ if (op.isEmpty()) {
+ qCWarning(lcShiboken).noquote().nospace() << msgUnknownOperator(func.get());
+ return "__UNKNOWN_OPERATOR__"_L1;
+ }
if (func->arguments().isEmpty()) {
- if (op == QLatin1String("__sub__"))
- op = QLatin1String("__neg__");
- else if (op == QLatin1String("__add__"))
- op = QLatin1String("__pos__");
+ if (op == u"__sub__")
+ op = u"__neg__"_s;
+ else if (op == u"__add__")
+ op = u"__pos__"_s;
} else if (func->isStatic() && func->arguments().size() == 2) {
// If a operator overload function has 2 arguments and
// is static we assume that it is a reverse operator.
- op = op.insert(2, QLatin1Char('r'));
+ op = op.insert(2, u'r');
}
return op;
}
-QString ShibokenGenerator::pythonRichCompareOperatorId(const QString &cppOpFuncName)
-{
- return QLatin1String("Py_") + pythonOperators().value(cppOpFuncName).toUpper();
-}
-
-QString ShibokenGenerator::pythonRichCompareOperatorId(const AbstractMetaFunctionCPtr &func)
-{
- return pythonRichCompareOperatorId(func->originalName());
-}
-
bool ShibokenGenerator::isNumber(const QString &cpythonApiName)
{
- return cpythonApiName == pyIntT()
- || cpythonApiName == pyFloatT() || cpythonApiName == pyLongT()
- || cpythonApiName == pyBoolT();
+ return cpythonApiName == pyFloatT || cpythonApiName == pyLongT
+ || cpythonApiName == pyBoolT;
}
static std::optional<TypeSystem::CPythonType>
- targetLangApiCPythonType(const PrimitiveTypeEntry *t)
+ targetLangApiCPythonType(const PrimitiveTypeEntryCPtr &t)
{
if (!t->hasTargetLangApiType())
return {};
- const auto *cte = t->targetLangApiType();
+ const auto cte = t->targetLangApiType();
if (cte->type() != TypeEntry::PythonType)
return {};
- return static_cast<const PythonTypeEntry *>(cte)->cPythonType();
+ return std::static_pointer_cast<const PythonTypeEntry>(cte)->cPythonType();
}
-bool ShibokenGenerator::isNumber(const TypeEntry *type)
+bool ShibokenGenerator::isNumber(const TypeEntryCPtr &type)
{
if (!type->isPrimitive())
return false;
- const auto *pte = type->asPrimitive()->basicReferencedTypeEntry();
+ const auto pte = basicReferencedTypeEntry(type);
const auto cPythonTypeOpt = targetLangApiCPythonType(pte);
// FIXME PYSIDE-1660: Return false here after making primitive types built-in?
if (!cPythonTypeOpt.has_value()) {
@@ -878,17 +848,17 @@ bool ShibokenGenerator::isNumber(const AbstractMetaType &type)
return isNumber(type.typeEntry());
}
-bool ShibokenGenerator::isPyInt(const TypeEntry *type)
+bool ShibokenGenerator::isPyInt(const TypeEntryCPtr &type)
{
if (!type->isPrimitive())
return false;
- const auto *pte = type->asPrimitive()->basicReferencedTypeEntry();
+ const auto pte = basicReferencedTypeEntry(type);
const auto cPythonTypeOpt = targetLangApiCPythonType(pte);
// FIXME PYSIDE-1660: Return false here after making primitive types built-in?
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;
}
@@ -900,15 +870,15 @@ bool ShibokenGenerator::isPyInt(const AbstractMetaType &type)
bool ShibokenGenerator::isNullPtr(const QString &value)
{
- return value == QLatin1String("0") || value == QLatin1String("nullptr")
- || value == QLatin1String("NULLPTR") || value == QLatin1String("{}");
+ return value == u"0" || value == u"nullptr"
+ || value == u"NULLPTR" || value == u"{}";
}
-QString ShibokenGenerator::cpythonCheckFunction(AbstractMetaType metaType) const
+QString ShibokenGenerator::cpythonCheckFunction(AbstractMetaType metaType)
{
- const auto *typeEntry = metaType.typeEntry();
+ const auto typeEntry = metaType.typeEntry();
if (typeEntry->isCustom()) {
- const auto *cte = static_cast<const CustomTypeEntry *>(typeEntry);
+ const auto cte = std::static_pointer_cast<const CustomTypeEntry>(typeEntry);
if (cte->hasCheckFunction())
return cte->checkFunction();
throw Exception(msgUnknownCheckFunction(typeEntry));
@@ -916,28 +886,30 @@ QString ShibokenGenerator::cpythonCheckFunction(AbstractMetaType metaType) const
if (metaType.isExtendedCppPrimitive()) {
if (metaType.isCString())
- return QLatin1String("Shiboken::String::check");
+ return u"Shiboken::String::check"_s;
if (metaType.isVoidPointer())
- return u"true"_qs;
+ return u"true"_s;
return cpythonCheckFunction(typeEntry);
}
if (typeEntry->isContainer()) {
- QString typeCheck = QLatin1String("Shiboken::Conversions::");
+ QString typeCheck = u"Shiboken::Conversions::"_s;
ContainerTypeEntry::ContainerKind type =
- static_cast<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
+ ? u"Iterable"_s : u"Sequence"_s;
const AbstractMetaType &type = metaType.instantiations().constFirst();
if (type.isPointerToWrapperType()) {
- typeCheck += u"checkSequenceTypes("_qs + cpythonTypeNameExt(type)
- + u", "_qs;
+ typeCheck += u"check"_s + containerType + u"Types("_s
+ + cpythonTypeNameExt(type) + u", "_s;
} else if (type.isWrapperType()) {
- typeCheck += u"convertibleSequenceTypes("_qs +
- cpythonTypeNameExt(type) + u", "_qs;
+ typeCheck += u"convertible"_s + containerType
+ + u"Types("_s + cpythonTypeNameExt(type) + u", "_s;
} else {
- typeCheck += u"convertibleSequenceTypes("_qs + converterObject(type)
- + u", "_qs;
+ typeCheck += u"convertible"_s + containerType
+ + u"Types("_s + converterObject(type) + u", "_s;
}
} else if (type == ContainerTypeEntry::MapContainer
|| type == ContainerTypeEntry::MultiMapContainer
@@ -945,11 +917,11 @@ QString ShibokenGenerator::cpythonCheckFunction(AbstractMetaType metaType) const
QString pyType;
if (type == ContainerTypeEntry::PairContainer)
- pyType = u"Pair"_qs;
+ pyType = u"Pair"_s;
else if (type == ContainerTypeEntry::MultiMapContainer)
- pyType = u"MultiDict"_qs;
+ pyType = u"MultiDict"_s;
else
- pyType = u"Dict"_qs;
+ pyType = u"Dict"_s;
const AbstractMetaType &firstType = metaType.instantiations().constFirst();
const AbstractMetaType &secondType = metaType.instantiations().constLast();
@@ -971,92 +943,89 @@ QString ShibokenGenerator::cpythonCheckFunction(AbstractMetaType metaType) const
return cpythonCheckFunction(typeEntry);
}
-QString ShibokenGenerator::cpythonCheckFunction(const TypeEntry *type) const
+QString ShibokenGenerator::cpythonCheckFunction(TypeEntryCPtr type)
{
if (type->isCustom()) {
- const auto *cte = static_cast<const CustomTypeEntry *>(type);
+ const auto cte = std::static_pointer_cast<const CustomTypeEntry>(type);
if (cte->hasCheckFunction())
return cte->checkFunction();
throw Exception(msgUnknownCheckFunction(type));
}
if (type->isEnum() || type->isFlags() || type->isWrapperType())
- return u"SbkObject_TypeCheck("_qs + cpythonTypeNameExt(type) + u", "_qs;
+ return u"SbkObject_TypeCheck("_s + cpythonTypeNameExt(type) + u", "_s;
if (type->isPrimitive())
- type = type->asPrimitive()->basicReferencedTypeEntry();
+ type = basicReferencedTypeEntry(type);
- if (auto *tla = type->targetLangApiType()) {
+ if (auto tla = type->targetLangApiType()) {
if (tla->hasCheckFunction())
return tla->checkFunction();
}
- if (type->isExtendedCppPrimitive()) {
- const auto *pte = type->asPrimitive();
- return pythonPrimitiveTypeName(pte->name())
- + QLatin1String("_Check");
- }
+ if (isExtendedCppPrimitive(type))
+ return pythonPrimitiveTypeName(type->name()) + u"_Check"_s;
return cpythonIsConvertibleFunction(type);
}
-QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntry *type)
+QString ShibokenGenerator::cpythonIsConvertibleFunction(const TypeEntryCPtr &type)
{
if (type->isWrapperType()) {
- QString result = QLatin1String("Shiboken::Conversions::");
+ QString result = u"Shiboken::Conversions::"_s;
bool isValue = false;
if (type->isValue()) {
- const auto *cte = static_cast<const ComplexTypeEntry *>(type);
+ const auto cte = std::static_pointer_cast<const ComplexTypeEntry>(type);
isValue = !cte->isValueTypeWithCopyConstructorOnly();
}
- result += isValue
- ? QLatin1String("isPythonToCppValueConvertible")
- : QLatin1String("isPythonToCppPointerConvertible");
- result += QLatin1String("(")
- + cpythonTypeNameExt(type) + QLatin1String(", ");
+ result += isValue ? u"isPythonToCppValueConvertible"_s
+ : u"isPythonToCppPointerConvertible"_s;
+ result += u"("_s + cpythonTypeNameExt(type) + u", "_s;
return result;
}
return QString::fromLatin1("Shiboken::Conversions::isPythonToCppConvertible(%1, ")
.arg(converterObject(type));
}
-QString ShibokenGenerator::cpythonIsConvertibleFunction(AbstractMetaType metaType)
+QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaType &metaType)
{
- const auto *typeEntry = metaType.typeEntry();
+ const auto typeEntry = metaType.typeEntry();
if (typeEntry->isCustom()) {
- const auto *cte = static_cast<const CustomTypeEntry *>(typeEntry);
+ const auto cte = std::static_pointer_cast<const CustomTypeEntry>(typeEntry);
if (cte->hasCheckFunction())
return cte->checkFunction();
throw Exception(msgUnknownCheckFunction(typeEntry));
}
- QString result = QLatin1String("Shiboken::Conversions::");
+ QString result = u"Shiboken::Conversions::"_s;
if (metaType.generateOpaqueContainer()) {
- result += u"pythonToCppReferenceConversion("_qs
- + converterObject(metaType) + u", "_qs;
+ result += u"pythonToCppReferenceConversion("_s
+ + converterObject(metaType) + u", "_s;
return result;
}
if (metaType.isWrapperType()) {
- if (metaType.isPointer() || metaType.isValueTypeWithCopyConstructorOnly())
- result += u"pythonToCppPointerConversion"_qs;
- else if (metaType.referenceType() == LValueReference)
- result += u"pythonToCppReferenceConversion"_qs;
- else
- result += u"pythonToCppValueConversion"_qs;
- result += u'(' + cpythonTypeNameExt(metaType) + u", "_qs;
+ if (metaType.isPointer() || metaType.isValueTypeWithCopyConstructorOnly()) {
+ result += u"pythonToCppPointerConversion"_s;
+ } else if (metaType.referenceType() == LValueReference
+ || (metaType.referenceType() == RValueReference && typeEntry->isObject())) {
+ result += u"pythonToCppReferenceConversion"_s;
+ } else {
+ result += u"pythonToCppValueConversion"_s;
+ }
+ result += u'(' + cpythonTypeNameExt(metaType) + u", "_s;
return result;
}
- result += u"pythonToCppConversion("_qs + converterObject(metaType);
+ result += u"pythonToCppConversion("_s + converterObject(metaType);
// Write out array sizes if known
const AbstractMetaTypeList nestedArrayTypes = metaType.nestedArrayTypes();
if (!nestedArrayTypes.isEmpty() && nestedArrayTypes.constLast().isCppPrimitive()) {
const int dim1 = metaType.arrayElementCount();
const int dim2 = nestedArrayTypes.constFirst().isArray()
? nestedArrayTypes.constFirst().arrayElementCount() : -1;
- result += QLatin1String(", ") + QString::number(dim1)
- + QLatin1String(", ") + QString::number(dim2);
+ result += u", "_s + QString::number(dim1)
+ + u", "_s + QString::number(dim2);
}
- result += QLatin1String(", ");
+ result += u", "_s;
return result;
}
@@ -1065,68 +1034,67 @@ QString ShibokenGenerator::cpythonIsConvertibleFunction(const AbstractMetaArgume
return cpythonIsConvertibleFunction(metaArg.type());
}
-QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaClass *metaClass)
+QString ShibokenGenerator::cpythonToCppConversionFunction(const AbstractMetaClassCPtr &metaClass)
{
- return QLatin1String("Shiboken::Conversions::pythonToCppPointer(")
- + cpythonTypeNameExt(metaClass->typeEntry()) + QLatin1String(", ");
+ 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 QLatin1String("Shiboken::Conversions::pythonToCpp")
- + (type.isPointer() ? QLatin1String("Pointer") : QLatin1String("Copy"))
- + u'(' + cpythonTypeNameExt(type) + QLatin1String(", ");
+ 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;
if (type.referenceType() == LValueReference
&& !(type.isValue() && type.isConstant()) && !type.isPointer()) {
- conversion = QLatin1String("reference");
+ conversion = u"reference"_s;
} else if (type.isValue() || type.isSmartPointer()) {
- conversion = QLatin1String("copy");
+ conversion = u"copy"_s;
} else {
- conversion = QLatin1String("pointer");
+ conversion = u"pointer"_s;
}
- QString result = QLatin1String("Shiboken::Conversions::") + conversion
- + QLatin1String("ToPython(")
- + cpythonTypeNameExt(type) + QLatin1String(", ");
- if (conversion != QLatin1String("pointer"))
- result += QLatin1Char('&');
+ QString result = u"Shiboken::Conversions::"_s + conversion
+ + u"ToPython("_s
+ + cpythonTypeNameExt(type) + u", "_s;
+ if (conversion != u"pointer")
+ result += u'&';
return result;
}
- return QStringLiteral("Shiboken::Conversions::copyToPython(%1, %2")
- .arg(converterObject(type),
- (type.isCString() || type.isVoidPointer()) ? QString() : QLatin1String("&"));
+
+ 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());
}
-QString ShibokenGenerator::cpythonToPythonConversionFunction(const TypeEntry *type)
+QString ShibokenGenerator::cpythonToPythonConversionFunction(const TypeEntryCPtr &type)
{
if (type->isWrapperType()) {
- const QString conversion = type->isValue() ? QLatin1String("copy") : QLatin1String("pointer");
- QString result = QLatin1String("Shiboken::Conversions::") + conversion
- + QLatin1String("ToPython(") + cpythonTypeNameExt(type)
- + QLatin1String(", ");
- if (conversion != QLatin1String("pointer"))
- result += QLatin1Char('&');
+ const QString conversion = type->isValue() ? u"copy"_s : u"pointer"_s;
+ QString result = u"Shiboken::Conversions::"_s + conversion
+ + u"ToPython("_s + cpythonTypeNameExt(type)
+ + u", "_s;
+ if (conversion != u"pointer")
+ result += u'&';
return result;
}
- return u"Shiboken::Conversions::copyToPython("_qs
- + converterObject(type) + u", &"_qs;
+ return u"Shiboken::Conversions::copyToPython("_s
+ + converterObject(type) + u", &"_s;
}
QString ShibokenGenerator::argumentString(const AbstractMetaFunctionCPtr &func,
@@ -1136,30 +1104,31 @@ 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(QLatin1Char('$'), QLatin1Char('.')); // Haehh?
+ arg.replace(u'$', u'.'); // Haehh?
// "int a", "int a[]"
- const int arrayPos = arg.indexOf(QLatin1Char('['));
+ const auto arrayPos = arg.indexOf(u'[');
if (arrayPos != -1)
- arg.insert(arrayPos, QLatin1Char(' ') + argument.name());
+ arg.insert(arrayPos, u' ' + argument.name());
else
- arg.append(QLatin1Char(' ') + argument.name());
+ arg.append(u' ' + argument.name());
if ((options & Generator::SkipDefaultValues) != Generator::SkipDefaultValues &&
!argument.originalDefaultValueExpression().isEmpty())
{
QString default_value = argument.originalDefaultValueExpression();
- if (default_value == QLatin1String("NULL"))
- default_value = QLatin1String(NULL_PTR);
+ if (default_value == u"NULL")
+ default_value = NULL_PTR;
//WORKAROUND: fix this please
- if (default_value.startsWith(QLatin1String("new ")))
+ if (default_value.startsWith(u"new "))
default_value.remove(0, 4);
- arg += QLatin1String(" = ") + default_value;
+ arg += u" = "_s + default_value;
}
return arg;
@@ -1177,11 +1146,12 @@ void ShibokenGenerator::writeFunctionArguments(TextStream &s,
const AbstractMetaFunctionCPtr &func,
Options options) const
{
- AbstractMetaArgumentList arguments = func->arguments();
-
int argUsed = 0;
- for (int i = 0; i < arguments.size(); ++i) {
- const auto &arg = arguments.at(i);
+ 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;
@@ -1192,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)) {
@@ -1217,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
@@ -1250,12 +1222,16 @@ void ShibokenGenerator::writeArgumentNames(TextStream &s,
const int index = argument.argumentIndex() + 1;
if (options.testFlag(Generator::SkipRemovedArguments) && argument.isModifiedRemoved())
continue;
+ const auto &type = argument.type();
+ if (argCount > 0)
+ s << ", ";
+ const bool isVirtualCall = options.testFlag(Option::VirtualCall);
+ const bool useStdMove = isVirtualCall && type.isUniquePointer() && type.passByValue();
+ s << (useStdMove ? stdMove(argument.name()) : argument.name());
- s << ((argCount > 0) ? ", " : "") << argument.name();
-
- if (((options & Generator::VirtualCall) == 0)
- && (!func->conversionRule(TypeSystem::NativeCode, index).isEmpty()
- || !func->conversionRule(TypeSystem::TargetLangCode, index).isEmpty())
+ if (!isVirtualCall
+ && (func->hasConversionRule(TypeSystem::NativeCode, index)
+ || func->hasConversionRule(TypeSystem::TargetLangCode, index))
&& !func->isConstructor()) {
s << CONV_RULE_OUT_VAR_SUFFIX;
}
@@ -1274,55 +1250,18 @@ void ShibokenGenerator::writeFunctionCall(TextStream &s,
s << ')';
}
-void ShibokenGenerator::writeUnusedVariableCast(TextStream &s, const QString &variableName)
-{
- s << "SBK_UNUSED(" << variableName<< ")\n";
-}
-
-static bool filterFunction(const AbstractMetaFunctionCPtr &func, bool avoidProtectedHack)
-{
- switch (func->functionType()) {
- case AbstractMetaFunction::DestructorFunction:
- case AbstractMetaFunction::SignalFunction:
- case AbstractMetaFunction::GetAttroFunction:
- case AbstractMetaFunction::SetAttroFunction:
- return false;
- default:
- break;
- }
- if (func->usesRValueReferences())
- return false;
- if (func->isModifiedRemoved() && !func->isAbstract()
- && (!avoidProtectedHack || !func->isProtected())) {
- return false;
- }
- return true;
-}
-
-AbstractMetaFunctionCList ShibokenGenerator::filterFunctions(const AbstractMetaClass *metaClass) const
-{
- AbstractMetaFunctionCList result;
- const AbstractMetaFunctionCList &funcs = metaClass->functions();
- result.reserve(funcs.size());
- for (const auto &func : funcs) {
- if (filterFunction(func, avoidProtectedHack()))
- result.append(func);
- }
- return result;
-}
-
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))
+ if (!shouldGenerate(metaClass->typeEntry()))
continue;
const auto &overloads = metaClass->operatorOverloads(OperatorQueryOption::ConversionOp);
for (const auto &convOp : overloads) {
// Get only the conversion operators that return a type from another module,
// that are value-types and were not removed in the type system.
- const TypeEntry *convType = convOp->type().typeEntry();
+ const auto convType = convOp->type().typeEntry();
if (convType->generateCode() || !convType->isValue()
|| convOp->isModifiedRemoved())
continue;
@@ -1332,15 +1271,13 @@ ShibokenGenerator::ExtendedConverterData ShibokenGenerator::getExtendedConverter
return extConvs;
}
-QList<const CustomConversion *> ShibokenGenerator::getPrimitiveCustomConversions()
+QList<CustomConversionPtr> ShibokenGenerator::getPrimitiveCustomConversions()
{
- QList<const CustomConversion *> conversions;
- const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
- for (const PrimitiveTypeEntry *type : primitiveTypeList) {
- if (!shouldGenerateTypeEntry(type) || !type->isUserPrimitive() || !type->customConversion())
- continue;
-
- conversions << type->customConversion();
+ QList<CustomConversionPtr> conversions;
+ const auto &primitiveTypeList = primitiveTypes();
+ for (const auto &type : primitiveTypeList) {
+ if (type->shouldGenerate() && isUserPrimitive(type) && type->hasCustomConversion())
+ conversions << type->customConversion();
}
return conversions;
}
@@ -1353,20 +1290,20 @@ 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();
- while (str.at(pos) == QLatin1Char(' ') || str.at(pos) == QLatin1Char('\t'))
+ while (str.at(pos) == u' ' || str.at(pos) == u'\t')
++pos;
- if (str.at(pos) == QLatin1Char('('))
+ if (str.at(pos) == u'(')
++pos;
int begin = pos;
int counter = 1;
while (counter != 0) {
- if (str.at(pos) == QLatin1Char('('))
+ if (str.at(pos) == u'(')
++counter;
- else if (str.at(pos) == QLatin1Char(')'))
+ else if (str.at(pos) == u')')
--counter;
++pos;
}
@@ -1391,14 +1328,13 @@ void ShibokenGenerator::processClassCodeSnip(QString &code, const GeneratorConte
auto metaClass = context.metaClass();
// Replace template variable by the Python Type object
// for the class context in which the variable is used.
- code.replace(QLatin1String("%PYTHONTYPEOBJECT"),
- u"(*"_qs + cpythonTypeName(metaClass) + u')');
- const QString className = context.useWrapper()
- ? context.wrapperName() : metaClass->qualifiedCppName();
- code.replace(QLatin1String("%TYPE"), className);
- code.replace(QLatin1String("%CPPTYPE"), metaClass->name());
+ code.replace(u"%PYTHONTYPEOBJECT"_s,
+ u"(*"_s + cpythonTypeName(metaClass) + u')');
+ const QString className = context.effectiveClassName();
+ 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
@@ -1416,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,
@@ -1425,30 +1370,30 @@ ShibokenGenerator::ArgumentVarReplacementList
TypeSystem::Language convLang = (language == TypeSystem::TargetLangCode)
? TypeSystem::NativeCode : TypeSystem::TargetLangCode;
int removed = 0;
- for (int i = 0; i < func->arguments().size(); ++i) {
+ for (qsizetype i = 0; i < func->arguments().size(); ++i) {
const AbstractMetaArgument &arg = func->arguments().at(i);
QString argValue;
if (language == TypeSystem::TargetLangCode) {
- bool hasConversionRule = !func->conversionRule(convLang, i+1).isEmpty();
+ const bool hasConversionRule = func->hasConversionRule(convLang, i + 1);
const bool argRemoved = arg.isModifiedRemoved();
if (argRemoved)
++removed;
if (argRemoved && hasConversionRule)
- argValue = arg.name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX);
+ argValue = arg.name() + CONV_RULE_OUT_VAR_SUFFIX;
else if (argRemoved || (lastArg && arg.argumentIndex() > lastArg->argumentIndex()))
- argValue = QLatin1String(CPP_ARG_REMOVED) + QString::number(i);
+ argValue = CPP_ARG_REMOVED(i);
if (!argRemoved && argValue.isEmpty()) {
int argPos = i - removed;
AbstractMetaType type = arg.modifiedType();
if (type.typeEntry()->isCustom()) {
argValue = usePyArgs
- ? pythonArgsAt(argPos) : QLatin1String(PYTHON_ARG);
+ ? pythonArgsAt(argPos) : PYTHON_ARG;
} else {
argValue = hasConversionRule
- ? arg.name() + QLatin1String(CONV_RULE_OUT_VAR_SUFFIX)
- : QLatin1String(CPP_ARG) + QString::number(argPos);
- if (type.shouldDereferenceArgument())
- AbstractMetaType::dereference(&argValue);
+ ? arg.name() + CONV_RULE_OUT_VAR_SUFFIX
+ : CPP_ARG_N(argPos);
+ const auto generatorArg = GeneratorArgument::fromMetaType(type);
+ AbstractMetaType::applyDereference(&argValue, generatorArg.indirections);
}
}
} else {
@@ -1488,13 +1433,12 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
static void replacePyArg0(TypeSystem::Language language, QString *code)
{
- static const QString pyArg0 = u"%PYARG_0"_qs;
- static const QString pyReturn = QLatin1String(PYTHON_RETURN_VAR);
+ static constexpr auto pyArg0 = "%PYARG_0"_L1;
if (!code->contains(pyArg0))
return;
if (language != TypeSystem::NativeCode) {
- code->replace(pyArg0, pyReturn);
+ code->replace(pyArg0, PYTHON_RETURN_VAR);
return;
}
@@ -1503,13 +1447,13 @@ static void replacePyArg0(TypeSystem::Language language, QString *code)
// situations (fex _PyVarObject_CAST(op) defined as ((PyVarObject*)(op))).
// Append ".object()" unless it is followed by a '.' indicating explicit
// AutoDecRef member invocation.
- static const QString pyObject = pyReturn + u".object()"_qs;
+ static const QString pyObject = PYTHON_RETURN_VAR + u".object()"_s;
qsizetype pos{};
while ( (pos = code->indexOf(pyArg0)) >= 0) {
const auto next = pos + pyArg0.size();
const bool memberInvocation = next < code->size() && code->at(next) == u'.';
code->replace(pos, pyArg0.size(),
- memberInvocation ? pyReturn : pyObject);
+ memberInvocation ? PYTHON_RETURN_VAR : pyObject);
}
}
@@ -1528,112 +1472,112 @@ 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, QLatin1String(PYTHON_ARGS) + QLatin1String("[\\1-1]"));
+ 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(QLatin1String("%PYARG_1"), QLatin1String(PYTHON_ARG));
+ code.replace(u"%PYARG_1"_s, PYTHON_ARG);
}
} 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, QLatin1String("PyTuple_SET_ITEM(")
- + QLatin1String(PYTHON_ARGS) + QLatin1String(", \\1-1, \\2)"));
- code.replace(pyArgsRegex, QLatin1String("PyTuple_GET_ITEM(")
- + QLatin1String(PYTHON_ARGS) + QLatin1String(", \\1-1)"));
+ code.replace(pyArgsAttributionRegex, u"PyTuple_SET_ITEM("_s
+ + PYTHON_ARGS + u".object(), \\1-1, \\2)"_s);
+ code.replace(pyArgsRegex, u"PyTuple_GET_ITEM("_s
+ + PYTHON_ARGS + u".object(), \\1-1)"_s);
}
// Replace %ARG#_TYPE variables.
const AbstractMetaArgumentList &arguments = func->arguments();
for (const AbstractMetaArgument &arg : arguments) {
- QString argTypeVar = u"%ARG"_qs + QString::number(arg.argumentIndex() + 1)
- + u"_TYPE"_qs;
+ QString argTypeVar = u"%ARG"_s + QString::number(arg.argumentIndex() + 1)
+ + u"_TYPE"_s;
QString argTypeVal = arg.type().cppSignature();
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.
if (func->isConstructor()) {
- code.replace(QLatin1String("%0."), QLatin1String("cptr->"));
- code.replace(QLatin1String("%0"), QLatin1String("cptr"));
+ code.replace(u"%0."_s, u"cptr->"_s);
+ code.replace(u"%0"_s, u"cptr"_s);
} else if (!func->isVoid()) {
QString returnValueOp = func->type().isPointerToWrapperType()
- ? QLatin1String("%1->") : QLatin1String("%1.");
+ ? u"%1->"_s : u"%1."_s;
if (func->type().isWrapperType())
- code.replace(QLatin1String("%0."), returnValueOp.arg(QLatin1String(CPP_RETURN_VAR)));
- code.replace(QLatin1String("%0"), QLatin1String(CPP_RETURN_VAR));
+ code.replace(u"%0."_s, returnValueOp.arg(CPP_RETURN_VAR));
+ code.replace(u"%0"_s, CPP_RETURN_VAR);
}
// Replace template variable for self Python object.
QString pySelf = language == TypeSystem::NativeCode
- ? QLatin1String("pySelf") : QLatin1String("self");
- code.replace(QLatin1String("%PYSELF"), pySelf);
+ ? u"pySelf"_s : u"self"_s;
+ code.replace(u"%PYSELF"_s, pySelf);
// Replace template variable for a pointer to C++ of this object.
if (func->implementingClass()) {
- QString replacement = func->isStatic() ? QLatin1String("%1::") : QLatin1String("%1->");
+ QString replacement = func->isStatic() ? u"%1::"_s : u"%1->"_s;
QString cppSelf;
if (func->isStatic())
cppSelf = func->ownerClass()->qualifiedCppName();
else if (language == TypeSystem::NativeCode)
- cppSelf = QLatin1String("this");
+ cppSelf = u"this"_s;
else
- cppSelf = QLatin1String(CPP_SELF_VAR);
+ cppSelf = CPP_SELF_VAR;
// On comparison operator CPP_SELF_VAR is always a reference.
if (func->isComparisonOperator())
- replacement = QLatin1String("%1.");
+ replacement = u"%1."_s;
if (func->isVirtual() && !func->isAbstract() && (!avoidProtectedHack() || !func->isProtected())) {
QString methodCallArgs = getArgumentsFromMethodCall(code);
if (!methodCallArgs.isEmpty()) {
- const QString pattern = u"%CPPSELF.%FUNCTION_NAME("_qs + methodCallArgs + u')';
- QString replacement = u"(Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject *>("_qs
- + pySelf + u")) ? "_qs;
- if (func->name() == QLatin1String("metaObject")) {
+ const QString pattern = u"%CPPSELF.%FUNCTION_NAME("_s + methodCallArgs + u')';
+ QString replacement = u"(Shiboken::Object::hasCppWrapper(reinterpret_cast<SbkObject *>("_s
+ + pySelf + u")) ? "_s;
+ if (func->name() == u"metaObject") {
QString wrapperClassName = wrapperName(func->ownerClass());
QString cppSelfVar = avoidProtectedHack()
- ? u"%CPPSELF"_qs
- : u"reinterpret_cast<"_qs + wrapperClassName + u" *>(%CPPSELF)"_qs;
- replacement += cppSelfVar + u"->::"_qs + wrapperClassName
- + u"::%FUNCTION_NAME("_qs + methodCallArgs
- + u") : %CPPSELF.%FUNCTION_NAME("_qs + methodCallArgs + u"))"_qs;
+ ? u"%CPPSELF"_s
+ : u"reinterpret_cast<"_s + wrapperClassName + u" *>(%CPPSELF)"_s;
+ replacement += cppSelfVar + u"->::"_s + wrapperClassName
+ + u"::%FUNCTION_NAME("_s + methodCallArgs
+ + u") : %CPPSELF.%FUNCTION_NAME("_s + methodCallArgs + u"))"_s;
} else {
- replacement += u"%CPPSELF->::%TYPE::%FUNCTION_NAME("_qs + methodCallArgs
- + u") : %CPPSELF.%FUNCTION_NAME("_qs + methodCallArgs + u"))"_qs;
+ replacement += u"%CPPSELF->::%TYPE::%FUNCTION_NAME("_s + methodCallArgs
+ + u") : %CPPSELF.%FUNCTION_NAME("_s + methodCallArgs + u"))"_s;
}
code.replace(pattern, replacement);
}
}
- code.replace(QLatin1String("%CPPSELF."), replacement.arg(cppSelf));
- code.replace(QLatin1String("%CPPSELF"), cppSelf);
+ code.replace(u"%CPPSELF."_s, replacement.arg(cppSelf));
+ code.replace(u"%CPPSELF"_s, cppSelf);
- if (code.indexOf(QLatin1String("%BEGIN_ALLOW_THREADS")) > -1) {
- if (code.count(QLatin1String("%BEGIN_ALLOW_THREADS")) == code.count(QLatin1String("%END_ALLOW_THREADS"))) {
- code.replace(QLatin1String("%BEGIN_ALLOW_THREADS"), QLatin1String(BEGIN_ALLOW_THREADS));
- code.replace(QLatin1String("%END_ALLOW_THREADS"), QLatin1String(END_ALLOW_THREADS));
+ if (code.indexOf(u"%BEGIN_ALLOW_THREADS") > -1) {
+ if (code.count(u"%BEGIN_ALLOW_THREADS"_s) == code.count(u"%END_ALLOW_THREADS"_s)) {
+ code.replace(u"%BEGIN_ALLOW_THREADS"_s, BEGIN_ALLOW_THREADS);
+ code.replace(u"%END_ALLOW_THREADS"_s, END_ALLOW_THREADS);
} else {
qCWarning(lcShiboken) << "%BEGIN_ALLOW_THREADS and %END_ALLOW_THREADS mismatch";
}
@@ -1642,11 +1586,11 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
// replace template variable for the Python Type object for the
// class implementing the method in which the code snip is written
if (func->isStatic()) {
- code.replace(QLatin1String("%PYTHONTYPEOBJECT"),
- u"(*"_qs + cpythonTypeName(func->implementingClass()) + u')');
+ code.replace(u"%PYTHONTYPEOBJECT"_s,
+ u"(*"_s + cpythonTypeName(func->implementingClass()) + u')');
} else {
- code.replace(QLatin1String("%PYTHONTYPEOBJECT."), pySelf + QLatin1String("->ob_type->"));
- code.replace(QLatin1String("%PYTHONTYPEOBJECT"), pySelf + QLatin1String("->ob_type"));
+ code.replace(u"%PYTHONTYPEOBJECT."_s, pySelf + u"->ob_type->"_s);
+ code.replace(u"%PYTHONTYPEOBJECT"_s, pySelf + u"->ob_type"_s);
}
}
@@ -1656,11 +1600,11 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
QStringList args;
for (const ArgumentVarReplacementPair &pair : argReplacements) {
- if (pair.second.startsWith(QLatin1String(CPP_ARG_REMOVED)))
+ if (pair.second.startsWith(CPP_ARG_REMOVED_PREFIX))
continue;
args << pair.second;
}
- code.replace(QLatin1String("%ARGUMENT_NAMES"), args.join(QLatin1String(", ")));
+ code.replace(u"%ARGUMENT_NAMES"_s, args.join(u", "_s));
for (const ArgumentVarReplacementPair &pair : argReplacements) {
const AbstractMetaArgument &arg = pair.first;
@@ -1668,10 +1612,11 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
AbstractMetaType type = arg.modifiedType();
if (type.isWrapperType()) {
QString replacement = pair.second;
- if (type.shouldDereferenceArgument())
+ const auto generatorArg = GeneratorArgument::fromMetaType(type);
+ if (generatorArg.indirections > 0)
AbstractMetaType::stripDereference(&replacement);
if (type.referenceType() == LValueReference || type.isPointer())
- code.replace(u'%' + QString::number(idx) + u'.', replacement + u"->"_qs);
+ code.replace(u'%' + QString::number(idx) + u'.', replacement + u"->"_s);
}
code.replace(CodeSnipAbstract::placeHolderRegex(idx), pair.second);
}
@@ -1680,11 +1625,11 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
// Replaces template %PYTHON_ARGUMENTS variable with a pointer to the Python tuple
// containing the converted virtual method arguments received from C++ to be passed
// to the Python override.
- code.replace(QLatin1String("%PYTHON_ARGUMENTS"), QLatin1String(PYTHON_ARGS));
+ code.replace(u"%PYTHON_ARGUMENTS"_s, PYTHON_ARGS);
// replace variable %PYTHON_METHOD_OVERRIDE for a pointer to the Python method
// override for the C++ virtual method in which this piece of code was inserted
- code.replace(QLatin1String("%PYTHON_METHOD_OVERRIDE"), QLatin1String(PYTHON_OVERRIDE_VAR));
+ code.replace(u"%PYTHON_METHOD_OVERRIDE"_s, PYTHON_OVERRIDE_VAR);
}
if (avoidProtectedHack()) {
@@ -1704,23 +1649,23 @@ void ShibokenGenerator::writeCodeSnips(TextStream &s,
}
if (isProtected) {
- code.replace(QLatin1String("%TYPE::%FUNCTION_NAME"),
- QStringLiteral("%1::%2_protected")
- .arg(wrapperName(func->ownerClass()), func->originalName()));
- code.replace(QLatin1String("%FUNCTION_NAME"),
- func->originalName() + QLatin1String("_protected"));
+ code.replace(u"%TYPE::%FUNCTION_NAME"_s,
+ wrapperName(func->ownerClass()) + "::"_L1
+ + func->originalName() + "_protected"_L1);
+ code.replace(u"%FUNCTION_NAME"_s,
+ func->originalName() + u"_protected"_s);
}
}
if (func->isConstructor() && shouldGenerateCppWrapper(func->ownerClass()))
- code.replace(QLatin1String("%TYPE"), wrapperName(func->ownerClass()));
+ code.replace(u"%TYPE"_s, wrapperName(func->ownerClass()));
if (func->ownerClass())
- code.replace(QLatin1String("%CPPTYPE"), func->ownerClass()->name());
+ code.replace(u"%CPPTYPE"_s, func->ownerClass()->name());
replaceTemplateVariables(code, func);
- processCodeSnip(code);
+ processCodeSnip(code, func->classQualifiedSignature());
s << "// Begin code injection\n" << code << "// End of code injection\n\n";
}
@@ -1728,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();
}
@@ -1741,15 +1686,15 @@ static QString miniNormalizer(const QString &varType)
QString normalized = varType.trimmed();
if (normalized.isEmpty())
return normalized;
- if (normalized.startsWith(QLatin1String("::")))
+ if (normalized.startsWith(u"::"))
normalized.remove(0, 2);
QString suffix;
- while (normalized.endsWith(QLatin1Char('*')) || normalized.endsWith(QLatin1Char('&'))) {
- suffix.prepend(normalized.at(normalized.count() - 1));
+ while (normalized.endsWith(u'*') || normalized.endsWith(u'&')) {
+ suffix.prepend(normalized.at(normalized.size() - 1));
normalized.chop(1);
normalized = normalized.trimmed();
}
- const QString result = normalized + QLatin1Char(' ') + suffix;
+ const QString result = normalized + u' ' + suffix;
return result.trimmed();
}
// The position must indicate the first character after the opening '('.
@@ -1760,7 +1705,7 @@ static QString getConverterTypeSystemVariableArgument(const QString &code, int p
QString arg;
int parenthesisDepth = 0;
int count = 0;
- while (pos + count < code.count()) {
+ while (pos + count < code.size()) {
char c = code.at(pos+count).toLatin1(); // toAscii is gone
if (c == '(') {
++parenthesisDepth;
@@ -1781,15 +1726,15 @@ static QString getConverterTypeSystemVariableArgument(const QString &code, int p
const QHash<int, QString> &ShibokenGenerator::typeSystemConvName()
{
static const QHash<int, QString> result = {
- {TypeSystemCheckFunction, QLatin1String("checkType")},
- {TypeSystemIsConvertibleFunction, QLatin1String("isConvertible")},
- {TypeSystemToCppFunction, QLatin1String("toCpp")},
- {TypeSystemToPythonFunction, QLatin1String("toPython")}
+ {TypeSystemCheckFunction, u"checkType"_s},
+ {TypeSystemIsConvertibleFunction, u"isConvertible"_s},
+ {TypeSystemToCppFunction, u"toCpp"_s},
+ {TypeSystemToPythonFunction, u"toPython"_s}
};
return result;
}
-using StringPair = QPair<QString, QString>;
+using StringPair = std::pair<QString, QString>;
void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVariable converterVariable,
QString &code) const
@@ -1815,7 +1760,7 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
StringStream c(TextStream::Language::Cpp);
int end = match.capturedStart();
int start = end;
- while (start > 0 && code.at(start) != QLatin1Char('\n'))
+ while (start > 0 && code.at(start) != u'\n')
--start;
while (code.at(start).isSpace())
++start;
@@ -1824,16 +1769,13 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
varType = miniNormalizer(varType);
QString varName = list.at(1).trimmed();
if (!varType.isEmpty()) {
- const QString conversionSignature = conversionType.cppSignature();
- if (varType != QLatin1String("auto") && varType != conversionSignature)
- throw Exception(msgConversionTypesDiffer(varType, conversionSignature));
c << getFullTypeName(conversionType) << ' ' << varName
<< minimalConstructorExpression(api(), conversionType) << ";\n";
}
c << cpythonToCppConversionFunction(conversionType);
QString prefix;
if (!AbstractMetaType::stripDereference(&varName))
- prefix = QLatin1Char('&');
+ prefix = u'&';
QString arg = getConverterTypeSystemVariableArgument(code, match.capturedEnd());
conversionString += arg;
c << arg << ", " << prefix << '(' << varName << ')';
@@ -1843,8 +1785,8 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
case TypeSystemCheckFunction:
conversion = cpythonCheckFunction(conversionType);
if (conversionType.typeEntry()->isPrimitive()
- && (conversionType.typeEntry()->name() == cPyObjectT()
- || !conversion.endsWith(QLatin1Char(' ')))) {
+ && (conversionType.typeEntry()->name() == cPyObjectT
+ || !conversion.endsWith(u' '))) {
conversion += u'(';
break;
}
@@ -1866,17 +1808,17 @@ void ShibokenGenerator::replaceConverterTypeSystemVariable(TypeSystemConverterVa
<< code << '\'';
throw Exception(m);
}
- if (conversion.contains(QLatin1String("%in"))) {
- conversion.prepend(QLatin1Char('('));
- conversion.replace(QLatin1String("%in"), arg);
+ if (conversion.contains(u"%in")) {
+ conversion.prepend(u'(');
+ conversion.replace(u"%in"_s, arg);
} else {
conversion += arg;
}
}
}
- replacements.append(qMakePair(conversionString, conversion));
+ replacements.append(std::make_pair(conversionString, conversion));
}
- for (const StringPair &rep : qAsConst(replacements))
+ for (const StringPair &rep : std::as_const(replacements))
code.replace(rep.first, rep.second);
}
@@ -1885,9 +1827,9 @@ bool ShibokenGenerator::injectedCodeCallsCppFunction(const GeneratorContext &con
{
if (func->injectedCodeContains(u"%FUNCTION_NAME("))
return true;
- QString funcCall = func->originalName() + QLatin1Char('(');
+ QString funcCall = func->originalName() + u'(';
if (func->isConstructor())
- funcCall.prepend(QLatin1String("new "));
+ funcCall.prepend(u"new "_s);
if (func->injectedCodeContains(funcCall))
return true;
if (!func->isConstructor())
@@ -1897,18 +1839,17 @@ bool ShibokenGenerator::injectedCodeCallsCppFunction(const GeneratorContext &con
const auto owner = func->ownerClass();
if (!owner->isPolymorphic())
return false;
- const QString className = context.useWrapper()
- ? context.wrapperName() : owner->qualifiedCppName();
- const QString wrappedCtorCall = QLatin1String("new ") + className + QLatin1Char('(');
+ const QString wrappedCtorCall = u"new "_s + context.effectiveClassName() + u'(';
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()) {
@@ -1920,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;
@@ -1932,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;
@@ -1948,7 +1889,7 @@ bool ShibokenGenerator::classNeedsGetattroFunctionImpl(const AbstractMetaClass *
const auto &functionGroup = getFunctionGroups(metaClass);
for (auto it = functionGroup.cbegin(), end = functionGroup.cend(); it != end; ++it) {
AbstractMetaFunctionCList overloads;
- for (const auto &func : qAsConst(it.value())) {
+ for (const auto &func : std::as_const(it.value())) {
if (func->isAssignmentOperator() || func->isConversionOperator()
|| func->isModifiedRemoved()
|| func->isPrivate() || func->ownerClass() != func->implementingClass()
@@ -1965,14 +1906,14 @@ bool ShibokenGenerator::classNeedsGetattroFunctionImpl(const AbstractMetaClass *
}
AbstractMetaFunctionCList
- ShibokenGenerator::getMethodsWithBothStaticAndNonStaticMethods(const AbstractMetaClass *metaClass)
+ ShibokenGenerator::getMethodsWithBothStaticAndNonStaticMethods(const AbstractMetaClassCPtr &metaClass)
{
AbstractMetaFunctionCList methods;
if (metaClass) {
const auto &functionGroups = getFunctionGroups(metaClass);
for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
AbstractMetaFunctionCList overloads;
- for (const auto &func : qAsConst(it.value())) {
+ for (const auto &func : std::as_const(it.value())) {
if (func->isAssignmentOperator() || func->isConversionOperator()
|| func->isModifiedRemoved()
|| func->isPrivate() || func->ownerClass() != func->implementingClass()
@@ -1989,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;
@@ -2000,24 +1942,48 @@ 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 AbstractMetaClassCPtr &metaClass) const
+{
+ IncludeGroupList result;
+ const auto typeEntry = metaClass->typeEntry();
+ //Extra includes
+ result.append(IncludeGroup{u"Extra includes"_s,
+ typeEntry->extraIncludes()});
+
+ result.append({u"Enum includes"_s, {}});
+ for (const auto &cppEnum : metaClass->enums())
+ result.back().includes.append(cppEnum.typeEntry()->extraIncludes());
+
+ result.append({u"Argument includes"_s, typeEntry->argumentIncludes()});
+ const auto implicitConvs = implicitConversions(typeEntry);
+ for (const auto &f : implicitConvs) {
+ if (f->isConversionOperator()) {
+ const auto source = f->ownerClass();
+ Q_ASSERT(source);
+ result.back().append(source->typeEntry()->include());
+ }
+ }
+ return result;
}
/*
static void dumpFunction(AbstractMetaFunctionList lst)
{
qDebug() << "DUMP FUNCTIONS: ";
- for (AbstractMetaFunction *func : qAsConst(lst))
+ for (AbstractMetaFunction *func : std::as_const(lst))
qDebug() << "*" << func->ownerClass()->name()
<< func->signature()
<< "Private: " << func->isPrivate()
@@ -2061,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)
@@ -2092,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;
}
@@ -2101,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);
@@ -2132,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())
@@ -2164,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();
@@ -2177,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
@@ -2207,258 +2336,237 @@ void ShibokenGenerator::getInheritedOverloads(const AbstractMetaClass *scope,
}
}
-Generator::OptionDescriptions ShibokenGenerator::options() const
-{
- auto result = Generator::options();
- result.append({
- {QLatin1String(AVOID_PROTECTED_HACK),
- QLatin1String("Avoid the use of the '#define protected public' hack.")},
- {QLatin1String(DISABLE_VERBOSE_ERROR_MESSAGES),
- QLatin1String("Disable verbose error messages. Turn the python code hard to debug\n"
- "but safe few kB on the generated bindings.")},
- {QLatin1String(PARENT_CTOR_HEURISTIC),
- QLatin1String("Enable heuristics to detect parent relationship on constructors.")},
- {QLatin1String(RETURN_VALUE_HEURISTIC),
- QLatin1String("Enable heuristics to detect parent relationship on return values\n"
- "(USE WITH CAUTION!)")},
- {QLatin1String(USE_ISNULL_AS_NB_NONZERO),
- QLatin1String("If a class have an isNull() const method, it will be used to compute\n"
- "the value of boolean casts")},
- {QLatin1String(USE_OPERATOR_BOOL_AS_NB_NONZERO),
- QLatin1String("If a class has an operator bool, it will be used to compute\n"
- "the value of boolean casts")},
- {QLatin1String(NO_IMPLICIT_CONVERSIONS),
- u"Do not generate implicit_conversions for function arguments."_qs},
- {QLatin1String(WRAPPER_DIAGNOSTICS),
- QLatin1String("Generate diagnostic code around wrappers")}
- });
- return result;
+QList<OptionDescription> ShibokenGenerator::options()
+{
+ 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},
+ {PARENT_CTOR_HEURISTIC,
+ u"Enable heuristics to detect parent relationship on constructors."_s},
+ {RETURN_VALUE_HEURISTIC,
+ u"Enable heuristics to detect parent relationship on return values\n"
+ "(USE WITH CAUTION!)"_s},
+ {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},
+ {LEAN_HEADERS,
+ u"Forward declare classes in module headers"_s},
+ {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},
+ {NO_IMPLICIT_CONVERSIONS,
+ u"Do not generate implicit_conversions for function arguments."_s},
+ {WRAPPER_DIAGNOSTICS,
+ u"Generate diagnostic code around wrappers"_s}
+ };
}
-bool ShibokenGenerator::handleOption(const QString &key, const QString &value)
+class ShibokenGeneratorOptionsParser : public OptionsParser
{
- if (Generator::handleOption(key, value))
- return true;
- if (key == QLatin1String(PARENT_CTOR_HEURISTIC))
- return (m_useCtorHeuristic = true);
- if (key == QLatin1String(RETURN_VALUE_HEURISTIC))
- return (m_userReturnValueHeuristic = true);
- if (key == QLatin1String(DISABLE_VERBOSE_ERROR_MESSAGES))
- return (m_verboseErrorMessagesDisabled = true);
- if (key == QLatin1String(USE_ISNULL_AS_NB_NONZERO))
- return (m_useIsNullAsNbNonZero = true);
- if (key == QLatin1String(USE_OPERATOR_BOOL_AS_NB_NONZERO))
- return (m_useOperatorBoolAsNbNonZero = true);
- if (key == QLatin1String(AVOID_PROTECTED_HACK))
- return (m_avoidProtectedHack = true);
- if (key == QLatin1String(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 == QLatin1String(WRAPPER_DIAGNOSTICS))
- return (m_wrapperDiagnostics = true);
+ if (key == WRAPPER_DIAGNOSTICS)
+ return (m_options->wrapperDiagnostics = true);
return false;
}
-static void getCode(QStringList &code, const CodeSnipList &codeSnips)
+std::shared_ptr<OptionsParser> ShibokenGenerator::createOptionsParser()
{
- for (const CodeSnip &snip : qAsConst(codeSnips))
- code.append(snip.code());
-}
-
-static void getCode(QStringList &code, const TypeEntry *type)
-{
- getCode(code, type->codeSnips());
-
- CustomConversion *customConversion = type->customConversion();
- if (!customConversion)
- return;
-
- if (!customConversion->nativeToTargetConversion().isEmpty())
- code.append(customConversion->nativeToTargetConversion());
-
- const CustomConversion::TargetToNativeConversions &toCppConversions = customConversion->targetToNativeConversions();
- if (toCppConversions.isEmpty())
- return;
-
- for (CustomConversion::TargetToNativeConversion *toNative : qAsConst(toCppConversions))
- code.append(toNative->conversion());
+ return std::make_shared<ShibokenGeneratorOptionsParser>(&m_options);
}
bool ShibokenGenerator::doSetup()
{
- QStringList snips;
- const PrimitiveTypeEntryList &primitiveTypeList = primitiveTypes();
- for (const PrimitiveTypeEntry *type : primitiveTypeList)
- getCode(snips, type);
- const ContainerTypeEntryList &containerTypeList = containerTypes();
- for (const ContainerTypeEntry *type : containerTypeList)
- getCode(snips, type);
- for (auto metaClass : api().classes())
- getCode(snips, metaClass->typeEntry());
-
- const TypeSystemTypeEntry *moduleEntry = TypeDatabase::instance()->defaultTypeSystemType();
- Q_ASSERT(moduleEntry);
- getCode(snips, moduleEntry);
-
- const auto &functionGroups = getGlobalFunctionGroups();
- for (auto it = functionGroups.cbegin(), end = functionGroups.cend(); it != end; ++it) {
- for (const auto &func : it.value())
- getCode(snips, func->injectedCodeSnips());
- }
-
- for (const QString &code : qAsConst(snips)) {
- collectContainerTypesFromConverterMacros(code, true);
- collectContainerTypesFromConverterMacros(code, false);
- }
-
return true;
}
-void ShibokenGenerator::collectContainerTypesFromConverterMacros(const QString &code, bool toPythonMacro)
-{
- QString convMacro = toPythonMacro ? QLatin1String("%CONVERTTOPYTHON[") : QLatin1String("%CONVERTTOCPP[");
- int offset = toPythonMacro ? sizeof("%CONVERTTOPYTHON") : sizeof("%CONVERTTOCPP");
- int start = 0;
- QString errorMessage;
- while ((start = code.indexOf(convMacro, start)) != -1) {
- int end = code.indexOf(QLatin1Char(']'), start);
- start += offset;
- if (code.at(start) != QLatin1Char('%')) {
- QString typeString = code.mid(start, end - start);
- auto type = AbstractMetaType::fromString(typeString, &errorMessage);
- if (type.has_value()) {
- addInstantiatedContainersAndSmartPointers(type.value(), type->originalTypeDescription());
- } else {
- QString m;
- QTextStream(&m) << __FUNCTION__ << ": Cannot translate type \""
- << typeString << "\": " << errorMessage;
- throw Exception(m);
- }
- }
- start = end;
- }
-}
-
-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::useOperatorBoolAsNbNonZero() const
+bool ShibokenGenerator::leanHeaders()
{
- return m_useOperatorBoolAsNbNonZero;
+ return m_options.leanHeaders;
}
-bool ShibokenGenerator::avoidProtectedHack() const
+bool ShibokenGenerator::useOperatorBoolAsNbBool()
{
- return m_avoidProtectedHack;
+ return m_options.useOperatorBoolAsNbBool;
}
-bool ShibokenGenerator::generateImplicitConversions() const
+bool ShibokenGenerator::generateImplicitConversions()
{
- return m_generateImplicitConversions;
+ return m_options.generateImplicitConversions;
}
QString ShibokenGenerator::moduleCppPrefix(const QString &moduleName)
{
QString result = moduleName.isEmpty() ? packageName() : moduleName;
- result.replace(QLatin1Char('.'), QLatin1Char('_'));
+ result.replace(u'.', u'_');
return result;
}
+QString ShibokenGenerator::cppApiVariableNameOld(const QString &moduleName)
+{
+ return "Sbk"_L1 + moduleCppPrefix(moduleName) + "Types"_L1;
+}
+
QString ShibokenGenerator::cppApiVariableName(const QString &moduleName)
{
- return QLatin1String("Sbk") + moduleCppPrefix(moduleName)
- + QLatin1String("Types");
+ return "Sbk"_L1 + moduleCppPrefix(moduleName) + "TypeStructs"_L1;
}
QString ShibokenGenerator::pythonModuleObjectName(const QString &moduleName)
{
- return QLatin1String("Sbk") + moduleCppPrefix(moduleName)
- + QLatin1String("ModuleObject");
+ 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(QLatin1String("Converters"));
+ result.append(u"Converters"_s);
return result;
}
static QString processInstantiationsVariableName(const AbstractMetaType &type)
{
- QString res = QLatin1Char('_') + _fixedCppTypeName(type.typeEntry()->qualifiedCppName()).toUpper();
+ QString res = u'_' + _fixedCppTypeName(type.typeEntry()->qualifiedCppName());
for (const auto &instantiation : type.instantiations()) {
res += instantiation.isContainer()
? processInstantiationsVariableName(instantiation)
- : QLatin1Char('_') + _fixedCppTypeName(instantiation.cppSignature()).toUpper();
+ : u'_' + _fixedCppTypeName(instantiation.cppSignature());
}
return res;
}
static void appendIndexSuffix(QString *s)
{
- if (!s->endsWith(QLatin1Char('_')))
- s->append(QLatin1Char('_'));
- s->append(QStringLiteral("IDX"));
+ if (!s->endsWith(u'_'))
+ s->append(u'_');
+ 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 = QLatin1String("SBK_")
- + _fixedCppTypeName(templateBaseClass->typeEntry()->qualifiedCppName()).toUpper();
+ QString result = u"SBK_"_s
+ + _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());
}
-QString ShibokenGenerator::getTypeIndexVariableName(const TypeEntry *type)
+QString ShibokenGenerator::getTypeIndexVariableName(TypeEntryCPtr type)
{
- if (type->isCppPrimitive())
- type = type->asPrimitive()->basicReferencedTypeEntry();
- QString result = QLatin1String("SBK_");
+ if (isCppPrimitive(type))
+ type = basicReferencedTypeEntry(type);
+ QString result = u"SBK_"_s;
// Disambiguate namespaces per module to allow for extending them.
if (type->isNamespace()) {
QString package = type->targetLangPackage();
- const int dot = package.lastIndexOf(QLatin1Char('.'));
+ 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;
}
QString ShibokenGenerator::getTypeIndexVariableName(const AbstractMetaType &type)
{
- QString result = QLatin1String("SBK");
+ QString result = u"SBK"_s;
if (type.typeEntry()->isContainer())
- result += QLatin1Char('_') + 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
@@ -2481,57 +2589,62 @@ QString ShibokenGenerator::minimalConstructorExpression(const ApiExtractorResult
return ctor->initialization();
const QString message =
- msgCouldNotFindMinimalConstructor(QLatin1String(__FUNCTION__),
+ msgCouldNotFindMinimalConstructor(QLatin1StringView(__FUNCTION__),
type.cppSignature(), errorMessage);
qCWarning(lcShiboken()).noquote() << message;
- return u";\n#error "_qs + message + u'\n';
+ return u";\n#error "_s + message + u'\n';
}
QString ShibokenGenerator::minimalConstructorExpression(const ApiExtractorResult &api,
- const TypeEntry *type)
+ const TypeEntryCPtr &type)
{
- if (type->isExtendedCppPrimitive())
+ if (isExtendedCppPrimitive(type))
return {};
const auto ctor = minimalConstructor(api, type);
if (ctor.has_value())
return ctor->initialization();
- const QString message = msgCouldNotFindMinimalConstructor(QLatin1String(__FUNCTION__),
- type->qualifiedCppName());
+ const QString message =
+ msgCouldNotFindMinimalConstructor(QLatin1StringView(__FUNCTION__),
+ type->qualifiedCppName());
qCWarning(lcShiboken()).noquote() << message;
- return u";\n#error "_qs + message + u'\n';
+ return u";\n#error "_s + message + u'\n';
}
QString ShibokenGenerator::pythonArgsAt(int i)
{
- return QLatin1String(PYTHON_ARGS) + QLatin1Char('[')
- + QString::number(i) + QLatin1Char(']');
+ return PYTHON_ARGS + u'[' + QString::number(i) + u']';
}
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(QLatin1String("%TYPE"), cpp_class->name());
+ code.replace(u"%TYPE"_s, cpp_class->name());
const AbstractMetaArgumentList &argument = func->arguments();
for (const AbstractMetaArgument &arg : argument)
- code.replace(QLatin1Char('%') + QString::number(arg.argumentIndex() + 1), arg.name());
+ code.replace(u'%' + QString::number(arg.argumentIndex() + 1), arg.name());
//template values
- code.replace(QLatin1String("%RETURN_TYPE"), translateType(func->type(), cpp_class));
- code.replace(QLatin1String("%FUNCTION_NAME"), func->originalName());
+ code.replace(u"%RETURN_TYPE"_s, translateType(func->type(), cpp_class));
+ code.replace(u"%FUNCTION_NAME"_s, func->originalName());
- if (code.contains(QLatin1String("%ARGUMENT_NAMES"))) {
+ if (code.contains(u"%ARGUMENT_NAMES")) {
StringStream aux_stream;
writeArgumentNames(aux_stream, func, Generator::SkipRemovedArguments);
- code.replace(QLatin1String("%ARGUMENT_NAMES"), aux_stream);
+ code.replace(u"%ARGUMENT_NAMES"_s, aux_stream);
}
- if (code.contains(QLatin1String("%ARGUMENTS"))) {
+ if (code.contains(u"%ARGUMENTS")) {
StringStream aux_stream;
writeFunctionArguments(aux_stream, func, Options(SkipDefaultValues) | SkipRemovedArguments);
- code.replace(QLatin1String("%ARGUMENTS"), aux_stream);
+ code.replace(u"%ARGUMENTS"_s, aux_stream);
}
}
+
+QString ShibokenGenerator::stdMove(const QString &c)
+{
+ return u"std::move("_s + c + u')';
+}
diff --git a/sources/shiboken6/generator/shiboken/shibokengenerator.h b/sources/shiboken6/generator/shiboken/shibokengenerator.h
index bf71bb0a3..22ee73fa2 100644
--- a/sources/shiboken6/generator/shiboken/shibokengenerator.h
+++ b/sources/shiboken6/generator/shiboken/shibokengenerator.h
@@ -1,66 +1,42 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SHIBOKENGENERATOR_H
#define SHIBOKENGENERATOR_H
-extern const char *CPP_ARG;
-extern const char *CPP_ARG_REMOVED;
-extern const char *CPP_RETURN_VAR;
-extern const char *CPP_SELF_VAR;
-extern const char *NULL_PTR;
-extern const char *PYTHON_ARG;
-extern const char *PYTHON_ARGS;
-extern const char *PYTHON_OVERRIDE_VAR;
-extern const char *PYTHON_RETURN_VAR;
-extern const char *PYTHON_TO_CPP_VAR;
-extern const char *SMART_POINTER_GETTER;
-
-extern const char *CONV_RULE_OUT_VAR_SUFFIX;
-extern const char *BEGIN_ALLOW_THREADS;
-extern const char *END_ALLOW_THREADS;
-
#include <generator.h>
-#include "typesystem.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;
class DocParser;
class CodeSnip;
class QPropertySpec;
class OverloadData;
-class TextStream;
+class TargetToNativeConversion;
struct GeneratorClassInfoCacheEntry;
+struct IncludeGroup;
+struct ShibokenGeneratorOptions;
+
+class TextStream;
+
+// Function to be used for implementing nb_bool
+struct BoolCastFunction
+{
+ AbstractMetaFunctionCPtr function;
+ bool invert = false; // Function is "isNull()", (invert result).
+};
-QT_FORWARD_DECLARE_CLASS(TextStream)
+using BoolCastFunctionOptional = std::optional<BoolCastFunction>;
/**
* Abstract generator that contains common methods used in CppGenerator and HeaderGenerator.
@@ -68,6 +44,29 @@ 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).
+ enum class FunctionGenerationFlag
+ {
+ None = 0x0,
+ /// Virtual method overridable in Python
+ VirtualMethod = 0x1,
+ /// Special QObject virtuals
+ QMetaObjectMethod = 0x2,
+ /// Needs a protected wrapper for avoidProtectedHack()
+ /// public "foo_protected()" calling "foo()"
+ ProtectedWrapper = 0x4, //
+ /// Pass through constructor
+ WrapperConstructor = 0x8,
+ /// Generate a special copy constructor
+ /// "FooBar_Wrapper(const Foo&)" for constructing a wrapper from a value
+ WrapperSpecialCopyConstructor = 0x10
+ };
+ Q_DECLARE_FLAGS(FunctionGeneration, FunctionGenerationFlag);
+
enum class AttroCheckFlag
{
None = 0x0,
@@ -90,15 +89,18 @@ 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,
- const TypeEntry *type);
+ const TypeEntryCPtr &type);
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.
@@ -106,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.
@@ -119,17 +126,17 @@ protected:
/// Write user's custom code snippets at class or module level.
void writeClassCodeSnips(TextStream &s,
- const CodeSnipList &codeSnips,
+ const QList<CodeSnip> &codeSnips,
TypeSystem::CodeSnipPosition position,
TypeSystem::Language language,
const GeneratorContext &context) const;
void writeCodeSnips(TextStream &s,
- const CodeSnipList &codeSnips,
+ const QList<CodeSnip> &codeSnips,
TypeSystem::CodeSnipPosition position,
TypeSystem::Language language) const;
/// Write user's custom code snippets at function level.
void writeCodeSnips(TextStream &s,
- const CodeSnipList &codeSnips,
+ const QList<CodeSnip> &codeSnips,
TypeSystem::CodeSnipPosition position,
TypeSystem::Language language,
const AbstractMetaFunctionCPtr &func,
@@ -138,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;
/**
@@ -163,156 +171,166 @@ 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);
- /// Condition to call WriteVirtualMethodNative. Was extracted because also used to count these calls.
- bool shouldWriteVirtualMethodNative(const AbstractMetaFunctionCPtr &func) const;
+ static bool shouldGenerateMetaObjectFunctions(const AbstractMetaClassCPtr &metaClass);
+
+ /// Returns which functions need to be generated into the wrapper class
+ static FunctionGeneration functionGeneration(const AbstractMetaFunctionCPtr &func);
// Return a list of implicit conversions if generation is enabled.
- AbstractMetaFunctionCList implicitConversions(const TypeEntry *t) const;
+ AbstractMetaFunctionCList implicitConversions(const TypeEntryCPtr &t) const;
+
+ static QString wrapperName(const AbstractMetaClassCPtr &metaClass);
+
+ static QString fullPythonClassName(const AbstractMetaClassCPtr &metaClass);
- QString wrapperName(const AbstractMetaClass *metaClass) const;
+ 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 QString &cppOpFuncName);
static QString pythonOperatorFunctionName(const AbstractMetaFunctionCPtr &func);
- static QString pythonRichCompareOperatorId(const QString &cppOpFuncName);
- static QString pythonRichCompareOperatorId(const AbstractMetaFunctionCPtr &func);
+ static QList<AbstractMetaFunctionCList>
+ filterGroupedOperatorFunctions(const AbstractMetaClassCPtr &metaClass,
+ OperatorQueryOptions query);
- static QString fixedCppTypeName(const CustomConversion::TargetToNativeConversion *toNative);
+ static QString fixedCppTypeName(const TargetToNativeConversion &toNative);
static QString fixedCppTypeName(const AbstractMetaType &type);
- static QString fixedCppTypeName(const TypeEntry *type, QString typeName = QString());
+ static QString fixedCppTypeName(const TypeEntryCPtr &type, QString typeName = {});
static bool isNumber(const QString &cpythonApiName);
- static bool isNumber(const TypeEntry *type);
+ static bool isNumber(const TypeEntryCPtr &type);
static bool isNumber(const AbstractMetaType &type);
- static bool isPyInt(const TypeEntry *type);
+ static bool isPyInt(const TypeEntryCPtr &type);
static bool isPyInt(const AbstractMetaType &type);
static bool isNullPtr(const QString &value);
static QString converterObject(const AbstractMetaType &type) ;
- static QString converterObject(const TypeEntry *type);
+ static QString converterObject(const TypeEntryCPtr &type);
- static QString cpythonBaseName(const AbstractMetaClass *metaClass);
- static QString cpythonBaseName(const TypeEntry *type);
+ 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 TypeEntry *type);
- static QString cpythonTypeNameExt(const TypeEntry *type);
- static QString cpythonTypeNameExt(const AbstractMetaType &type) ;
- QString cpythonCheckFunction(const TypeEntry *type) const;
- QString cpythonCheckFunction(AbstractMetaType metaType) const;
- static QString cpythonIsConvertibleFunction(const TypeEntry *type);
- static QString cpythonIsConvertibleFunction(AbstractMetaType metaType);
+ 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 cpythonCheckFunction(TypeEntryCPtr type);
+ static QString cpythonCheckFunction(AbstractMetaType metaType);
+ static QString cpythonIsConvertibleFunction(const TypeEntryCPtr &type);
+ 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 cpythonToPythonConversionFunction(const TypeEntry *type);
+ 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 = QLatin1String("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 TypeEntry *type, const QString &argName);
+ static QString cpythonWrapperCPtr(const TypeEntryCPtr &type, const QString &argName);
- /// Guesses the scope to where belongs an argument's default value.
- QString guessScopeForDefaultValue(const AbstractMetaFunctionCPtr &func,
- const AbstractMetaArgument &arg) const;
-
- static QString cpythonEnumName(const EnumTypeEntry *enumEntry);
+ static QString cpythonEnumName(const EnumTypeEntryCPtr &enumEntry);
static QString cpythonEnumName(const AbstractMetaEnum &metaEnum);
- static QString cpythonFlagsName(const FlagsTypeEntry *flagsEntry);
+ 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);
-
- static QString getFormatUnitString(const AbstractMetaFunctionCPtr &func, bool incRef = false);
+ /// 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());
- OptionDescriptions options() const override;
- bool handleOption(const QString &key, const QString &value) override;
+ /// Includes for header (native wrapper class) or binding source
+ 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
+ static bool leanHeaders();
/// Returns true if the generator should use operator bool to compute boolean casts.
- bool useOperatorBoolAsNbNonZero() const;
- /// Returns true if the generated code should use the "#define protected public" hack.
- bool avoidProtectedHack() 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 getTypeIndexVariableName(const TypeEntry *type);
+ 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);
@@ -320,18 +338,14 @@ protected:
const AbstractMetaFunctionCPtr &metaFunc,
Options options = NoOption);
- static void writeUnusedVariableCast(TextStream &s, const QString &variableName);
-
- AbstractMetaFunctionCList filterFunctions(const AbstractMetaClass *metaClass) const;
-
// All data about extended converters: the type entries of the target type, and a
// list of AbstractMetaClasses accepted as argument for the conversion.
- using ExtendedConverterData = QHash<const TypeEntry *, AbstractMetaClassCList>;
+ using ExtendedConverterData = QHash<TypeEntryCPtr, AbstractMetaClassCList>;
/// Returns all extended conversions for the current module.
ExtendedConverterData getExtendedConverters() const;
/// Returns a list of converters for the non wrapper types of the current module.
- static QList<const CustomConversion *> getPrimitiveCustomConversions() ;
+ static QList<CustomConversionPtr> getPrimitiveCustomConversions();
/// Returns true if the Python wrapper for the received OverloadData must accept a list of arguments.
bool pythonFunctionWrapperUsesListOfArguments(const AbstractMetaFunctionCPtr &func) const;
@@ -341,21 +355,28 @@ protected:
static QString pythonArgsAt(int i);
- static const QHash<QString, QString> &formatUnits();
+ /// Return the format character for C++->Python->C++ conversion (Py_BuildValue)
+ static const QHash<QString, QChar> &formatUnits();
+
+ static QString stdMove(const QString &c);
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;
/**
@@ -364,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);
@@ -393,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,
@@ -401,7 +422,7 @@ private:
const AbstractMetaArgument *lastArg);
/// Returns a string with the user's custom code snippets that comply with \p position and \p language.
- static QString getCodeSnippets(const CodeSnipList &codeSnips,
+ static QString getCodeSnippets(const QList<CodeSnip> &codeSnips,
TypeSystem::CodeSnipPosition position,
TypeSystem::Language language);
@@ -455,15 +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;
- bool m_useOperatorBoolAsNbNonZero = false;
- bool m_avoidProtectedHack = 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();
@@ -472,6 +485,7 @@ private:
static const TypeSystemConverterRegExps &typeSystemConvRegExps();
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(ShibokenGenerator::FunctionGeneration);
Q_DECLARE_OPERATORS_FOR_FLAGS(ShibokenGenerator::AttroCheck);
#endif // SHIBOKENGENERATOR_H
diff --git a/sources/shiboken6/generatorrunnermacros.h b/sources/shiboken6/generatorrunnermacros.h
index 1f1119dfa..1b204bf62 100644
--- a/sources/shiboken6/generatorrunnermacros.h
+++ b/sources/shiboken6/generatorrunnermacros.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef GENERATORRUNNERMACROS_H
#define GENERATORRUNNERMACROS_H
diff --git a/sources/shiboken6/generators/shiboken/shiboken.cpp b/sources/shiboken6/generators/shiboken/shiboken.cpp
deleted file mode 100644
index a047c15f1..000000000
--- a/sources/shiboken6/generators/shiboken/shiboken.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#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 5c454b578..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)
@@ -23,13 +26,25 @@ else()
set(embedding_option "")
endif()
+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}")
+ if(PYTHON_LIMITED_API)
+ set(use_pyc_in_embedding FALSE)
+ else()
+ set(use_pyc_in_embedding TRUE)
+ endif()
+endif()
+
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_bootstrap_inc.h"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/embed/signature_inc.h"
- COMMAND ${PYTHON_EXECUTABLE} -E
+ COMMAND ${host_python_path} -E
"${CMAKE_CURRENT_SOURCE_DIR}/embed/embedding_generator.py"
--cmake-dir "${CMAKE_CURRENT_BINARY_DIR}/embed"
- --limited-api ${PYTHON_LIMITED_API}
+ --use-pyc ${use_pyc_in_embedding}
${embedding_option}
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/embed/embedding_generator.py"
"${CMAKE_CURRENT_SOURCE_DIR}/embed/signature_bootstrap.py"
@@ -43,44 +58,49 @@ 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
-sbkfeature_base.cpp
-sbkmodule.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
)
-if (NOT "${NUMPY_INCLUDE_DIR}" STREQUAL "")
- message(STATUS "NUMPY_INCLUDE_DIR: " ${NUMPY_INCLUDE_DIR})
- list(APPEND libshiboken_SRC sbknumpyarrayconverter.cpp)
-else()
- message(STATUS "NUMPY not found")
-endif()
-
-set(APIEXTRACTOR_EXTRA_INCLUDES ${APIEXTRACTOR_EXTRA_INCLUDES} ${LIBXSLT_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
+# 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)
@@ -92,10 +112,16 @@ target_include_directories(libshiboken PUBLIC
)
if (NOT "${NUMPY_INCLUDE_DIR}" STREQUAL "")
+ message(STATUS "NUMPY_INCLUDE_DIR: " ${NUMPY_INCLUDE_DIR})
target_include_directories(libshiboken PRIVATE ${NUMPY_INCLUDE_DIR})
target_compile_definitions(libshiboken PRIVATE -DHAVE_NUMPY
PRIVATE -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION)
+else()
+ message(STATUS "NUMPY not found")
+endif()
+if(SHIBOKEN_IS_CROSS_BUILD)
+ target_compile_definitions(libshiboken PRIVATE -DSHIBOKEN_NO_EMBEDDING_PYC=1)
endif()
shiboken_compute_python_includes()
@@ -124,6 +150,8 @@ set_target_properties(libshiboken PROPERTIES OUTPUT_NAME "shiboken6${shiboken6_S
SOVERSION ${libshiboken_SOVERSION}
DEFINE_SYMBOL BUILD_LIBSHIBOKEN)
+qfp_strip_library("libshiboken")
+
install(FILES
autodecref.h
basewrapper.h
@@ -131,15 +159,20 @@ 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
+ sbknumpycheck.h
+ sbknumpyview.h
sbkstring.h
sbkcppstring.h
+ sbksmartpointer.h
sbkstaticstrings.h
sbktypefactory.h
shiboken.h
@@ -147,13 +180,15 @@ 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"
signature.h
- signature/signature_p.h
+ signature_p.h
DESTINATION include/shiboken6${shiboken6_SUFFIX})
install(TARGETS libshiboken EXPORT Shiboken6Targets
@@ -161,4 +196,4 @@ install(TARGETS libshiboken EXPORT Shiboken6Targets
ARCHIVE DESTINATION "${LIB_INSTALL_DIR}"
RUNTIME DESTINATION bin)
install(EXPORT Shiboken6Targets NAMESPACE Shiboken6::
- DESTINATION ${LIB_INSTALL_DIR}/cmake/Shiboken6-${shiboken6_VERSION})
+ DESTINATION ${LIB_INSTALL_DIR}/cmake/Shiboken6)
diff --git a/sources/shiboken6/libshiboken/autodecref.h b/sources/shiboken6/libshiboken/autodecref.h
index 45a42d6a5..62a8584e1 100644
--- a/sources/shiboken6/libshiboken/autodecref.h
+++ b/sources/shiboken6/libshiboken/autodecref.h
@@ -1,47 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 AUTODECREF_H
#define AUTODECREF_H
#include "sbkpython.h"
-#include "basewrapper.h"
+
+#include <utility>
struct SbkObject;
namespace Shiboken
@@ -50,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()
@@ -80,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);
}
@@ -106,11 +70,18 @@ public:
m_pyObj = other;
Py_XDECREF(_py_tmp);
}
+
+ PyObject *release()
+ {
+ PyObject *result = m_pyObj;
+ m_pyObj = nullptr;
+ return result;
+ }
+
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 cc62205b7..8443af33d 100644
--- a/sources/shiboken6/libshiboken/basewrapper.cpp
+++ b/sources/shiboken6/libshiboken/basewrapper.cpp
@@ -1,52 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 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 "basewrapper.h"
#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 "sbkstring.h"
#include "sbkstaticstrings.h"
#include "sbkstaticstrings_p.h"
+#include "sbktypefactory.h"
#include "autodecref.h"
#include "gilstate.h"
#include <string>
@@ -57,9 +23,12 @@
#include <algorithm>
#include "threadstatesaver.h"
#include "signature.h"
+#include "signature_p.h"
#include "voidptr.h"
+#include <string>
#include <iostream>
+#include <sstream>
#if defined(__APPLE__)
#include <dlfcn.h>
@@ -69,7 +38,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;
@@ -78,6 +113,8 @@ static void callDestructor(const Shiboken::DtorAccumulatorVisitor::DestructorEnt
}
}
+} // namespace Shiboken
+
extern "C"
{
@@ -89,11 +126,11 @@ 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 SbkObjectTypeDealloc(PyTypeObject *pyType);
-static PyTypeObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwds);
+static void SbkObjectType_tp_dealloc(PyTypeObject *pyType);
+static PyTypeObject *SbkObjectType_tp_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds);
static DestroyQAppHook DestroyQApplication = nullptr;
@@ -103,6 +140,25 @@ void setDestroyQApplication(DestroyQAppHook func)
DestroyQApplication = 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);
+ Py_DECREF(ret);
+ return ret;
+#else
+ auto *sbkObj = reinterpret_cast<SbkObject *>(op);
+ if (!sbkObj->ob_dict) {
+ Shiboken::GilState state;
+ sbkObj->ob_dict = PyDict_New();
+ }
+ return sbkObj->ob_dict;
+#endif
+}
+
static int
check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *name)
{
@@ -121,20 +177,18 @@ check_set_special_type_attr(PyTypeObject *type, PyObject *value, const char *nam
// PYSIDE-1177: Add a setter to allow setting type doc.
static int
-type_set_doc(PyTypeObject *type, PyObject *value, void *context)
+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.
-static PyGetSetDef SbkObjectType_Type_getsetlist[] = {
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(Sbk_TypeGet___signature__),
- nullptr, nullptr, nullptr},
+// explicitly pass __doc__.
+static PyGetSetDef SbkObjectType_tp_getset[] = {
{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__),
@@ -142,79 +196,93 @@ static PyGetSetDef SbkObjectType_Type_getsetlist[] = {
{nullptr, nullptr, nullptr, nullptr, nullptr} // Sentinel
};
-static PyType_Slot SbkObjectType_Type_slots[] = {
- {Py_tp_dealloc, reinterpret_cast<void *>(SbkObjectTypeDealloc)},
- {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 *>(SbkObjectTypeTpNew)},
- {Py_tp_free, reinterpret_cast<void *>(PyObject_GC_Del)},
- {Py_tp_getset, reinterpret_cast<void *>(SbkObjectType_Type_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 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;
}
static PyObject *SbkObjectGetDict(PyObject *pObj, void *)
{
- auto *obj = reinterpret_cast<SbkObject *>(pObj);
- if (!obj->ob_dict)
- obj->ob_dict = PyDict_New();
- if (!obj->ob_dict)
- return nullptr;
- Py_INCREF(obj->ob_dict);
- return obj->ob_dict;
+ auto *ret = SbkObject_GetDict_NoRef(pObj);
+ Py_XINCREF(ret);
+ return ret;
}
-static PyGetSetDef SbkObjectGetSetList[] = {
+static PyGetSetDef SbkObject_tp_getset[] = {
{const_cast<char *>("__dict__"), SbkObjectGetDict, nullptr, nullptr, nullptr},
{nullptr, nullptr, nullptr, nullptr, nullptr} // Sentinel
};
-static int SbkObject_traverse(PyObject *self, visitproc visit, void *arg)
+static int SbkObject_tp_traverse(PyObject *self, visitproc visit, void *arg)
{
auto *sbkSelf = reinterpret_cast<SbkObject *>(self);
//Visit children
- Shiboken::ParentInfo *pInfo = sbkSelf->d->parentInfo;
- if (pInfo) {
+ if (auto *pInfo = sbkSelf->d->parentInfo) {
for (SbkObject *c : pInfo->children)
Py_VISIT(c);
}
//Visit refs
- Shiboken::RefCountMap *rInfo = sbkSelf->d->referredObjects;
- if (rInfo) {
- for (auto it = rInfo->begin(), end = rInfo->end(); it != end; ++it)
- Py_VISIT(it->second);
+ if (auto *rInfo = sbkSelf->d->referredObjects) {
+ for (const auto &p : *rInfo)
+ Py_VISIT(p.second);
}
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;
}
-static int SbkObject_clear(PyObject *self)
+static int SbkObject_tp_clear(PyObject *self)
{
auto *sbkSelf = reinterpret_cast<SbkObject *>(self);
@@ -230,41 +298,53 @@ static int SbkObject_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_traverse)},
- {Py_tp_clear, reinterpret_cast<void *>(SbkObject_clear)},
- // unsupported: {Py_tp_weaklistoffset, (void *)offsetof(SbkObject, weakreflist)},
- {Py_tp_getset, reinterpret_cast<void *>(SbkObjectGetSetList)},
- // 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_BMDWBD(&SbkObject_Type_spec,
- nullptr, // bases
- SbkObjectType_TypeF(),
- offsetof(SbkObject, ob_dict),
- offsetof(SbkObject, weakreflist),
- nullptr, // bufferprocs
- nullptr); // add to tp_dict
+ static auto *type = createObjectType(); // bufferprocs
return type;
}
+static const char *SbkObject_SignatureStrings[] = {
+ "Shiboken.Object(self)",
+ nullptr}; // Sentinel
+
static int mainThreadDeletionHandler(void *)
{
if (Py_IsInitialized())
@@ -327,9 +407,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]};
@@ -340,17 +419,18 @@ static void SbkDeallocWrapperCommon(PyObject *pyObj, bool canDelete)
}
}
- PyObject *error_type, *error_value, *error_traceback;
+ PyObject *error_type{};
+ PyObject *error_value{};
+ PyObject *error_traceback{};
/* Save the current exception, if any. */
PyErr_Fetch(&error_type, &error_value, &error_traceback);
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);
@@ -376,6 +456,17 @@ static void SbkDeallocWrapperCommon(PyObject *pyObj, bool canDelete)
}
}
+static inline PyObject *_Sbk_NewVarObject(PyTypeObject *type)
+{
+ // PYSIDE-1970: Support __slots__, implemented by PyVarObject
+ auto const baseSize = sizeof(SbkObject);
+ auto varCount = Py_SIZE(type);
+ auto *self = PyObject_GC_NewVar(PyObject, type, varCount);
+ if (varCount)
+ std::memset(reinterpret_cast<char *>(self) + baseSize, 0, varCount * sizeof(void *));
+ return self;
+}
+
void SbkDeallocWrapper(PyObject *pyObj)
{
SbkDeallocWrapperCommon(pyObj, true);
@@ -393,14 +484,18 @@ void SbkDeallocWrapperWithPrivateDtor(PyObject *self)
SbkDeallocWrapperCommon(self, false);
}
-void SbkObjectTypeDealloc(PyTypeObject *sbkType)
+void SbkObjectType_tp_dealloc(PyTypeObject *sbkType)
{
SbkObjectTypePrivate *sotp = PepType_SOTP(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
Py_TRASHCAN_SAFE_BEGIN(pyObj);
+# endif
#endif
if (sotp) {
if (sotp->user_data && sotp->d_func) {
@@ -413,8 +508,12 @@ void SbkObjectTypeDealloc(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
Py_TRASHCAN_SAFE_END(pyObj);
+# endif
#endif
if (PepRuntime_38_flag) {
// PYSIDE-939: Handling references correctly.
@@ -437,7 +536,7 @@ PyObject *MakeQAppWrapper(PyTypeObject *type)
static PyObject *qApp_last = nullptr;
// protecting from multiple application instances
- if (!(type == nullptr || qApp_last == Py_None)) {
+ if (type != nullptr && qApp_last != Py_None) {
const char *res_name = qApp_last != nullptr
? PepType_GetNameStr(Py_TYPE(qApp_last)) : "<Unknown>";
const char *type_name = PepType_GetNameStr(type);
@@ -447,7 +546,7 @@ PyObject *MakeQAppWrapper(PyTypeObject *type)
}
// monitoring the last application state
- PyObject *qApp_curr = type != nullptr ? PyObject_GC_New(PyObject, type) : Py_None;
+ PyObject *qApp_curr = type != nullptr ? _Sbk_NewVarObject(type) : Py_None;
static PyObject *builtins = PyEval_GetBuiltins();
if (PyDict_SetItem(builtins, Shiboken::PyName::qApp(), qApp_curr) < 0)
return nullptr;
@@ -457,15 +556,14 @@ PyObject *MakeQAppWrapper(PyTypeObject *type)
// exactly the needed reference that keeps qApp alive from alone!
Py_INCREF(qApp_curr);
// PYSIDE-1470: As a side effect, the interactive "_" variable tends to
- // create reference cycles. It was found when using gc.collect(). But using
- // PyGC_collect() inside the C code had no effect in the interactive shell.
- // The cycle exists only in the eval loop of the interpreter!
- if (PyDict_GetItem(builtins, Shiboken::PyName::underscore()))
- PyDict_SetItem(builtins, Shiboken::PyName::underscore(), Py_None);
+ // create reference cycles. This is disturbing when trying
+ // to remove qApp with del.
+ // PYSIDE-1758: Since we moved to an explicit qApp.shutdown() call, we
+ // no longer initialize "_" with Py_None.
return qApp_curr;
}
-static PyTypeObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
+static PyTypeObject *SbkObjectType_tp_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
{
// Check if all bases are new style before calling type.tp_new
// Was causing gc assert errors in test_bug704.py when
@@ -476,12 +574,12 @@ static PyTypeObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args,
// Before we changed to heap types, it was sufficient to remove the
// Py_TPFLAGS_BASETYPE flag. That does not work, because PySide does
// not respect this flag itself!
- PyObject *name;
- PyObject *pyBases;
- PyObject *dict;
+ PyObject *name{};
+ PyObject *pyBases{};
+ 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))
@@ -489,22 +587,26 @@ static PyTypeObject *SbkObjectTypeTpNew(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;
@@ -553,11 +655,11 @@ static PyTypeObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args,
return newType;
}
-static PyObject *_setupNew(SbkObject *self, PyTypeObject *subtype)
+static PyObject *_setupNew(PyObject *obSelf, PyTypeObject *subtype)
{
auto *obSubtype = reinterpret_cast<PyObject *>(subtype);
auto *sbkSubtype = subtype;
- auto *obSelf = reinterpret_cast<PyObject *>(self);
+ auto *self = reinterpret_cast<SbkObject *>(obSelf);
Py_INCREF(obSubtype);
auto d = new SbkObjectPrivate;
@@ -573,36 +675,37 @@ static PyObject *_setupNew(SbkObject *self, PyTypeObject *subtype)
d->parentInfo = nullptr;
d->referredObjects = nullptr;
d->cppObjectCreated = 0;
+ d->isQAppSingleton = 0;
self->ob_dict = nullptr;
self->weakreflist = nullptr;
self->d = d;
PyObject_GC_Track(obSelf);
- return reinterpret_cast<PyObject *>(self);
+ return obSelf;
}
-PyObject *SbkObjectTpNew(PyTypeObject *subtype, PyObject *, PyObject *)
+PyObject *SbkObject_tp_new(PyTypeObject *subtype, PyObject * /* args */, PyObject * /* kwds */)
{
- SbkObject *self = PyObject_GC_New(SbkObject, subtype);
+ PyObject *self = _Sbk_NewVarObject(subtype);
return _setupNew(self, subtype);
}
-PyObject *SbkQAppTpNew(PyTypeObject *subtype, PyObject *, PyObject *)
+PyObject *SbkQApp_tp_new(PyTypeObject *subtype, PyObject *, PyObject *)
{
- auto self = reinterpret_cast<SbkObject *>(MakeQAppWrapper(subtype));
+ auto *obSelf = MakeQAppWrapper(subtype);
+ auto *self = reinterpret_cast<SbkObject *>(obSelf);
if (self == nullptr)
return nullptr;
- auto ret = _setupNew(self, subtype);
- auto priv = self->d;
- priv->isQAppSingleton = 1;
+ auto *ret = _setupNew(obSelf, subtype);
+ self->d->isQAppSingleton = 1;
return ret;
}
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;
}
@@ -611,7 +714,7 @@ PyObject *FallbackRichCompare(PyObject *self, PyObject *other, int op)
{
// This is a very simple implementation that supplies a simple identity.
static const char * const opstrings[] = {"<", "<=", "==", "!=", ">", ">="};
- PyObject *res;
+ PyObject *res{};
switch (op) {
@@ -633,6 +736,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"
@@ -657,54 +766,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()
@@ -720,14 +799,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();
@@ -735,14 +813,20 @@ void init()
}
// PYSIDE-1415: Publish Shiboken objects.
-void initSignature(PyObject *module)
+// PYSIDE-1735: Initialize the whole Shiboken startup.
+void initShibokenSupport(PyObject *module)
{
- auto *type = SbkObject_TypeF();
- if (InitSignatureStrings(type, SbkObject_SignatureStrings) < 0)
- return;
-
Py_INCREF(SbkObject_TypeF());
PyModule_AddObject(module, "Object", reinterpret_cast<PyObject *>(SbkObject_TypeF()));
+
+ // PYSIDE-1735: When the initialization was moved into Shiboken import, this
+ // Py_INCREF became necessary. No idea why.
+ Py_INCREF(module);
+ init_shibokensupport_module();
+
+ auto *type = SbkObject_TypeF();
+ if (InitSignatureStrings(type, SbkObject_SignatureStrings) < 0)
+ Py_FatalError("Error in initShibokenSupport");
}
// setErrorAboutWrongArguments now gets overload info from the signature module.
@@ -752,19 +836,48 @@ void setErrorAboutWrongArguments(PyObject *args, const char *funcName, PyObject
SetError_Argument(args, funcName, info);
}
-class FindBaseTypeVisitor : public HierarchyVisitor
+PyObject *returnWrongArguments(PyObject *args, const char *funcName, PyObject *info)
{
-public:
- explicit FindBaseTypeVisitor(PyTypeObject *typeToFind) : m_typeToFind(typeToFind) {}
+ setErrorAboutWrongArguments(args, funcName, info);
+ return {};
+}
- bool visit(PyTypeObject *node) override
- {
- return node == m_typeToFind;
- }
+int returnWrongArguments_Zero(PyObject *args, const char *funcName, PyObject *info)
+{
+ setErrorAboutWrongArguments(args, funcName, info);
+ return 0;
+}
-private:
- PyTypeObject *m_typeToFind;
-};
+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;
+ // for seterror_argument(), signature/errorhandler.py
+ if (numArgs > maxArgs) {
+ static PyObject *const tooMany = Shiboken::String::createStaticString(">");
+ result = tooMany;
+ Py_INCREF(result);
+ } else if (numArgs < minArgs) {
+ static PyObject *const tooFew = Shiboken::String::createStaticString("<");
+ static PyObject *const noArgs = Shiboken::String::createStaticString("0");
+ result = numArgs > 0 ? tooFew : noArgs;
+ Py_INCREF(result);
+ }
+ return result;
+}
std::vector<SbkObject *> splitPyObject(PyObject *pyObj)
{
@@ -806,8 +919,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;
}
@@ -879,31 +992,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);
+ 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);
@@ -918,16 +1034,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;
@@ -950,6 +1069,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
@@ -1029,7 +1168,7 @@ bool wasCreatedByPython(SbkObject *pyObj)
void callCppDestructors(SbkObject *pyObj)
{
- auto priv = pyObj->d;
+ auto *priv = pyObj->d;
if (priv->isQAppSingleton && DestroyQApplication) {
// PYSIDE-1470: Allow to destroy the application from Shiboken.
DestroyQApplication();
@@ -1038,9 +1177,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();
@@ -1165,10 +1302,9 @@ static void recursive_invalidate(SbkObject *self, std::set<SbkObject *> &seen)
}
// If has ref to other objects invalidate all
- if (self->d->referredObjects) {
- RefCountMap &refCountMap = *(self->d->referredObjects);
- for (auto it = refCountMap.begin(), end = refCountMap.end(); it != end; ++it)
- recursive_invalidate(it->second, seen);
+ if (auto *rInfo = self->d->referredObjects) {
+ for (const auto &p : *rInfo)
+ recursive_invalidate(p.second, seen);
}
}
@@ -1189,11 +1325,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));
}
}
}
@@ -1229,7 +1364,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;
@@ -1240,6 +1376,7 @@ bool setCppPointer(SbkObject *sbkObj, PyTypeObject *desiredType, void *cptr)
bool isValid(PyObject *pyObj)
{
if (!pyObj || pyObj == Py_None
+ || PyType_Check(pyObj) != 0
|| Py_TYPE(Py_TYPE(pyObj)) != SbkObjectType_TypeF()) {
return true;
}
@@ -1320,20 +1457,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;
@@ -1363,7 +1547,7 @@ PyObject *newObject(PyTypeObject *instanceType,
}
if (shouldCreate) {
- self = reinterpret_cast<SbkObject *>(SbkObjectTpNew(instanceType, nullptr, nullptr));
+ self = reinterpret_cast<SbkObject *>(SbkObject_tp_new(instanceType, nullptr, nullptr));
self->d->cptr[0] = cptr;
self->d->hasOwnership = hasOwnership;
self->d->validCppObject = 1;
@@ -1542,7 +1726,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)
@@ -1625,16 +1809,62 @@ void clearReferences(SbkObject *self)
self->d->referredObjects->clear();
}
+// Helpers for debug / info formatting
+
+static std::vector<PyTypeObject *> getBases(SbkObject *self)
+{
+ return ObjectType::isUserType(Py_TYPE(self))
+ ? getCppBaseClasses(Py_TYPE(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);
+ auto *d = self->d;
+ if (!d) {
+ s << "[Invalid]";
+ return;
+ }
+ if (d->cptr) {
+ const std::vector<PyTypeObject *> bases = getBases(self);
+ for (size_t i = 0, size = bases.size(); i < size; ++i)
+ s << ", C++: " << bases[i]->tp_name << '/' << self->d->cptr[i];
+ } else {
+ s << " [Deleted]";
+ }
+ if (d->hasOwnership)
+ s << " [hasOwnership]";
+ if (d->containsCppWrapper)
+ s << " [containsCppWrapper]";
+ if (d->validCppObject)
+ 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
+ << '/' << parent;
+ if (!d->parentInfo->children.empty())
+ s << ", " << d->parentInfo->children.size() << " child(ren)";
+ }
+ if (d->referredObjects && !d->referredObjects->empty())
+ s << ", " << d->referredObjects->size() << " referred object(s)";
+}
+
std::string info(SbkObject *self)
{
std::ostringstream s;
if (self->d && self->d->cptr) {
- std::vector<PyTypeObject *> bases;
- if (ObjectType::isUserType(Py_TYPE(self)))
- bases = getCppBaseClasses(Py_TYPE(self));
- else
- bases.push_back(Py_TYPE(self));
+ const std::vector<PyTypeObject *> bases = getBases(self);
s << "C++ address....... ";
for (size_t i = 0, size = bases.size(); i < size; ++i)
@@ -1648,8 +1878,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............ ";
@@ -1667,17 +1898,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 2c8da098f..5e77d0c4f 100644
--- a/sources/shiboken6/libshiboken/basewrapper.h
+++ b/sources/shiboken6/libshiboken/basewrapper.h
@@ -1,48 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 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 BASEWRAPPER_H
#define BASEWRAPPER_H
#include "sbkpython.h"
#include "shibokenmacros.h"
-#include "sbktypefactory.h"
#include <vector>
#include <string>
@@ -74,32 +37,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 PyObject *(*SelectableFeatureHook)(PyTypeObject *);
+using SelectableFeatureHook = void (*)(PyTypeObject *);
+using SelectableFeatureCallback = void (*)(bool);
LIBSHIBOKEN_API SelectableFeatureHook initSelectableFeature(SelectableFeatureHook func);
-
-/// PYSIDE-1019: Get access to PySide reserved bits.
-LIBSHIBOKEN_API int SbkObjectType_GetReserved(PyTypeObject *type);
-LIBSHIBOKEN_API void SbkObjectType_SetReserved(PyTypeObject *type, int value);
+LIBSHIBOKEN_API void setSelectableFeatureCallback(SelectableFeatureCallback func);
/// PYSIDE-1626: Enforcing a context switch without further action.
LIBSHIBOKEN_API void SbkObjectType_UpdateFeature(PyTypeObject *type);
@@ -108,10 +69,16 @@ LIBSHIBOKEN_API void SbkObjectType_UpdateFeature(PyTypeObject *type);
LIBSHIBOKEN_API const char **SbkObjectType_GetPropertyStrings(PyTypeObject *type);
LIBSHIBOKEN_API void SbkObjectType_SetPropertyStrings(PyTypeObject *type, const char **strings);
+/// PYSIDE-1735: Store the enumFlagInfo.
+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)
+LIBSHIBOKEN_API PyObject *SbkObject_GetDict_NoRef(PyObject *op);
+
extern LIBSHIBOKEN_API PyTypeObject *SbkObjectType_TypeF(void);
extern LIBSHIBOKEN_API PyTypeObject *SbkObject_TypeF(void);
@@ -119,10 +86,10 @@ extern LIBSHIBOKEN_API PyTypeObject *SbkObject_TypeF(void);
struct SbkObjectTypePrivate;
/// PyTypeObject extended with C++ multiple inheritance information.
-LIBSHIBOKEN_API PyObject *SbkObjectTpNew(PyTypeObject *subtype, PyObject *, PyObject *);
+LIBSHIBOKEN_API PyObject *SbkObject_tp_new(PyTypeObject *subtype, PyObject *, PyObject *);
/// The special case of a switchable singleton Q*Application.
-LIBSHIBOKEN_API PyObject *SbkQAppTpNew(PyTypeObject *subtype, PyObject *, PyObject *);
+LIBSHIBOKEN_API PyObject *SbkQApp_tp_new(PyTypeObject *subtype, PyObject *, PyObject *);
/// Create a new Q*Application wrapper and monitor it.
LIBSHIBOKEN_API PyObject *MakeQAppWrapper(PyTypeObject *type);
@@ -141,6 +108,12 @@ LIBSHIBOKEN_API PyObject *SbkDummyNew(PyTypeObject *type, PyObject *, PyObject *
/// PYSIDE-74: Fallback used in all types now.
LIBSHIBOKEN_API PyObject *FallbackRichCompare(PyObject *self, PyObject *other, int op);
+/// 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
@@ -152,7 +125,7 @@ namespace Shiboken
LIBSHIBOKEN_API void init();
/// PYSIDE-1415: Publish Shiboken objects.
-LIBSHIBOKEN_API void initSignature(PyObject *module);
+LIBSHIBOKEN_API void initShibokenSupport(PyObject *module);
/// Delete the class T allocated on \p cptr.
template<typename T>
@@ -161,11 +134,30 @@ 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,
+ Py_ssize_t maxArgs);
+
namespace ObjectType {
/**
@@ -207,14 +199,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
};
/**
@@ -235,13 +228,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.
@@ -272,6 +264,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 {
@@ -304,7 +304,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++
@@ -318,6 +319,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 f7355dd1c..fb9140793 100644
--- a/sources/shiboken6/libshiboken/basewrapper_p.h
+++ b/sources/shiboken6/libshiboken/basewrapper_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 BASEWRAPPER_P_H
#define BASEWRAPPER_P_H
@@ -47,6 +11,7 @@
#include <set>
#include <string>
#include <vector>
+#include <iosfwd>
struct SbkObject;
struct SbkConverter;
@@ -65,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
@@ -86,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.
@@ -132,15 +101,6 @@ struct SbkObjectTypePrivate
TypeDiscoveryFuncV2 type_discovery;
/// Pointer to a function responsible for deletion of the C++ instance calling the proper destructor.
ObjectDestructor cpp_dtor;
- /// PYSIDE-1019: Caching the current select Id
- unsigned int pyside_reserved_bits : 8; // MSVC has bug with the sign bit!
- /// 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.
- 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;
- unsigned int delete_in_main_thread : 1;
/// C++ name
char *original_name;
/// Type user data
@@ -148,6 +108,18 @@ struct SbkObjectTypePrivate
DeleteUserDataFunc d_func;
void (*subtype_init)(PyTypeObject *, PyObject *, PyObject *);
const char **propertyStrings;
+ const char **enumFlagInfo;
+ PyObject *enumFlagsDict;
+ PyObject *enumTypeDict;
+
+ /// 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 (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;
+ unsigned int delete_in_main_thread : 1;
};
@@ -171,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
{
@@ -286,6 +158,8 @@ void clearReferences(SbkObject *self);
**/
void deallocData(SbkObject *self, bool doCleanup);
+
+void _debugFormat(std::ostream &str, SbkObject *self);
} // namespace Object
} // namespace Shiboken
diff --git a/sources/shiboken6/libshiboken/bindingmanager.cpp b/sources/shiboken6/libshiboken/bindingmanager.cpp
index 20b331bde..df1079af8 100644
--- a/sources/shiboken6/libshiboken/bindingmanager.cpp
+++ b/sources/shiboken6/libshiboken/bindingmanager.cpp
@@ -1,157 +1,188 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 "autodecref.h"
#include "basewrapper.h"
#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>;
WrapperMap wrapperMapper;
+ // Guard wrapperMapper mainly for QML which calls into the generated
+ // QObject::metaObject() and elsewhere from threads without GIL, causing
+ // crashes for example in retrieveWrapper(). std::shared_mutex was rejected due to:
+ // https://stackoverflow.com/questions/50972345/when-is-stdshared-timed-mutex-slower-than-stdmutex-and-when-not-to-use-it
+ 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.
@@ -164,18 +195,44 @@ 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));
}
-BindingManager::BindingManager()
+void BindingManager::BindingManagerPrivate::assignWrapper(SbkObject *wrapper, const void *cptr,
+ const int *bases)
{
- m_d = new BindingManager::BindingManagerPrivate;
+ 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)
+{
#ifdef SHIBOKEN_INSTALL_FREE_DEBUG_HOOK
debugInstallFreeHook();
#endif
@@ -187,12 +244,14 @@ 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
* shutting down. */
if (Py_IsInitialized()) { // ensure the interpreter is still valid
+ std::lock_guard<std::recursive_mutex> guard(m_d->wrapperMapLock);
while (!m_d->wrapperMapper.empty()) {
Object::destroy(m_d->wrapperMapper.begin()->second, const_cast<void *>(m_d->wrapperMapper.begin()->first));
}
@@ -208,6 +267,7 @@ BindingManager &BindingManager::instance() {
bool BindingManager::hasWrapper(const void *cptr)
{
+ std::lock_guard<std::recursive_mutex> guard(m_d->wrapperMapLock);
return m_d->wrapperMapper.find(cptr) != m_d->wrapperMapper.end();
}
@@ -221,15 +281,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)
@@ -239,17 +291,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;
}
@@ -268,6 +313,7 @@ void BindingManager::addToDeletionInMainThread(const DestructorEntry &e)
SbkObject *BindingManager::retrieveWrapper(const void *cptr)
{
+ std::lock_guard<std::recursive_mutex> guard(m_d->wrapperMapLock);
auto iter = m_d->wrapperMapper.find(cptr);
if (iter == m_d->wrapperMapper.end())
return nullptr;
@@ -281,7 +327,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.
@@ -289,11 +335,6 @@ PyObject *BindingManager::getOverride(const void *cptr,
int flag = currentSelectId(Py_TYPE(wrapper));
int propFlag = isdigit(methodName[0]) ? methodName[0] - '0' : 0;
- if ((flag & 0x02) != 0 && (propFlag & 3) != 0) {
- // PYSIDE-1019: Handle overriding with properties.
- // They cannot be overridden (make that sure by the metaclass).
- return nullptr;
- }
bool is_snake = flag & 0x01;
PyObject *pyMethodName = nameCache[is_snake]; // borrowed
if (pyMethodName == nullptr) {
@@ -303,12 +344,13 @@ PyObject *BindingManager::getOverride(const void *cptr,
nameCache[is_snake] = pyMethodName;
}
- if (wrapper->ob_dict) {
- PyObject *method = PyDict_GetItem(wrapper->ob_dict, pyMethodName);
- if (method) {
- Py_INCREF(method);
- return method;
- }
+ 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;
}
PyObject *method = PyObject_GetAttr(reinterpret_cast<PyObject *>(wrapper), pyMethodName);
@@ -318,6 +360,7 @@ PyObject *BindingManager::getOverride(const void *cptr,
// PYSIDE-1523: PyMethod_Check is not accepting compiled methods, we do this rather
// crude check for them.
if (method) {
+ // PYSIDE-535: This macro is redefined in a compatible way in pep384
if (PyMethod_Check(method)) {
if (PyMethod_GET_SELF(method) == reinterpret_cast<PyObject *>(wrapper)) {
function = PyMethod_GET_FUNCTION(method);
@@ -326,7 +369,8 @@ PyObject *BindingManager::getOverride(const void *cptr,
method = nullptr;
}
} else if (PyObject_HasAttr(method, PyName::im_self())
- && PyObject_HasAttr(method, PyName::im_func())) {
+ && PyObject_HasAttr(method, PyName::im_func())
+ && PyObject_HasAttr(method, Shiboken::PyMagicName::code())) {
PyObject *im_self = PyObject_GetAttr(method, PyName::im_self());
// Not retaining a reference inline with what PyMethod_GET_SELF does.
Py_DECREF(im_self);
@@ -346,41 +390,59 @@ 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()
{
std::set<PyObject *> pyObjects;
+ std::lock_guard<std::recursive_mutex> guard(m_d->wrapperMapLock);
const WrapperMap &wrappersMap = m_d->wrapperMapper;
auto it = wrappersMap.begin();
for (; it != wrappersMap.end(); ++it)
@@ -392,10 +454,95 @@ 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 = 0;
+ const Py_ssize_t 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 + 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 bd87bc636..54c4e486a 100644
--- a/sources/shiboken6/libshiboken/bindingmanager.h
+++ b/sources/shiboken6/libshiboken/bindingmanager.h
@@ -1,57 +1,27 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 BINDINGMANAGER_H
#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
{
@@ -74,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.
@@ -82,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();
@@ -95,6 +73,9 @@ public:
*/
void visitAllPyObjects(ObjectVisitor visitor, void *data);
+ bool dumpTypeGraph(const char *fileName) const;
+ void dumpWrapperMap();
+
private:
~BindingManager();
BindingManager();
@@ -103,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.cpp b/sources/shiboken6/libshiboken/bufferprocs_py37.cpp
index da6bb00a3..4ccf970e5 100644
--- a/sources/shiboken6/libshiboken/bufferprocs_py37.cpp
+++ b/sources/shiboken6/libshiboken/bufferprocs_py37.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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
/*****************************************************************************
*
diff --git a/sources/shiboken6/libshiboken/bufferprocs_py37.h b/sources/shiboken6/libshiboken/bufferprocs_py37.h
index 6fc7a3ece..e16194e50 100644
--- a/sources/shiboken6/libshiboken/bufferprocs_py37.h
+++ b/sources/shiboken6/libshiboken/bufferprocs_py37.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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
/*
PSF LICENSE AGREEMENT FOR PYTHON 3.7.0
@@ -103,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 3d52d88dc..13df6bd6c 100644
--- a/sources/shiboken6/libshiboken/debugfreehook.cpp
+++ b/sources/shiboken6/libshiboken/debugfreehook.cpp
@@ -1,49 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 "debugfreehook.h"
#include "bindingmanager.h"
#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/debugfreehook.h b/sources/shiboken6/libshiboken/debugfreehook.h
index fdf98d5d3..c19e36ab2 100644
--- a/sources/shiboken6/libshiboken/debugfreehook.h
+++ b/sources/shiboken6/libshiboken/debugfreehook.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 DEBUGFREEHOOK_H
#define DEBUGFREEHOOK_H
diff --git a/sources/shiboken6/libshiboken/embed/embedding_generator.py b/sources/shiboken6/libshiboken/embed/embedding_generator.py
index 1477ff541..a058fd372 100644
--- a/sources/shiboken6/libshiboken/embed/embedding_generator.py
+++ b/sources/shiboken6/libshiboken/embed/embedding_generator.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of PySide6.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
"""
embedding_generator.py
@@ -81,7 +45,7 @@ def runpy(cmd, **kw):
subprocess.call([sys.executable, '-E'] + cmd.split(), **kw)
-def create_zipfile(limited_api, quiet):
+def create_zipfile(use_pyc, quiet):
"""
Collect all Python files, compile them, create a zip file
and make a chunked base64 encoded file from it.
@@ -110,7 +74,7 @@ def create_zipfile(limited_api, quiet):
if embed_dir != work_dir:
utils.copyfile(embed_dir / "signature_bootstrap.py", work_dir)
- if limited_api:
+ if not use_pyc:
pass # We cannot compile, unless we have folders per Python version
else:
files = ' '.join(fn for fn in os.listdir('.'))
@@ -126,9 +90,9 @@ def create_zipfile(limited_api, quiet):
tmp.close()
# also generate a simple embeddable .pyc file for signature_bootstrap.pyc
- boot_name = "signature_bootstrap.py" if limited_api else "signature_bootstrap.pyc"
+ boot_name = "signature_bootstrap.py" if not use_pyc else "signature_bootstrap.pyc"
with open(boot_name, "rb") as ldr, open("signature_bootstrap_inc.h", "w") as inc:
- _embed_bytefile(ldr, inc, limited_api)
+ _embed_bytefile(ldr, inc, not use_pyc)
os.chdir(cur_dir)
if quiet:
return
@@ -158,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):
@@ -247,9 +212,9 @@ def str2bool(v):
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--cmake-dir', nargs="?")
- parser.add_argument('--limited-api', type=str2bool)
+ parser.add_argument('--use-pyc', type=str2bool)
parser.add_argument('--quiet', action='store_true')
args = parser.parse_args()
if args.cmake_dir:
work_dir = Path(args.cmake_dir).resolve()
- create_zipfile(args.limited_api, args.quiet)
+ create_zipfile(args.use_pyc, args.quiet)
diff --git a/sources/shiboken6/libshiboken/embed/module_collector.py b/sources/shiboken6/libshiboken/embed/module_collector.py
index 42ce2667c..a58ce6e4f 100644
--- a/sources/shiboken6/libshiboken/embed/module_collector.py
+++ b/sources/shiboken6/libshiboken/embed/module_collector.py
@@ -1,44 +1,5 @@
-# This Python file uses the following encoding: utf-8
-# It has been edited by fix-complaints.py .
-
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
"""
module_collector.py
diff --git a/sources/shiboken6/libshiboken/embed/qt_python_license.txt b/sources/shiboken6/libshiboken/embed/qt_python_license.txt
index b5f8c581a..e5fdfdf4d 100644
--- a/sources/shiboken6/libshiboken/embed/qt_python_license.txt
+++ b/sources/shiboken6/libshiboken/embed/qt_python_license.txt
@@ -1,44 +1,5 @@
-# This Python file uses the following encoding: utf-8
-# It has been edited by fix-complaints.py .
-
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
##
## PSF LICENSE AGREEMENT FOR PYTHON 3.7.0
diff --git a/sources/shiboken6/libshiboken/embed/signature_bootstrap.py b/sources/shiboken6/libshiboken/embed/signature_bootstrap.py
index b76a83c51..37f95cd35 100644
--- a/sources/shiboken6/libshiboken/embed/signature_bootstrap.py
+++ b/sources/shiboken6/libshiboken/embed/signature_bootstrap.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of PySide6.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
"""
signature_bootstrap.py
@@ -62,6 +26,7 @@ recursion_trap = 0
import base64
import importlib
import io
+import os
import sys
import traceback
import zipfile
@@ -97,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/gilstate.cpp b/sources/shiboken6/libshiboken/gilstate.cpp
index 76a4d0e61..8daa93b8b 100644
--- a/sources/shiboken6/libshiboken/gilstate.cpp
+++ b/sources/shiboken6/libshiboken/gilstate.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 "gilstate.h"
diff --git a/sources/shiboken6/libshiboken/gilstate.h b/sources/shiboken6/libshiboken/gilstate.h
index fbf39ead0..abad9d955 100644
--- a/sources/shiboken6/libshiboken/gilstate.h
+++ b/sources/shiboken6/libshiboken/gilstate.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 GILSTATE_H
#define GILSTATE_H
diff --git a/sources/shiboken6/libshiboken/helper.cpp b/sources/shiboken6/libshiboken/helper.cpp
index f6e0840a7..46af68956 100644
--- a/sources/shiboken6/libshiboken/helper.cpp
+++ b/sources/shiboken6/libshiboken/helper.cpp
@@ -1,67 +1,64 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 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 "helper.h"
+#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 std::optional<int> getIntAttr(PyObject *obj, const char *what)
+{
+ 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 formatPyTypeObject(const PyTypeObject *obj, std::ostream &str)
+static void formatTypeTuple(PyObject *t, const char *what, std::ostream &str);
+
+static void formatPyTypeObject(const PyTypeObject *obj, std::ostream &str, bool verbose)
{
- if (obj) {
- str << '"' << obj->tp_name << "\", 0x" << std::hex
- << obj->tp_flags << std::dec;
+ 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)
@@ -84,8 +81,59 @@ static void formatPyTypeObject(const PyTypeObject *obj, std::ostream &str)
str << " [type]";
if (obj->tp_flags & Py_TPFLAGS_IS_ABSTRACT)
str << " [abstract]";
- } else {
- str << '0';
+ 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]";
+# ifndef Py_LIMITED_API
+ if (obj->tp_flags & Py_TPFLAGS_HAVE_VECTORCALL)
+ str << " [vectorcall]";
+# 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
+ 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
+ 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 << '}';
}
}
@@ -110,6 +158,37 @@ static void formatPySequence(PyObject *obj, std::ostream &str)
str << '>';
}
+static void formatPyTuple(PyObject *obj, std::ostream &str)
+{
+
+ const Py_ssize_t size = PyTuple_Size(obj);
+ str << size << " <";
+ for (Py_ssize_t i = 0; i < size; ++i) {
+ if (i)
+ str << ", ";
+ str << '(';
+ PyObject *item = PyTuple_GetItem(obj, i);
+ formatPyObject(item, str);
+ str << ')';
+ Py_XDECREF(item);
+ }
+ str << '>';
+}
+
+static void formatPyDict(PyObject *obj, std::ostream &str)
+{
+ PyObject *key;
+ PyObject *value;
+ Py_ssize_t pos = 0;
+ str << '{';
+ while (PyDict_Next(obj, &pos, &key, &value) != 0) {
+ if (pos)
+ str << ", ";
+ str << Shiboken::debugPyObject(key) << '=' << Shiboken::debugPyObject(value);
+ }
+ str << '}';
+}
+
// Helper to format a 0-terminated character sequence
template <class Char>
static void formatCharSequence(const Char *s, std::ostream &str)
@@ -133,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;
@@ -160,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);
@@ -190,24 +275,107 @@ static void formatPyUnicode(PyObject *obj, std::ostream &str)
#endif // !Py_LIMITED_API
}
-static void formatPyObject(PyObject *obj, std::ostream &str)
+static std::string getQualName(PyObject *obj)
{
- if (obj) {
- formatPyTypeObject(obj->ob_type, str);
- str << ", ";
- if (PyLong_Check(obj))
- str << PyLong_AsLong(obj);
- else if (PyFloat_Check(obj))
- str << PyFloat_AsDouble(obj);
- else if (PyUnicode_Check(obj))
- formatPyUnicode(obj, str);
- else if (PySequence_Check(obj))
- formatPySequence(obj, str);
- else
- str << "<unknown>";
- } else {
- str << '0';
+ 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 << ", ";
+ 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, true);
+ return;
+ }
+ formatPyTypeObject(obj->ob_type, str, false);
+ str << ", ";
+ 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))
+ formatPyDict(obj, str);
+ else if (PyTuple_CheckExact(obj))
+ formatPyTuple(obj, str);
+ else
+ str << "<unknown>";
+}
+
+static void formatPyObject(PyObject *obj, std::ostream &str)
+{
+ str << obj;
+ if (obj)
+ formatPyObjectHelper(obj, str);
}
namespace Shiboken
@@ -217,6 +385,10 @@ debugPyObject::debugPyObject(PyObject *o) : m_object(o)
{
}
+debugSbkObject::debugSbkObject(SbkObject *o) : m_object(o)
+{
+}
+
debugPyTypeObject::debugPyTypeObject(const PyTypeObject *o) : m_object(o)
{
}
@@ -228,7 +400,18 @@ 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;
+}
+
+std::ostream &operator<<(std::ostream &str, const debugSbkObject &o)
+{
+ str << "SbkObject(" << o.m_object;
+ if (o.m_object) {
+ Shiboken::Object::_debugFormat(str, o.m_object);
+ formatPyObjectHelper(reinterpret_cast<PyObject *>(o.m_object), str);
+ }
str << ')';
return str;
}
@@ -253,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).
@@ -396,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 8221d68b0..f226e8c24 100644
--- a/sources/shiboken6/libshiboken/helper.h
+++ b/sources/shiboken6/libshiboken/helper.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 HELPER_H
#define HELPER_H
@@ -72,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.
*/
@@ -84,8 +52,9 @@ class AutoArrayPointer
AutoArrayPointer &operator=(const AutoArrayPointer &) = delete;
AutoArrayPointer &operator=(AutoArrayPointer &&) = delete;
- explicit AutoArrayPointer(ssize_t size) { data = new T[size]; }
- T &operator[](ssize_t pos) { return data[pos]; }
+
+ explicit AutoArrayPointer(Py_ssize_t size) { data = new T[size]; }
+ T &operator[](Py_ssize_t pos) { return data[pos]; }
operator T *() const { return data; }
~AutoArrayPointer() { delete[] data; }
private:
@@ -96,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.
*/
@@ -108,6 +79,13 @@ struct LIBSHIBOKEN_API debugPyObject
PyObject *m_object;
};
+struct LIBSHIBOKEN_API debugSbkObject
+{
+ explicit debugSbkObject(SbkObject *o);
+
+ SbkObject *m_object;
+};
+
struct LIBSHIBOKEN_API debugPyTypeObject
{
explicit debugPyTypeObject(const PyTypeObject *o);
@@ -122,10 +100,20 @@ struct LIBSHIBOKEN_API debugPyBuffer
const Py_buffer &m_buffer;
};
+struct debugPyArrayObject
+{
+ explicit debugPyArrayObject(PyObject *object) : m_object(object) {}
+
+ PyObject *m_object;
+};
+
LIBSHIBOKEN_API std::ostream &operator<<(std::ostream &str, const debugPyObject &o);
+LIBSHIBOKEN_API std::ostream &operator<<(std::ostream &str, const debugSbkObject &o);
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 c20edeefa..000000000
--- a/sources/shiboken6/libshiboken/pep384_issue33738.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// 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 .
-
-// Update: I did the long-term solution for python 3.7 in issue 33738.
-
-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;
-
-int PyIndex_Check(PyObject *obj)
-{
- PyOldTypeObject *type = reinterpret_cast<PyOldTypeObject *>(Py_TYPE(obj));
- return type->tp_as_number != NULL &&
- type->tp_as_number->nb_index != NULL;
-}
-
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 fd862b7b0..f51296851 100644
--- a/sources/shiboken6/libshiboken/pep384impl.cpp
+++ b/sources/shiboken6/libshiboken/pep384impl.cpp
@@ -1,41 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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"
@@ -44,8 +10,7 @@
#include "basewrapper.h"
#include "basewrapper_p.h"
#include "sbkenum.h"
-#include "sbkenum_p.h"
-#include "sbkconverter.h"
+#include "voidptr.h"
#include <cstdlib>
#include <cstring>
@@ -54,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
@@ -72,16 +37,16 @@ dummy_func(PyObject * /* self */, PyObject * /* args */)
}
static struct PyMethodDef probe_methoddef[] = {
- {"dummy", dummy_func, METH_NOARGS},
- {nullptr}
+ {"dummy", dummy_func, METH_NOARGS, nullptr},
+ {nullptr, nullptr, 0, nullptr}
};
static PyGetSetDef probe_getseters[] = {
- {nullptr} /* Sentinel */
+ {nullptr, nullptr, nullptr, nullptr, nullptr} /* Sentinel */
};
static PyMemberDef probe_members[] = {
- {nullptr} /* Sentinel */
+ {nullptr, 0, 0, 0, nullptr} /* Sentinel */
};
#define probe_tp_dealloc make_dummy(1)
@@ -140,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
@@ -168,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
@@ -182,18 +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);
}
-#if PY_VERSION_HEX < PY_ISSUE33738_SOLVED
-#include "pep384_issue33738.cpp"
-#endif
-
#endif // Py_LIMITED_API
/*****************************************************************************
@@ -215,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;
@@ -229,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()) {
@@ -287,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 */
@@ -300,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 {
@@ -322,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;
@@ -339,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)
@@ -361,12 +362,29 @@ 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)
return "";
auto *asciiObj = reinterpret_cast<PepASCIIObject *>(str);
- if (asciiObj->state.kind != PepUnicode_1BYTE_KIND)
+ 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;
@@ -381,18 +399,21 @@ static const char *utf8FastPath(PyObject *str)
const char *_PepUnicode_AsString(PyObject *str)
{
/*
- * We need to keep the string alive but cannot borrow the Python object.
- * Ugly easy way out: We re-code as an interned bytes string. This
- * produces a pseudo-leak as long as there are new strings.
- * Typically, this function is used for name strings, and the dict size
- * will not grow so much.
+ * This function is the surrogate for PyUnicode_AsUTF8, which keeps the data
+ * in the unicode object as long as that object exists.
+ *
+ * The function does too much if not optimized by utf8, because it keeps the
+ * string alive, unconditionally.
+ * We should not rely on this behavior and think of PyUnicode_AsUTF8, only.
*/
#define STRINGIFY(x) #x
#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) {
@@ -461,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
@@ -483,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
@@ -685,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));
}
@@ -712,6 +787,29 @@ PyStaticMethod_New(PyObject *callable)
}
#endif // Py_LIMITED_API
+#ifdef PYPY_VERSION
+PyTypeObject *PepBuiltinMethod_TypePtr = nullptr;
+
+static PyTypeObject *
+getBuiltinMethodType(void)
+{
+ // PYSIDE-535: PyPy has a special builtin method that acts almost like PyCFunction.
+ //
+ // There is no public declaration for the "builtin method" type.
+ // We also cannot grep it with a Python script since the import is too early.
+ // Pick a demo "builtin method" by using the VoidPtr type.
+ // Create the equivalent of
+ // "from shiboken6.Shiboken import VoidPtr\n"
+ // "result = type(VoidPtr(0).toBytes)\n";
+ auto *pyVoidP = reinterpret_cast<PyObject *>(SbkVoidPtr_TypeF());
+ Shiboken::AutoDecRef arg(Py_BuildValue("i", 0));
+ Shiboken::AutoDecRef inst(PyObject_CallFunctionObjArgs(pyVoidP, arg.object(), nullptr));
+ Shiboken::AutoDecRef meth(PyObject_GetAttrString(inst, "toBytes"));
+ auto *result = reinterpret_cast<PyTypeObject *>(PyObject_Type(meth));
+ return result;
+}
+#endif
+
/*****************************************************************************
*
* Common newly needed functions
@@ -731,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)
@@ -762,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.
@@ -773,15 +896,13 @@ PepRun_GetResult(const char *command)
/*
* Evaluate a string and return the variable `result`
*/
- PyObject *d, *v, *res;
-
- d = PyDict_New();
+ PyObject *d = PyDict_New();
if (d == nullptr
|| PyDict_SetItem(d, Shiboken::PyMagicName::builtins(), PyEval_GetBuiltins()) < 0) {
return nullptr;
}
- v = PyRun_String(command, Py_file_input, d, d);
- res = v ? PyDict_GetItem(d, Shiboken::PyName::result()) : nullptr;
+ PyObject *v = PyRun_String(command, Py_file_input, d, d);
+ PyObject *res = v ? PyDict_GetItem(d, Shiboken::PyName::result()) : nullptr;
Py_XDECREF(v);
Py_DECREF(d);
return res;
@@ -789,7 +910,7 @@ PepRun_GetResult(const char *command)
PyTypeObject *PepType_Type_tp_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
{
- auto ret = PyType_Type.tp_new(metatype, args, kwds);
+ auto *ret = PyType_Type.tp_new(metatype, args, kwds);
return reinterpret_cast<PyTypeObject *>(ret);
}
@@ -818,7 +939,7 @@ _Pep_PrivateMangle(PyObject *self, PyObject *name)
Py_INCREF(name);
return name;
}
- size_t nlen = PyUnicode_GET_LENGTH(name);
+ const Py_ssize_t nlen = PyUnicode_GET_LENGTH(name);
/* Don't mangle __id__ or names with dots. */
if ((PyUnicode_READ_CHAR(name, nlen-1) == '_' &&
PyUnicode_READ_CHAR(name, nlen-2) == '_') ||
@@ -832,9 +953,9 @@ _Pep_PrivateMangle(PyObject *self, PyObject *name)
// PYSIDE-1436: _Py_Mangle is no longer exposed; implement it always.
// The rest of this function is our own implementation of _Py_Mangle.
// Please compare the original function in compile.c .
- size_t plen = PyUnicode_GET_LENGTH(privateobj.object());
+ Py_ssize_t plen = PyUnicode_GET_LENGTH(privateobj.object());
/* Strip leading underscores from class name */
- size_t ipriv = 0;
+ Py_ssize_t ipriv = 0;
while (PyUnicode_READ_CHAR(privateobj.object(), ipriv) == '_')
ipriv++;
if (ipriv == plen) {
@@ -848,18 +969,18 @@ _Pep_PrivateMangle(PyObject *self, PyObject *name)
"private identifier too large to be mangled");
return nullptr;
}
- size_t const amount = ipriv + 1 + plen + nlen;
- size_t const big_stack = 1000;
+ const Py_ssize_t amount = ipriv + 1 + plen + nlen;
+ const Py_ssize_t big_stack = 1000;
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);
@@ -885,6 +1006,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
@@ -894,33 +1030,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
*/
@@ -930,6 +1141,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);
@@ -948,31 +1160,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)
-{
- 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
+
+// PyType_GetDict: replacement for <static type>.tp_dict, which is
+// zero for builtin types since 3.12.
+PyObject *PepType_GetDict(PyTypeObject *type)
+{
+#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;
}
-void PepType_PFTP_delete(PySideQFlagsType *flagsType)
+// 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)
{
- PFTP_extender.erase(flagsType);
- PFTP_key = nullptr;
+ 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;
}
/***************************************************************************
@@ -1006,16 +1263,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);
}
@@ -1052,6 +1309,9 @@ Pep384_Init()
PepFunction_TypePtr = getFunctionType();
PepStaticMethod_TypePtr = getStaticMethodType();
#endif // Py_LIMITED_API
+#ifdef PYPY_VERSION
+ PepBuiltinMethod_TypePtr = getBuiltinMethodType();
+#endif
}
} // extern "C"
diff --git a/sources/shiboken6/libshiboken/pep384impl.h b/sources/shiboken6/libshiboken/pep384impl.h
index 134199788..7188366e2 100644
--- a/sources/shiboken6/libshiboken/pep384impl.h
+++ b/sources/shiboken6/libshiboken/pep384impl.h
@@ -1,50 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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
#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"
{
@@ -91,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 */
@@ -139,14 +135,6 @@ 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 in Python 3.8 .
-#define PY_ISSUE33738_SOLVED 0x03080000
-#if PY_VERSION_HEX < PY_ISSUE33738_SOLVED
-#undef PyIndex_Check
-LIBSHIBOKEN_API int PyIndex_Check(PyObject *obj);
-#endif
-
LIBSHIBOKEN_API PyObject *_PepType_Lookup(PyTypeObject *type, PyObject *name);
#else // Py_LIMITED_API
@@ -155,6 +143,8 @@ LIBSHIBOKEN_API PyObject *_PepType_Lookup(PyTypeObject *type, PyObject *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
@@ -173,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
@@ -197,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
/*****************************************************************************
@@ -227,12 +226,17 @@ LIBSHIBOKEN_API int Pep_GetVerboseFlag(void);
// PyUnicode_GetSize is deprecated in favor of PyUnicode_GetLength.
#define PepUnicode_GetLength(op) PyUnicode_GetLength((PyObject *)(op))
+// Unfortunately, we cannot ask this at runtime
+// #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
+// FIXME: Python 3.10: Replace _PepUnicode_AsString by PyUnicode_AsUTF8
#ifdef Py_LIMITED_API
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
@@ -247,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
@@ -309,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)
@@ -339,11 +345,8 @@ LIBSHIBOKEN_API PyObject *PyRun_String(const char *, int, PyObject *, PyObject *
// buffer functions.
// But this is no problem as we check it's validity for every version.
-#define PYTHON_BUFFER_VERSION_COMPATIBLE (PY_VERSION_HEX >= 0x03030000 && \
- PY_VERSION_HEX < 0x030AFFFF)
-#if !PYTHON_BUFFER_VERSION_COMPATIBLE
-# error Please check the buffer compatibility for this python version!
-#endif
+// PYSIDE-1960 The buffer interface is since Python 3.11 part of the stable
+// API and we do not need to check the compatibility by hand anymore.
typedef struct {
getbufferproc bf_getbuffer;
@@ -427,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
@@ -444,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
/*****************************************************************************
@@ -532,6 +546,10 @@ LIBSHIBOKEN_API PyObject *PyStaticMethod_New(PyObject *callable);
#define PepStaticMethod_TypePtr &PyStaticMethod_Type
#endif
+#ifdef PYPY_VERSION
+extern LIBSHIBOKEN_API PyTypeObject *PepBuiltinMethod_TypePtr;
+#endif
+
// Although not PEP specific, we resolve this similar issue, here:
#define PepMethodDescr_TypePtr &PyMethodDescr_Type
@@ -541,9 +559,9 @@ LIBSHIBOKEN_API PyObject *PyStaticMethod_New(PyObject *callable);
*
* 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);
@@ -568,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/pep384impl_doc.rst b/sources/shiboken6/libshiboken/pep384impl_doc.rst
deleted file mode 100644
index 9ee74a26c..000000000
--- a/sources/shiboken6/libshiboken/pep384impl_doc.rst
+++ /dev/null
@@ -1,704 +0,0 @@
-****************************************
-The Transition To The Limited Python API
-****************************************
-
-
-Foreword
-========
-
-Python supports a limited API that restricts access to certain structures.
-Besides eliminating whole modules and all functions and macros which names
-start with an
-underscore, the most drastic restriction is the removal of normal type object
-declarations.
-
-For details about the eliminated modules and functions, please see the
-`PEP 384`_ page for reference.
-
-
-.. _`PEP 384`: https://www.python.org/dev/peps/pep-0384/
-
-
-
-Changed Modules
-===============
-
-All changed module's include files are listed with the changed functions here.
-As a general rule, it was tried to keep the changes to a minimum diff.
-Macros which are not available were changed to functions with the same name
-if possible. Completely removed names ``Py{name}`` were re-implemented as ``Pep{name}``.
-
-
-memoryobject.h
---------------
-
-The buffer protocol was completely removed. We redefined all the structures
-and methods, because PySide uses that. This is an exception to the limited API
-that we have to check ourselves. The code is extracted in bufferprocs_py37.h .
-This is related to the following:
-
-
-abstract.h
-----------
-
-This belongs to the buffer protocol like memoryobject.h .
-As replacement for ``Py_buffer`` we defined ``Pep_buffer`` and several other
-internal macros.
-
-The version is checked by hand, and the version number must be updated only
-if the implementation does not change. Otherwise, we need to write version
-dependent code paths.
-
-It is questionable if it is worthwhile to continue using the buffer protocol
-or if we should try to get rid of ``Pep_buffer``, completely.
-
-
-pydebug.h
----------
-
-We have no direct access to ``Py_VerboseFlag`` because debugging is not
-supported. We redefined it as macro ``Py_VerboseFlag`` which calls ``Pep_VerboseFlag``.
-
-
-unicodeobject.h
----------------
-
-The macro ``PyUnicode_GET_SIZE`` was removed and replaced by ``PepUnicode_GetLength``
-which evaluates to ``PyUnicode_GetSize`` for Python 2 and ``PyUnicode_GetLength`` for Python 3.
-Since Python 3.3, ``PyUnicode_GetSize`` would have the bad side effect of requiring the GIL!
-
-Function ``_PyUnicode_AsString`` is unavailable and was replaced by a macro
-that calls ``_PepUnicode_AsString``. The implementation was a bit involved,
-and it would be better to change the code and replace this function.
-
-
-bytesobject.h
--------------
-
-The macros ``PyBytes_AS_STRING`` and ``PyBytes_GET_SIZE`` were redefined to call
-the according functions.
-
-
-floatobject.h
--------------
-
-``PyFloat_AS_DOUBLE`` now calls ``PyFloat_AsDouble``.
-
-
-tupleobject.h
--------------
-
-``PyTuple_GET_ITEM``, ``PyTuple_SET_ITEM`` and ``PyTuple_GET_SIZE`` were redefined as
-function calls.
-
-
-listobject.h
-------------
-
-``PyList_GET_ITEM``, ``PyList_SET_ITEM`` and ``PyList_GET_SIZE`` were redefined as
-function calls.
-
-
-dictobject.h
-------------
-
-``PyDict_GetItem`` also exists in a ``PyDict_GetItemWithError`` version that does
-not suppress errors. This suppression has the side effect of touching global
-structures. This function exists in Python 2 only since Python 2.7.12 and has
-a different name. We simply implemented the function.
-Needed to avoid the GIL when accessing dictionaries.
-
-
-methodobject.h
---------------
-
-``PyCFunction_GET_FUNCTION``, ``PyCFunction_GET_SELF`` and ``PyCFunction_GET_FLAGS``
-were redefined as function calls.
-
-Direct access to the methoddef structure is not available, and we defined
-``PepCFunction_GET_NAMESTR`` as accessor for name strings.
-
-
-pythonrun.h
------------
-
-The simple function ``PyRun_String`` is not available. It was re-implemented
-in a simplified version for the signature module.
-
-
-funcobject.h
-------------
-
-The definitions of funcobject.h are completely missing, although there
-are extra ``#ifdef`` conditional defines inside, too. This suggests that the exclusion
-was unintended.
-
-We therefore redefined ``PyFunctionObject`` as an opaque type.
-
-The missing macro ``PyFunction_Check`` was defined, and the macro
-``PyFunction_GET_CODE`` calls the according function.
-
-There is no equivalent for function name access, therefore we introduced
-``PepFunction_GetName`` either as a function or as a macro.
-
-*TODO: We should fix funcobject.h*
-
-
-classobject.h
--------------
-
-Classobject is also completely not imported, instead of defining an opaque type.
-
-We defined the missing functions ``PyMethod_New``, ``PyMethod_Function`` and
-``PyMethod_Self`` and also redefined ``PyMethod_GET_SELF`` and
-``PyMethod_GET_FUNCTION`` as calls to these functions.
-
-*TODO: We should fix classobject.h*
-
-
-code.h
-------
-
-The whole code.c code is gone, although it may make sense to
-define some minimum accessibility. This will be clarified on
-`Python-Dev`_. We needed access to code objects and defined the missing
-PepCode_GET_FLAGS and PepCode_GET_ARGCOUNT either as function or macro.
-We further added the missing flags, although few are used:
-
-``CO_OPTIMIZED`` ``CO_NEWLOCALS`` ``CO_VARARGS`` ``CO_VARKEYWORDS`` ``CO_NESTED``
-``CO_GENERATOR``
-
-*TODO: We should maybe fix code.h*
-
-.. _`Python-Dev`: https://mail.python.org/mailman/listinfo/python-dev
-
-datetime.h
-----------
-
-The DateTime module is explicitly not included in the limited API.
-We defined all the needed functions but called them via Python instead
-of direct call macros. This has a slight performance impact.
-
-The performance could be easily improved by providing an interface
-that fetches all attributes at once, instead of going through the object
-protocol every time.
-
-The re-defined macros and methods are::
-
- PyDateTime_GET_YEAR
- PyDateTime_GET_MONTH
- PyDateTime_GET_DAY
- PyDateTime_DATE_GET_HOUR
- PyDateTime_DATE_GET_MINUTE
- PyDateTime_DATE_GET_SECOND
- PyDateTime_DATE_GET_MICROSECOND
- PyDateTime_DATE_GET_FOLD
- PyDateTime_TIME_GET_HOUR
- PyDateTime_TIME_GET_MINUTE
- PyDateTime_TIME_GET_SECOND
- PyDateTime_TIME_GET_MICROSECOND
- PyDateTime_TIME_GET_FOLD
-
- PyDate_Check
- PyDateTime_Check
- PyTime_Check
-
- PyDate_FromDate
- PyDateTime_FromDateAndTime
- PyTime_FromTime
-
-*XXX: We should maybe provide an optimized interface to datetime*
-
-
-object.h
---------
-
-The file object.h contains the ``PyTypeObject`` structure, which is supposed
-to be completely opaque. All access to types should be done through
-``PyType_GetSlot`` calls. Due to bugs and deficiencies in the limited API
-implementation, it was not possible to do that. Instead, we have defined
-a simplified structure for ``PyTypeObject`` that has only the fields that
-are used in PySide.
-
-We will explain later why and how this was done. Here is the reduced
-structure::
-
- typedef struct _typeobject {
- PyVarObject ob_base;
- const char *tp_name;
- 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;
- void *X10; // PyNumberMethods *tp_as_number;
- void *X11; // PySequenceMethods *tp_as_sequence;
- void *X12; // PyMappingMethods *tp_as_mapping;
- void *X13; // hashfunc tp_hash;
- ternaryfunc tp_call;
- reprfunc tp_str;
- void *X16; // getattrofunc tp_getattro;
- void *X17; // setattrofunc tp_setattro;
- void *X18; // PyBufferProcs *tp_as_buffer;
- void *X19; // unsigned long tp_flags;
- void *X20; // const char *tp_doc;
- traverseproc tp_traverse;
- inquiry tp_clear;
- void *X23; // richcmpfunc tp_richcompare;
- Py_ssize_t tp_weaklistoffset;
- void *X25; // getiterfunc tp_iter;
- void *X26; // iternextfunc tp_iternext;
- struct PyMethodDef *tp_methods;
- void *X28; // struct PyMemberDef *tp_members;
- void *X29; // struct PyGetSetDef *tp_getset;
- struct _typeobject *tp_base;
- PyObject *tp_dict;
- descrgetfunc tp_descr_get;
- void *X33; // descrsetfunc tp_descr_set;
- Py_ssize_t tp_dictoffset;
- initproc tp_init;
- allocfunc tp_alloc;
- newfunc tp_new;
- freefunc tp_free;
- inquiry tp_is_gc; /* For PyObject_IS_GC */
- PyObject *tp_bases;
- PyObject *tp_mro; /* method resolution order */
- } PyTypeObject;
-
-Function ``PyIndex_Check`` had to be defined in an unwanted way due to
-a Python issue. See file pep384_issue33738.cpp .
-
-There are extension structures which have been isolated as special macros that
-dynamically compute the right offsets of the extended type structures:
-
-* ``PepType_SOTP`` for ``SbkObjectTypePrivate``
-* ``PepType_SETP`` for ``SbkEnumTypePrivate``
-* ``PepType_PFTP`` for ``PySideQFlagsTypePrivate``
-
-How these extension structures are used can best be seen by searching
-``PepType_{four}`` in the source.
-
-Due to the new heaptype interface, the names of certain types contain
-now the module name in the ``tp_name`` field. To have a compatible way
-to access simple type names as C string, ``PepType_GetNameStr`` has been
-written that skips over dotted name parts.
-
-Finally, the function ``_PyObject_Dump`` was excluded from the limited API.
-This is a useful debugging aid that we always want to have available,
-so it is added back, again. Anyway, we did not reimplement it, and so
-Windows is not supported.
-Therefore, a forgotten debugging call of this functions will break COIN. :-)
-
-
-Using The New Type API
-======================
-
-After converting everything but the object.h file, we were a little
-bit shocked: it suddenly was clear that we would have no more
-access to type objects, and even more scary that all types which we
-use have to be heap types, only!
-
-For PySide with its intense use of heap type extensions in various
-flavors, the situation looked quite unsolvable. In the end, it was
-nicely solved, but it took almost 3.5 months to get that right.
-
-Before we see how this is done, we will explain the differences
-between the APIs and their consequences.
-
-
-The Interface
--------------
-
-The old type API of Python knows static types and heap types.
-Static types are written down as a declaration of a ``PyTypeObject``
-structure with all its fields filled in. Here is for example
-the definition of the Python type ``object`` (Python 3.6)::
-
- PyTypeObject PyBaseObject_Type = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "object", /* tp_name */
- sizeof(PyObject), /* tp_basicsize */
- 0, /* tp_itemsize */
- object_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- object_repr, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- (hashfunc)_Py_HashPointer, /* tp_hash */
- 0, /* tp_call */
- object_str, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- PyObject_GenericSetAttr, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- PyDoc_STR("object()\n--\n\nThe most base type"), /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- object_richcompare, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- object_methods, /* tp_methods */
- 0, /* tp_members */
- object_getsets, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- object_init, /* tp_init */
- PyType_GenericAlloc, /* tp_alloc */
- object_new, /* tp_new */
- PyObject_Del, /* tp_free */
- };
-
-We can write the same structure in form of a ``PyType_Spec`` structure,
-and there is even an incomplete tool *abitype.py* that does this conversion
-for us. With a few corrections, the result looks like this::
-
- static PyType_Slot PyBaseObject_Type_slots[] = {
- {Py_tp_dealloc, (void *)object_dealloc},
- {Py_tp_repr, (void *)object_repr},
- {Py_tp_hash, (void *)_Py_HashPointer},
- {Py_tp_str, (void *)object_str},
- {Py_tp_getattro, (void *)PyObject_GenericGetAttr},
- {Py_tp_setattro, (void *)PyObject_GenericSetAttr},
- {Py_tp_richcompare, (void *)object_richcompare},
- {Py_tp_methods, (void *)object_methods},
- {Py_tp_getset, (void *)object_getsets},
- {Py_tp_init, (void *)object_init},
- {Py_tp_alloc, (void *)PyType_GenericAlloc},
- {Py_tp_new, (void *)object_new},
- {Py_tp_free, (void *)PyObject_Del},
- {0, 0},
- };
- static PyType_Spec PyBaseObject_Type_spec = {
- "object",
- sizeof(PyObject),
- 0,
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- PyBaseObject_Type_slots,
- };
-
-This new structure is almost compatible with the old one, but there
-are some subtle differences.
-
-* The new types are generated in one step
-
-This seems to be no problem, but it was very much, due to the way the
-types were built in PySide. Types were assembled piece by piece, and
-finally the ``PyType_Ready`` function was called.
-
-With the new API, ``PyType_Ready`` is called already at the end of
-``PyType_FromSpec``, and that meant that the logic of type creation became
-completely turned upside down.
-
-* The new types are always heaptypes
-
-With the new type creation functions, it is no longer possible to
-create "normal" types. Instead, they all have to be allocated on the
-heap and garbage collected. The user should normally not recognize this.
-But type creation is more constrained, and you cannot create a subtype
-if the ``Py_TPFLAGS_BASETYPE`` is not set. This constraint was already
-violated by PySide and needed a quite profound fix.
-
-* The new types always need a module
-
-While this is not a problem per se, the above new type spec will not create
-a usable new type, but complain with::
-
- DeprecationWarning: builtin type object has no __module__ attribute
-
-But there are more problems:
-
-* The new types have unexpected defaults
-
-When fields are empty, you would usually assume that they stay empty.
-There are just a few corrections that ``PyType_Ready`` will do to a type.
-
-But there is the following clause in ``PyType_FromSpec`` that can give you
-many headaches::
-
- if (type->tp_dealloc == NULL) {
- /* It's a heap type, so needs the heap types' dealloc.
- subtype_dealloc will call the base type's tp_dealloc, if
- necessary. */
- type->tp_dealloc = subtype_dealloc;
- }
-
-In fact, before the move to the new API, the ``PyType_Ready`` function
-filled empty ``tp_dealloc`` fields with ``object_dealloc``. And the code
-that has been written with that in mind now becomes pretty wrong if suddenly
-``subtype_dealloc`` is used.
-
-The way out was to explicitly provide an ``object_dealloc`` function.
-This would then again impose a problem, because ``object_dealloc`` is not
-public. Writing our own version is easy, but it again needs access to
-type objects. But fortunately, we have broken this rule, already...
-
-
-* The new types are only partially allocated
-
-The structures used in ``PyType_FromSpec`` are almost all allocated,
-only the name field is static. This is no problem for types which are
-statically created once. But if you want to parameterize things and
-create multiple types with a single slots and spec definition, the name
-field that is used for tp_name must be allocated dynamically.
-This is misleading, since all the slots already are copies.
-
-* The new types don't support special offsets
-
-The special fields ``tp_weaklistoffset`` and ``tp_dictoffset`` are not supported
-by ``PyType_FromSpec``. Unfortunately the documentation does not tell you
-if you are allowed to set these fields manually after creating the type or not.
-We finally did it and it worked, but we are not sure about correctness.
-
-See basewrapper.cpp function ``SbkObject_TypeF()`` as the only reference to
-these fields in PySide. This single reference is absolutely necessary and
-very important, since all derived types invisibly inherit these two fields.
-
-
-Future Versions Of The Limited API
-==================================
-
-As we have seen, the current version of the limited API does a bit of
-cheating, because it uses parts of the data structure that should be
-an opaque type. At the moment, this works fine because the data is
-still way more compatible as it could be.
-
-But what if this is changed in the future?
-
-We know that the data structures are stable until Python 3.8 comes out.
-Until then, the small bugs and omissions will hopefully all be solved.
-Then it will be possible to replace the current small tricks by calls
-to ``PyType_GetSlot`` in the way things should be.
-
-At the very moment when the current assumptions about the data structure
-are no longer true, we will rewrite the direct attribute access with
-calls to ``PyType_GetSlot``. After that, no more changes will be necessary.
-
-
-Appendix A: The Transition To Simpler Types
-===========================================
-
-After all code had been converted to the limited API, there was a
-remaining problem with the ``PyHeapTypeObject``.
-
-Why a problem? Well, all the type structures in shiboken use
-special extra fields at the end of the heap type object. This
-currently enforces extra knowledge at compile time about how large the
-heap type object is. In a clean implementation, we would only use
-the ``PyTypeObject`` itself and access the fields *behind* the type
-by a pointer that is computed at runtime.
-
-
-Restricted PyTypeObject
------------------------
-
-Before we are going into details, let us motivate the existence of
-the restricted ``PyTypeObject``:
-
-Originally, we wanted to use ``PyTypeObject`` as an opaque type and
-restrict ourselves to only use the access function ``PyType_GetSlot``.
-This function allows access to all fields which are supported by
-the limited API.
-
-But this is a restriction, because we get no access to ``tp_dict``,
-which we need to support the signature extension. But we can work
-around that.
-
-The real restriction is that ``PyType_GetSlot`` only works for heap
-types. This makes the function quite useless, because we have
-no access to ``PyType_Type``, which is the most important type ``type``
-in Python. We need that for instance to compute the size of
-``PyHeapTypeObject`` dynamically.
-
-With much effort, it is possible to clone ``PyType_Type`` as a heap
-type. But due to a bug in the Pep 384 support, we need
-access to the ``nb_index`` field of a normal type. Cloning does not
-help because ``PyNumberMethods`` fields are *not* inherited.
-
-After we realized this dead end, we changed concept and did not
-use ``PyType_GetSlot`` at all (except in function ``copyNumberMethods``),
-but created a restricted ``PyTypeObject`` with only those fields
-defined that are needed in PySide.
-
-Is this breakage of the limited API? I don't think so. A special
-function runs on program startup that checks the correct position
-of the fields of ``PyTypeObject``, although a change in those fields is
-more than unlikely.
-The really crucial thing is to no longer use ``PyHeapTypeObject``
-explicitly because that *does* change its layout over time.
-
-
-Diversification
----------------
-
-There were multiple ``Sbk{something}`` structures which all used a "d" field
-for their private data. This made it not easy to find the right
-fields when switching between objects and types::
-
- struct LIBSHIBOKEN_API SbkObject
- {
- PyObject_HEAD
- PyObject *ob_dict;
- PyObject *weakreflist;
- SbkObjectPrivate *d;
- };
-
- struct LIBSHIBOKEN_API SbkObjectType
- {
- PyHeapTypeObject super;
- SbkObjectTypePrivate *d;
- };
-
-The first step was to rename the SbkObjectTypePrivate part from "d" to
-"sotp". It was chosen to be short but easy to remember as abbreviation
-of "SbkObjectTypePrivate", leading to::
-
- struct LIBSHIBOKEN_API SbkObjectType
- {
- PyHeapTypeObject super;
- SbkObjectTypePrivate *sotp;
- };
-
-After renaming, it was easier to do the following transformations.
-
-
-Abstraction
------------
-
-After renaming the type extension pointers to ``sotp``, I replaced
-them by function-like macros which did the special access *behind*
-the types, instead of those explicit fields. For instance, the
-expression::
-
- type->sotp->converter
-
-became::
-
- PepType_SOTP(type)->converter
-
-The macro expansion can be seen here::
-
- #define PepHeapType_SIZE \
- (reinterpret_cast<PyTypeObject *>(&PyType_Type)->tp_basicsize)
-
- #define _genericTypeExtender(etype) \
- (reinterpret_cast<char *>(etype) + PepHeapType_SIZE)
-
- #define PepType_SOTP(etype) \
- (*reinterpret_cast<SbkObjectTypePrivate **>(_genericTypeExtender(etype)))
-
-This looks complicated, but in the end there is only a single new
-indirection via ``PyType_Type``, which happens at runtime. This is the
-key to fulfil what Pep 384 wants to achieve: *No more version-dependent fields*.
-
-
-Simplification
---------------
-
-After all type extension fields were replaced by macro calls, we
-could remove the following version dependent re-definition of ``PyHeapTypeObject``
-::
-
- typedef struct _pyheaptypeobject {
- union {
- PyTypeObject ht_type;
- void *opaque[PY_HEAPTYPE_SIZE];
- };
- } PyHeapTypeObject;
-
-, and the version dependent structure::
-
- struct LIBSHIBOKEN_API SbkObjectType
- {
- PyHeapTypeObject super;
- SbkObjectTypePrivate *sotp;
- };
-
-could be removed. SbkObjectType remains as a (deprecated)
-type alias to PyTypeObject.
-
-
-Appendix B: Verification Of PyTypeObject
-========================================
-
-We have introduced a limited PyTypeObject in the same place
-as the original PyTypeObject, and now we need to prove that
-we are allowed to do so.
-
-When using the limited API as intended, then types are completely
-opaque, and access is only through ``PyType_FromSpec`` and (from
-version 3.5 upwards) through ``PyType_GetSlot``.
-
-Python then uses all the slot definitions in the type description
-and produces a regular heap type object.
-
-
-Unused Information
-------------------
-
-We know many things about types that are not explicitly said,
-but they are inherently clear:
-
-(a) The basic structure of a type is always the same, regardless
- if it is a static type or a heap type.
-
-(b) types are evolving very slowly, and a field is never replaced
- by another field with different semantics.
-
-Inherent rule (a) gives us the following information: If we calculate
-the offsets of the basic fields, then this info is also usable for non-heap
-types.
-
-The validation checks if rule (b) is still valid.
-
-
-How it Works
-------------
-
-The basic idea of the validation is to produce a new type using
-``PyType_FromSpec`` and to see where in the type structure these fields
-show up. So we build a ``PyType_Slot`` structure with all the fields we
-are using and make sure that these values are all unique in the
-type.
-
-Most fields are not interrogated by ``PyType_FromSpec``, and so we
-simply used some numeric value. Some fields are interpreted, like
-``tp_members``. This field must really be a ``PyMemberDef``. And there are
-``tp_base`` and ``tp_bases`` which have to be type objects and lists
-thereof. It was easiest to not produce these fields from scratch
-but use them from the ``type`` object ``PyType_Type``.
-
-Then one would think to write a function that searches the known
-values in the opaque type structure.
-
-But we can do better and use optimistically the observation (b):
-We simply use the restricted ``PyTypeObject`` structure and assume that
-every field lands exactly where we are awaiting it.
-
-And that is the whole proof: If we find all the disjoint values at
-the places where we expect them, then verification is done.
-
-
-About ``tp_dict``
------------------
-
-One word about the ``tp_dict`` field: This field is a bit special in
-the proof, since it does not appear in the spec and cannot easily
-be checked by ``type.__dict__`` because that creates a *dictproxy*
-object. So how do we prove that is really the right dict?
-
-We have to create that ``PyMethodDef`` structure anyway, and instead of
-leaving it empty, we insert a dummy function. Then we ask the
-``tp_dict`` field if it has the awaited object in it, and that's it!
-
-#EOT
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 3960295aa..bcc3fb767 100644
--- a/sources/shiboken6/libshiboken/sbkarrayconverter.cpp
+++ b/sources/shiboken6/libshiboken/sbkarrayconverter.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 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 "sbkarrayconverter.h"
#include "sbkarrayconverter_p.h"
@@ -50,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>
@@ -280,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 32bbd8284..dcb9bfb38 100644
--- a/sources/shiboken6/libshiboken/sbkarrayconverter.h
+++ b/sources/shiboken6/libshiboken/sbkarrayconverter.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 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 SBKARRAYCONVERTERS_H
#define SBKARRAYCONVERTERS_H
@@ -47,8 +11,7 @@ extern "C" {
struct SbkArrayConverter;
}
-namespace Shiboken {
-namespace Conversions {
+namespace Shiboken::Conversions {
enum : int {
SBK_UNIMPLEMENTED_ARRAY_IDX,
@@ -107,7 +70,7 @@ template <class T, int columns>
class Array2Handle
{
public:
- typedef T RowType[columns];
+ using RowType = T[columns];
Array2Handle() = default;
@@ -168,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 a7b46702b..63d03fb12 100644
--- a/sources/shiboken6/libshiboken/sbkarrayconverter_p.h
+++ b/sources/shiboken6/libshiboken/sbkarrayconverter_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 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 SBKARRAYCONVERTER_P_H
#define SBKARRAYCONVERTER_P_H
@@ -46,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 98fd700aa..7de1f03e6 100644
--- a/sources/shiboken6/libshiboken/sbkcontainer.cpp
+++ b/sources/shiboken6/libshiboken/sbkcontainer.cpp
@@ -1,52 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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
#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 97062a198..8ad5aadc6 100644
--- a/sources/shiboken6/libshiboken/sbkcontainer.h
+++ b/sources/shiboken6/libshiboken/sbkcontainer.h
@@ -1,51 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 SBK_CONTAINER_H
#define SBK_CONTAINER_H
#include "sbkpython.h"
#include "shibokenmacros.h"
+#include "shibokenbuffer.h"
#include <algorithm>
#include <iterator>
#include <optional>
+#include <utility>
extern "C"
{
@@ -67,6 +33,21 @@ struct ShibokenContainerValueConverter
static std::optional<Value> convertValueToCpp(PyObject pyArg);
};
+// SFINAE test for the presence of reserve() in a sequence container (std::vector/QList)
+template <typename T>
+class ShibokenContainerHasReserve
+{
+private:
+ using YesType = char[1];
+ using NoType = char[2];
+
+ template <typename C> static YesType& test( decltype(&C::reserve) ) ;
+ template <typename C> static NoType& test(...);
+
+public:
+ enum { value = sizeof(test<T>(nullptr)) == sizeof(YesType) };
+};
+
template <class SequenceContainer>
class ShibokenSequenceContainerPrivate // Helper for sequence type containers
{
@@ -82,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;
@@ -90,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;
@@ -102,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)
@@ -113,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);
}
@@ -129,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())
@@ -141,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())
@@ -160,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())
@@ -179,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;
@@ -191,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;
@@ -203,15 +180,70 @@ 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;
}
+ // Support for containers with reserve/capacity
+ static PyObject *reserve(PyObject *self, PyObject *pyArg)
+ {
+ auto *d = get(self);
+ 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 {
+ return PyErr_Format(PyExc_TypeError, "Container does not support reserve().");
+ }
+
+ Py_RETURN_NONE;
+ }
+
+ static PyObject *capacity(PyObject *self)
+ {
+ Py_ssize_t result = -1;
+ if constexpr (ShibokenContainerHasReserve<SequenceContainer>::value) {
+ const auto *d = get(self);
+ result = d->m_list->capacity();
+ }
+ return PyLong_FromSsize_t(result);
+ }
+
+ static PyObject *data(PyObject *self)
+ {
+ PyObject *result = nullptr;
+ if constexpr (ShibokenContainerHasReserve<SequenceContainer>::value) {
+ const auto *d = get(self);
+ auto *data = d->m_list->data();
+ const Py_ssize_t size = sizeof(value_type) * d->m_list->size();
+ result = Shiboken::Buffer::newObject(data, size, Shiboken::Buffer::ReadWrite);
+ } else {
+ PyErr_SetString(PyExc_TypeError, "Container does not support data().");
+ }
+ return result;
+ }
+
+ static PyObject *constData(PyObject *self)
+ {
+ PyObject *result = nullptr;
+ if constexpr (ShibokenContainerHasReserve<SequenceContainer>::value) {
+ const auto *d = get(self);
+ const auto *data = std::as_const(d->m_list)->data();
+ const Py_ssize_t size = sizeof(value_type) * d->m_list->size();
+ result = Shiboken::Buffer::newObject(data, size);
+ } else {
+ PyErr_SetString(PyExc_TypeError, "Container does not support constData().");
+ }
+ return result;
+ }
+
static ShibokenSequenceContainerPrivate *get(PyObject *self)
{
auto *data = reinterpret_cast<ShibokenContainer *>(self);
diff --git a/sources/shiboken6/libshiboken/sbkconverter.cpp b/sources/shiboken6/libshiboken/sbkconverter.cpp
index 334fb4297..dac3fb638 100644
--- a/sources/shiboken6/libshiboken/sbkconverter.cpp
+++ b/sources/shiboken6/libshiboken/sbkconverter.cpp
@@ -1,45 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 "sbkconverter.h"
#include "sbkconverter_p.h"
#include "sbkarrayconverter_p.h"
+#include "sbkmodule.h"
#include "basewrapper_p.h"
#include "bindingmanager.h"
#include "autodecref.h"
@@ -47,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();
@@ -108,13 +77,110 @@ 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,
CppToPythonFunc pointerToPythonFunc,
CppToPythonFunc copyToPythonFunc)
{
- auto converter = new SbkConverter;
+ auto *converter = new SbkConverter;
converter->pythonType = type;
// PYSIDE-595: All types are heaptypes now, so provide reference.
Py_XINCREF(type);
@@ -183,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);
@@ -264,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);
@@ -439,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);
@@ -459,11 +573,41 @@ 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];
}
+bool checkIterableTypes(PyTypeObject *type, PyObject *pyIn)
+{
+ Shiboken::AutoDecRef it(PyObject_GetIter(pyIn));
+ if (it.isNull()) {
+ PyErr_Clear();
+ return false;
+ }
+
+ while (true) {
+ Shiboken::AutoDecRef pyItem(PyIter_Next(it.object()));
+ if (pyItem.isNull()) {
+ if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_StopIteration))
+ PyErr_Clear();
+ break;
+ }
+ if (!PyObject_TypeCheck(pyItem, type))
+ return false;
+ }
+ return true;
+}
+
bool checkSequenceTypes(PyTypeObject *type, PyObject *pyIn)
{
assert(type);
@@ -480,6 +624,28 @@ bool checkSequenceTypes(PyTypeObject *type, PyObject *pyIn)
}
return true;
}
+
+bool convertibleIterableTypes(const SbkConverter *converter, PyObject *pyIn)
+{
+ Shiboken::AutoDecRef it(PyObject_GetIter(pyIn));
+ if (it.isNull()) {
+ PyErr_Clear();
+ return false;
+ }
+
+ while (true) {
+ Shiboken::AutoDecRef pyItem(PyIter_Next(it.object()));
+ if (pyItem.isNull()) {
+ if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_StopIteration))
+ PyErr_Clear();
+ break;
+ }
+ if (!isPythonToCppConvertible(converter, pyItem))
+ return false;
+ }
+ return true;
+}
+
bool convertibleSequenceTypes(const SbkConverter *converter, PyObject *pyIn)
{
assert(converter);
@@ -500,6 +666,13 @@ bool convertibleSequenceTypes(PyTypeObject *type, PyObject *pyIn)
return convertibleSequenceTypes(sotp->converter, pyIn);
}
+bool convertibleIterableTypes(PyTypeObject *type, PyObject *pyIn)
+{
+ assert(type);
+ auto *sotp = PepType_SOTP(type);
+ return convertibleIterableTypes(sotp->converter, pyIn);
+}
+
bool checkPairTypes(PyTypeObject *firstType, PyTypeObject *secondType, PyObject *pyIn)
{
assert(firstType);
@@ -734,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 0cf8e5c0d..2b3d50069 100644
--- a/sources/shiboken6/libshiboken/sbkconverter.h
+++ b/sources/shiboken6/libshiboken/sbkconverter.h
@@ -1,49 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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_CONVERTER_H
#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>
@@ -79,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
@@ -92,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
@@ -103,7 +67,7 @@ typedef void (*PythonToCppFunc)(PyObject *,void *);
*
* Python -> C++ ?
*/
-typedef PythonToCppFunc (*IsConvertibleToCppFunc)(PyObject *);
+using IsConvertibleToCppFunc = PythonToCppFunc (*)(PyObject *);
} // extern "C"
@@ -183,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 ---------------------------------------------------------------------------
@@ -240,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.
@@ -309,12 +277,24 @@ LIBSHIBOKEN_API SbkConverter *primitiveTypeConverter(int index);
/// Returns true if a Python sequence is comprised of objects of the given \p type.
LIBSHIBOKEN_API bool checkSequenceTypes(PyTypeObject *type, PyObject *pyIn);
+/// Returns true if a Python type is iterable and comprised of objects of the
+/// given \p type.
+LIBSHIBOKEN_API bool checkIterableTypes(PyTypeObject *type, PyObject *pyIn);
+
/// Returns true if a Python sequence is comprised of objects of a type convertible to the one represented by the given \p converter.
LIBSHIBOKEN_API bool convertibleSequenceTypes(const SbkConverter *converter, PyObject *pyIn);
/// Returns true if a Python sequence is comprised of objects of a type convertible to \p type.
LIBSHIBOKEN_API bool convertibleSequenceTypes(PyTypeObject *type, PyObject *pyIn);
+/// Returns true if a Python type is iterable and comprised of objects of a
+/// type convertible to the one represented by the given \p converter.
+LIBSHIBOKEN_API bool convertibleIterableTypes(const SbkConverter *converter, PyObject *pyIn);
+
+/// Returns true if a Python type is iterable and comprised of objects of a
+/// type convertible to \p type.
+LIBSHIBOKEN_API bool convertibleIterableTypes(PyTypeObject *type, PyObject *pyIn);
+
/// Returns true if a Python sequence can be converted to a C++ pair.
LIBSHIBOKEN_API bool checkPairTypes(PyTypeObject *firstType, PyTypeObject *secondType, PyObject *pyIn);
@@ -359,27 +339,29 @@ LIBSHIBOKEN_API bool pythonTypeIsObjectType(const SbkConverter *converter);
/// Returns true if the Python type associated with the converter is a wrapper type.
LIBSHIBOKEN_API bool pythonTypeIsWrapperType(const SbkConverter *converter);
-#define SBK_PY_LONG_LONG_IDX 0
+enum : int {
+SBK_PY_LONG_LONG_IDX = 0,
// Qt5: name collision in QtCore after QBool is replaced by bool
-#define SBK_BOOL_IDX_1 1
-#define SBK_CHAR_IDX 2
-#define SBK_CONSTCHARPTR_IDX 3
-#define SBK_DOUBLE_IDX 4
-#define SBK_FLOAT_IDX 5
-#define SBK_INT_IDX 6
-#define SBK_SIGNEDINT_IDX 6
-#define SBK_LONG_IDX 7
-#define SBK_SHORT_IDX 8
-#define SBK_SIGNEDCHAR_IDX 9
-#define SBK_STD_STRING_IDX 10
-#define SBK_STD_WSTRING_IDX 11
-#define SBK_UNSIGNEDPY_LONG_LONG_IDX 12
-#define SBK_UNSIGNEDCHAR_IDX 13
-#define SBK_UNSIGNEDINT_IDX 14
-#define SBK_UNSIGNEDLONG_IDX 15
-#define SBK_UNSIGNEDSHORT_IDX 16
-#define SBK_VOIDPTR_IDX 17
-#define SBK_NULLPTR_T_IDX 18
+SBK_BOOL_IDX_1 = 1,
+SBK_CHAR_IDX = 2,
+SBK_CONSTCHARPTR_IDX = 3,
+SBK_DOUBLE_IDX = 4,
+SBK_FLOAT_IDX = 5,
+SBK_INT_IDX = 6,
+SBK_SIGNEDINT_IDX = 6,
+SBK_LONG_IDX = 7,
+SBK_SHORT_IDX = 8,
+SBK_SIGNEDCHAR_IDX = 9,
+SBK_STD_STRING_IDX = 10,
+SBK_STD_WSTRING_IDX = 11,
+SBK_UNSIGNEDPY_LONG_LONG_IDX = 12,
+SBK_UNSIGNEDCHAR_IDX = 13,
+SBK_UNSIGNEDINT_IDX = 14,
+SBK_UNSIGNEDLONG_IDX = 15,
+SBK_UNSIGNEDSHORT_IDX = 16,
+SBK_VOIDPTR_IDX = 17,
+SBK_NULLPTR_T_IDX = 18
+};
template<typename T> SbkConverter *PrimitiveTypeConverter() { return nullptr; }
template<> inline SbkConverter *PrimitiveTypeConverter<PY_LONG_LONG>() { return primitiveTypeConverter(SBK_PY_LONG_LONG_IDX); }
@@ -434,7 +416,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 9e509591d..08fc4c8e1 100644
--- a/sources/shiboken6/libshiboken/sbkconverter_p.h
+++ b/sources/shiboken6/libshiboken/sbkconverter_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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_CONVERTER_P_H
#define SBK_CONVERTER_P_H
@@ -314,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)
@@ -363,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)
{
@@ -542,7 +506,7 @@ struct Primitive<std::wstring> : TwoPrimitive<std::wstring>
// nullptr_t
template <>
-struct Primitive<std::nullptr_t> : TwoPrimitive<std::nullptr_t>
+struct Primitive<std::nullptr_t> : OnePrimitive<std::nullptr_t>
{
static PyObject *toPython(const void * /* cppIn */)
{
@@ -558,25 +522,21 @@ struct Primitive<std::nullptr_t> : TwoPrimitive<std::nullptr_t>
return toCpp;
return nullptr;
}
- static void otherToCpp(PyObject * /* pyIn */, void *cppOut)
- {
- *reinterpret_cast<std::nullptr_t *>(cppOut) = nullptr;
- }
- static PythonToCppFunc isOtherConvertible(PyObject *pyIn)
- {
- if (pyIn == nullptr)
- return otherToCpp;
- return nullptr;
- }
};
-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 7f4494337..8e8324f5e 100644
--- a/sources/shiboken6/libshiboken/sbkcppstring.cpp
+++ b/sources/shiboken6/libshiboken/sbkcppstring.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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
#include "sbkcppstring.h"
#include "autodecref.h"
@@ -48,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 5878e8084..7ffe11c75 100644
--- a/sources/shiboken6/libshiboken/sbkcppstring.h
+++ b/sources/shiboken6/libshiboken/sbkcppstring.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 SBKCPPSTRING_H
#define SBKCPPSTRING_H
@@ -44,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
new file mode 100644
index 000000000..7637efa70
--- /dev/null
+++ b/sources/shiboken6/libshiboken/sbkcpptonumpy.cpp
@@ -0,0 +1,67 @@
+// 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
+
+// included by sbknumpy.cpp
+
+namespace Shiboken::Numpy {
+
+#ifdef HAVE_NUMPY
+
+// Helper to create a 1-dimensional numpy array
+template <class Type>
+static PyObject *_createArray1(Py_ssize_t size, int numpyType, const Type *data)
+{
+ const npy_intp dims[1] = {size};
+ PyObject *result = PyArray_EMPTY(1, dims, numpyType, 0);
+ auto *array = reinterpret_cast<PyArrayObject *>(result);
+ auto *rawTargetData = PyArray_DATA(array);
+ auto *targetData = reinterpret_cast<Type *>(rawTargetData);
+ std::copy(data, data + size, targetData);
+ return result;
+}
+
+PyObject *createByteArray1(Py_ssize_t size, const uint8_t *data)
+{
+ return _createArray1(size, NPY_BYTE, data);
+}
+
+PyObject *createDoubleArray1(Py_ssize_t size, const double *data)
+{
+ return _createArray1(size, NPY_DOUBLE, data);
+}
+
+PyObject *createFloatArray1(Py_ssize_t size, const float *data)
+{
+ return _createArray1(size, NPY_FLOAT, data);
+}
+
+PyObject *createIntArray1(Py_ssize_t size, const int *data)
+{
+ return _createArray1(size, NPY_INT, data);
+}
+
+#else // HAVE_NUMPY
+
+PyObject *createByteArray1(Py_ssize_t, const uint8_t *)
+{
+ return Py_None;
+}
+
+PyObject *createDoubleArray1(Py_ssize_t, const double *)
+{
+ Py_RETURN_NONE;
+}
+
+PyObject *createFloatArray1(Py_ssize_t, const float *)
+{
+ Py_RETURN_NONE;
+}
+
+PyObject *createIntArray1(Py_ssize_t, const int *)
+{
+ Py_RETURN_NONE;
+}
+
+#endif // !HAVE_NUMPY
+
+} //namespace Shiboken::Numpy
diff --git a/sources/shiboken6/libshiboken/sbkcpptonumpy.h b/sources/shiboken6/libshiboken/sbkcpptonumpy.h
new file mode 100644
index 000000000..8b9b0cfd2
--- /dev/null
+++ b/sources/shiboken6/libshiboken/sbkcpptonumpy.h
@@ -0,0 +1,41 @@
+// 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 SBKCPPTONUMPY_H
+#define SBKCPPTONUMPY_H
+
+#include <sbkpython.h>
+#include <shibokenmacros.h>
+
+#include <cstdint>
+
+namespace Shiboken::Numpy
+{
+
+/// Create a one-dimensional numpy array of type uint8/NPY_BYTE
+/// \param size Size
+/// \param data Data
+/// \return PyArrayObject
+LIBSHIBOKEN_API PyObject *createByteArray1(Py_ssize_t size, const uint8_t *data);
+
+/// Create a one-dimensional numpy array of type double/NPY_DOUBLE
+/// \param size Size
+/// \param data Data
+/// \return PyArrayObject
+LIBSHIBOKEN_API PyObject *createDoubleArray1(Py_ssize_t size, const double *data);
+
+/// Create a one-dimensional numpy array of type float/NPY_FLOAT
+/// \param size Size
+/// \param data Data
+/// \return PyArrayObject
+LIBSHIBOKEN_API PyObject *createFloatArray1(Py_ssize_t size, const float *data);
+
+/// Create a one-dimensional numpy array of type int/NPY_INT
+/// \param size Size
+/// \param data Data
+/// \return PyArrayObject
+LIBSHIBOKEN_API PyObject *createIntArray1(Py_ssize_t size, const int *data);
+
+} //namespace Shiboken::Numpy
+
+#endif // SBKCPPTONUMPY_H
diff --git a/sources/shiboken6/libshiboken/sbkenum.cpp b/sources/shiboken6/libshiboken/sbkenum.cpp
index 34ca1f155..d43756249 100644
--- a/sources/shiboken6/libshiboken/sbkenum.cpp
+++ b/sources/shiboken6/libshiboken/sbkenum.cpp
@@ -1,60 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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
#include "sbkenum.h"
-#include "sbkenum_p.h"
#include "sbkstring.h"
+#include "helper.h"
#include "sbkstaticstrings.h"
#include "sbkstaticstrings_p.h"
#include "sbkconverter.h"
#include "basewrapper.h"
#include "autodecref.h"
-#include "sbkpython.h"
-#include "signature.h"
+#include "sbktypefactory.h"
#include <cstring>
#include <vector>
+#include <sstream>
-#define SbkEnumType_Check(o) (Py_TYPE(Py_TYPE(o)) == SbkEnumType_TypeF())
-using enum_func = PyObject *(*)(PyObject *, PyObject *);
-
-static void cleanupEnumTypes();
+using namespace Shiboken;
extern "C"
{
@@ -64,701 +25,431 @@ struct SbkEnumType
PyTypeObject type;
};
-struct SbkEnumObject
-{
- PyObject_HEAD
- long ob_value;
- PyObject *ob_name;
-};
-
-static PyTypeObject *SbkEnum_TypeF(); // forward
-
-static PyObject *SbkEnumObject_repr(PyObject *self)
+// Initialization
+static bool _init_enum()
{
- const SbkEnumObject *enumObj = reinterpret_cast<SbkEnumObject *>(self);
- auto name = Py_TYPE(self)->tp_name;
- if (enumObj->ob_name) {
- return Shiboken::String::fromFormat("%s.%s", name,
- PyBytes_AS_STRING(enumObj->ob_name));
+ AutoDecRef shibo(PyImport_ImportModule("shiboken6.Shiboken"));
+ return !shibo.isNull();
+}
+
+static PyObject *PyEnumModule{};
+static PyObject *PyEnumMeta{};
+static PyObject *PyEnum{};
+static PyObject *PyIntEnum{};
+static PyObject *PyFlag{};
+static PyObject *PyIntFlag{};
+static PyObject *PyFlag_KEEP{};
+
+bool PyEnumMeta_Check(PyObject *ob)
+{
+ return Py_TYPE(ob) == reinterpret_cast<PyTypeObject *>(PyEnumMeta);
+}
+
+PyTypeObject *getPyEnumMeta()
+{
+ if (PyEnumMeta)
+ return reinterpret_cast<PyTypeObject *>(PyEnumMeta);
+
+ static auto *mod = PyImport_ImportModule("enum");
+ if (mod) {
+ PyEnumModule = mod;
+ PyEnumMeta = PyObject_GetAttrString(mod, "EnumMeta");
+ if (PyEnumMeta && PyType_Check(PyEnumMeta))
+ PyEnum = PyObject_GetAttrString(mod, "Enum");
+ if (PyEnum && PyType_Check(PyEnum))
+ PyIntEnum = PyObject_GetAttrString(mod, "IntEnum");
+ if (PyIntEnum && PyType_Check(PyIntEnum))
+ PyFlag = PyObject_GetAttrString(mod, "Flag");
+ if (PyFlag && PyType_Check(PyFlag))
+ PyIntFlag = PyObject_GetAttrString(mod, "IntFlag");
+ if (PyIntFlag && PyType_Check(PyIntFlag)) {
+ // KEEP is defined from Python 3.11 on.
+ PyFlag_KEEP = PyObject_GetAttrString(mod, "KEEP");
+ PyErr_Clear();
+ return reinterpret_cast<PyTypeObject *>(PyEnumMeta);
+ }
}
- return Shiboken::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;
+ Py_FatalError("Python module 'enum' not found");
+ return nullptr;
}
-static PyObject *SbkEnum_tp_new(PyTypeObject *type, PyObject *args, PyObject *)
+void init_enum()
{
- 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;
+ static bool isInitialized = false;
+ if (isInitialized)
+ return;
+ 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 *option = PySys_GetObject("pyside6_option_python_enum");
+ if (!option || !PyLong_Check(option)) {
+ PyErr_Clear();
+ option = PyLong_FromLong(1);
}
-
- SbkEnumObject *self = PyObject_New(SbkEnumObject, type);
- if (!self)
- return nullptr;
- self->ob_value = itemValue;
- Shiboken::AutoDecRef item(Shiboken::Enum::getEnumItemFromValue(type, itemValue));
- self->ob_name = item.object() ? SbkEnumObject_name(item, nullptr) : nullptr;
- return reinterpret_cast<PyObject *>(self);
+ int ignoreOver{};
+ Enum::enumOption = PyLong_AsLongAndOverflow(option, &ignoreOver);
+ getPyEnumMeta();
+ isInitialized = true;
}
-static const char *SbkEnum_SignatureStrings[] = {
- "Shiboken.Enum(self,itemValue:int=0)",
- nullptr}; // Sentinel
-
-void enum_object_dealloc(PyObject *ob)
+// PYSIDE-1735: Helper function supporting QEnum
+int enumIsFlag(PyObject *ob_type)
{
- 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;
- }
- }
+ init_enum();
- // Without an enum we are not supporting the operation
- if (!(enumA || enumB)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
+ auto *metatype = Py_TYPE(ob_type);
+ if (metatype != reinterpret_cast<PyTypeObject *>(PyEnumMeta))
+ return -1;
+ auto *mro = reinterpret_cast<PyTypeObject *>(ob_type)->tp_mro;
+ 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;
}
-
- 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);
+ return 0;
}
-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);
-}
+///////////////////////////////////////////////////////////////////////
+//
+// Support for Missing Values
+// ==========================
+//
+// Qt enums sometimes use undefined values in enums.
+// The enum module handles this by the option "KEEP" for Flag and
+// IntFlag. The handling of missing enum values is still strict.
+//
+// We changed that (also for compatibility with some competitor)
+// and provide a `_missing_` function that creates the missing value.
+//
+// The idea:
+// ---------
+// We cannot modify the already created class.
+// But we can create a one-element class with the new value and
+// pretend that this is the already existing class.
+//
+// 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 *enum_multiply(PyObject *self, PyObject *v)
+static PyObject *missing_func(PyObject * /* self */ , PyObject *args)
{
- return _enum_op(PyNumber_Multiply, self, v);
-}
+ // In order to relax matters to be more compatible with C++, we need
+ // to create a pseudo-member with that value.
+ static auto *const _sbk_missing = Shiboken::String::createStaticString("_sbk_missing_");
+ static auto *const _name = Shiboken::String::createStaticString("__name__");
+ static auto *const _mro = Shiboken::String::createStaticString("__mro__");
+ static auto *const _class = Shiboken::String::createStaticString("__class__");
-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;
- }
+ PyObject *klass{};
+ PyObject *value{};
+ if (!PyArg_UnpackTuple(args, "missing", 2, 2, &klass, &value))
+ Py_RETURN_NONE;
+ if (!PyLong_Check(value))
+ Py_RETURN_NONE;
+ auto *type = reinterpret_cast<PyTypeObject *>(klass);
+ AutoDecRef tpDict(PepType_GetDict(type));
+ auto *sbk_missing = PyDict_GetItem(tpDict.object(), _sbk_missing);
+ if (!sbk_missing) {
+ sbk_missing = PyDict_New();
+ PyDict_SetItem(tpDict.object(), _sbk_missing, sbk_missing);
}
-
- // Without an enum we are not supporting the operation
- if (!(enumA || enumB)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
+ // See if the value is already in the dict.
+ AutoDecRef val_str(PyObject_CallMethod(value, "__str__", nullptr));
+ auto *ret = PyDict_GetItem(sbk_missing, val_str);
+ if (ret) {
+ Py_INCREF(ret);
+ return ret;
}
- 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
+ // No, we must create a new object and insert it into the dict.
+ AutoDecRef cls_name(PyObject_GetAttr(klass, _name));
+ AutoDecRef mro(PyObject_GetAttr(klass, _mro));
+ auto *baseClass(PyTuple_GetItem(mro, 1));
+ AutoDecRef param(PyDict_New());
+ PyDict_SetItem(param, val_str, value);
+ AutoDecRef fake(PyObject_CallFunctionObjArgs(baseClass, cls_name.object(), param.object(),
+ nullptr));
+ ret = PyObject_GetAttr(fake, val_str);
+ PyDict_SetItem(sbk_missing, val_str, ret);
+ // Now the real fake: Pretend that the type is our original type!
+ PyObject_SetAttr(ret, _class, klass);
+ return ret;
+}
+
+static struct PyMethodDef dummy_methods[] = {
+ {"_missing_", reinterpret_cast<PyCFunction>(missing_func), METH_VARARGS|METH_STATIC, nullptr},
+ {nullptr, nullptr, 0, nullptr}
};
-static void SbkEnumTypeDealloc(PyObject *pyObj);
-static PyTypeObject *SbkEnumTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwds);
-
-static PyType_Slot SbkEnumType_Type_slots[] = {
- {Py_tp_dealloc, reinterpret_cast<void *>(SbkEnumTypeDealloc)},
+static PyType_Slot dummy_slots[] = {
{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_methods, reinterpret_cast<void *>(dummy_methods)},
{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",
+static PyType_Spec dummy_spec = {
+ "1:builtins.EnumType",
+ 0,
0,
- 0, // sizeof(PyMemberDef), not for PyPy without a __len__ defined
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
- SbkEnumType_Type_slots,
+ dummy_slots,
};
-PyTypeObject *SbkEnumType_TypeF(void)
+static PyObject *create_missing_func(PyObject *klass)
{
- static auto *type = SbkType_FromSpec(&SbkEnumType_Type_spec);
- return type;
-}
-
-void SbkEnumTypeDealloc(PyObject *pyObj)
-{
- auto *enumType = reinterpret_cast<SbkEnumType *>(pyObj);
- auto *setp = PepType_SETP(enumType);
-
- PyObject_GC_UnTrack(pyObj);
-#ifndef Py_LIMITED_API
- Py_TRASHCAN_SAFE_BEGIN(pyObj);
-#endif
- if (setp->converter)
- Shiboken::Conversions::deleteConverter(setp->converter);
- PepType_SETP_delete(enumType);
-#ifndef Py_LIMITED_API
- Py_TRASHCAN_SAFE_END(pyObj);
-#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)
-{
- return PepType_Type_tp_new(metatype, args, kwds);
+ // When creating the class, memorize it in the missing function by
+ // a partial function argument.
+ static auto *const type = SbkType_FromSpec(&dummy_spec);
+ 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 partial = Pep_GetPartialFunction();
+ return PyObject_CallFunctionObjArgs(partial, func, klass, nullptr);
}
+//
+////////////////////////////////////////////////////////////////////////
} // extern "C"
-///////////////////////////////////////////////////////////////
-//
-// PYSIDE-15: Pickling Support for Qt Enum objects
-// This works very well and fixes the issue.
-//
-extern "C" {
+namespace Shiboken::Enum {
-static PyObject *enum_unpickler = nullptr;
+int enumOption{};
-// Pickling: reduce the Qt Enum object
-static PyObject *enum___reduce__(PyObject *obj)
+bool check(PyObject *pyObj)
{
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 {
+ static PyTypeObject *meta = getPyEnumMeta();
+ return Py_TYPE(Py_TYPE(pyObj)) == reinterpret_cast<PyTypeObject *>(meta);
+}
-// Unpickling: rebuild the Qt Enum object
-PyObject *unpickleEnum(PyObject *enum_class_name, PyObject *value)
+PyObject *getEnumItemFromValue(PyTypeObject *enumType, EnumValueType itemValue)
{
- Shiboken::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",
- Shiboken::String::toCString(top_name));
+ init_enum();
+
+ auto *obEnumType = reinterpret_cast<PyObject *>(enumType);
+ AutoDecRef val2members(PyObject_GetAttrString(obEnumType, "_value2member_map_"));
+ if (val2members.isNull()) {
+ PyErr_Clear();
return nullptr;
}
- Shiboken::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",
- Shiboken::String::toCString(enum_class_name));
- return nullptr;
- }
- cur_thing.reset(thing);
- }
- PyObject *klass = cur_thing;
- return PyObject_CallFunctionObjArgs(klass, value, nullptr);
-}
-
-} // namespace Enum
-} // namespace Shiboken
-
-extern "C" {
-
-// Initialization
-static bool _init_enum()
-{
- Shiboken::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;
+ AutoDecRef ob_value(PyLong_FromLongLong(itemValue));
+ auto *result = PyDict_GetItem(val2members, ob_value);
+ Py_XINCREF(result);
+ return result;
}
-void init_enum()
+PyObject *newItem(PyTypeObject *enumType, EnumValueType itemValue,
+ const char *itemName)
{
- static bool is_initialized = false;
- if (!(is_initialized || enum_unpickler || _init_enum()))
- Py_FatalError("could not load enum pickling helper function");
- Py_AtExit(cleanupEnumTypes);
- is_initialized = true;
-}
-
-static PyMethodDef SbkEnumObject_Methods[] = {
- {"__reduce__", reinterpret_cast<PyCFunction>(enum___reduce__),
- METH_NOARGS, nullptr},
- {nullptr, nullptr, 0, nullptr} // Sentinel
-};
-
-} // extern "C"
+ init_enum();
-//
-///////////////////////////////////////////////////////////////
+ auto *obEnumType = reinterpret_cast<PyObject *>(enumType);
+ if (!itemName)
+ return PyObject_CallFunction(obEnumType, "L", itemValue);
-namespace Shiboken {
+ 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;
+}
-class DeclaredEnumTypes
+EnumValueType getValue(PyObject *enumItem)
{
-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;
-};
+ init_enum();
-namespace Enum {
+ assert(Enum::check(enumItem));
-bool check(PyObject *pyObj)
-{
- return Py_TYPE(Py_TYPE(pyObj)) == SbkEnumType_TypeF();
+ AutoDecRef pyValue(PyObject_GetAttrString(enumItem, "value"));
+ return PyLong_AsLongLong(pyValue);
}
-PyObject *getEnumItemFromValue(PyTypeObject *enumType, long itemValue)
+void setTypeConverter(PyTypeObject *type, SbkConverter *converter)
{
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- PyObject *values = PyDict_GetItem(enumType->tp_dict, Shiboken::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;
+ auto *enumType = reinterpret_cast<SbkEnumType *>(type);
+ PepType_SETP(enumType)->converter = converter;
}
-static PyTypeObject *createEnum(const char *fullName, const char *cppName,
- PyTypeObject *flagsType)
+static PyTypeObject *createEnumForPython(PyObject *scopeOrModule,
+ const char *fullName,
+ PyObject *pyEnumItems)
{
- PyTypeObject *enumType = newTypeWithName(fullName, cppName, flagsType);
- if (PyType_Ready(enumType) < 0) {
- Py_XDECREF(enumType);
- return nullptr;
- }
- return enumType;
-}
+ const char *colon = strchr(fullName, ':');
+ assert(colon);
+ int package_level = atoi(fullName);
+ const char *mod = colon + 1;
-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;
+ const char *qual = mod;
+ for (int idx = package_level; idx > 0; --idx) {
+ const char *dot = strchr(qual, '.');
+ if (!dot)
+ break;
+ qual = dot + 1;
}
- if (flagsType && PyModule_AddObject(module, PepType_GetNameStr(flagsType),
- reinterpret_cast<PyObject *>(flagsType)) < 0) {
- Py_DECREF(enumType);
- return nullptr;
+ 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));
+
+ 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.
+ auto type = reinterpret_cast<PyTypeObject *>(scopeOrModule);
+ auto *sotp = PepType_SOTP(type);
+ if (!sotp->enumFlagsDict)
+ initEnumFlagsDict(type);
+ enumName = PyDict_GetItem(sotp->enumTypeDict, name);
}
- 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;
+ SBK_UNUSED(getPyEnumMeta()); // enforce PyEnumModule creation
+ assert(PyEnumModule != nullptr);
+ AutoDecRef PyEnumType(PyObject_GetAttr(PyEnumModule, enumName));
+ assert(PyEnumType.object());
+ bool isFlag = PyObject_IsSubclass(PyEnumType, PyFlag);
+
+ // See if we should use the Int versions of the types, again
+ bool useIntInheritance = Enum::enumOption & Enum::ENOPT_INHERIT_INT;
+ if (useIntInheritance) {
+ auto *surrogate = PyObject_IsSubclass(PyEnumType, PyFlag) ? PyIntFlag : PyIntEnum;
+ Py_INCREF(surrogate);
+ PyEnumType.reset(surrogate);
}
- 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, long itemValue)
-{
- PyObject *enumItem = newItem(enumType, itemValue, itemName);
- if (PyDict_SetItemString(enumType->tp_dict, itemName, enumItem) < 0) {
- Py_DECREF(enumItem);
+ // Walk the enumItemStrings and create a Python enum type.
+ auto *pyName = name.object();
+
+ // 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, pyEnumItems));
+ AutoDecRef callDict(PyDict_New());
+ static PyObject *boundary = String::createStaticString("boundary");
+ if (PyFlag_KEEP)
+ PyDict_SetItem(callDict, boundary, PyFlag_KEEP);
+ auto *obNewType = PyObject_Call(PyEnumType, callArgs, callDict);
+ if (!obNewType || PyObject_SetAttr(scopeOrModule, pyName, obNewType) < 0)
return nullptr;
- }
- return enumItem;
-}
-
-bool createGlobalEnumItem(PyTypeObject *enumType, PyObject *module, const char *itemName, long itemValue)
-{
- PyObject *enumItem = createEnumItem(enumType, itemName, itemValue);
- if (!enumItem)
- return false;
- int ok = PyModule_AddObject(module, itemName, enumItem);
- Py_DECREF(enumItem);
- return ok >= 0;
-}
-
-bool createScopedEnumItem(PyTypeObject *enumType, PyTypeObject *scope,
- const char *itemName, long itemValue)
-{
- PyObject *enumItem = createEnumItem(enumType, itemName, itemValue);
- if (!enumItem)
- return false;
- int ok = PyDict_SetItemString(scope->tp_dict, itemName, enumItem);
- Py_DECREF(enumItem);
- return ok >= 0;
-}
-PyObject *
-newItem(PyTypeObject *enumType, long 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;
+ // For compatibility with Qt enums, provide a permissive missing method for (Int)?Enum.
+ if (!isFlag) {
+ bool supportMissing = !(Enum::enumOption & Enum::ENOPT_NO_MISSING);
+ if (supportMissing) {
+ AutoDecRef enum_missing(create_missing_func(obNewType));
+ PyObject_SetAttrString(obNewType, "_missing_", enum_missing);
+ }
}
- 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, Shiboken::PyName::values());
- if (values == nullptr) {
- if (PyErr_Occurred())
- return nullptr;
- Shiboken::AutoDecRef new_values(values = PyDict_New());
- if (values == nullptr)
- return nullptr;
- if (PyDict_SetItem(dict, Shiboken::PyName::values(), values) < 0)
- return nullptr;
+ auto *newType = reinterpret_cast<PyTypeObject *>(obNewType);
+ 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);
+ 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;
+ }
}
- PyDict_SetItemString(values, itemName, reinterpret_cast<PyObject *>(enumObj));
}
- return reinterpret_cast<PyObject *>(enumObj);
+ return newType;
}
-} // 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()
+template <typename IntT>
+static PyObject *toPyObject(IntT v)
{
- static auto type = SbkType_FromSpec(&SbkNewEnum_spec);
- return type;
+ 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);
+}
+
+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);
}
-namespace Shiboken { namespace Enum {
+// Now we have to concretize these functions explicitly,
+// otherwise templates will not work across modules.
-static void
-copyNumberMethods(PyTypeObject *flagsType,
- PyType_Slot number_slots[],
- int *pidx)
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int64_t enumValues[])
{
- 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;
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
}
-PyTypeObject *
-newTypeWithName(const char *name,
- const char *cppName,
- PyTypeObject *numbers_fromFlag)
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint64_t enumValues[])
{
- // 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;
- Shiboken::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;
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
}
-const char *getCppName(PyTypeObject *enumType)
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int32_t enumValues[])
{
- assert(Py_TYPE(enumType) == SbkEnumType_TypeF());
- auto *type = reinterpret_cast<SbkEnumType *>(enumType);
- auto *setp = PepType_SETP(type);
- return setp->cppName;
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
}
-long int getValue(PyObject *enumItem)
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint32_t enumValues[])
{
- assert(Shiboken::Enum::check(enumItem));
- return reinterpret_cast<SbkEnumObject *>(enumItem)->ob_value;
-}
-
-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;
- }
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
}
-} // namespace Enum
-
-DeclaredEnumTypes &DeclaredEnumTypes::instance()
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int16_t enumValues[])
{
- static DeclaredEnumTypes me;
- return me;
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
}
-DeclaredEnumTypes::DeclaredEnumTypes() = default;
-
-DeclaredEnumTypes::~DeclaredEnumTypes()
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint16_t enumValues[])
{
- cleanup();
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
}
-void DeclaredEnumTypes::cleanup()
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const int8_t enumValues[])
{
- for (const auto &e : m_enumTypes) {
- std::free(e.name);
- Py_DECREF(e.type);
- }
- m_enumTypes.clear();
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
}
-} // namespace Shiboken
-
-static void cleanupEnumTypes()
+PyTypeObject *createPythonEnum(PyObject *module,
+ const char *fullName, const char *enumItemStrings[], const uint8_t enumValues[])
{
- Shiboken::DeclaredEnumTypes::instance().cleanup();
+ return createPythonEnumHelper(module, fullName, enumItemStrings, enumValues);
}
+} // namespace Shiboken::Enum
diff --git a/sources/shiboken6/libshiboken/sbkenum.h b/sources/shiboken6/libshiboken/sbkenum.h
index 4ec79b923..e19ca4b4c 100644
--- a/sources/shiboken6/libshiboken/sbkenum.h
+++ b/sources/shiboken6/libshiboken/sbkenum.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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_H
#define SBKENUM_H
@@ -46,77 +10,93 @@
extern "C"
{
+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[])
{
- 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, long 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, long itemValue);
-
- LIBSHIBOKEN_API PyObject *newItem(PyTypeObject *enumType, long 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 long getValue(PyObject *enumItem);
- LIBSHIBOKEN_API PyObject *getEnumItemFromValue(PyTypeObject *enumType, long 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 895c1ddcb..000000000
--- a/sources/shiboken6/libshiboken/sbkenum_p.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef SBKENUM_P_H
-#define SBKENUM_P_H
-
-#include "sbkpython.h"
-#include "shibokenmacros.h"
-
-struct SbkEnumTypePrivate
-{
- SbkConverter *converter;
- const char *cppName;
-};
-
-#endif // SKB_PYENUM_P_H
diff --git a/sources/shiboken6/libshiboken/sbkerrors.cpp b/sources/shiboken6/libshiboken/sbkerrors.cpp
new file mode 100644
index 000000000..84c080f8d
--- /dev/null
+++ b/sources/shiboken6/libshiboken/sbkerrors.cpp
@@ -0,0 +1,215 @@
+// 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
+
+#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
+{
+
+void setInstantiateAbstractClass(const char *name)
+{
+ PyErr_Format(PyExc_NotImplementedError,
+ "'%s' represents a C++ abstract class and cannot be instantiated", name);
+}
+
+void setInstantiateAbstractClassDisabledWrapper(const char *name)
+{
+ PyErr_Format(PyExc_NotImplementedError,
+ "Abstract class '%s' cannot be instantiated since the wrapper has been disabled.",
+ name);
+}
+
+void setInvalidTypeDeletion(const char *name)
+{
+ PyErr_Format(PyExc_TypeError, "'%s' may not be deleted", name);
+}
+
+void setOperatorNotImplemented()
+{
+ PyErr_SetString(PyExc_NotImplementedError, "operator not implemented.");
+}
+
+void setPureVirtualMethodError(const char *name)
+{
+ PyErr_Format(PyExc_NotImplementedError, "pure virtual method '%s' not implemented.", name);
+}
+
+void setPrivateMethod(const char *name)
+{
+ PyErr_Format(PyExc_TypeError, "%s is a private method.\", ", name);
+}
+
+void setReverseOperatorNotImplemented()
+{
+ PyErr_SetString(PyExc_NotImplementedError, "reverse operator not implemented.");
+}
+
+void setSequenceTypeError(const char *expectedType)
+{
+ PyErr_Format(PyExc_TypeError,
+ "attributed value with wrong type, '%s' or other convertible type expected",
+ expectedType);
+}
+
+void setSetterTypeError(const char *name, const char *expectedType)
+{
+ PyErr_Format(PyExc_TypeError,
+ "wrong type attributed to '%s', '%s' or convertible type expected",
+ name, expectedType);
+}
+
+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
+{
+void warnInvalidReturnValue(const char *className, const char *functionName,
+ const char *expectedType, const char *actualType)
+{
+ Shiboken::warning(PyExc_RuntimeWarning, 2,
+ "Invalid return value in function '%s.%s', expected %s, got %s.",
+ className, functionName, expectedType, actualType);
+}
+
+void warnDeprecated(const char *functionName)
+{
+ Shiboken::warning(PyExc_DeprecationWarning, 1,
+ "Function: '%s' is marked as deprecated, please check "
+ "the documentation for more information.",
+ functionName);
+}
+
+void warnDeprecated(const char *className, const char *functionName)
+{
+ Shiboken::warning(PyExc_DeprecationWarning, 1,
+ "Function: '%s.%s' is marked as deprecated, please check "
+ "the documentation for more information.",
+ className, functionName);
+}
+
+void warnDeprecatedEnum(const char *enumName)
+{
+ Shiboken::warning(PyExc_DeprecationWarning, 1,
+ "Enum: '%s' is marked as deprecated, please check "
+ "the documentation for more information.",
+ enumName);
+}
+
+void warnDeprecatedEnumValue(const char *enumName, const char *valueName)
+{
+ Shiboken::warning(PyExc_DeprecationWarning, 1,
+ "Enum value '%s.%s' is marked as deprecated, please check "
+ "the documentation for more information.",
+ enumName, valueName);
+
+}
+
+} // namespace Warnings
+} // namespace Shiboken
diff --git a/sources/shiboken6/libshiboken/sbkerrors.h b/sources/shiboken6/libshiboken/sbkerrors.h
new file mode 100644
index 000000000..18ce701e7
--- /dev/null
+++ b/sources/shiboken6/libshiboken/sbkerrors.h
@@ -0,0 +1,78 @@
+// 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 SBKERRORS_H
+#define SBKERRORS_H
+
+#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
+{
+
+LIBSHIBOKEN_API void setInstantiateAbstractClass(const char *name);
+LIBSHIBOKEN_API void setInstantiateAbstractClassDisabledWrapper(const char *name);
+LIBSHIBOKEN_API void setInvalidTypeDeletion(const char *name);
+LIBSHIBOKEN_API void setOperatorNotImplemented();
+LIBSHIBOKEN_API void setPureVirtualMethodError(const char *name);
+LIBSHIBOKEN_API void setPrivateMethod(const char *name);
+LIBSHIBOKEN_API void setReverseOperatorNotImplemented();
+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
+{
+/// Warn about invalid return value of overwritten virtual
+LIBSHIBOKEN_API void warnInvalidReturnValue(const char *className, const char *functionName,
+ const char *expectedType, const char *actualType);
+LIBSHIBOKEN_API void warnDeprecated(const char *functionName);
+LIBSHIBOKEN_API void warnDeprecated(const char *className, const char *functionName);
+LIBSHIBOKEN_API void warnDeprecatedEnum(const char *enumName);
+LIBSHIBOKEN_API void warnDeprecatedEnumValue(const char *enumName, const char *valueName);
+} // namespace Warnings
+
+} // namespace Shiboken
+
+#endif // SBKERRORS_H
diff --git a/sources/shiboken6/libshiboken/sbkfeature_base.cpp b/sources/shiboken6/libshiboken/sbkfeature_base.cpp
index 6b2037ecd..971835c53 100644
--- a/sources/shiboken6/libshiboken/sbkfeature_base.cpp
+++ b/sources/shiboken6/libshiboken/sbkfeature_base.cpp
@@ -1,50 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 "basewrapper.h"
#include "basewrapper_p.h"
#include "autodecref.h"
+#include "pep384ext.h"
+#include "sbkenum.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
#include "sbkstaticstrings_p.h"
#include "signature.h"
#include "sbkfeature_base.h"
+#include "gilstate.h"
+
+#include <cctype>
using namespace Shiboken;
@@ -53,64 +22,304 @@ extern "C"
////////////////////////////////////////////////////////////////////////////
//
-// getFeatureSelectId
+// Minimal __feature__ support in Shiboken
//
-// This function is needed here already for signature handling.
-// Maybe the same function from feature_select.cpp will be replaced.
+int currentSelectId(PyTypeObject *type)
+{
+ AutoDecRef tpDict(PepType_GetDict(type));
+ PyObject *PyId = PyObject_GetAttr(tpDict.object(), PyName::select_id());
+ if (PyId == nullptr) {
+ PyErr_Clear();
+ return 0x00;
+ }
+ int sel = PyLong_AsLong(PyId);
+ Py_DECREF(PyId);
+ return sel;
+}
+
+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;
+}
//
+////////////////////////////////////////////////////////////////////////////
+
+// This useful function is for debugging
+void disassembleFrame(const char *marker)
+{
+ Shiboken::GilState gil;
+ PyObject *error_type, *error_value, *error_traceback;
+ PyErr_Fetch(&error_type, &error_value, &error_traceback);
+ 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());
+ 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);
+}
-static PyObject *cached_globals = nullptr;
-static PyObject *last_select_id = nullptr;
+// Python 3.13
+static int const LOAD_ATTR_313 = 82;
+static int const CALL_313 = 53;
+static int const PUSH_NULL_313 = 34;
+// Python 3.12
+static int const CALL_312 = 171;
+// Python 3.11
+static int const PRECALL = 166;
+// we have "big instructions" with gaps after them
+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_312 = 106;
+// NoGil (how long will this exist in this form?)
+static int const LOAD_METHOD_NOGIL = 55;
+static int const CALL_METHOD_NOGIL = 72;
-PyObject *getFeatureSelectId()
+static bool currentOpcode_Is_CallMethNoArgs()
{
- static PyObject *undef = PyLong_FromLong(-1);
- static PyObject *feature_dict = GetFeatureDict();
- // these things are all borrowed
- PyObject *globals = PyEval_GetGlobals();
- if (globals == nullptr
- || globals == cached_globals)
- return last_select_id;
+ static auto number = _PepRuntimeVersion();
+ static int LOAD_ATTR = number < 0x030D00 ? LOAD_ATTR_312 : LOAD_ATTR_313;
+ static int CALL = number < 0x030D00 ? CALL_312 : CALL_313;
+ // 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_LIMITED_API && !defined(PYPY_VERSION)
+ auto *f_code = PyFrame_GetCode(frame);
+#else
+ static PyObject *const _f_code = Shiboken::String::createStaticString("f_code");
+ AutoDecRef dec_f_code(PyObject_GetAttr(reinterpret_cast<PyObject *>(frame), _f_code));
+ auto *f_code = dec_f_code.object();
+#endif
+#if PY_VERSION_HEX >= 0x030B0000 && !Py_LIMITED_API
+ AutoDecRef dec_co_code(PyCode_GetCode(f_code));
+ Py_ssize_t f_lasti = PyFrame_GetLasti(frame);
+#else
+ static PyObject *const _f_lasti = Shiboken::String::createStaticString("f_lasti");
+ static PyObject *const _co_code = Shiboken::String::createStaticString("co_code");
+ AutoDecRef dec_co_code(PyObject_GetAttr(reinterpret_cast<PyObject *>(f_code), _co_code));
+ AutoDecRef dec_f_lasti(PyObject_GetAttr(reinterpret_cast<PyObject *>(frame), _f_lasti));
+ Py_ssize_t f_lasti = PyLong_AsSsize_t(dec_f_lasti);
+#endif
+ Py_ssize_t code_len;
+ 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];
+ if (number < 0x030B00)
+ return opcode1 == LOAD_METHOD && opcode2 == CALL_METHOD && oparg2 == 0;
- PyObject *modname = PyDict_GetItem(globals, PyMagicName::name());
- if (modname == nullptr)
- return last_select_id;
+ 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_312)
+ f_lasti += LOAD_ATTR_GAP_311;
+ else
+ return false;
- PyObject *select_id = PyDict_GetItem(feature_dict, modname);
- if (select_id == nullptr
- || !PyLong_Check(select_id) // int/long cheating
- || select_id == undef)
- return last_select_id;
+ opcode2 = co_code[f_lasti + 2];
+ oparg2 = co_code[f_lasti + 3];
- cached_globals = globals;
- last_select_id = select_id;
- assert(PyLong_AsSsize_t(select_id) >= 0);
- return select_id;
+ 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_ATTR)
+ f_lasti += LOAD_ATTR_GAP;
+ else
+ return false;
+
+ if (number >= 0x030D00) {
+ int opcode3 = co_code[f_lasti + 2];
+ if (opcode3 == PUSH_NULL_313)
+ f_lasti += 2;
+ }
+ opcode2 = co_code[f_lasti + 2];
+ oparg2 = co_code[f_lasti + 3];
+
+ return opcode2 == CALL && oparg2 == 0;
}
-int currentSelectId(PyTypeObject *type)
+void initEnumFlagsDict(PyTypeObject *type)
{
- int sel = SbkObjectType_GetReserved(type);
- // This could theoretically be -1 if used too early.
- assert(sel >= 0);
- return sel;
+ // We create a dict for all flag enums that holds the original C++ name
+ // and a dict that gives every enum/flag type name.
+ static PyObject *const split = Shiboken::String::createStaticString("split");
+ static PyObject *const colon = Shiboken::String::createStaticString(":");
+ auto sotp = PepType_SOTP(type);
+ auto **enumFlagInfo = sotp->enumFlagInfo;
+ auto *dict = PyDict_New();
+ auto *typeDict = PyDict_New();
+ for (; *enumFlagInfo; ++enumFlagInfo) {
+ AutoDecRef line(PyUnicode_FromString(*enumFlagInfo));
+ AutoDecRef parts(PyObject_CallMethodObjArgs(line, split, colon, nullptr));
+ auto *name = PyList_GetItem(parts, 0);
+ if (PyList_Size(parts) == 3) {
+ auto *key = PyList_GetItem(parts, 2);
+ auto *value = name;
+ PyDict_SetItem(dict, key, value);
+ }
+ auto *typeName = PyList_GetItem(parts, 1);
+ PyDict_SetItem(typeDict, name, typeName);
+ }
+ sotp->enumFlagsDict = dict;
+ sotp->enumTypeDict = typeDict;
}
-void initFeatureShibokenPart()
+static PyObject *replaceNoArgWithZero(PyObject *callable)
{
- static PyObject *no_sel = PyLong_FromLong(0);
- last_select_id = no_sel;
- // Reset the cache. This is called at any "from __feature__ import".
- cached_globals = nullptr;
+ static auto *partial = Pep_GetPartialFunction();
+ static auto *zero = PyLong_FromLong(0);
+ return PyObject_CallFunctionObjArgs(partial, callable, zero, nullptr);
}
-static SelectableFeatureHook SelectFeatureSet = nullptr;
-
-SelectableFeatureHook initSelectableFeature(SelectableFeatureHook func)
+static PyObject *lookupUnqualifiedOrOldEnum(PyTypeObject *type, PyObject *name)
{
- auto ret = SelectFeatureSet;
- SelectFeatureSet = func;
- return ret;
+ // 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)
@@ -121,22 +330,64 @@ 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 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();
+
if (SelectFeatureSet != nullptr)
- type->tp_dict = SelectFeatureSet(type);
- return type_getattro(reinterpret_cast<PyObject *>(type), name);
+ SelectFeatureSet(type);
+ auto *ret = type_getattro(reinterpret_cast<PyObject *>(type), name);
+
+ // PYSIDE-1735: Be forgiving with strict enums and fetch the enum, silently.
+ // 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 forgiveness:
+ //
+ // The duplication of enum values into the enclosing scope, allowing to write
+ // Qt.AlignLeft instead of Qt.Alignment.AlignLeft, is still implemented but
+ // no longer advertized in PYI files or line completion.
+
+ if (ret && Py_TYPE(ret) == EnumMeta && currentOpcode_Is_CallMethNoArgs()) {
+ bool useZeroDefault = !(Enum::enumOption & Enum::ENOPT_NO_ZERODEFAULT);
+ if (useZeroDefault) {
+ // We provide a zero argument for compatibility if it is a call with no args.
+ auto *hold = replaceNoArgWithZero(ret);
+ Py_DECREF(ret);
+ ret = hold;
+ }
+ }
+
+ if (!ret && name != ignAttr1 && name != ignAttr2) {
+ PyObject *error_type{}, *error_value{}, *error_traceback{};
+ PyErr_Fetch(&error_type, &error_value, &error_traceback);
+ 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);
+ }
+ }
+ return ret;
}
-PyObject *Sbk_TypeGet___dict__(PyTypeObject *type, void *context)
+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)
- dict = SelectFeatureSet(type);
+ if (SelectFeatureSet != nullptr) {
+ SelectFeatureSet(type);
+ tpDict.reset(PepType_GetDict(type));
+ dict = tpDict.object();
+ }
return PyDictProxy_New(dict);
}
@@ -147,7 +398,7 @@ PyObject *SbkObject_GenericGetAttr(PyObject *obj, PyObject *name)
{
auto type = Py_TYPE(obj);
if (SelectFeatureSet != nullptr)
- type->tp_dict = SelectFeatureSet(type);
+ SelectFeatureSet(type);
return PyObject_GenericGetAttr(obj, name);
}
@@ -155,21 +406,10 @@ int SbkObject_GenericSetAttr(PyObject *obj, PyObject *name, PyObject *value)
{
auto type = Py_TYPE(obj);
if (SelectFeatureSet != nullptr)
- type->tp_dict = SelectFeatureSet(type);
+ SelectFeatureSet(type);
return PyObject_GenericSetAttr(obj, name, value);
}
-// Caching the select Id.
-int SbkObjectType_GetReserved(PyTypeObject *type)
-{
- return PepType_SOTP(type)->pyside_reserved_bits;
-}
-
-void SbkObjectType_SetReserved(PyTypeObject *type, int value)
-{
- PepType_SOTP(type)->pyside_reserved_bits = value;
-}
-
const char **SbkObjectType_GetPropertyStrings(PyTypeObject *type)
{
return PepType_SOTP(type)->propertyStrings;
@@ -180,11 +420,16 @@ void SbkObjectType_SetPropertyStrings(PyTypeObject *type, const char **strings)
PepType_SOTP(type)->propertyStrings = strings;
}
+void SbkObjectType_SetEnumFlagInfo(PyTypeObject *type, const char **strings)
+{
+ PepType_SOTP(type)->enumFlagInfo = strings;
+}
+
// PYSIDE-1626: Enforcing a context switch without further action.
void SbkObjectType_UpdateFeature(PyTypeObject *type)
{
if (SelectFeatureSet != nullptr)
- type->tp_dict = SelectFeatureSet(type);
+ SelectFeatureSet(type);
}
} // extern "C"
diff --git a/sources/shiboken6/libshiboken/sbkfeature_base.h b/sources/shiboken6/libshiboken/sbkfeature_base.h
index 064bd8ab4..290884062 100644
--- a/sources/shiboken6/libshiboken/sbkfeature_base.h
+++ b/sources/shiboken6/libshiboken/sbkfeature_base.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 SBKFEATURE_BASE_H
#define SBKFEATURE_BASE_H
@@ -43,9 +7,7 @@
extern "C"
{
-LIBSHIBOKEN_API PyObject *getFeatureSelectId();
LIBSHIBOKEN_API int currentSelectId(PyTypeObject *type);
-LIBSHIBOKEN_API void initFeatureShibokenPart();
LIBSHIBOKEN_API PyObject *mangled_type_getattro(PyTypeObject *type, PyObject *name);
LIBSHIBOKEN_API PyObject *Sbk_TypeGet___dict__(PyTypeObject *type, void *context);
LIBSHIBOKEN_API PyObject *SbkObject_GenericGetAttr(PyObject *obj, PyObject *name);
diff --git a/sources/shiboken6/libshiboken/sbkmodule.cpp b/sources/shiboken6/libshiboken/sbkmodule.cpp
index e5f4e2f88..acadc60fa 100644
--- a/sources/shiboken6/libshiboken/sbkmodule.cpp
+++ b/sources/shiboken6/libshiboken/sbkmodule.cpp
@@ -1,91 +1,515 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 "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) == 0)
+ 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;
+// Python 3.13
+static int const LOAD_CONST_313 = 83;
+static int const IMPORT_NAME_313 = 75;
+
+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");
+
+ static int LOAD_CONST = _PepRuntimeVersion() < 0x030D00 ? LOAD_CONST_312 : LOAD_CONST_313;
+ static int IMPORT_NAME = _PepRuntimeVersion() < 0x030D00 ? IMPORT_NAME_312 : IMPORT_NAME_313;
+
+ 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 && opcode2 == IMPORT_NAME) {
+ 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{
+ "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;
+}
+
+static int lazyLoadDefault()
+{
+#ifndef PYPY_VERSION
+ int result = 1;
+#else
+ int result = 0;
+#endif
+ if (auto *flag = getenv("PYSIDE6_OPTION_LAZY"))
+ result = std::atoi(flag);
+ return result;
+}
+
+void checkIfShouldLoadImmediately(PyObject *module, const std::string &name,
+ const NameToTypeFunctionMap &nameToFunc)
+{
+ static const int value = lazyLoadDefault();
+
+ // 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.emplace_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, keeping a reference.
+ origImportFunc = PyDict_GetItemString(builtins, "__import__");
+ Py_INCREF(origImportFunc);
+ AutoDecRef func(PyCFunction_NewEx(lazy_methods, nullptr, nullptr));
+ PyDict_SetItemString(builtins, "__import__", func);
+ 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 02e4a2706..2c407e09d 100644
--- a/sources/shiboken6/libshiboken/sbkmodule.h
+++ b/sources/shiboken6/libshiboken/sbkmodule.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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_MODULE_H
#define SBK_MODULE_H
@@ -48,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.
@@ -66,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.
@@ -94,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
new file mode 100644
index 000000000..b6422e73f
--- /dev/null
+++ b/sources/shiboken6/libshiboken/sbknumpy.cpp
@@ -0,0 +1,57 @@
+// 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
+
+
+#ifdef HAVE_NUMPY
+// Include numpy first to get the proper PyArray_Check
+# include <numpy/arrayobject.h>
+#endif
+
+#include "helper.h"
+#include "sbknumpycheck.h"
+#include "sbkcpptonumpy.h"
+#include "sbknumpyview.h"
+
+#include <algorithm>
+
+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);
+ return false;
+#endif
+}
+
+} //namespace Shiboken::Numpy
+
+// Include all sources files using numpy so that they are in the same
+// translation unit (see comment at initNumPyArrayConverters()).
+
+#include "sbknumpyview.cpp"
+#include "sbkcpptonumpy.cpp"
+#ifdef HAVE_NUMPY
+# include "sbknumpyarrayconverter.cpp"
+#endif
diff --git a/sources/shiboken6/libshiboken/sbknumpyarrayconverter.cpp b/sources/shiboken6/libshiboken/sbknumpyarrayconverter.cpp
index 996968fa1..835a97524 100644
--- a/sources/shiboken6/libshiboken/sbknumpyarrayconverter.cpp
+++ b/sources/shiboken6/libshiboken/sbknumpyarrayconverter.cpp
@@ -1,41 +1,7 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 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
+
+// included by sbknumpy.cpp
#include "sbkarrayconverter.h"
#include "helper.h"
@@ -43,8 +9,6 @@
#include "sbkconverter_p.h"
#include "sbkarrayconverter_p.h"
-#include <numpy/arrayobject.h>
-
#include <algorithm>
#include <iostream>
#include <cstdint>
@@ -116,8 +80,13 @@ std::ostream &operator<<(std::ostream &str, PyArrayObject *o)
str << " NPY_ARRAY_NOTSWAPPED";
if ((flags & NPY_ARRAY_WRITEABLE) != 0)
str << " NPY_ARRAY_WRITEABLE";
+#if NPY_VERSION >= 0x00000010 // NPY_1_23_API_VERSION
+ if ((flags & NPY_ARRAY_WRITEBACKIFCOPY) != 0)
+ str << " NPY_ARRAY_WRITEBACKIFCOPY";
+#else
if ((flags & NPY_ARRAY_UPDATEIFCOPY) != 0)
str << " NPY_ARRAY_UPDATEIFCOPY";
+#endif
} else {
str << '0';
}
@@ -125,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);
@@ -136,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);
@@ -241,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);
@@ -266,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>();
@@ -304,5 +267,4 @@ void initNumPyArrayConverters()
extendArrayConverter2<double, NPY_DOUBLE>();
}
-} // namespace Conversions
-} // namespace Shiboken
+} // namespace Shiboken::Conversions
diff --git a/sources/shiboken6/libshiboken/sbknumpycheck.h b/sources/shiboken6/libshiboken/sbknumpycheck.h
new file mode 100644
index 000000000..cfe65372c
--- /dev/null
+++ b/sources/shiboken6/libshiboken/sbknumpycheck.h
@@ -0,0 +1,30 @@
+// 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 SBKNUMPYCHECK_H
+#define SBKNUMPYCHECK_H
+
+#include <sbkpython.h>
+#include <shibokenmacros.h>
+
+
+// This header provides a PyArray_Check() definition that can be used to avoid
+// having to include the numpy headers. When using numpy headers, make sure
+// to include this header after them to skip the definition. Also remember
+// that import_array() must then be called to initialize numpy.
+
+namespace Shiboken::Numpy
+{
+
+/// Check whether the object is a PyArrayObject
+/// \param pyIn object
+/// \return Whether it is a PyArrayObject
+LIBSHIBOKEN_API bool check(PyObject *pyIn);
+
+} //namespace Shiboken::Numpy
+
+#ifndef PyArray_Check
+# define PyArray_Check(op) Shiboken::Numpy::check(op)
+#endif
+
+#endif // SBKNUMPYCHECK_H
diff --git a/sources/shiboken6/libshiboken/sbknumpyview.cpp b/sources/shiboken6/libshiboken/sbknumpyview.cpp
new file mode 100644
index 000000000..bafbf8038
--- /dev/null
+++ b/sources/shiboken6/libshiboken/sbknumpyview.cpp
@@ -0,0 +1,265 @@
+// 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
+
+// included by sbknumpy.cpp
+
+#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)
+ return {};
+ auto *ar = reinterpret_cast<PyArrayObject *>(pyIn);
+ if ((PyArray_FLAGS(ar) & NPY_ARRAY_C_CONTIGUOUS) == 0)
+ return {};
+ const int ndim = PyArray_NDIM(ar);
+ if (ndim > 2)
+ return {};
+
+ const auto typeO = viewTypeFromNumPy(PyArray_TYPE(ar));
+ if (!typeO.has_value())
+ return {};
+
+ View result;
+ result.ndim = ndim;
+ result.type = typeO.value();
+ result.data = PyArray_DATA(ar);
+ result.dimensions[0] = PyArray_DIMS(ar)[0];
+ result.stride[0] = PyArray_STRIDES(ar)[0];
+ if (ndim > 1) {
+ result.dimensions[1] = PyArray_DIMS(ar)[1];
+ result.stride[1] = PyArray_STRIDES(ar)[1];
+ } else {
+ result.dimensions[1] = result.stride[1] = 0;
+ }
+ return result;
+}
+
+} // namespace Numpy
+
+template <class T>
+static void debugArray(std::ostream &str, const T *data, int n)
+{
+ static const int maxData = 10;
+ str << " = ";
+ auto *end = data + std::min(n, maxData);
+ for (auto *d = data; d != end; ++d) {
+ if (d != data)
+ str << ", ";
+ str << *d;
+ }
+ if (n > maxData)
+ str << "...";
+}
+
+std::ostream &operator<<(std::ostream &str, const debugPyArrayObject &a)
+{
+ str << "PyArrayObject(";
+ if (a.m_object == nullptr) {
+ str << '0';
+ } else if (PyArray_Check(a.m_object) != 0) {
+ auto *ar = reinterpret_cast<PyArrayObject *>(a.m_object);
+ const int ndim = PyArray_NDIM(ar);
+ const int type = PyArray_TYPE(ar);
+ const int flags = PyArray_FLAGS(ar);
+ str << "ndim=" << ndim << " [";
+ for (int d = 0; d < ndim; ++d) {
+ if (d)
+ str << ", ";
+ str << PyArray_DIMS(ar)[d];
+ }
+ str << "], type=";
+ switch (type) {
+ case NPY_SHORT:
+ str << "short";
+ break;
+ case NPY_USHORT:
+ str << "ushort";
+ break;
+ case NPY_INT:
+ str << "int32";
+ break;
+ case NPY_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";
+ break;
+ case NPY_DOUBLE:
+ str << "double";
+ break;
+ default:
+ str << '(' << type << ')';
+ break;
+ }
+ str << ", flags=0x" << std::hex << flags << std::dec;
+ if ((flags & NPY_ARRAY_C_CONTIGUOUS) != 0)
+ str << " [C-contiguous]";
+ if ((flags & NPY_ARRAY_F_CONTIGUOUS) != 0)
+ str << " [Fortran-contiguous]";
+ if ((flags & NPY_ARRAY_ALIGNED) != 0)
+ str << " [aligned]";
+ if ((flags & NPY_ARRAY_OWNDATA) != 0)
+ str << " [owndata]";
+ if ((flags & NPY_ARRAY_WRITEABLE) != 0)
+ str << " [writeable]";
+
+ 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;
+ case NPY_DOUBLE:
+ debugArray(str, reinterpret_cast<const double *>(data), dim0);
+ break;
+ }
+ }
+ } else {
+ str << "Invalid";
+ }
+ str << ')';
+ return str;
+}
+
+} //namespace Shiboken
+
+#else // HAVE_NUMPY
+
+namespace Shiboken::Numpy
+{
+
+View View::fromPyObject(PyObject *)
+{
+ return {};
+}
+
+std::ostream &operator<<(std::ostream &str, const debugPyArrayObject &)
+{
+ str << "Unimplemented function " << __FUNCTION__ << ", (numpy was not found).";
+ return str;
+}
+
+} //namespace Shiboken::Numpy
+
+#endif // !HAVE_NUMPY
+
+namespace Shiboken::Numpy
+{
+
+bool View::sameLayout(const View &rhs) const
+{
+ return rhs && *this && ndim == rhs.ndim && type == rhs.type;
+}
+
+bool View::sameSize(const View &rhs) const
+{
+ return sameLayout(rhs)
+ && dimensions[0] == rhs.dimensions[0] && dimensions[1] == rhs.dimensions[1];
+}
+
+std::ostream &operator<<(std::ostream &str, const View &v)
+{
+ str << "Shiboken::Numpy::View(";
+ if (v) {
+ str << "type=" << v.type << ", ndim=" << v.ndim << " ["
+ << v.dimensions[0];
+ if (v.ndim > 1)
+ str << ", " << v.dimensions[1];
+ str << "], stride=[" << v.stride[0];
+ if (v.ndim > 1)
+ str << ", " << v.stride[1];
+ str << "], data=" << v.data;
+ } else {
+ str << "invalid";
+ }
+ str << ')';
+ return str;
+}
+
+} //namespace Shiboken::Numpy
diff --git a/sources/shiboken6/libshiboken/sbknumpyview.h b/sources/shiboken6/libshiboken/sbknumpyview.h
new file mode 100644
index 000000000..918913b78
--- /dev/null
+++ b/sources/shiboken6/libshiboken/sbknumpyview.h
@@ -0,0 +1,47 @@
+// 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 SBKNUMPYVIEW_H
+#define SBKNUMPYVIEW_H
+
+#include <sbkpython.h>
+#include <shibokenmacros.h>
+
+#include <iosfwd>
+
+namespace Shiboken::Numpy
+{
+
+/// Check whether the object is a PyArrayObject
+/// \param pyIn object
+/// \return Whether it is a PyArrayObject
+LIBSHIBOKEN_API bool check(PyObject *pyIn);
+
+/// A simple view of an up to 2 dimensional, C-contiguous array of a standard
+/// type. It can be passed to compilation units that do not include the
+/// numpy headers.
+struct LIBSHIBOKEN_API View
+{
+ enum Type { Int, Unsigned, Float, Double, Int16, Unsigned16, Int64, Unsigned64 };
+
+ static View fromPyObject(PyObject *pyIn);
+
+ operator bool() const { return ndim > 0; }
+
+ /// Return whether rhs is of the same type and dimensionality
+ bool sameLayout(const View &rhs) const;
+ /// Return whether rhs is of the same type dimensionality and size
+ bool sameSize(const View &rhs) const;
+
+ int ndim = 0;
+ Py_ssize_t dimensions[2];
+ Py_ssize_t stride[2];
+ void *data = nullptr;
+ Type type = Int;
+};
+
+LIBSHIBOKEN_API std::ostream &operator<<(std::ostream &, const View &v);
+
+} //namespace Shiboken::Numpy
+
+#endif // SBKNUMPYVIEW_H
diff --git a/sources/shiboken6/libshiboken/sbkpython.h b/sources/shiboken6/libshiboken/sbkpython.h
index cef9f81a6..e62fa13ae 100644
--- a/sources/shiboken6/libshiboken/sbkpython.h
+++ b/sources/shiboken6/libshiboken/sbkpython.h
@@ -1,47 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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
#ifndef SBKPYTHON_H
#define SBKPYTHON_H
#include "sbkversion.h"
-#define PyEnumMeta_Check(x) (strcmp(Py_TYPE(x)->tp_name, "EnumMeta") == 0)
// Qt's "slots" macro collides with the "slots" member variables
// used in some Python structs. For compilers that support push_macro,
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 20aa1b8a0..023de0ea4 100644
--- a/sources/shiboken6/libshiboken/sbkstaticstrings.cpp
+++ b/sources/shiboken6/libshiboken/sbkstaticstrings.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 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 "sbkstaticstrings.h"
#include "sbkstaticstrings_p.h"
@@ -60,12 +24,13 @@ 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")
-STATIC_STRING_IMPL(underscore, "_")
STATIC_STRING_IMPL(value, "value")
STATIC_STRING_IMPL(values, "values")
+STATIC_STRING_IMPL(qtStaticMetaObject, "staticMetaObject")
// Internal:
STATIC_STRING_IMPL(classmethod, "classmethod")
@@ -96,12 +61,14 @@ STATIC_STRING_IMPL(property_methods, "__property_methods__")
STATIC_STRING_IMPL(qualname, "__qualname__")
STATIC_STRING_IMPL(self, "__self__")
STATIC_STRING_IMPL(select_i, "__self__")
+STATIC_STRING_IMPL(code, "__code__")
+STATIC_STRING_IMPL(rlshift, "__rlshift__")
+STATIC_STRING_IMPL(rrshift, "__rrshift__")
// Internal:
STATIC_STRING_IMPL(base, "__base__")
STATIC_STRING_IMPL(bases, "__bases__")
STATIC_STRING_IMPL(builtins, "__builtins__")
-STATIC_STRING_IMPL(code, "__code__")
STATIC_STRING_IMPL(dictoffset, "__dictoffset__")
STATIC_STRING_IMPL(func, "__func__")
STATIC_STRING_IMPL(func_kind, "__func_kind__")
@@ -109,8 +76,13 @@ 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
+
+namespace Messages
+{
+STATIC_STRING_IMPL(unknownException, "An unknown exception was caught")
+}
+
} // namespace Shiboken
diff --git a/sources/shiboken6/libshiboken/sbkstaticstrings.h b/sources/shiboken6/libshiboken/sbkstaticstrings.h
index fd0c06e43..017790ee3 100644
--- a/sources/shiboken6/libshiboken/sbkstaticstrings.h
+++ b/sources/shiboken6/libshiboken/sbkstaticstrings.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 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 SBKSTATICSTRINGS_H
#define SBKSTATICSTRINGS_H
@@ -59,11 +23,12 @@ 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 *underscore();
LIBSHIBOKEN_API PyObject *value();
LIBSHIBOKEN_API PyObject *values();
+LIBSHIBOKEN_API PyObject *qtStaticMetaObject();
} // namespace PyName
namespace PyMagicName
@@ -82,7 +47,15 @@ LIBSHIBOKEN_API PyObject *property_methods();
LIBSHIBOKEN_API PyObject *qualname();
LIBSHIBOKEN_API PyObject *self();
LIBSHIBOKEN_API PyObject *opaque_container();
+LIBSHIBOKEN_API PyObject *code();
+LIBSHIBOKEN_API PyObject *rlshift();
+LIBSHIBOKEN_API PyObject *rrshift();
} // namespace PyMagicName
+
+namespace Messages
+{
+LIBSHIBOKEN_API PyObject *unknownException();
+} // Messages
} // namespace Shiboken
#endif // SBKSTATICSTRINGS_H
diff --git a/sources/shiboken6/libshiboken/sbkstaticstrings_p.h b/sources/shiboken6/libshiboken/sbkstaticstrings_p.h
index 308966481..2a337bf7e 100644
--- a/sources/shiboken6/libshiboken/sbkstaticstrings_p.h
+++ b/sources/shiboken6/libshiboken/sbkstaticstrings_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 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 "sbkpython.h"
#include "shibokenmacros.h"
diff --git a/sources/shiboken6/libshiboken/sbkstring.cpp b/sources/shiboken6/libshiboken/sbkstring.cpp
index 0a2cd5c60..b5e87ca5a 100644
--- a/sources/shiboken6/libshiboken/sbkstring.cpp
+++ b/sources/shiboken6/libshiboken/sbkstring.cpp
@@ -1,49 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 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 "sbkstring.h"
+#include "sbkenum.h"
#include "sbkstaticstrings_p.h"
#include "autodecref.h"
-#include <vector>
-#include <unordered_set>
-
namespace Shiboken::String
{
@@ -53,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{};
@@ -215,50 +182,9 @@ Py_ssize_t len(PyObject *str)
// PyObject *attr = PyObject_GetAttr(obj, name());
//
-using StaticStrings = std::unordered_set<PyObject *>;
-
-static void finalizeStaticStrings(); // forward
-
-static StaticStrings &staticStrings()
-{
- static StaticStrings result;
- return result;
-}
-
-static void finalizeStaticStrings()
-{
- auto &set = staticStrings();
- for (PyObject *ob : set) {
- Py_SET_REFCNT(ob, 1);
- Py_DECREF(ob);
- }
- set.clear();
-}
-
PyObject *createStaticString(const char *str)
{
- static bool initialized = false;
- if (!initialized) {
- Py_AtExit(finalizeStaticStrings);
- initialized = true;
- }
- PyObject *result = PyUnicode_InternFromString(str);
- if (result == nullptr) {
- // This error is never checked, but also very unlikely. Report and exit.
- PyErr_Print();
- Py_FatalError("unexpected error in createStaticString()");
- }
- auto it = staticStrings().find(result);
- if (it == staticStrings().end())
- staticStrings().insert(result);
- /*
- * Note: We always add one reference even if we have a new string.
- * This makes the strings immortal, and we are safe if someone
- * uses AutoDecRef, although the set cannot cope with deletions.
- * The exit handler cleans that up, anyway.
- */
- Py_INCREF(result);
- return result;
+ return PyUnicode_InternFromString(str);
}
///////////////////////////////////////////////////////////////////////
@@ -313,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 500149bed..3ff2805e2 100644
--- a/sources/shiboken6/libshiboken/sbkstring.h
+++ b/sources/shiboken6/libshiboken/sbkstring.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 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 SBKSTRING_H
#define SBKSTRING_H
@@ -43,12 +7,12 @@
#include "sbkpython.h"
#include "shibokenmacros.h"
-namespace Shiboken
-{
-namespace String
+namespace Shiboken::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);
@@ -65,11 +29,8 @@ 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
-
+} // namespace Shiboken::String
#endif
-
-
diff --git a/sources/shiboken6/libshiboken/sbktypefactory.cpp b/sources/shiboken6/libshiboken/sbktypefactory.cpp
index b560cdb95..079548eed 100644
--- a/sources/shiboken6/libshiboken/sbktypefactory.cpp
+++ b/sources/shiboken6/libshiboken/sbktypefactory.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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
#include "sbktypefactory.h"
#include "shiboken.h"
@@ -43,38 +7,98 @@
extern "C"
{
-PyTypeObject *SbkType_FromSpec(PyType_Spec *spec)
-{
- return SbkType_FromSpec_BMDWBD(spec, nullptr, nullptr, 0, 0, nullptr, nullptr);
-}
+using Shiboken::AutoDecRef;
-PyTypeObject *SbkType_FromSpecAddDict(PyType_Spec *spec, PyObject *dict_add)
+PyTypeObject *SbkType_FromSpec(PyType_Spec *spec)
{
- return SbkType_FromSpec_BMDWBD(spec, nullptr, nullptr, 0, 0, nullptr, dict_add);
+ return SbkType_FromSpec_BMDWB(spec, nullptr, nullptr, 0, 0, nullptr);
}
PyTypeObject *SbkType_FromSpecWithMeta(PyType_Spec *spec, PyTypeObject *meta)
{
- return SbkType_FromSpec_BMDWBD(spec, nullptr, meta, 0, 0, nullptr, nullptr);
+ return SbkType_FromSpec_BMDWB(spec, nullptr, meta, 0, 0, nullptr);
}
PyTypeObject *SbkType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
{
- return SbkType_FromSpec_BMDWBD(spec, bases, nullptr, 0, 0, nullptr, nullptr);
+ return SbkType_FromSpec_BMDWB(spec, bases, nullptr, 0, 0, nullptr);
}
PyTypeObject *SbkType_FromSpecBasesMeta(PyType_Spec *spec, PyObject *bases, PyTypeObject *meta)
{
- return SbkType_FromSpec_BMDWBD(spec, bases, meta, 0, 0, nullptr, nullptr);
+ return SbkType_FromSpec_BMDWB(spec, bases, meta, 0, 0, nullptr);
}
-PyTypeObject *SbkType_FromSpec_BMDWBD(PyType_Spec *spec,
- PyObject *bases,
- PyTypeObject *meta,
- int dictoffset,
- int weaklistoffset,
- PyBufferProcs *bufferprocs,
- PyObject *dict_add)
+#ifdef PYPY_VERSION
+
+static PyObject *_PyType_FromSpecWithBases(PyType_Spec *, PyObject *);
+
+#else
+
+#define _PyType_FromSpecWithBases PyType_FromSpecWithBases
+
+#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,
+ int dictoffset,
+ int weaklistoffset,
+ PyBufferProcs *bufferprocs)
{
// PYSIDE-1286: Generate correct __module__ and __qualname__
// The name field can now be extended by an "n:" prefix which is
@@ -93,7 +117,7 @@ PyTypeObject *SbkType_FromSpec_BMDWBD(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;
@@ -105,18 +129,14 @@ PyTypeObject *SbkType_FromSpec_BMDWBD(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));
- if (PyObject_SetAttr(obType, Shiboken::PyMagicName::module(), module) < 0)
- return nullptr;
- if (PyObject_SetAttr(obType, Shiboken::PyMagicName::qualname(), qualname) < 0)
- return nullptr;
+ AutoDecRef module(Shiboken::String::fromCString(mod, mlen));
+ AutoDecRef qualname(Shiboken::String::fromCString(qual));
auto *type = reinterpret_cast<PyTypeObject *>(obType);
if (meta) {
PyTypeObject *hold = Py_TYPE(type);
- Py_TYPE(type) = meta;
+ obType->ob_type = meta;
Py_INCREF(Py_TYPE(type));
if (hold->tp_flags & Py_TPFLAGS_HEAPTYPE)
Py_DECREF(hold);
@@ -128,11 +148,260 @@ PyTypeObject *SbkType_FromSpec_BMDWBD(PyType_Spec *spec,
type->tp_weaklistoffset = weaklistoffset;
if (bufferprocs)
PepType_AS_BUFFER(type) = bufferprocs;
- if (dict_add)
- PyDict_Update(reinterpret_cast<PyObject *>(type->tp_dict), dict_add);
+#ifdef PYPY_VERSION
+ // PYSIDE-535: Careful: Using PyObject_SetAttr would have the side-effect of calling
+ // PyType_Ready too early. (at least in PyPy, which caused pretty long debugging.)
+ auto *ht = reinterpret_cast<PyHeapTypeObject *>(type);
+ ht->ht_qualname = qualname;
+ AutoDecRef tpDict(PepType_GetDict(type));
+ if (PyDict_SetItem(tpDict.object(), Shiboken::PyMagicName::qualname(), qualname))
+ return nullptr;
+ if (PyDict_SetItem(tpDict.object(), Shiboken::PyMagicName::module(), module))
+ return nullptr;
+ PyType_Ready(type);
+#else
+ if (PyObject_SetAttr(obType, Shiboken::PyMagicName::module(), module) < 0)
+ return nullptr;
+ if (PyObject_SetAttr(obType, Shiboken::PyMagicName::qualname(), qualname) < 0)
+ return nullptr;
PyType_Modified(type);
+#endif
return type;
}
+#ifdef PYPY_VERSION
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Reimplementation of `PyType_FromSpecWithBases`
+//
+// This is almost the original code from Python 3.7 with a few changes.
+// Especially the call to `PyType_Ready` is deferred until the needed
+// post-actions are carried out in `SbkType_FromSpec_BMDWBD`.
+//
+// FIXME remove ASAP.
+// Version is not clear, yet. Current version == 7.3.6
+//
+
+static const short slotoffsets[] = {
+ -1, /* invalid slot */
+/* Generated by typeslots.py */
+0,
+0,
+offsetof(PyHeapTypeObject, as_mapping.mp_ass_subscript),
+offsetof(PyHeapTypeObject, as_mapping.mp_length),
+offsetof(PyHeapTypeObject, as_mapping.mp_subscript),
+offsetof(PyHeapTypeObject, as_number.nb_absolute),
+offsetof(PyHeapTypeObject, as_number.nb_add),
+offsetof(PyHeapTypeObject, as_number.nb_and),
+offsetof(PyHeapTypeObject, as_number.nb_bool),
+offsetof(PyHeapTypeObject, as_number.nb_divmod),
+offsetof(PyHeapTypeObject, as_number.nb_float),
+offsetof(PyHeapTypeObject, as_number.nb_floor_divide),
+offsetof(PyHeapTypeObject, as_number.nb_index),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_add),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_and),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_floor_divide),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_lshift),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_multiply),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_or),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_power),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_remainder),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_rshift),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_subtract),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_true_divide),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_xor),
+offsetof(PyHeapTypeObject, as_number.nb_int),
+offsetof(PyHeapTypeObject, as_number.nb_invert),
+offsetof(PyHeapTypeObject, as_number.nb_lshift),
+offsetof(PyHeapTypeObject, as_number.nb_multiply),
+offsetof(PyHeapTypeObject, as_number.nb_negative),
+offsetof(PyHeapTypeObject, as_number.nb_or),
+offsetof(PyHeapTypeObject, as_number.nb_positive),
+offsetof(PyHeapTypeObject, as_number.nb_power),
+offsetof(PyHeapTypeObject, as_number.nb_remainder),
+offsetof(PyHeapTypeObject, as_number.nb_rshift),
+offsetof(PyHeapTypeObject, as_number.nb_subtract),
+offsetof(PyHeapTypeObject, as_number.nb_true_divide),
+offsetof(PyHeapTypeObject, as_number.nb_xor),
+offsetof(PyHeapTypeObject, as_sequence.sq_ass_item),
+offsetof(PyHeapTypeObject, as_sequence.sq_concat),
+offsetof(PyHeapTypeObject, as_sequence.sq_contains),
+offsetof(PyHeapTypeObject, as_sequence.sq_inplace_concat),
+offsetof(PyHeapTypeObject, as_sequence.sq_inplace_repeat),
+offsetof(PyHeapTypeObject, as_sequence.sq_item),
+offsetof(PyHeapTypeObject, as_sequence.sq_length),
+offsetof(PyHeapTypeObject, as_sequence.sq_repeat),
+offsetof(PyHeapTypeObject, ht_type.tp_alloc),
+offsetof(PyHeapTypeObject, ht_type.tp_base),
+offsetof(PyHeapTypeObject, ht_type.tp_bases),
+offsetof(PyHeapTypeObject, ht_type.tp_call),
+offsetof(PyHeapTypeObject, ht_type.tp_clear),
+offsetof(PyHeapTypeObject, ht_type.tp_dealloc),
+offsetof(PyHeapTypeObject, ht_type.tp_del),
+offsetof(PyHeapTypeObject, ht_type.tp_descr_get),
+offsetof(PyHeapTypeObject, ht_type.tp_descr_set),
+offsetof(PyHeapTypeObject, ht_type.tp_doc),
+offsetof(PyHeapTypeObject, ht_type.tp_getattr),
+offsetof(PyHeapTypeObject, ht_type.tp_getattro),
+offsetof(PyHeapTypeObject, ht_type.tp_hash),
+offsetof(PyHeapTypeObject, ht_type.tp_init),
+offsetof(PyHeapTypeObject, ht_type.tp_is_gc),
+offsetof(PyHeapTypeObject, ht_type.tp_iter),
+offsetof(PyHeapTypeObject, ht_type.tp_iternext),
+offsetof(PyHeapTypeObject, ht_type.tp_methods),
+offsetof(PyHeapTypeObject, ht_type.tp_new),
+offsetof(PyHeapTypeObject, ht_type.tp_repr),
+offsetof(PyHeapTypeObject, ht_type.tp_richcompare),
+offsetof(PyHeapTypeObject, ht_type.tp_setattr),
+offsetof(PyHeapTypeObject, ht_type.tp_setattro),
+offsetof(PyHeapTypeObject, ht_type.tp_str),
+offsetof(PyHeapTypeObject, ht_type.tp_traverse),
+offsetof(PyHeapTypeObject, ht_type.tp_members),
+offsetof(PyHeapTypeObject, ht_type.tp_getset),
+offsetof(PyHeapTypeObject, ht_type.tp_free),
+offsetof(PyHeapTypeObject, as_number.nb_matrix_multiply),
+offsetof(PyHeapTypeObject, as_number.nb_inplace_matrix_multiply),
+offsetof(PyHeapTypeObject, as_async.am_await),
+offsetof(PyHeapTypeObject, as_async.am_aiter),
+offsetof(PyHeapTypeObject, as_async.am_anext),
+offsetof(PyHeapTypeObject, ht_type.tp_finalize),
+};
+
+static PyTypeObject *
+best_base(PyObject *bases)
+{
+ // We always have only one base
+ return reinterpret_cast<PyTypeObject *>(PyTuple_GET_ITEM(bases, 0));
+}
+
+static PyObject *
+_PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
+{
+ PyHeapTypeObject *res = reinterpret_cast<PyHeapTypeObject *>(
+ PyType_GenericAlloc(&PyType_Type, 0));
+ PyTypeObject *type, *base;
+ PyObject *modname;
+ char *s;
+ char *res_start = reinterpret_cast<char *>(res);
+ PyType_Slot *slot;
+
+ if (res == nullptr)
+ return nullptr;
+
+ if (spec->name == nullptr) {
+ PyErr_SetString(PyExc_SystemError,
+ "Type spec does not define the name field.");
+ goto fail;
+ }
+
+ /* Set the type name and qualname */
+ s = strrchr(const_cast<char *>(spec->name), '.');
+ if (s == nullptr)
+ s = (char*)spec->name;
+ else
+ s++;
+
+ type = &res->ht_type;
+ /* The flags must be initialized early, before the GC traverses us */
+ type->tp_flags = spec->flags | Py_TPFLAGS_HEAPTYPE;
+ res->ht_name = PyUnicode_FromString(s);
+ if (!res->ht_name)
+ goto fail;
+ res->ht_qualname = res->ht_name;
+ Py_INCREF(res->ht_qualname);
+ type->tp_name = spec->name;
+
+ /* Adjust for empty tuple bases */
+ if (!bases) {
+ base = &PyBaseObject_Type;
+ /* See whether Py_tp_base(s) was specified */
+ for (slot = spec->slots; slot->slot; slot++) {
+ if (slot->slot == Py_tp_base)
+ base = reinterpret_cast<PyTypeObject *>(slot->pfunc);
+ else if (slot->slot == Py_tp_bases) {
+ bases = reinterpret_cast<PyObject *>(slot->pfunc);
+ Py_INCREF(bases);
+ }
+ }
+ if (!bases)
+ bases = PyTuple_Pack(1, base);
+ if (!bases)
+ goto fail;
+ }
+ else
+ Py_INCREF(bases);
+
+ /* Calculate best base, and check that all bases are type objects */
+ base = best_base(bases);
+ if (base == nullptr) {
+ goto fail;
+ }
+
+ /* Initialize essential fields */
+ type->tp_as_async = &res->as_async;
+ type->tp_as_number = &res->as_number;
+ type->tp_as_sequence = &res->as_sequence;
+ type->tp_as_mapping = &res->as_mapping;
+ type->tp_as_buffer = &res->as_buffer;
+ /* Set tp_base and tp_bases */
+ type->tp_bases = bases;
+ bases = nullptr;
+ Py_INCREF(base);
+ type->tp_base = base;
+
+ type->tp_basicsize = spec->basicsize;
+ type->tp_itemsize = spec->itemsize;
+
+ for (slot = spec->slots; slot->slot; slot++) {
+ if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases)
+ /* Processed above */
+ continue;
+ *reinterpret_cast<void **>(res_start + slotoffsets[slot->slot]) = slot->pfunc;
+
+ /* need to make a copy of the docstring slot, which usually
+ points to a static string literal */
+ if (slot->slot == Py_tp_doc) {
+ const char *old_doc = reinterpret_cast<char *>(slot->pfunc);
+ //_PyType_DocWithoutSignature(type->tp_name, slot->pfunc);
+ size_t len = strlen(old_doc)+1;
+ char *tp_doc = reinterpret_cast<char *>(PyObject_MALLOC(len));
+ if (tp_doc == nullptr) {
+ type->tp_doc = nullptr;
+ PyErr_NoMemory();
+ goto fail;
+ }
+ memcpy(tp_doc, old_doc, len);
+ type->tp_doc = tp_doc;
+ }
+ }
+ if (type->tp_dealloc == nullptr) {
+ /* It's a heap type, so needs the heap types' dealloc.
+ subtype_dealloc will call the base type's tp_dealloc, if
+ necessary. */
+ type->tp_dealloc = _PyPy_subtype_dealloc;
+ }
+
+ /// Here is the only change needed: Do not finalize type creation.
+ // if (PyType_Ready(type) < 0)
+ // goto fail;
+ PepType_SetDict(type, PyDict_New());
+ /// This is not found in PyPy:
+ // if (type->tp_dictoffset) {
+ // res->ht_cached_keys = _PyDict_NewKeysForClass();
+ // }
+
+ /* Set type.__module__ */
+ /// Removed __module__ handling, already implemented.
+
+ return (PyObject*)res;
+
+ fail:
+ Py_DECREF(res);
+ return nullptr;
+}
+
+#endif // PYPY_VERSION
+
} //extern "C"
diff --git a/sources/shiboken6/libshiboken/sbktypefactory.h b/sources/shiboken6/libshiboken/sbktypefactory.h
index f17427052..81cb32d41 100644
--- a/sources/shiboken6/libshiboken/sbktypefactory.h
+++ b/sources/shiboken6/libshiboken/sbktypefactory.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 SBKTYPEFACTORY_H
#define SBKTYPEFACTORY_H
@@ -47,17 +11,15 @@ extern "C"
// PYSIDE-535: Encapsulation of PyType_FromSpec special-cased for PyPy
LIBSHIBOKEN_API PyTypeObject *SbkType_FromSpec(PyType_Spec *);
-LIBSHIBOKEN_API PyTypeObject *SbkType_FromSpecAddDict(PyType_Spec *, PyObject *);
LIBSHIBOKEN_API PyTypeObject *SbkType_FromSpecWithMeta(PyType_Spec *, PyTypeObject *);
LIBSHIBOKEN_API PyTypeObject *SbkType_FromSpecWithBases(PyType_Spec *, PyObject *);
LIBSHIBOKEN_API PyTypeObject *SbkType_FromSpecBasesMeta(PyType_Spec *, PyObject *, PyTypeObject *);
-LIBSHIBOKEN_API PyTypeObject *SbkType_FromSpec_BMDWBD(PyType_Spec *spec,
- PyObject *bases,
- PyTypeObject *meta,
- int dictoffset,
- int weaklistoffset,
- PyBufferProcs *bufferprocs,
- PyObject *dict_add);
+LIBSHIBOKEN_API PyTypeObject *SbkType_FromSpec_BMDWB(PyType_Spec *spec,
+ PyObject *bases,
+ PyTypeObject *meta,
+ int dictoffset,
+ int weaklistoffset,
+ PyBufferProcs *bufferprocs);
} //extern "C"
diff --git a/sources/shiboken6/libshiboken/sbkversion.h.in b/sources/shiboken6/libshiboken/sbkversion.h.in
index 99ee7f93e..5c0b38fdb 100644
--- a/sources/shiboken6/libshiboken/sbkversion.h.in
+++ b/sources/shiboken6/libshiboken/sbkversion.h.in
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 SBKVERSION_H
#define SBKVERSION_H
@@ -46,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 3e1df5235..27ba05fa7 100644
--- a/sources/shiboken6/libshiboken/shiboken.h
+++ b/sources/shiboken6/libshiboken/shiboken.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 SHIBOKEN_H
#define SHIBOKEN_H
@@ -47,12 +11,15 @@
#include "gilstate.h"
#include "threadstatesaver.h"
#include "helper.h"
+#include "pyobjectholder.h"
#include "sbkarrayconverter.h"
#include "sbkconverter.h"
#include "sbkenum.h"
+#include "sbkerrors.h"
#include "sbkmodule.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
+#include "sbktypefactory.h"
#include "shibokenmacros.h"
#include "shibokenbuffer.h"
#include "signature.h"
diff --git a/sources/shiboken6/libshiboken/shibokenbuffer.cpp b/sources/shiboken6/libshiboken/shibokenbuffer.cpp
index 45c727717..d04613895 100644
--- a/sources/shiboken6/libshiboken/shibokenbuffer.cpp
+++ b/sources/shiboken6/libshiboken/shibokenbuffer.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 "shibokenbuffer.h"
#include <cstdlib>
diff --git a/sources/shiboken6/libshiboken/shibokenbuffer.h b/sources/shiboken6/libshiboken/shibokenbuffer.h
index 512d9db4d..068a5e9fd 100644
--- a/sources/shiboken6/libshiboken/shibokenbuffer.h
+++ b/sources/shiboken6/libshiboken/shibokenbuffer.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 SHIBOKEN_BUFFER_H
#define SHIBOKEN_BUFFER_H
@@ -43,10 +7,7 @@
#include "sbkpython.h"
#include "shibokenmacros.h"
-namespace Shiboken
-{
-
-namespace Buffer
+namespace Shiboken::Buffer
{
enum Type {
ReadOnly,
@@ -87,7 +48,6 @@ namespace Buffer
*/
LIBSHIBOKEN_API void *copyData(PyObject *pyObj, Py_ssize_t *size = nullptr);
-} // namespace Buffer
-} // namespace Shiboken
+} // namespace Shiboken::Buffer
#endif
diff --git a/sources/shiboken6/libshiboken/shibokenmacros.h b/sources/shiboken6/libshiboken/shibokenmacros.h
index 1a93d8c3b..3c083c5bb 100644
--- a/sources/shiboken6/libshiboken/shibokenmacros.h
+++ b/sources/shiboken6/libshiboken/shibokenmacros.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 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 SHIBOKENMACROS_H
#define SHIBOKENMACROS_H
diff --git a/sources/shiboken6/libshiboken/signature.h b/sources/shiboken6/libshiboken/signature.h
index 0459d8661..e0130b5a6 100644
--- a/sources/shiboken6/libshiboken/signature.h
+++ b/sources/shiboken6/libshiboken/signature.h
@@ -1,52 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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
#ifndef SIGNATURE_H
#define SIGNATURE_H
+#include "shibokenmacros.h"
+#include "sbkpython.h"
+
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 2894dbace..45269844e 100644
--- a/sources/shiboken6/libshiboken/signature/signature.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 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
////////////////////////////////////////////////////////////////////////////
//
@@ -49,13 +13,16 @@
// General documentation can be found in `signature_doc.rst`.
//
+#include "signature.h"
+#include "signature_p.h"
+
#include "basewrapper.h"
#include "autodecref.h"
#include "sbkstring.h"
#include "sbkstaticstrings.h"
#include "sbkstaticstrings_p.h"
#include "sbkfeature_base.h"
-#include "signature_p.h"
+
#include <structmember.h>
using namespace Shiboken;
@@ -86,6 +53,11 @@ PyObject *GetClassOrModOf(PyObject *ob)
Py_INCREF(ob);
return ob;
}
+#ifdef PYPY_VERSION
+ // PYSIDE-535: PyPy has a special builtin method that acts almost like PyCFunction.
+ if (Py_TYPE(ob) == PepBuiltinMethod_TypePtr)
+ return _get_class_of_bm(ob);
+#endif
if (PyType_IsSubtype(Py_TYPE(ob), &PyCFunction_Type))
return _get_class_of_cf(ob);
if (Py_TYPE(ob) == PepStaticMethod_TypePtr)
@@ -106,27 +78,24 @@ PyObject *GetTypeKey(PyObject *ob)
*
* PYSIDE-1286: We use correct __module__ and __qualname__, now.
*/
- // XXX we obtain also the current selection.
- // from the current module name.
AutoDecRef module_name(PyObject_GetAttr(ob, PyMagicName::module()));
if (module_name.isNull()) {
// We have no module_name because this is a module ;-)
PyErr_Clear();
module_name.reset(PyObject_GetAttr(ob, PyMagicName::name()));
- return Py_BuildValue("O"/*i"*/, module_name.object()/*, getFeatureSelectId()*/);
+ return Py_BuildValue("O", module_name.object());
}
AutoDecRef class_name(PyObject_GetAttr(ob, PyMagicName::qualname()));
if (class_name.isNull()) {
Py_FatalError("Signature: missing class name in GetTypeKey");
return nullptr;
}
- return Py_BuildValue("(O"/*i*/"O)", module_name.object(), /*getFeatureSelectId(),*/
- class_name.object());
+ return Py_BuildValue("(OO)", module_name.object(), class_name.object());
}
static PyObject *empty_dict = nullptr;
-PyObject *TypeKey_to_PropsDict(PyObject *type_key, PyObject *obtype)
+PyObject *TypeKey_to_PropsDict(PyObject *type_key)
{
PyObject *dict = PyDict_GetItem(pyside_globals->arg_dict, type_key);
if (dict == nullptr) {
@@ -167,6 +136,24 @@ static PyObject *_GetSignature_Cached(PyObject *props, PyObject *func_kind, PyOb
return Py_INCREF(value), value;
}
+#ifdef PYPY_VERSION
+PyObject *GetSignature_Method(PyObject *obfunc, PyObject *modifier)
+{
+ AutoDecRef obtype_mod(GetClassOrModOf(obfunc));
+ AutoDecRef type_key(GetTypeKey(obtype_mod));
+ if (type_key.isNull())
+ Py_RETURN_NONE;
+ PyObject *dict = TypeKey_to_PropsDict(type_key);
+ if (dict == nullptr)
+ return nullptr;
+ AutoDecRef func_name(PyObject_GetAttr(obfunc, PyMagicName::name()));
+ PyObject *props = !func_name.isNull() ? PyDict_GetItem(dict, func_name) : nullptr;
+ if (props == nullptr)
+ Py_RETURN_NONE;
+ return _GetSignature_Cached(props, PyName::method(), modifier);
+}
+#endif
+
PyObject *GetSignature_Function(PyObject *obfunc, PyObject *modifier)
{
// make sure that we look into PyCFunction, only...
@@ -176,7 +163,7 @@ PyObject *GetSignature_Function(PyObject *obfunc, PyObject *modifier)
AutoDecRef type_key(GetTypeKey(obtype_mod));
if (type_key.isNull())
Py_RETURN_NONE;
- PyObject *dict = TypeKey_to_PropsDict(type_key, obtype_mod);
+ PyObject *dict = TypeKey_to_PropsDict(type_key);
if (dict == nullptr)
return nullptr;
AutoDecRef func_name(PyObject_GetAttr(obfunc, PyMagicName::name()));
@@ -204,13 +191,13 @@ PyObject *GetSignature_Wrapper(PyObject *ob, PyObject *modifier)
AutoDecRef class_key(GetTypeKey(objclass));
if (func_name.isNull() || objclass.isNull() || class_key.isNull())
return nullptr;
- PyObject *dict = TypeKey_to_PropsDict(class_key, objclass);
+ PyObject *dict = TypeKey_to_PropsDict(class_key);
if (dict == nullptr)
return nullptr;
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;
}
@@ -222,7 +209,7 @@ PyObject *GetSignature_TypeMod(PyObject *ob, PyObject *modifier)
AutoDecRef ob_name(PyObject_GetAttr(ob, PyMagicName::name()));
AutoDecRef ob_key(GetTypeKey(ob));
- PyObject *dict = TypeKey_to_PropsDict(ob_key, ob);
+ PyObject *dict = TypeKey_to_PropsDict(ob_key);
if (dict == nullptr)
return nullptr;
PyObject *props = PyDict_GetItem(dict, ob_name);
@@ -240,9 +227,17 @@ 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)
{
+#ifdef PYPY_VERSION
+ // PYSIDE-535: PyPy has a special builtin method that acts almost like PyCFunction.
+ if (Py_TYPE(ob) == PepBuiltinMethod_TypePtr) {
+ return pyside_bm_get___signature__(ob, modifier);
+ }
+#endif
if (PyType_IsSubtype(Py_TYPE(ob), &PyCFunction_Type))
return pyside_cf_get___signature__(ob, modifier);
if (Py_TYPE(ob) == PepStaticMethod_TypePtr)
@@ -253,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;
}
@@ -261,8 +259,6 @@ static PyObject *get_signature(PyObject * /* self */, PyObject *args)
PyObject *ob;
PyObject *modifier = nullptr;
- init_module_1();
-
if (!PyArg_ParseTuple(args, "O|O", &ob, &modifier))
return nullptr;
if (Py_TYPE(ob) == PepFunction_TypePtr)
@@ -294,14 +290,25 @@ static PyObject *feature_import(PyObject * /* self */, PyObject *args, PyObject
if (import_func == nullptr) {
Py_FatalError("builtins has no \"__orig_import__\" function");
}
- return PyObject_Call(import_func, args, kwds);
+ ret = PyObject_Call(import_func, args, kwds);
+ if (ret) {
+ // PYSIDE-2029: Intercept after the import to search for PySide usage.
+ PyObject *post = PyObject_CallFunctionObjArgs(pyside_globals->feature_imported_func,
+ ret, nullptr);
+ Py_XDECREF(post);
+ if (post == nullptr) {
+ Py_DECREF(ret);
+ return nullptr;
+ }
+ }
+ return ret;
}
PyMethodDef signature_methods[] = {
- {"__feature_import__", (PyCFunction)feature_import, METH_VARARGS | METH_KEYWORDS},
+ {"__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"},
- {nullptr, nullptr}
+ "get the signature, passing an optional string parameter"},
+ {nullptr, nullptr, 0, nullptr}
};
////////////////////////////////////////////////////////////////////////////
@@ -324,7 +331,6 @@ PyMethodDef signature_methods[] = {
static int PySide_BuildSignatureArgs(PyObject *obtype_mod, const char *signatures[])
{
- init_module_1();
AutoDecRef type_key(GetTypeKey(obtype_mod));
/*
* PYSIDE-996: Avoid string overflow in MSVC, which has a limit of
@@ -352,7 +358,6 @@ PyObject *PySide_BuildSignatureProps(PyObject *type_key)
* We simply pick up the arguments that we stored here and replace
* them by the function result.
*/
- init_module_2();
if (type_key == nullptr)
return nullptr;
PyObject *numkey = PyDict_GetItem(pyside_globals->arg_dict, type_key);
@@ -382,8 +387,24 @@ PyObject *PySide_BuildSignatureProps(PyObject *type_key)
//
////////////////////////////////////////////////////////////////////////////
+#ifdef PYPY_VERSION
+static bool get_lldebug_flag()
+{
+ 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;
+}
+
+#endif
+
static int PySide_FinishSignatures(PyObject *module, const char *signatures[])
{
+#ifdef PYPY_VERSION
+ static const bool have_problem = get_lldebug_flag();
+ if (have_problem)
+ return 0; // crash with lldebug at `PyDict_Next`
+#endif
/*
* Initialization of module functions and resolving of static methods.
*/
@@ -403,15 +424,15 @@ static int PySide_FinishSignatures(PyObject *module, const char *signatures[])
* to the PyCFunction attributes. Therefore I simplified things
* and always use our own mapping.
*/
- PyObject *key, *func, *obdict = PyModule_GetDict(module);
+ PyObject *key{};
+ PyObject *func{};
+ PyObject *obdict = PyModule_GetDict(module);
Py_ssize_t pos = 0;
while (PyDict_Next(obdict, &pos, &key, &func))
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).
@@ -433,9 +454,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);
}
@@ -452,7 +476,17 @@ 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!
*/
- if ( PySide_PatchTypes() < 0
+ init_shibokensupport_module();
+
+#ifndef PYPY_VERSION
+ static const bool patch_types = true;
+#else
+ // PYSIDE-535: On PyPy we cannot patch builtin types. This can be
+ // re-implemented later. For now, we use `get_signature`, instead.
+ static const bool patch_types = false;
+#endif
+
+ if ((patch_types && PySide_PatchTypes() < 0)
|| PySide_FinishSignatures(module, signatures) < 0) {
PyErr_Print();
PyErr_SetNone(PyExc_ImportError);
@@ -494,7 +528,11 @@ static PyObject *adjustFuncName(const char *func_name)
return nullptr;
// Run `eval` on the type string to get the object.
+ // PYSIDE-1710: If the eval does not work, return the given string.
AutoDecRef obtype(PyRun_String(_path, Py_eval_input, ns, ns));
+ if (obtype.isNull())
+ return String::fromCString(func_name);
+
if (PyModule_Check(obtype.object())) {
// This is a plain function. Return the unmangled name.
return String::fromCString(func_name);
@@ -502,9 +540,9 @@ static PyObject *adjustFuncName(const char *func_name)
assert(PyType_Check(obtype)); // This was not true for __init__!
// Find the feature flags
- auto type = reinterpret_cast<PyTypeObject *>(obtype.object());
- auto dict = type->tp_dict;
- int id = SbkObjectType_GetReserved(type);
+ auto *type = reinterpret_cast<PyTypeObject *>(obtype.object());
+ AutoDecRef dict(PepType_GetDict(type));
+ int id = currentSelectId(type);
id = id < 0 ? 0 : id; // if undefined, set to zero
auto lower = id & 0x01;
auto is_prop = id & 0x02;
@@ -512,7 +550,7 @@ static PyObject *adjustFuncName(const char *func_name)
// Compute all needed info.
PyObject *name = String::getSnakeCaseName(_name, lower);
- PyObject *prop_name;
+ PyObject *prop_name{};
if (is_prop) {
PyObject *prop_methods = PyDict_GetItem(dict, PyMagicName::property_methods());
prop_name = PyDict_GetItem(prop_methods, name);
@@ -524,36 +562,39 @@ static PyObject *adjustFuncName(const char *func_name)
// Finally, generate the correct path expression.
char _buf[250 + 1] = {};
- if (is_prop) {
+ if (prop_name) {
auto _prop_name = String::toCString(prop_name);
if (is_class_prop)
- sprintf(_buf, "%s.__dict__['%s'].fset", _path, _prop_name);
+ snprintf(_buf, sizeof(_buf), "%s.__dict__['%s'].fset", _path, _prop_name);
else
- sprintf(_buf, "%s.%s.fset", _path, _prop_name);
+ snprintf(_buf, sizeof(_buf), "%s.%s.fset", _path, _prop_name);
}
else {
auto _name = String::toCString(name);
- sprintf(_buf, "%s.%s", _path, _name);
+ snprintf(_buf, sizeof(_buf), "%s.%s", _path, _name);
}
return String::fromCString(_buf);
}
void SetError_Argument(PyObject *args, const char *func_name, PyObject *info)
{
+ init_shibokensupport_module();
/*
* This function replaces the type error construction with extra
* overloads parameter in favor of using the signature module.
* Error messages are rare, so we do it completely in Python.
*/
- init_module_1();
- init_module_2();
// PYSIDE-1305: Handle errors set by fillQtProperties.
if (PyErr_Occurred()) {
- PyObject *e, *v, *t;
+ PyObject *e{};
+ PyObject *v{};
+ PyObject *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));
@@ -569,7 +610,8 @@ void SetError_Argument(PyObject *args, const char *func_name, PyObject *info)
PyErr_Print();
Py_FatalError("seterror_argument did not receive a result");
}
- PyObject *err, *msg;
+ PyObject *err{};
+ PyObject *msg{};
if (!PyArg_UnpackTuple(res, func_name, 2, 2, &err, &msg)) {
PyErr_Print();
Py_FatalError("unexpected failure in seterror_argument");
@@ -584,21 +626,19 @@ 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)
-{
- return pyside_tp_get___signature__(ob, modifier);
-}
-
PyObject *Sbk_TypeGet___doc__(PyObject *ob)
{
+ init_shibokensupport_module();
return pyside_tp_get___doc__(ob);
}
PyObject *GetFeatureDict()
{
- init_module_1();
+ init_shibokensupport_module();
return pyside_globals->feature_dict;
}
diff --git a/sources/shiboken6/libshiboken/signature/signature_doc.rst b/sources/shiboken6/libshiboken/signature/signature_doc.rst
deleted file mode 100644
index 0fb26ae52..000000000
--- a/sources/shiboken6/libshiboken/signature/signature_doc.rst
+++ /dev/null
@@ -1,376 +0,0 @@
-*************************
-The signature C extension
-*************************
-
-This module is a C extension for CPython 3.5 and up, and CPython 2.7.
-Its purpose is to provide support for the ``__signature__`` attribute
-of builtin PyCFunction objects.
-
-
-Short Introduction to the Topic
-===============================
-
-Beginning with CPython 3.5, Python functions began to grow a ``__signature__``
-attribute for normal Python functions. This is totally optional and just
-a nice-to-have feature in Python.
-
-PySide, on the other hand, could use ``__signature__`` very much, because the
-typing info for the 15000+ PySide functions is really missing, and it
-would be nice to have this info directly available.
-
-
-The Idea to Support Signatures
-==============================
-
-We want to have an additional ``__signature__`` attribute in all PySide
-methods, without changing lots of generated code.
-Therefore, we did not change any of the existing data structures,
-but supported the new attribute by a global dictionary.
-
-When the ``__signature__`` property is requested, a method is called that
-does a lookup in the global dict. This is a flexible approach with little impact
-to the rest of the project. It has very limited overhead compared to direct
-attribute access, but for the need of a signature access from time to time,
-this is an adequate compromise.
-
-
-How this Code Works
--------------------
-
-Signatures are supported for regular Python functions, only. Creating signatures
-for ``PyCFunction`` objects would require quite some extra effort in Python.
-
-Fortunately, we found this special *stealth* technique, that saves us most of the
-needed effort:
-
-The basic idea is to create a dummy Python function with **varnames**, **defaults**
-and **annotations** properties, and then to use the inspect
-module to create a signature object. This object is returned as the computed
-result of the ``__signature__`` attribute of the real ``PyCFunction`` object.
-
-There is one thing that really changes Python a bit:
-
-* We added the ``__signature__`` attribute to every function.
-
-That is a little change to Python that does not harm, but it saves us
-tons of code, that was needed in the early versions of the module.
-
-The internal work is done in two steps:
-
-* All functions of a class get the *signature text* when the module is imported.
- This is only a very small overhead added to the startup time. It is a single
- string for each whole class.
-* The actual signature object is created later, when the attribute is really
- requested. Signatures are cached and only created on first access.
-
-Example:
-
-The ``PyCFunction`` ``QtWidgets.QApplication.palette`` is interrogated for its
-signature. That means ``pyside_sm_get___signature__()`` is called.
-It calls ``GetSignature_Function`` which returns the signature if it is found.
-
-
-Why this Code is Fast
----------------------
-
-It costs a little time (maybe 6 seconds) to run through every single signature
-object, since these are more than 25000 Python objects. But all the signature
-objects will be rarely accessed but in special applications.
-The normal case are only a few accesses, and these are working pretty fast.
-
-The key to make this signature module fast is to avoid computation as much as
-possible. When no signature objects are used, then almost no time is lost in
-initialization. Only the above mentioned strings and some support modules are
-additionally loaded on ``import PySide6``.
-When it comes to signature usage, then late initialization is used and cached.
-This technique is also known as *full laziness* in haskell.
-
-There are actually two locations where late initialization occurs:
-
-* ``dict`` can be no dict but a tuple. That is the initial argument tuple that
- was saved by ``PySide_BuildSignatureArgs`` at module load time.
- If so, then ``pyside_type_init`` in parser.py will be called,
- which parses the string and creates the dict.
-* ``props`` can be empty. Then ``create_signature`` in loader.py
- is called, which uses a dummy function to produce a signature instance
- with the inspect module.
-
-The initialization that is always done is just two dictionary writes
-per class, and we have about 1000 classes.
-To measure the additional overhead, we have simulated what happens
-when ``from PySide6 import *`` is performed.
-It turned out that the overhead is below 0.5 ms.
-
-
-The Signature Package Structure
--------------------------------
-
-The C++ code involved with the signature module is completely in the file
-shiboken6/libshiboken/signature.cpp . All other functionality is implemented in
-the ``signature`` Python package. It has the following structure::
-
- shiboken6/files.dir/shibokensupport/
- backport_inspect.py
-
- signature/
- loader.py
- parser.py
- mapping.py
- errorhandler.py
- layout.py
-
- lib/
- enum_sig.py
- tool.py
-
-
-
-Really important are the **parser**, **mapping**, **errorhandler**, **enum_sig**,
-**layout** and **loader** modules. The rest is needed to create Python 2 compatibility
-or be compatible with embedding and installers.
-
-
-loader.py
-~~~~~~~~~
-
-This module assembles and imports the ``inspect`` module, and then exports the
-``create_signature`` function. This function takes a fake function and some
-attributes and builds a ``__signature__`` object with the inspect module.
-
-
-parser.py
-~~~~~~~~~
-
-This module takes a class signatures string from C++ and parses it into the
-needed properties for the ``create_signature`` function. Its entry point is the
-``pyside_type_init`` function, which is called from the C module via ``loader.py``.
-
-
-mapping.py
-~~~~~~~~~~
-
-The purpose of the mapping module is maintaining a list of replacement strings
-that map from the *signature text* in C to the property strings that Python
-needs. A lot of mappings are resolved by rather complex expressions in ``parser.py``,
-but a few hundred cases are better to spell explicitly, here.
-
-
-errorhandler.py
-~~~~~~~~~~~~~~~
-
-Since ``Qt For Python 5.12``, we no longer use the builtin type error messages from C++.
-Instead, we get much better results with the signature module. At the same time,
-this enforced supporting shiboken as well, and the signature module was no longer
-optional.
-
-
-enum_sig.py
-~~~~~~~~~~~
-
-The diverse applications of the signature module all needed to iterate over modules,
-classes and functions. In order to centralize this enumeration, the process has
-been factored out as a context manager. The user has only to supply functions
-that do the actual formatting.
-
-See for example the .pyi generator ``pyside6/PySide6/support/generate_pyi.py``.
-
-
-layout.py
-~~~~~~~~~
-
-As more applications used the signature module, different formatting of signatures
-was needed. To support that, we created the function ``create_signature``, which
-has a parameter to choose from some predefined layouts.
-
-
-*typing27.py*
-~~~~~~~~~~~~~
-
-Python 2 has no typing module at all. This is a backport of the minimum that is needed.
-
-
-*backport_inspect.py*
-~~~~~~~~~~~~~~~~~~~~~
-
-Python 2 has an inspect module, but lacks the signature functions, completely.
-This module adds the missing functionality, which is merged at runtime into
-the inspect module.
-
-
-Multiple Arities
-----------------
-
-One aspect that was ignored so far was *multiple arities*: How to handle it when
-a function has more than one signature?
-
-I did not find any note on how multiple signatures should be treated in Python,
-but this simple rules seem to work well:
-
-* If there is a list, then it is a multi-signature.
-* Otherwise, it is a simple signature.
-
-
-Impacts of The Signature Module
-===============================
-
-The signature module has a number of impacts to other PySide modules, which were
-created as a consequence of its existence, and there will be a few more in the
-future:
-
-
-existence_test.py
------------------
-
-The file ``pyside6/tests/registry/existence_test.py`` was written using the
-signatures from the signatures module. The idea is that there are some 15000
-functions with a certain signature.
-
-These functions should not get lost by some bad check-in. Therefore, a list
-of all existing signatures is kept as a module that assembles a
-dictionary. The function existence is checked, and also the exact arity.
-
-This module exists for every PySide release and every platform. The initial
-module is generated once and saved as ``exists_{plat}_{version}.py``.
-
-An error is normally only reported as a warning, but:
-
-
-Interaction With The Coin Module
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When this test program is run in COIN, then the warnings are turned into
-errors. The reason is that only in COIN, we have a stable configuration
-of PySide modules that can reliably be compared.
-
-These modules have the name ``exists_{platf}_{version}_ci.py``, and as a big
-exception for generated code, these files are *intentionally* checked in.
-
-
-What Happens When a List is Missing?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-When a new version of PySide gets created, then the existence test files
-initially do not exist.
-
-When a COIN test is run, then it will complain about the error and create
-the missing module on standard output.
-But since COIN tests are run multiple times, the output that was generated
-by the first test will still exist at the subsequent runs.
-(If COIN was properly implemented, we could not take that advantage and
-would need to implement that as an extra exception.)
-
-As a result, a missing module will be reported as a test which partially
-succeeded (called "FLAKY"). To avoid further flaky tests and to activate as a real test,
-we can now capture the error output of COIN and check the generated module
-in.
-
-
-Explicitly Enforcing Recreation
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The former way to regenerate the registry files was to remove the files
-and check that in. This has the desired effect, but creates huge deltas.
-As a more efficient way, we have prepared a comment in the first line
-that contains the word "recreate".
-By uncommenting this line, a NameError is triggered, which has the same
-effect.
-
-
-init_platform.py
-~~~~~~~~~~~~~~~~
-
-For generating the ``exists_{platf}_{version}`` modules, the module
-``pyside6/tests/registry/init_platform.py`` was written. It can be used
-standalone from the commandline, to check the compatibility of some
-changes, directly.
-
-
-scrape_testresults.py
----------------------
-
-To simplify and automate the process of extracting the ``exists_{platf}_{version}_ci.py``
-files, the script ``pyside6/tests/registry/scrape_testresults.py`` has been written.
-
-This script scans the whole testresults website for PySide, that is::
-
- https://testresults.qt.io/coin/api/results/pyside/pyside-setup/
-
-On the first scan, the script runs less than 30 minutes. After that, a cache
-is generated and the scan works *much* faster. The test results are placed
-into the folder ``pyside6/tests/registry/testresults/embedded/`` with a
-unique name that allows for easy sorting. Example::
-
- testresults/embedded/2018_09_10_10_40_34-test_1536891759-exists_linux_5_11_2_ci.py
-
-These files are created only once. If they already exist, they are not touched, again.
-The file `pyside6/tests/registry/known_urls.json`` holds all scanned URLs after
-a successful scan. The ``testresults/embedded`` folder can be kept for reference
-or can be removed. Important is only the json file.
-
-The result of a scan is then directly placed into the ``pyside6/tests/registry/``
-folder. It should be reviewed and then eventually checked in.
-
-
-generate_pyi.py
----------------
-
-``pyside6/PySide6/support/generate_pyi.py`` is still under development.
-This module generates so-called hinting stubs for integration of PySide
-with diverse *Python IDEs*.
-
-Although this module creates the stubs as an add-on, the
-impact on the quality of the signature module is considerable:
-
-The module must create syntactically correct ``.pyi`` files which contain
-not only signatures but also constants and enums of all PySide modules.
-This serves as an extra challenge that has a very positive effect on
-the completeness and correctness of signatures.
-
-The module has a ``--feature`` option to generate modified .pyi files.
-A shortcut for this command is ``pyside6-genpyi``.
-
-A useful command to change all .pyi files to use all features is
-
-.. code-block:: python
-
- pyside6-genpyi all --feature snake_case true_property
-
-
-pyi_generator.py
-----------------
-
-``shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/pyi_generator.py``
-has been extracted from ``generate_pyi.py``. It allows the generation of ``.pyi``
-files from arbitrary extension modules created with shiboken.
-
-A shortcut for this command is ``shiboken6-genpyi``.
-
-
-Current Extensions
-------------------
-
-Before the signature module was written, there already existed the concept of
-signatures, but in a more C++ - centric way. From that time, there existed
-the error messages, which are created when a function gets wrong argument types.
-
-These error messages were replaced by text generated on demand by
-the signature module, in order to be more consistent and correct.
-This was implemented in ``Qt For Python 5.12.0``.
-
-Additionally, the ``__doc__`` attribute of PySide methods was not set.
-It was easy to get a nice ``help()`` feature by creating signatures
-as default content for docstrings.
-This was implemented in ``Qt For Python 5.12.1``.
-
-
-Literature
-==========
-
- `PEP 362 – Function Signature Object <https://www.python.org/dev/peps/pep-0362/>`__
-
- `PEP 484 – Type Hints <https://www.python.org/dev/peps/pep-0484/>`__
-
- `PEP 3107 – Function Annotations <https://www.python.org/dev/peps/pep-3107/>`__
-
-
-*Personal Remark: This module is dedicated to our lovebird "Püppi", who died on 2017-09-15.*
diff --git a/sources/shiboken6/libshiboken/signature/signature_extend.cpp b/sources/shiboken6/libshiboken/signature/signature_extend.cpp
index 67a37e41c..3ce9e21e3 100644
--- a/sources/shiboken6/libshiboken/signature/signature_extend.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature_extend.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 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
////////////////////////////////////////////////////////////////////////////
//
@@ -48,12 +12,14 @@
// PyMethodDescr_Type
// PyCFunction_Type
// PyStaticMethod_Type
-// PyType_Type
+// (*) PyType_Type
// PyWrapperDescr_Type
//
-// Their `tp_getset` fields are modified so support the `__signature__`
+// Their `tp_getset` fields are modified to support the `__signature__`
// attribute and additions to the `__doc__` attribute.
//
+// PYSIDE-535: PyType_Type patching is removed,
+// Shiboken.ObjectType and Shiboken.EnumMeta have new getsets, instead.
#include "autodecref.h"
#include "sbkstring.h"
@@ -89,27 +55,29 @@ static PyObject *_get_written_signature(signaturefunc sf, PyObject *ob, PyObject
return ret;
}
+#ifdef PYPY_VERSION
+PyObject *pyside_bm_get___signature__(PyObject *func, PyObject *modifier)
+{
+ return _get_written_signature(GetSignature_Method, func, modifier);
+}
+#endif
+
PyObject *pyside_cf_get___signature__(PyObject *func, PyObject *modifier)
{
- init_module_2();
return _get_written_signature(GetSignature_Function, func, modifier);
}
PyObject *pyside_sm_get___signature__(PyObject *sm, PyObject *modifier)
{
- init_module_2();
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);
}
PyObject *pyside_md_get___signature__(PyObject *ob_md, PyObject *modifier)
{
- init_module_2();
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);
@@ -117,13 +85,11 @@ PyObject *pyside_md_get___signature__(PyObject *ob_md, PyObject *modifier)
PyObject *pyside_wd_get___signature__(PyObject *ob, PyObject *modifier)
{
- init_module_2();
return _get_written_signature(GetSignature_Wrapper, ob, modifier);
}
PyObject *pyside_tp_get___signature__(PyObject *obtype_mod, PyObject *modifier)
{
- init_module_2();
return _get_written_signature(GetSignature_TypeMod, obtype_mod, modifier);
}
@@ -153,29 +119,27 @@ static int handle_doc_in_progress = 0;
static PyObject *handle_doc(PyObject *ob, PyObject *old_descr)
{
- init_module_1();
- init_module_2();
AutoDecRef ob_type_mod(GetClassOrModOf(ob));
- const char *name;
- if (PyModule_Check(ob_type_mod.object()))
- name = PyModule_GetName(ob_type_mod.object());
- else
- name = reinterpret_cast<PyTypeObject *>(ob_type_mod.object())->tp_name;
+ bool isModule = PyModule_Check(ob_type_mod.object());
+ const char *name = isModule
+ ? PyModule_GetName(ob_type_mod.object())
+ : reinterpret_cast<PyTypeObject *>(ob_type_mod.object())->tp_name;
+ PyObject *res{};
+
if (handle_doc_in_progress || name == nullptr
- || strncmp(name, "PySide6.", 8) != 0)
- return PyObject_CallMethodObjArgs(old_descr,
- PyMagicName::get(),
- ob, nullptr);
- handle_doc_in_progress++;
- PyObject *res = PyObject_CallFunction(
- pyside_globals->make_helptext_func,
- "(O)", ob);
- handle_doc_in_progress--;
- if (res == nullptr) {
- PyErr_Print();
- Py_FatalError("handle_doc did not receive a result");
+ || (isModule && strncmp(name, "PySide6.", 8) != 0)) {
+ res = PyObject_CallMethodObjArgs(old_descr, PyMagicName::get(), ob, nullptr);
+ } else {
+ handle_doc_in_progress++;
+ res = PyObject_CallFunction(pyside_globals->make_helptext_func, "(O)", ob);
+ handle_doc_in_progress--;
}
- return res;
+
+ if (res)
+ return res;
+
+ PyErr_Clear();
+ Py_RETURN_NONE;
}
static PyObject *pyside_cf_get___doc__(PyObject *cf)
@@ -203,66 +167,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_PyType_getsets[] = {
- {const_cast<char *>("__doc__"), reinterpret_cast<getter>(pyside_tp_get___doc__),
- nullptr, nullptr, nullptr},
- {const_cast<char *>("__signature__"), reinterpret_cast<getter>(pyside_tp_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}
};
@@ -276,23 +203,20 @@ int PySide_PatchTypes(void)
AutoDecRef wrap_descr(PyObject_GetAttrString(
reinterpret_cast<PyObject *>(Py_TYPE(Py_True)), "__add__"));
// abbreviations for readability
- auto md_gs = new_PyMethodDescr_getsets;
- auto md_doc = &old_md_doc_descr;
- auto cf_gs = new_PyCFunction_getsets;
- auto cf_doc = &old_cf_doc_descr;
- auto sm_gs = new_PyStaticMethod_getsets;
- auto sm_doc = &old_sm_doc_descr;
- auto tp_gs = new_PyType_getsets;
- auto tp_doc = &old_tp_doc_descr;
- auto wd_gs = new_PyWrapperDescr_getsets;
- auto wd_doc = &old_wd_doc_descr;
+ auto *md_gs = new_PyMethodDescr_getsets;
+ auto *md_doc = &old_md_doc_descr;
+ auto *cf_gs = new_PyCFunction_getsets;
+ auto *cf_doc = &old_cf_doc_descr;
+ auto *sm_gs = new_PyStaticMethod_getsets;
+ auto *sm_doc = &old_sm_doc_descr;
+ auto *wd_gs = new_PyWrapperDescr_getsets;
+ auto *wd_doc = &old_wd_doc_descr;
if (meth_descr.isNull() || wrap_descr.isNull()
|| PyType_Ready(Py_TYPE(meth_descr)) < 0
|| add_more_getsets(PepMethodDescr_TypePtr, md_gs, md_doc) < 0
|| add_more_getsets(&PyCFunction_Type, cf_gs, cf_doc) < 0
|| add_more_getsets(PepStaticMethod_TypePtr, sm_gs, sm_doc) < 0
- || add_more_getsets(&PyType_Type, tp_gs, tp_doc) < 0
|| add_more_getsets(Py_TYPE(wrap_descr), wd_gs, wd_doc) < 0
)
return -1;
diff --git a/sources/shiboken6/libshiboken/signature/signature_globals.cpp b/sources/shiboken6/libshiboken/signature/signature_globals.cpp
index 744ce0407..0a08309cc 100644
--- a/sources/shiboken6/libshiboken/signature/signature_globals.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature_globals.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 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
////////////////////////////////////////////////////////////////////////////
//
@@ -64,51 +28,37 @@ static const unsigned char PySide_SignatureLoader[] = {
#include "embed/signature_bootstrap_inc.h"
};
-static PyObject *_init_pyside_extension(PyObject * /* self */, PyObject * /* args */)
+static safe_globals_struc *init_phase_1()
{
- init_module_1();
- init_module_2();
- Py_RETURN_NONE;
-}
-
-// This function will be inserted into __builtins__.
-static PyMethodDef init_methods[] = {
- {"_init_pyside_extension", (PyCFunction)_init_pyside_extension, METH_NOARGS},
- {nullptr, nullptr}
-};
-
-static safe_globals_struc *init_phase_1(PyMethodDef *init_meth)
-{
- {
+ do {
auto *p = reinterpret_cast<safe_globals_struc *>
(malloc(sizeof(safe_globals_struc)));
if (p == nullptr)
- goto error;
+ break;
/*
* Initializing module signature_bootstrap.
* Since we now have an embedding script, we can do this without any
* Python strings in the C code.
*/
-#ifdef Py_LIMITED_API
- // We must work for multiple versions, so use source code.
+#if defined(Py_LIMITED_API) || defined(SHIBOKEN_NO_EMBEDDING_PYC)
+ // We must work for multiple versions or we are cross-building for a different
+ // Python version interpreter, so use source code.
#else
- AutoDecRef marshal_module(PyImport_Import(PyName::marshal()));
- if (marshal_module.isNull())
- goto error;
+ AutoDecRef marshal_module(PyImport_Import(PyName::marshal())); // builtin
AutoDecRef loads(PyObject_GetAttr(marshal_module, PyName::loads()));
if (loads.isNull())
- goto error;
+ break;
#endif
char *bytes_cast = reinterpret_cast<char *>(
const_cast<unsigned char *>(PySide_SignatureLoader));
AutoDecRef bytes(PyBytes_FromStringAndSize(bytes_cast, sizeof(PySide_SignatureLoader)));
if (bytes.isNull())
- goto error;
-#ifdef Py_LIMITED_API
+ break;
+#if defined(Py_LIMITED_API) || defined(SHIBOKEN_NO_EMBEDDING_PYC)
PyObject *builtins = PyEval_GetBuiltins();
PyObject *compile = PyDict_GetItem(builtins, PyName::compile());
if (compile == nullptr)
- goto error;
+ break;
AutoDecRef code_obj(PyObject_CallFunction(compile, "Oss",
bytes.object(), "signature_bootstrap.py", "exec"));
#else
@@ -116,69 +66,62 @@ static safe_globals_struc *init_phase_1(PyMethodDef *init_meth)
loads, bytes.object(), nullptr));
#endif
if (code_obj.isNull())
- goto error;
+ break;
p->helper_module = PyImport_ExecCodeModule("signature_bootstrap", code_obj);
if (p->helper_module == nullptr)
- goto error;
+ break;
// Initialize the module
PyObject *mdict = PyModule_GetDict(p->helper_module);
if (PyDict_SetItem(mdict, PyMagicName::builtins(), PyEval_GetBuiltins()) < 0)
- goto error;
- /*
- * Unpack an embedded ZIP file with more signature modules.
+ break;
+
+ /*********************************************************************
+ *
+ * Attention!
+ * ----------
+ *
+ * We are unpacking an embedded ZIP file with more signature modules.
* They will be loaded later with the zipimporter.
- * Due to MSVC's limitation to 64k strings, we need to assemble pieces.
+ * The file `signature_bootstrap.py` does the unpacking and starts the
+ * loader. See `init_phase_2`.
+ *
+ * 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, *zipped_string_sequence = PyList_New(0);
- if (zipped_string_sequence == nullptr)
- return nullptr;
+ 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)
- goto error;
+ break;
}
if (PyDict_SetItemString(mdict, "zipstring_sequence", zipped_string_sequence) < 0)
- goto error;
- Py_DECREF(zipped_string_sequence);
+ break;
// build a dict for diverse mappings
p->map_dict = PyDict_New();
- if (p->map_dict == nullptr)
- goto error;
// build a dict for the prepared arguments
p->arg_dict = PyDict_New();
- if (p->arg_dict == nullptr
- || PyObject_SetAttrString(p->helper_module, "pyside_arg_dict", p->arg_dict) < 0)
- goto error;
+ if (PyObject_SetAttrString(p->helper_module, "pyside_arg_dict", p->arg_dict) < 0)
+ break;
// build a dict for assigned signature values
p->value_dict = PyDict_New();
- if (p->value_dict == nullptr)
- goto error;
// PYSIDE-1019: build a __feature__ dict
p->feature_dict = PyDict_New();
- if (p->feature_dict == nullptr
- || PyObject_SetAttrString(p->helper_module, "pyside_feature_dict", p->feature_dict) < 0)
- goto error;
+ if (PyObject_SetAttrString(p->helper_module, "pyside_feature_dict", p->feature_dict) < 0)
+ break;
// This function will be disabled until phase 2 is done.
p->finish_import_func = nullptr;
- // Initialize the explicit init function.
- AutoDecRef init(PyCFunction_NewEx(init_meth, nullptr, nullptr));
- if (init.isNull()
- || PyDict_SetItemString(PyEval_GetBuiltins(), init_meth->ml_name, init) != 0)
- goto error;
-
return p;
- }
-error:
+
+ } while (false);
+
PyErr_Print();
Py_FatalError("could not initialize part 1");
return nullptr;
@@ -186,15 +129,13 @@ error:
static int init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
{
- {
- PyMethodDef *ml;
-
+ do {
// The single function to be called, but maybe more to come.
- for (ml = methods; ml->ml_name != nullptr; ml++) {
+ for (PyMethodDef *ml = methods; ml->ml_name != nullptr; ++ml) {
PyObject *v = PyCFunction_NewEx(ml, nullptr, nullptr);
if (v == nullptr
|| PyObject_SetAttrString(p->helper_module, ml->ml_name, v) != 0)
- goto error;
+ break;
Py_DECREF(v);
}
// The first entry is __feature_import__, add documentation.
@@ -205,33 +146,59 @@ static int init_phase_2(safe_globals_struc *p, PyMethodDef *methods)
PyObject *bootstrap_func = PyObject_GetAttrString(p->helper_module, "bootstrap");
if (bootstrap_func == nullptr)
- goto error;
- // The return value of the bootstrap function is the loader module.
- PyObject *loader = PyObject_CallFunction(bootstrap_func, "()");
+ break;
+
+ /*********************************************************************
+ *
+ * Attention!
+ * ----------
+ *
+ * This is the entry point where everything in folder
+ * `shibokensupport` becomes initialized. It starts with
+ * `signature_bootstrap.py` and continues from there to `loader.py`.
+ *
+ * The return value of the bootstrap function is the loader module.
+ */
+ PyObject *loader = PyObject_CallFunctionObjArgs(bootstrap_func, nullptr);
if (loader == nullptr)
- goto error;
+ break;
+
// now the loader should be initialized
p->pyside_type_init_func = PyObject_GetAttrString(loader, "pyside_type_init");
if (p->pyside_type_init_func == nullptr)
- goto error;
+ break;
p->create_signature_func = PyObject_GetAttrString(loader, "create_signature");
if (p->create_signature_func == nullptr)
- goto error;
+ break;
p->seterror_argument_func = PyObject_GetAttrString(loader, "seterror_argument");
if (p->seterror_argument_func == nullptr)
- goto error;
+ break;
p->make_helptext_func = PyObject_GetAttrString(loader, "make_helptext");
if (p->make_helptext_func == nullptr)
- goto error;
+ break;
p->finish_import_func = PyObject_GetAttrString(loader, "finish_import");
if (p->finish_import_func == nullptr)
- goto error;
+ break;
p->feature_import_func = PyObject_GetAttrString(loader, "feature_import");
if (p->feature_import_func == nullptr)
- goto error;
+ break;
+ 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;
- }
-error:
+
+ } while (0);
+
PyErr_Print();
Py_FatalError("could not initialize part 2");
return -1;
@@ -240,25 +207,23 @@ error:
#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) {
#if defined(__GLIBC__)
void *array[30];
- size_t size;
-
// get void *'s for all entries on the stack
- size = backtrace(array, 30);
+ const int size = backtrace(array, 30);
// 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
@@ -268,14 +233,14 @@ static void handler(int sig) {
////////////////////////////////////////////////////////////////////////////
#endif // _WIN32
-safe_globals pyside_globals = nullptr;
+safe_globals_struc *pyside_globals = nullptr;
-void init_module_1(void)
+void init_shibokensupport_module(void)
{
static int init_done = 0;
if (!init_done) {
- pyside_globals = init_phase_1(init_methods);
+ pyside_globals = init_phase_1();
if (pyside_globals != nullptr)
init_done = 1;
@@ -286,17 +251,6 @@ void init_module_1(void)
signal(SIGSEGV, handler); // install our handler
#endif // _WIN32
- }
-}
-
-void init_module_2(void)
-{
- static int init_done = 0;
-
- if (!init_done) {
- // Phase 2 will call __init__.py which touches a signature, itself.
- // Therefore we set init_done prior to init_phase_2().
- init_done = 1;
init_phase_2(pyside_globals, signature_methods);
// Enum must be initialized when signatures exist, not earlier.
init_enum();
diff --git a/sources/shiboken6/libshiboken/signature/signature_helper.cpp b/sources/shiboken6/libshiboken/signature/signature_helper.cpp
index d27ddeabb..9aab7a6a9 100644
--- a/sources/shiboken6/libshiboken/signature/signature_helper.cpp
+++ b/sources/shiboken6/libshiboken/signature/signature_helper.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 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
////////////////////////////////////////////////////////////////////////////
//
@@ -53,6 +17,8 @@
#include "signature_p.h"
+#include <cstring>
+
using namespace Shiboken;
extern "C" {
@@ -79,8 +45,6 @@ static int _fixup_getset(PyTypeObject *type, const char *name, PyGetSetDef *new_
for (; md->name != nullptr; md++)
if (strcmp(md->name, name) == 0)
return 1;
- // staticmethod has just a `__doc__` in the class
- assert(strcmp(type->tp_name, "staticmethod") == 0 && strcmp(name, "__doc__") == 0);
return 0;
}
@@ -89,10 +53,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) {
@@ -107,6 +74,9 @@ int add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **doc_descr)
AutoDecRef descr(PyDescr_NewGetSet(type, gsp));
if (descr.isNull())
return -1;
+ // PYSIDE-535: We cannot set the attribute. For simplicity, we use
+ // get_signature in PyPy, instead. This can be re-implemented
+ // later by deriving extra heap types.
if (PyDict_SetItemString(dict, gsp->name, descr) < 0)
return -1;
}
@@ -147,11 +117,11 @@ static PyObject *_func_with_new_name(PyTypeObject *type,
* but does not create a descriptor.
* XXX Maybe we can get rid of this, completely?
*/
- auto obtype = reinterpret_cast<PyObject *>(type);
- int len = strlen(new_name);
- auto name = new char[len + 1];
- strcpy(name, new_name);
- auto new_meth = new PyMethodDef;
+ auto *obtype = reinterpret_cast<PyObject *>(type);
+ const size_t len = std::strlen(new_name);
+ auto *name = new char[len + 1];
+ std::strcpy(name, new_name);
+ auto *new_meth = new PyMethodDef;
new_meth->ml_name = name;
new_meth->ml_meth = meth->ml_meth;
new_meth->ml_flags = meth->ml_flags;
@@ -223,13 +193,13 @@ static PyObject *_build_new_entry(PyObject *new_name, PyObject *value)
PyObject *new_value = PyDict_Copy(value);
PyObject *multi = PyDict_GetItem(value, PyName::multi());
if (multi != nullptr && Py_TYPE(multi) == &PyList_Type) {
- ssize_t len = PyList_Size(multi);
+ Py_ssize_t len = PyList_Size(multi);
AutoDecRef list(PyList_New(len));
if (list.isNull())
return nullptr;
for (int idx = 0; idx < len; ++idx) {
- auto multi_entry = PyList_GetItem(multi, idx);
- auto dup = PyDict_Copy(multi_entry);
+ auto *multi_entry = PyList_GetItem(multi, idx);
+ auto *dup = PyDict_Copy(multi_entry);
if (PyDict_SetItem(dup, PyName::name(), new_name) < 0)
return nullptr;
if (PyList_SetItem(list, idx, dup) < 0)
@@ -247,7 +217,8 @@ static PyObject *_build_new_entry(PyObject *new_name, PyObject *value)
int insert_snake_case_variants(PyObject *dict)
{
AutoDecRef snake_dict(PyDict_New());
- PyObject *key, *value;
+ PyObject *key{};
+ PyObject *value{};
Py_ssize_t pos = 0;
while (PyDict_Next(dict, &pos, &key, &value)) {
AutoDecRef name(String::getSnakeCaseName(key, true));
@@ -258,6 +229,15 @@ int insert_snake_case_variants(PyObject *dict)
return PyDict_Merge(dict, snake_dict, 0);
}
+#ifdef PYPY_VERSION
+PyObject *_get_class_of_bm(PyObject *ob_bm)
+{
+ AutoDecRef self(PyObject_GetAttr(ob_bm, PyMagicName::self()));
+ auto *klass = PyObject_GetAttr(self, PyMagicName::class_());
+ return klass;
+}
+#endif
+
PyObject *_get_class_of_cf(PyObject *ob_cf)
{
PyObject *selftype = PyCFunction_GET_SELF(ob_cf);
@@ -301,7 +281,7 @@ PyObject *_address_to_stringlist(PyObject *numkey)
* When needed in `PySide_BuildSignatureProps`, the strings are
* finally materialized.
*/
- ssize_t address = PyNumber_AsSsize_t(numkey, PyExc_ValueError);
+ Py_ssize_t address = PyNumber_AsSsize_t(numkey, PyExc_ValueError);
if (address == -1 && PyErr_Occurred())
return nullptr;
char **sig_strings = reinterpret_cast<char **>(address);
@@ -317,7 +297,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.
@@ -333,7 +313,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)
@@ -376,8 +366,8 @@ static int _build_func_to_type(PyObject *obtype)
if (descr == nullptr)
return -1;
char mangled_name[200];
- strcpy(mangled_name, meth->ml_name);
- strcat(mangled_name, ".overload");
+ std::strcpy(mangled_name, meth->ml_name);
+ std::strcat(mangled_name, ".overload");
if (PyDict_SetItemString(dict, mangled_name, descr) < 0)
return -1;
if (meth->ml_flags & METH_STATIC) {
@@ -399,26 +389,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/signature_p.h b/sources/shiboken6/libshiboken/signature/signature_p.h
deleted file mode 100644
index 7e622f3f1..000000000
--- a/sources/shiboken6/libshiboken/signature/signature_p.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef SIGNATURE_IMPL_H
-#define SIGNATURE_IMPL_H
-
-#include "signature.h"
-
-extern "C" {
-
-// signature_globals.cpp
-
-typedef struct safe_globals_struc {
- // init part 1: get arg_dict
- PyObject *helper_module;
- PyObject *arg_dict;
- PyObject *map_dict;
- PyObject *value_dict; // for writing signatures
- PyObject *feature_dict; // registry for PySide.support.__feature__
- // init part 2: run module
- PyObject *pyside_type_init_func;
- PyObject *create_signature_func;
- PyObject *seterror_argument_func;
- PyObject *make_helptext_func;
- PyObject *finish_import_func;
- PyObject *feature_import_func;
-} safe_globals_struc, *safe_globals;
-
-extern safe_globals pyside_globals;
-extern PyMethodDef signature_methods[];
-
-void init_module_1(void);
-void init_module_2(void);
-
-// signature.cpp
-
-PyObject *GetTypeKey(PyObject *ob);
-
-PyObject *GetSignature_Function(PyObject *, PyObject *);
-PyObject *GetSignature_TypeMod(PyObject *, PyObject *);
-PyObject *GetSignature_Wrapper(PyObject *, PyObject *);
-
-PyObject *get_signature_intern(PyObject *ob, PyObject *modifier);
-PyObject *PySide_BuildSignatureProps(PyObject *class_mod);
-PyObject *GetClassOrModOf(PyObject *ob);
-
-// signature_extend.cpp
-
-PyObject *pyside_cf_get___signature__(PyObject *func, PyObject *modifier);
-PyObject *pyside_sm_get___signature__(PyObject *sm, PyObject *modifier);
-PyObject *pyside_md_get___signature__(PyObject *ob_md, PyObject *modifier);
-PyObject *pyside_wd_get___signature__(PyObject *ob, PyObject *modifier);
-PyObject *pyside_tp_get___signature__(PyObject *obtype_mod, PyObject *modifier);
-
-int PySide_PatchTypes(void);
-PyObject *pyside_tp_get___doc__(PyObject *tp);
-
-// signature_helper.cpp
-
-int add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **doc_descr);
-PyObject *name_key_to_func(PyObject *ob);
-int insert_snake_case_variants(PyObject *dict);
-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 _finish_nested_classes(PyObject *dict);
-
-} // extern "C"
-
-#endif // SIGNATURE_IMPL_H
diff --git a/sources/shiboken6/libshiboken/signature_p.h b/sources/shiboken6/libshiboken/signature_p.h
new file mode 100644
index 000000000..d0c4ee537
--- /dev/null
+++ b/sources/shiboken6/libshiboken/signature_p.h
@@ -0,0 +1,78 @@
+// Copyright (C) 2020 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 SIGNATURE_IMPL_H
+#define SIGNATURE_IMPL_H
+
+#include "signature.h"
+
+extern "C" {
+
+// signature_globals.cpp
+
+struct safe_globals_struc {
+ // init part 1: get arg_dict
+ PyObject *helper_module;
+ PyObject *arg_dict;
+ PyObject *map_dict;
+ PyObject *value_dict; // for writing signatures
+ PyObject *feature_dict; // registry for PySide.support.__feature__
+ // init part 2: run module
+ PyObject *pyside_type_init_func;
+ PyObject *create_signature_func;
+ PyObject *seterror_argument_func;
+ PyObject *make_helptext_func;
+ PyObject *finish_import_func;
+ PyObject *feature_import_func;
+ PyObject *feature_imported_func;
+};
+
+extern safe_globals_struc *pyside_globals;
+extern PyMethodDef signature_methods[];
+
+void init_shibokensupport_module(void);
+
+// signature.cpp
+
+PyObject *GetTypeKey(PyObject *ob);
+
+PyObject *GetSignature_Function(PyObject *, PyObject *);
+PyObject *GetSignature_TypeMod(PyObject *, PyObject *);
+PyObject *GetSignature_Wrapper(PyObject *, PyObject *);
+
+LIBSHIBOKEN_API PyObject *get_signature_intern(PyObject *ob, PyObject *modifier);
+PyObject *PySide_BuildSignatureProps(PyObject *class_mod);
+PyObject *GetClassOrModOf(PyObject *ob);
+
+// signature_extend.cpp
+PyObject *pyside_cf_get___signature__(PyObject *func, PyObject *modifier);
+PyObject *pyside_sm_get___signature__(PyObject *sm, PyObject *modifier);
+PyObject *pyside_md_get___signature__(PyObject *ob_md, PyObject *modifier);
+PyObject *pyside_wd_get___signature__(PyObject *ob, PyObject *modifier);
+PyObject *pyside_tp_get___signature__(PyObject *obtype_mod, PyObject *modifier);
+
+int PySide_PatchTypes(void);
+PyObject *pyside_tp_get___doc__(PyObject *tp);
+
+// signature_helper.cpp
+
+int add_more_getsets(PyTypeObject *type, PyGetSetDef *gsp, PyObject **doc_descr);
+PyObject *name_key_to_func(PyObject *ob);
+int insert_snake_case_variants(PyObject *dict);
+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
+// PyPy has a special builtin method.
+PyObject *GetSignature_Method(PyObject *, PyObject *);
+PyObject *pyside_bm_get___signature__(PyObject *func, PyObject *modifier);
+PyObject *_get_class_of_bm(PyObject *ob_cf);
+#endif
+
+} // extern "C"
+
+#endif // SIGNATURE_IMPL_H
diff --git a/sources/shiboken6/libshiboken/threadstatesaver.cpp b/sources/shiboken6/libshiboken/threadstatesaver.cpp
index 7c587b405..9f74ed442 100644
--- a/sources/shiboken6/libshiboken/threadstatesaver.cpp
+++ b/sources/shiboken6/libshiboken/threadstatesaver.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 "threadstatesaver.h"
diff --git a/sources/shiboken6/libshiboken/threadstatesaver.h b/sources/shiboken6/libshiboken/threadstatesaver.h
index ddfbcb93b..4289f6726 100644
--- a/sources/shiboken6/libshiboken/threadstatesaver.h
+++ b/sources/shiboken6/libshiboken/threadstatesaver.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 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 THREADSTATESAVER_H
#define THREADSTATESAVER_H
diff --git a/sources/shiboken6/libshiboken/voidptr.cpp b/sources/shiboken6/libshiboken/voidptr.cpp
index 7a6a04e3a..ce85d4946 100644
--- a/sources/shiboken6/libshiboken/voidptr.cpp
+++ b/sources/shiboken6/libshiboken/voidptr.cpp
@@ -1,67 +1,32 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 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 "voidptr.h"
+#include "pep384ext.h"
#include "sbkconverter.h"
#include "basewrapper.h"
#include "basewrapper_p.h"
+#include "sbktypefactory.h"
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)
+PyObject *SbkVoidPtrObject_new(PyTypeObject *type, PyObject * /* args */, PyObject * /* kwds */)
{
// PYSIDE-560: It is much safer to first call a function and then do a
// type cast than to do everything in one line. The bad construct looked
// 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;
@@ -72,12 +37,12 @@ PyObject *SbkVoidPtrObject_new(PyTypeObject *type, PyObject *args, PyObject *kwd
return reinterpret_cast<PyObject *>(self);
}
-#define SbkVoidPtr_Check(op) (Py_TYPE(op) == SbkVoidPtrTypeF())
+#define SbkVoidPtr_Check(op) (Py_TYPE(op) == SbkVoidPtr_TypeF())
int SbkVoidPtrObject_init(PyObject *self, PyObject *args, PyObject *kwds)
{
- PyObject *addressObject;
+ PyObject *addressObject{};
Py_ssize_t size = -1;
int isWritable = 0;
auto *sbkSelf = reinterpret_cast<SbkVoidPtrObject *>(self);
@@ -189,13 +154,12 @@ PyObject *SbkVoidPtrObject_int(PyObject *v)
return PyLong_FromVoidPtr(sbkObject->cptr);
}
-PyObject *toBytes(PyObject *self, PyObject *args)
+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);
@@ -203,8 +167,8 @@ PyObject *toBytes(PyObject *self, PyObject *args)
}
static struct PyMethodDef SbkVoidPtrObject_methods[] = {
- {"toBytes", toBytes, METH_NOARGS},
- {nullptr}
+ {"toBytes", toBytes, METH_NOARGS, nullptr},
+ {nullptr, nullptr, 0, nullptr}
};
static Py_ssize_t SbkVoidPtrObject_length(PyObject *v)
@@ -292,46 +256,49 @@ 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.shiboken6.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 *SbkVoidPtrTypeF(void)
+PyTypeObject *SbkVoidPtr_TypeF(void)
{
- static PyTypeObject *type = SbkType_FromSpec_BMDWBD(&SbkVoidPtrType_spec,
- nullptr, nullptr, 0, 0,
- &SbkVoidPtrObjectBufferProc,
- nullptr);
+ static auto *type = createVoidPtrType();
return type;
}
+} // extern "C"
+
namespace VoidPtr {
static int voidPointerInitialized = false;
void init()
{
- if (PyType_Ready(SbkVoidPtrTypeF()) < 0)
+ if (PyType_Ready(SbkVoidPtr_TypeF()) < 0)
Py_FatalError("[libshiboken] Failed to initialize Shiboken.VoidPtr type.");
else
voidPointerInitialized = true;
@@ -340,9 +307,9 @@ void init()
void addVoidPtrToModule(PyObject *module)
{
if (voidPointerInitialized) {
- Py_INCREF(SbkVoidPtrTypeF());
- PyModule_AddObject(module, PepType_GetNameStr(SbkVoidPtrTypeF()),
- reinterpret_cast<PyObject *>(SbkVoidPtrTypeF()));
+ Py_INCREF(SbkVoidPtr_TypeF());
+ PyModule_AddObject(module, PepType_GetNameStr(SbkVoidPtr_TypeF()),
+ reinterpret_cast<PyObject *>(SbkVoidPtr_TypeF()));
}
}
@@ -351,7 +318,7 @@ static PyObject *createVoidPtr(void *cppIn, Py_ssize_t size = 0, bool isWritable
if (!cppIn)
Py_RETURN_NONE;
- SbkVoidPtrObject *result = PyObject_New(SbkVoidPtrObject, SbkVoidPtrTypeF());
+ SbkVoidPtrObject *result = PyObject_New(SbkVoidPtrObject, SbkVoidPtr_TypeF());
if (!result)
Py_RETURN_NONE;
@@ -424,7 +391,7 @@ static PythonToCppFunc PythonBufferToCppIsConvertible(PyObject *pyIn)
SbkConverter *createConverter()
{
- SbkConverter *converter = Shiboken::Conversions::createConverter(SbkVoidPtrTypeF(), toPython);
+ SbkConverter *converter = Shiboken::Conversions::createConverter(SbkVoidPtr_TypeF(), toPython);
Shiboken::Conversions::addPythonToCppValueConversion(converter,
VoidPtrToCpp,
VoidPtrToCppIsConvertible);
@@ -439,28 +406,28 @@ SbkConverter *createConverter()
void setSize(PyObject *voidPtr, Py_ssize_t size)
{
- assert(voidPtr->ob_type == SbkVoidPtrTypeF());
+ assert(voidPtr->ob_type == SbkVoidPtr_TypeF());
auto *voidPtrObj = reinterpret_cast<SbkVoidPtrObject *>(voidPtr);
voidPtrObj->size = size;
}
Py_ssize_t getSize(PyObject *voidPtr)
{
- assert(voidPtr->ob_type == SbkVoidPtrTypeF());
+ assert(voidPtr->ob_type == SbkVoidPtr_TypeF());
auto *voidPtrObj = reinterpret_cast<SbkVoidPtrObject *>(voidPtr);
return voidPtrObj->size;
}
bool isWritable(PyObject *voidPtr)
{
- assert(voidPtr->ob_type == SbkVoidPtrTypeF());
+ assert(voidPtr->ob_type == SbkVoidPtr_TypeF());
auto *voidPtrObj = reinterpret_cast<SbkVoidPtrObject *>(voidPtr);
return voidPtrObj->isWritable;
}
void setWritable(PyObject *voidPtr, bool isWritable)
{
- assert(voidPtr->ob_type == SbkVoidPtrTypeF());
+ assert(voidPtr->ob_type == SbkVoidPtr_TypeF());
auto *voidPtrObj = reinterpret_cast<SbkVoidPtrObject *>(voidPtr);
voidPtrObj->isWritable = isWritable;
}
diff --git a/sources/shiboken6/libshiboken/voidptr.h b/sources/shiboken6/libshiboken/voidptr.h
index 018f6124e..8360bf9c7 100644
--- a/sources/shiboken6/libshiboken/voidptr.h
+++ b/sources/shiboken6/libshiboken/voidptr.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 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 VOIDPTR_H
#define VOIDPTR_H
@@ -48,7 +12,7 @@ extern "C"
{
// Void pointer type declaration.
-extern LIBSHIBOKEN_API PyTypeObject *SbkVoidPtrTypeF(void);
+extern LIBSHIBOKEN_API PyTypeObject *SbkVoidPtr_TypeF(void);
} // extern "C"
diff --git a/sources/shiboken6/shiboken_tool.py b/sources/shiboken6/shiboken_tool.py
index e136794f7..30d334f44 100755
--- a/sources/shiboken6/shiboken_tool.py
+++ b/sources/shiboken6/shiboken_tool.py
@@ -1,43 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
import sys
import os
import subprocess
@@ -53,10 +16,12 @@ def main():
def genpyi():
- shiboken_dir = Path(__file__).resolve().parents[2] / "shiboken6"
- support = shiboken_dir / "files.dir" / "shibokensupport"
- cmd = support / "signature" / "lib" / "pyi_generator.py"
- command = [sys.executable, os.fspath(cmd)] + sys.argv[1:]
+ # After we changed the shibokensupport module to be totally virtual,
+ # it is no longer possible to call the pyi generator from the file system.
+ command = [sys.executable, "-c",
+ "import shiboken6;"
+ "from shibokensupport.signature.lib.pyi_generator import main;"
+ "main()"] + sys.argv[1:]
sys.exit(subprocess.call(command))
diff --git a/sources/shiboken6/shiboken_version.py b/sources/shiboken6/shiboken_version.py
index b5ebfa59c..07b247316 100644
--- a/sources/shiboken6/shiboken_version.py
+++ b/sources/shiboken6/shiboken_version.py
@@ -1,53 +1,17 @@
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
-major_version = "6"
-minor_version = "0"
-patch_version = "0"
+major_version = "@shiboken_MAJOR_VERSION@"
+minor_version = "@shiboken_MINOR_VERSION@"
+patch_version = "@shiboken_MICRO_VERSION@"
# For example: "a", "b", "rc"
# (which means "alpha", "beta", "release candidate").
# An empty string means the generated package will be an official release.
-release_version_type = "a"
+release_version_type = "@shiboken_PRE_RELEASE_VERSION_TYPE@"
# For example: "1", "2" (which means "beta1", "beta2", if type is "b").
-pre_release_version = "1"
+pre_release_version = "@shiboken_PRE_RELEASE_VERSION@"
if __name__ == '__main__':
# Used by CMake.
diff --git a/sources/shiboken6/shibokenmodule/CMakeLists.txt b/sources/shiboken6/shibokenmodule/CMakeLists.txt
index 085613510..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"
@@ -7,24 +10,30 @@ set(sample_SRC ${CMAKE_CURRENT_BINARY_DIR}/Shiboken/shiboken_module_wrapper.cpp)
set(shibokenmodule_TYPESYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_shiboken.xml)
+shiboken_get_tool_shell_wrapper(shiboken tool_wrapper)
+
add_custom_command(
-OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
-BYPRODUCTS ${sample_SRC}
-# Note: shiboken6 is an executable target. By not specifying its explicit
-# path, CMAKE figures it out, itself!
-# This fixes an issue with Visual Studio, see https://github.com/PySide/shiboken6/pull/11
-COMMAND shiboken6 --project-file=${CMAKE_CURRENT_BINARY_DIR}/shibokenmodule.txt ${GENERATOR_EXTRA_FLAGS}
-DEPENDS ${shibokenmodule_TYPESYSTEM}
-WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-COMMENT "Running generator for 'Shiboken'..."
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+ BYPRODUCTS ${sample_SRC}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Shiboken6::shiboken6>
+ --project-file=${CMAKE_CURRENT_BINARY_DIR}/shibokenmodule.txt
+ ${GENERATOR_EXTRA_FLAGS}
+ DEPENDS ${shibokenmodule_TYPESYSTEM}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Running generator for 'Shiboken'..."
)
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")
@@ -33,6 +42,8 @@ target_link_libraries(shibokenmodule PUBLIC libshiboken)
create_generator_target(shibokenmodule)
+qfp_strip_library("shibokenmodule")
+
install(TARGETS shibokenmodule DESTINATION ${PYTHON_SITE_PACKAGES}/shiboken6)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/_config.py.in"
@@ -40,6 +51,11 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/_config.py.in"
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_config.py"
DESTINATION "${PYTHON_SITE_PACKAGES}/shiboken6")
+if ("${MINIMUM_PYTHON_VERSION}" STREQUAL "")
+ set(MINIMUM_PYTHON_VERSION None)
+ set(MAXIMUM_PYTHON_VERSION None)
+endif()
+
# PYSIDE-1497: This `..` is the crucial trick to unify the path location of `Shiboken`.
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in"
"${CMAKE_CURRENT_BINARY_DIR}/../__init__.py" @ONLY)
diff --git a/sources/shiboken6/shibokenmodule/Shiboken.pyi b/sources/shiboken6/shibokenmodule/Shiboken.pyi
index e312f6912..6a1a63217 100644
--- a/sources/shiboken6/shibokenmodule/Shiboken.pyi
+++ b/sources/shiboken6/shibokenmodule/Shiboken.pyi
@@ -1,42 +1,5 @@
-# This Python file uses the following encoding: utf-8
-#############################################################################
-##
-## Copyright (C) 2021 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
from __future__ import annotations
@@ -55,19 +18,20 @@ 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: ...
-def createdByPython(arg__1: object) -> bool: ...
-def delete(arg__1: object) -> None: ...
-def dump(arg__1: object) -> object: ...
-def getAllValidWrappers() -> object: ...
-def getCppPointer(arg__1: object) -> object: ...
-def invalidate(arg__1: object) -> None: ...
+def createdByPython(arg__1: Shiboken.Object) -> bool: ...
+def delete(arg__1: Shiboken.Object) -> None: ...
+def dump(arg__1: object) -> str: ...
+def getAllValidWrappers() -> list[Shiboken.Object]: ...
+def getCppPointer(arg__1: Shiboken.Object) -> tuple[int, ...]: ...
+def invalidate(arg__1: Shiboken.Object) -> None: ...
def isValid(arg__1: object) -> bool: ...
-def ownedByPython(arg__1: object) -> bool: ...
-def wrapInstance(arg__1: int, arg__2: type) -> object: ...
+def ownedByPython(arg__1: Shiboken.Object) -> bool: ...
+def wrapInstance(arg__1: int, arg__2: type) -> Shiboken.Object: ...
# eof
diff --git a/sources/shiboken6/shibokenmodule/__init__.py.in b/sources/shiboken6/shibokenmodule/__init__.py.in
index 3dd59b024..c859160bc 100644
--- a/sources/shiboken6/shibokenmodule/__init__.py.in
+++ b/sources/shiboken6/shibokenmodule/__init__.py.in
@@ -1,5 +1,7 @@
__version__ = "@FINAL_PACKAGE_VERSION@"
__version_info__ = (@shiboken_MAJOR_VERSION@, @shiboken_MINOR_VERSION@, @shiboken_MICRO_VERSION@, "@shiboken_PRE_RELEASE_VERSION_TYPE@", "@shiboken_PRE_RELEASE_VERSION@")
+__minimum_python_version__ = @MINIMUM_PYTHON_VERSION@
+__maximum_python_version__ = @MAXIMUM_PYTHON_VERSION@
# PYSIDE-932: Python 2 cannot import 'zipfile' for embedding while being imported, itself.
# We simply pre-load all imports for the signature extension.
@@ -23,6 +25,3 @@ import functools
import typing
from shiboken6.Shiboken import *
-
-# Trigger signature initialization via __builtins__.
-_init_pyside_extension()
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/__init__.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/__init__.py
index 2d640cb89..e54bec75a 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/__init__.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/__init__.py
@@ -1,40 +1,4 @@
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
# this file intentionally left blank
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/feature.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/feature.py
index 8776c7de9..7a0871ee7 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/feature.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/feature.py
@@ -1,41 +1,8 @@
-#############################################################################
-##
-## Copyright (C) 2020 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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)
@@ -51,9 +18,10 @@ 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
import sys
from contextlib import contextmanager
@@ -68,7 +36,7 @@ all_feature_names = [
"_feature_80",
]
-__all__ = ["all_feature_names", "set_selection", "info"] + all_feature_names
+__all__ = ["all_feature_names", "info", "reset", "set_selection"] + all_feature_names
snake_case = 0x01
true_property = 0x02
@@ -115,11 +83,13 @@ 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.
# PYSIDE-1338: The "1" below is the redirection in loader.py .
# PYSIDE-1548: Ensure that features are not affected by other imports.
+ # PYSIDE-2029: Need to always switch. The cache was wrong interpreted.
calling_frame = _cf = sys._getframe(1).f_back
importing_module = _cf.f_globals.get("__name__", "__main__") if _cf else "__main__"
existing = pyside_feature_dict.get(importing_module, 0)
@@ -141,24 +111,66 @@ def feature_import(name, *args, **kwargs):
# Initialize feature (multiple times allowed) and clear cache.
sys.modules["PySide6.QtCore"].__init_feature__()
return sys.modules["__feature__"]
-
- if importing_module not in pyside_feature_dict:
- # Ignore new modules if not from PySide.
- default = 0 if name.split(".")[0] == "PySide6" else -1
- pyside_feature_dict[importing_module] = default
# Redirect to the original import
return None
+
_is_initialized = False
+
def __init__():
global _is_initialized
if not _is_initialized:
# use _one_ recursive import...
import PySide6.QtCore
# Initialize all prior imported modules
- for name in sys.modules:
- pyside_feature_dict.setdefault(name, -1)
+ for name, module in sys.modules.items():
+ if name not in pyside_feature_dict:
+ pyside_feature_dict[name] = 0 if _mod_uses_pyside(module) else -1
+ _is_initialized = True
+
+
+def feature_imported(module):
+ # PYSIDE-2029: Need to inspect imported modules for PySide usage.
+ """
+ Set the module feature default after import.
+
+ A module that uses PySide has a switching default of 0 = "no feature".
+ Otherwise the default is -1 = "ignore this module".
+ """
+
+ # 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):
+ """
+ Find out if this module uses PySide.
+
+ Simple approach: Search the source code for the string "PySide6".
+ Maybe we later support source-less modules by inspecting all code objects.
+ """
+ try:
+ source = inspect.getsource(module)
+ except TypeError:
+ # this is a builtin module like sys
+ return False
+ 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
def set_selection(select_id, mod_name=None):
@@ -177,6 +189,14 @@ def set_selection(select_id, mod_name=None):
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():
+ set_selection(0)
+ pyside_feature_dict.clear()
+ _is_initialized = False
+
+
def info(mod_name=None):
"""
Internal use: Return the current selection
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/fix-complaints.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/fix-complaints.py
index 396f6ca4c..f7190b12f 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/fix-complaints.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/fix-complaints.py
@@ -1,44 +1,5 @@
-# This Python file uses the following encoding: utf-8
-# It has been edited by fix-complaints.py .
-
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
"""
fix-complaints.py
@@ -48,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
@@ -63,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()
@@ -80,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 = []
@@ -90,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/__init__.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/__init__.py
index 7ae0a7f18..bebf56c7e 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/__init__.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/__init__.py
@@ -1,40 +1,4 @@
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
__all__ = "get_signature layout mapping lib".split()
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
index 71f2ffbab..c2a19efef 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py
@@ -1,41 +1,7 @@
-#############################################################################
-##
-## Copyright (C) 2020 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
@@ -54,21 +20,33 @@ enough to produce a useful ValueError.
This matter will be improved in a later version.
"""
-import inspect
-import sys
+import collections.abc
+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
def qt_isinstance(inst, the_type):
if the_type == float:
- return isinstance(inst, int) or isinstance(int, float)
+ # Qt thinks differently about int and float - simply keep it.
+ return isinstance(inst, int) or isinstance(inst, float)
+ if the_type.__module__ == "typing":
+ if the_type is typing.Any:
+ return True
+ if the_type.__origin__ is typing.Union:
+ return any(qt_isinstance(inst, _) for _ in the_type.__args__)
+ if the_type.__origin__ in (collections.abc.Sequence,
+ collections.abc.Iterable):
+ try:
+ return all(qt_isinstance(_, the_type.__args__[0]) for _ in inst)
+ except TypeError:
+ return False
try:
return isinstance(inst, the_type)
except TypeError as e:
- print("FIXME", e)
+ print(f"FIXME qt_isinstance({inst}, {the_type}):", e)
return False
@@ -82,13 +60,7 @@ def matched_type(args, sigs):
if params[k].default is params[k].empty:
# this is a necessary parameter, so it fails.
continue
- ok = True
- for arg, param in zip(args, params):
- ann = param.annotation
- if qt_isinstance(arg, ann):
- continue
- ok = False
- if ok:
+ if all(qt_isinstance(arg, param.annotation) for arg, param in zip(args, params)):
return sig
return None
@@ -98,12 +70,15 @@ def seterror_argument(args, func_name, info):
try:
func = eval(func_name, namespace)
except Exception as e:
- msg = f"Internal error evaluating {func_name}: " + str(e)
- return TypeError, msg
+ msg = f"Error evaluating `{func_name}`: {e}"
+ return type(e), msg
if info and type(info) is str:
err = TypeError
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.")
elif info == ">":
msg = f"{func_name}(): too many arguments"
elif info.isalnum():
@@ -112,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
@@ -151,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 b37aefbb5..bae264294 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
"""
importhandler.py
@@ -70,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:
@@ -98,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 2fd2b6c4f..0e781cbcb 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/layout.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
"""
layout.py
@@ -115,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()
@@ -151,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__"]:
@@ -203,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:
@@ -219,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):
@@ -236,7 +202,7 @@ def create_signature(props, key):
# parser.
pass
else:
- if varnames[0] in ("self", "cls"):
+ if varnames and varnames[0] in ("self", "cls"):
varnames = varnames[1:]
# calculate the modifications
@@ -270,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/__init__.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py
index 2d640cb89..e54bec75a 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py
@@ -1,40 +1,4 @@
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
# this file intentionally left blank
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 149881e01..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
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2020 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
"""
enum_sig.py
@@ -50,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
"""
@@ -67,6 +29,16 @@ declared in the same class, we use `builtins.property` in the class and
all sub-classes. The same consideration holds for "overload".
"""
+_normal_functions = (types.BuiltinFunctionType, types.FunctionType)
+if hasattr(sys, "pypy_version_info"):
+ # In PyPy, there are more types because our builtin functions
+ # are created differently in C++ and not in PyPy.
+ _normal_functions += (type(get_sig),)
+
+
+def signal_check(thing):
+ return thing and type(thing) in (Signal, SignalInstance)
+
class ExactEnumerator(object):
"""
@@ -78,13 +50,13 @@ class ExactEnumerator(object):
"""
def __init__(self, formatter, result_type=dict):
- global EnumMeta
+ global EnumMeta, Signal, SignalInstance
try:
# Lazy import
- from PySide6.QtCore import Qt
+ from PySide6.QtCore import Qt, Signal, SignalInstance
EnumMeta = type(Qt.Key)
except ImportError:
- EnumMeta = None
+ EnumMeta = Signal = SignalInstance = None
self.fmt = formatter
self.result_type = result_type
@@ -98,7 +70,7 @@ class ExactEnumerator(object):
We check if it is a simple function.
"""
tp = type(self.func)
- return tp not in (types.BuiltinFunctionType, types.FunctionType)
+ return tp not in _normal_functions
def section(self):
if hasattr(self.fmt, "section"):
@@ -126,9 +98,13 @@ class ExactEnumerator(object):
def klass(self, class_name, klass):
ret = self.result_type()
+ if ("._") in class_name:
+ # This happens when introspecting enum.Enum etc. Python 3.8.8 does not
+ # like this, but we want to remove that, anyway.
+ 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 = []
@@ -146,9 +122,19 @@ class ExactEnumerator(object):
functions = []
enums = []
properties = []
+ signals = []
+ attributes = {}
for thing_name, thing in class_members:
- if inspect.isclass(thing):
+ 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):
@@ -156,22 +142,32 @@ class ExactEnumerator(object):
functions.append((func_name, thing))
elif type(type(thing)) is EnumMeta:
# take the real enum name, not what is in the dict
- enums.append((thing_name, type(thing).__qualname__, thing))
+ if not thing_name.startswith("_"):
+ 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)
- enums.sort(key=lambda tup: tup[1 : 3]) # sort by class then enum value
+ # sort by class then enum value
+ 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 hasattr(_[1], "__signature__") and _[1].__signature__)
- self.fmt.have_body = bool(subclasses or sigs or properties or enums or init_signature)
+ sigs = list(_ for _ in functions if get_sig(_[1]))
+ 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
@@ -181,8 +177,25 @@ 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, int(value)):
+ with self.fmt.enum(enum_class_name, enum_name, value.value):
pass
+ if hasattr(self.fmt, "signal"):
+ # this is an optional feature
+ if len(signals):
+ self.section()
+ for signal_name, signal in signals:
+ sig_class = type(signal)
+ sig_class_name = f"{sig_class.__qualname__}"
+ 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:
@@ -206,7 +219,7 @@ class ExactEnumerator(object):
@staticmethod
def get_signature(func):
- return func.__signature__
+ return get_sig(func)
def function(self, func_name, func, decorator=None):
self.func = func # for is_method()
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 8a786b574..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
@@ -1,44 +1,10 @@
LICENSE_TEXT = """
-#############################################################################
-##
-## Copyright (C) 2021 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
+
"""
pyi_generator.py
@@ -50,7 +16,6 @@ import io
import logging
import os
import re
-import subprocess
import sys
import typing
@@ -58,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
@@ -96,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:
@@ -111,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.
@@ -121,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
@@ -138,8 +108,6 @@ class Formatter(Writer):
txt = f"""\
# Module `{mod_name}`
- from shiboken6 import Shiboken
-
<<IMPORTS>>
"""
self.print(dedent(txt))
@@ -190,17 +158,34 @@ class Formatter(Writer):
self.print(f"{spaces}{enum_name:25}: {class_name} = ... # {hexval}")
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}")
+ yield
+
def find_imports(text):
return [imp for imp in PySide6.__all__ if f"PySide6.{imp}." in text]
FROM_IMPORTS = [
- ("typing", typing.__all__),
- ("PySide6.QtCore", ["PyClassProperty"]),
(None, ["builtins"]),
+ (None, ["os"]),
+ (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
@@ -210,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", 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
@@ -250,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()
@@ -282,35 +272,30 @@ def generate_pyi(import_name, outpath, options):
# we remove the "<<IMPORTS>>" marker and insert imports if needed
if line == "<<IMPORTS>>":
text = outfile.getvalue()
+ wr.print("import " + import_name)
+ for mod_name in find_imports(text):
+ imp = "PySide6." + mod_name
+ if imp != import_name:
+ wr.print("import " + imp)
+ wr.print()
for mod, imports in filter_from_imports(FROM_IMPORTS, text):
import_args = ', '.join(imports)
if mod is None:
# special case, a normal import
wr.print(f"import {import_args}")
- elif mod != import_name:
+ else:
wr.print(f"from {mod} import {import_args}")
wr.print()
- if need_imports:
- for mod_name in find_imports(text):
- imp = "PySide6." + mod_name
- if imp != import_name:
- wr.print("import " + imp)
- # Do not import Shiboken which is handled already.
- if import_name != "Shiboken":
- wr.print("import " + import_name)
wr.print()
+ wr.print("NoneType: TypeAlias = type[None]")
wr.print()
else:
wr.print(line)
if not options.quiet:
options.logger.info(f"Generated: {outfilepath}")
- if options and (options.check or options.is_ci):
- # Python 3.7 and up: We can check the file directly if the syntax is ok.
- if USE_PEP563:
- subprocess.check_output([sys.executable, os.fspath(outfilepath)])
-if __name__ == "__main__":
+def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=dedent("""\
@@ -322,11 +307,10 @@ if __name__ == "__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
@@ -344,4 +328,7 @@ if __name__ == "__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 4ded95c36..979dcf4ce 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
"""
tool.py
@@ -80,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
__ = " "
@@ -115,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 82d6f75b6..fb4c9eeca 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/loader.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/loader.py
@@ -1,44 +1,8 @@
-# This Python file uses the following encoding: utf-8
-# It has been edited by fix-complaints.py .
-
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
@@ -69,39 +33,54 @@ 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
global feature_import
- feature_import = __feature__.feature_import
+ 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
+ global feature_imported
+ feature_imported = feature.feature_imported
+ return feature_imported(*args, **kwds)
+
+
import builtins
import signature_bootstrap
-from shibokensupport import signature, feature as __feature__
+from shibokensupport import signature, feature
signature.get_signature = signature_bootstrap.get_signature
# PYSIDE-1019: Publish the __feature__ dictionary.
-__feature__.pyside_feature_dict = signature_bootstrap.pyside_feature_dict
+feature.pyside_feature_dict = signature_bootstrap.pyside_feature_dict
builtins.__feature_import__ = signature_bootstrap.__feature_import__
del signature_bootstrap
+is_pypy = hasattr(sys, "pypy_version_info")
+
def put_into_package(package, module, override=None):
# take the last component of the module name
@@ -124,7 +103,8 @@ def move_into_pyside_package():
except ModuleNotFoundError:
# This can happen in the embedding case.
put_into_package(PySide6, shibokensupport, "support")
- put_into_package(PySide6.support, __feature__, "__feature__")
+ if not is_pypy:
+ put_into_package(PySide6.support, feature)
put_into_package(PySide6.support, signature)
put_into_package(PySide6.support.signature, mapping)
put_into_package(PySide6.support.signature, errorhandler)
@@ -136,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
@@ -146,21 +127,32 @@ from shibokensupport.signature.lib import enum_sig
from shibokensupport.signature.lib import pyi_generator
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, so this is actually no import
- 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 73da611ba..944a928e6 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/mapping.py
@@ -1,41 +1,7 @@
-#############################################################################
-##
-## Copyright (C) 2021 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
@@ -54,16 +20,17 @@ import typing
from pathlib import Path
from typing import TypeVar, Generic
-from shibokensupport.signature.lib.tool import with_metaclass
+from _imp import is_builtin
+
class ellipsis(object):
def __repr__(self):
return "..."
+
ellipsis = ellipsis()
-Point = typing.Tuple[float, float]
+Point = typing.Tuple[int, int]
Variant = typing.Any
-ModelIndexList = typing.List[int]
QImageCleanupFunction = typing.Callable
# unfortunately, typing.Optional[t] expands to typing.Union[t, NoneType]
@@ -75,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
@@ -111,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)".
@@ -123,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.
@@ -135,6 +104,7 @@ class Missing(_NotCalled):
class Invalid(_NotCalled):
pass
+
# Helper types
class Default(_NotCalled):
pass
@@ -143,6 +113,7 @@ class Default(_NotCalled):
class Instance(_NotCalled):
pass
+
# Parameterized primitive variables
class _Parameterized(object):
def __init__(self, type):
@@ -152,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)
@@ -179,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 False
+ return bool(hasattr(mod, "__name__") and is_builtin(mod.__name__))
def update(self):
"""
@@ -217,28 +191,29 @@ 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,
- "char*": str,
- "char*const": str,
"double": float,
"float": float,
"int": int,
"List": ArrayLikeVariable,
"Optional": typing.Optional,
"long": int,
+ "long long": int,
"nullptr": None,
"PyCallable": typing.Callable,
"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,
@@ -255,6 +230,7 @@ type_map.update({
"uintptr_t": int,
"qintptr": int,
"qsizetype": int,
+ "QFunctionPointer": int,
"QList": ArrayLikeVariable,
"qlonglong": int,
"QMap": typing.Dict,
@@ -265,6 +241,7 @@ type_map.update({
"qreal": float,
"QSet": typing.Set,
"QString": str,
+ "QLatin1String": str,
"QStringView": str,
"QStringList": StringList,
"quint16": int,
@@ -276,6 +253,7 @@ type_map.update({
"uint32_t": int,
"uint64_t": int,
"uint8_t": int,
+ "Union": typing.Union,
"quintptr": int,
"qulonglong": int,
"QVariant": Variant,
@@ -287,6 +265,7 @@ type_map.update({
"signed long": int,
"std.list": typing.List,
"std.map": typing.Dict,
+ "std.nullptr_t": NoneType,
"std.pair": typing.Tuple,
"std.string": str,
"std.wstring": str,
@@ -300,17 +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,
- "Unspecified": None,
"ushort": int,
- "void": int, # be more specific?
+ "void": int, # be more specific?
"WId": WId,
"zero(bytes)": b"",
"zero(Char)": 0,
@@ -320,7 +298,11 @@ type_map.update({
"zero(str)": "",
"zero(typing.Any)": None,
"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:
@@ -332,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
@@ -344,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:
@@ -368,6 +350,7 @@ type_map.update({
"qint32*" : ResultVariable(int),
"qint64*" : ResultVariable(int),
"qreal*" : ResultVariable(float),
+ "qsizetype*" : ResultVariable(int),
"QString*" : ResultVariable(str),
"qintptr*" : ResultVariable(int),
"quintptr*" : ResultVariable(int),
@@ -375,7 +358,7 @@ type_map.update({
"uint*" : ResultVariable(int),
"unsigned int*" : ResultVariable(int),
"QStringList*" : ResultVariable(StringList),
- })
+})
type_map.update({
@@ -383,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({
@@ -406,6 +390,7 @@ def init_Shiboken():
})
return locals()
+
def init_minimal():
type_map.update({
"MinBool": bool,
@@ -418,8 +403,10 @@ def init_sample():
type_map.update({
"char": int,
"char**": typing.List[str],
+ "const char*": str,
"Complex": complex,
"double": float,
+ "ByteArray&": typing.Union[bytes, bytearray, memoryview],
"Foo.HANDLE": int,
"HANDLE": int,
"Null": None,
@@ -427,6 +414,7 @@ def init_sample():
"OddBool": bool,
"PStr": str,
"PyDate": datetime.date,
+ "PyBuffer": typing.Union[bytes, bytearray, memoryview],
"sample.bool": bool,
"sample.char": int,
"sample.double": float,
@@ -437,6 +425,7 @@ def init_sample():
"sample.Photon.TemplateBase[Photon.IdentityType]": sample.Photon.ValueIdentity,
"sample.Point": Point,
"sample.PStr": str,
+ "SampleNamespace.InValue.ZeroIn": 0,
"sample.unsigned char": int,
"std.size_t": int,
"std.string": str,
@@ -461,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
@@ -473,8 +463,8 @@ def init_smart():
# The PySide Part
def init_PySide6_QtCore():
from PySide6.QtCore import Qt, QUrl, QDir, QKeyCombination
- from PySide6.QtCore import QRect, QSize, QPoint, QLocale, QByteArray
- from PySide6.QtCore import QMarginsF # 5.9
+ from PySide6.QtCore import QRect, QRectF, QSize, QPoint, QLocale, QByteArray
+ from PySide6.QtCore import QMarginsF # 5.9
from PySide6.QtCore import SignalInstance
try:
# seems to be not generated by 5.9 ATM.
@@ -485,61 +475,69 @@ 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?!
- "QModelIndexList": ModelIndexList,
- "QModelIndexList": ModelIndexList,
+ "QModelIndex()": Invalid("PySide6.QtCore.QModelIndex"), # repr is btw. very wrong, fix it?!
+ "QModelIndexList": typing.List[PySide6.QtCore.QModelIndex],
"PySideSignalInstance": SignalInstance,
"QString()": "",
"Flag.Default": Instance("PySide6.QtCore.QStringConverterBase.Flags"),
"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.
pass
+
+ # special case - char* can either be 'bytes' or 'str'. The default is 'bytes'.
+ # Here we manually set it to map to 'str'.
+ type_map.update({("PySide6.QtCore.QObject.setProperty", "char*"): str})
+ type_map.update({("PySide6.QtCore.QObject.property", "char*"): str})
+
return locals()
@@ -554,37 +552,48 @@ 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,
"GL_COLOR_BUFFER_BIT": GL_COLOR_BUFFER_BIT,
"GL_NEAREST": GL_NEAREST,
"int32_t": int,
- "QPixmap()": Default("PySide6.QtGui.QPixmap"), # can't create without qApp
- "QPlatformSurface*": int, # a handle
- "QVector< QTextLayout.FormatRange >()": [], # do we need more structure?
+ "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?
"uint32_t": int,
"uint8_t": int,
"USHRT_MAX": ushort_max,
})
+
+ # special case - char* can either be 'bytes' or 'str'. The default is 'bytes'.
+ # Here we manually set it to map to 'str'.
+ type_map.update({("PySide6.QtGui.QPixmap.save", "char*"): str})
+
return locals()
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)"),
"QWidget.RenderFlags(DrawWindowBackground | DrawChildren)": Instance(
"QWidget.RenderFlags(QWidget.DrawWindowBackground | QWidget.DrawChildren)"),
- "SH_Default": QStyleHintReturn.SH_Default,
- "SO_Complex": QStyleOptionComplex.SO_Complex,
- "SO_Default": QStyleOption.SO_Default,
"static_cast<Qt.MatchFlags>(Qt.MatchExactly|Qt.MatchCaseSensitive)": Instance(
"Qt.MatchFlags(Qt.MatchExactly | Qt.MatchCaseSensitive)"),
- "Type": PySide6.QtWidgets.QListWidgetItem.Type,
+ "static_cast<Qt.MatchFlag>(Qt.MatchExactly|Qt.MatchCaseSensitive)": Instance(
+ "Qt.MatchFlag(Qt.MatchExactly | Qt.MatchCaseSensitive)"),
+ "QListWidgetItem.ItemType.Type": PySide6.QtWidgets.QListWidgetItem.Type,
+ "QTableWidgetItem.ItemType.Type": PySide6.QtWidgets.QTableWidgetItem.Type,
+ "QTreeWidgetItem.ItemType.Type": PySide6.QtWidgets.QTreeWidgetItem.Type,
})
return locals()
@@ -592,8 +601,8 @@ def init_PySide6_QtWidgets():
def init_PySide6_QtSql():
from PySide6.QtSql import QSqlDatabase
type_map.update({
- "QLatin1String(defaultConnection)": QSqlDatabase.defaultConnection,
- "QVariant.Invalid": Invalid("Variant"), # not sure what I should create, here...
+ "QLatin1StringView(QSqlDatabase.defaultConnection)": QSqlDatabase.defaultConnection,
+ "QVariant.Invalid": Invalid("Variant"), # not sure what I should create, here...
})
return locals()
@@ -613,27 +622,11 @@ def init_PySide6_QtNetwork():
return locals()
-def init_PySide6_QtMultimedia():
- # PYSIDE-1599: We force pyi testing in wheel_tester. This seems to fail, sometimes.
- try:
- import PySide6.QtMultimediaWidgets
- check_module(PySide6.QtMultimediaWidgets)
- except SystemError:
- print("Failure importing QtMultimediaWidgets")
- return locals()
- type_map.update({
- "QGraphicsVideoItem": PySide6.QtMultimediaWidgets.QGraphicsVideoItem,
- "qint64": int,
- "QVideoWidget": PySide6.QtMultimediaWidgets.QVideoWidget,
- })
- return locals()
-
-
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,
})
@@ -651,7 +644,7 @@ def init_PySide6_QtQuick():
type_map.update({
"PySide6.QtQuick.QSharedPointer[PySide6.QtQuick.QQuickItemGrabResult]":
PySide6.QtQuick.QQuickItemGrabResult,
- "UnsignedShortType": int,
+ "QSGGeometry.Type.UnsignedShortType": int,
})
return locals()
@@ -690,9 +683,36 @@ 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),
+ })
+ return locals()
+
+
def init_testbinding():
type_map.update({
"testbinding.PySideCPP2.TestObjectWithoutNamespace": testbinding.TestObjectWithoutNamespace,
+ "testbinding.FlagsNamespace.Options": testbinding.Option,
+ "FlagsNamespace.Option.NoOptions": 0,
+ "StdIntList": typing.List[int],
+ 'Str("")': str(""),
})
return locals()
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py
index 8adac0725..9b48ab442 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/parser.py
@@ -1,55 +1,19 @@
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
-import sys
+import ast
+import enum
+import keyword
+import os
import re
-import warnings
-import types
+import sys
import typing
-import keyword
-import functools
+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
@@ -74,6 +38,65 @@ 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, # noqa F:401
+ __minimum_python_version__ as pyminver,
+ __maximum_python_version__ as pymaxver)
+
+ # PYSIDE-1735: Use the new Enums per default if version is >= 6.4
+ # This decides between delivered vs. dev versions.
+ # When 6.4 is out, the switching mode will be gone.
+ flag = ver[:2] >= (6, 4)
+ envname = "PYSIDE6_OPTION_PYTHON_ENUM"
+ sysname = envname.lower()
+ opt = os.environ.get(envname)
+ if opt:
+ opt = opt.lower()
+ if opt in ("yes", "on", "true"):
+ flag = True
+ elif opt in ("no", "off", "false"):
+ flag = False
+ else:
+ # instead of a simple int() conversion, let's allow for "0xf" or "0b1111"
+ try:
+ flag = ast.literal_eval(opt)
+ except Exception:
+ flag = False # turn a forbidden option into an error
+ elif hasattr(sys, sysname):
+ opt2 = flag = getattr(sys, sysname)
+ if not isinstance(flag, int):
+ flag = False # turn a forbidden option into an error
+ p = f"\n *** Python is at version {'.'.join(map(str, pyminver or (0,)))} now."
+ 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 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"{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
+
+
+class EnumSelect(enum.Enum):
+ # PYSIDE-1735: Here we could save object.value expressions by using IntEnum.
+ # But it is nice to use just an Enum for selecting Enum version.
+ OLD = 1
+ NEW = 2
+ SELECTION = NEW if _get_flag_enum_option() else OLD
+
+
def dprint(*args, **kw):
if _DEBUG:
import pprint
@@ -84,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
@@ -165,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.
@@ -174,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
@@ -189,10 +213,11 @@ def make_good_value(thing, valtype):
if thing.endswith("()"):
thing = f'Default("{thing[:-2]}")'
else:
- ret = eval(thing, namespace)
+ # PYSIDE-1735: Use explicit globals and locals because of a bug in VsCode
+ ret = eval(thing, globals(), namespace)
if valtype and repr(ret).startswith("<"):
thing = f'Instance("{thing}")'
- return eval(thing, namespace)
+ return eval(thing, globals(), namespace)
except Exception:
pass
@@ -216,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."):
@@ -264,30 +291,44 @@ def _resolve_arraytype(thing, line):
def to_string(thing):
+ # This function returns a string that creates the same object.
+ # It is absolutely crucial that str(eval(thing)) == str(thing),
+ # i.e. it must be an idempotent mapping.
if isinstance(thing, str):
return thing
if hasattr(thing, "__name__") and thing.__module__ != "typing":
- dot = "." in str(thing)
+ m = thing.__module__
+ dot = "." in str(thing) or m not in (thing.__qualname__, "builtins")
name = get_name(thing)
- return thing.__module__ + "." + name if dot else name
+ ret = m + "." + name if dot else name
+ assert (eval(ret, globals(), namespace))
+ return ret
# Note: This captures things from the typing module:
return str(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, namespace)
+ return eval(result, globals(), namespace)
-def _resolve_type(thing, line, level, var_handler):
+def _resolve_type(thing, line, level, var_handler, func_name=None):
+ # manual set of 'str' instead of 'bytes'
+ if func_name:
+ new_thing = (func_name, thing)
+ if new_thing in type_map:
+ return type_map[new_thing]
+
# Capture total replacements, first. Happens in
# "PySide6.QtCore.QCborStreamReader.StringResult[PySide6.QtCore.QByteArray]"
if thing in type_map:
return type_map[thing]
+
# Now the nested structures are handled.
if "[" in thing:
# handle primitive arrays
@@ -298,13 +339,13 @@ def _resolve_type(thing, line, level, var_handler):
# 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)
@@ -313,8 +354,8 @@ def _resolve_type(thing, line, level, var_handler):
result = f"{contr}[{thing}]"
# PYSIDE-1538: Make sure that the eval does not crash.
try:
- return eval(result, namespace)
- except Exception as e:
+ return eval(result, globals(), namespace)
+ except Exception:
warnings.warn(f"""pyside_type_init:_resolve_type
UNRECOGNIZED: {result!r}
@@ -372,11 +413,11 @@ def calculate_props(line):
name, ann = tup[:2]
if ann == "...":
name = "*args" if name.startswith("arg_") else "*" + name
- # copy the pathed fields back
+ # copy the patched fields back
ann = 'nullptr' # maps to None
tup = name, ann
arglist[idx] = tup
- annotations[name] = _resolve_type(ann, line, 0, handle_argvar)
+ annotations[name] = _resolve_type(ann, line, 0, handle_argvar, parsed.funcname)
if len(tup) == 3:
default = _resolve_value(tup[2], ann, line)
_defaults.append(default)
@@ -393,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)
@@ -441,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:
@@ -449,7 +489,7 @@ def fix_variables(props, line):
else:
retvars_str = ", ".join(map(to_string, retvars))
typestr = f"typing.Tuple[{retvars_str}]"
- returntype = eval(typestr, namespace)
+ returntype = eval(typestr, globals(), namespace)
props.annotations["return"] = returntype
props.varnames = tuple(varnames)
props.defaults = tuple(defaults)
diff --git a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/qt_attribution.json b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/qt_attribution.json
index 4cbec4824..0f05aea8b 100644
--- a/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/qt_attribution.json
+++ b/sources/shiboken6/shibokenmodule/files.dir/shibokensupport/signature/qt_attribution.json
@@ -3,7 +3,7 @@
"Name": "Python",
"QDocModule": "QtForPython",
"QtUsage": "Used for Qt for Python in the signature extension.",
- "Description": "Qt for Python is an add-on for Python. The signature packages of PySide uses certain copied and adapted source files (backport_inspect.py, typing27.py). See the folder sources/shiboken6/files.dir/shibokensupport/signature .",
+ "Description": "Qt for Python is an add-on for Python. The signature packages of PySide uses certain copied and adapted source files. See the folder sources/shiboken6/files.dir/shibokensupport .",
"Homepage": "http://www.python.org/",
"Version": "3.7.0",
"LicenseId": "Python-2.0",
diff --git a/sources/shiboken6/shibokenmodule/nothing.h b/sources/shiboken6/shibokenmodule/nothing.h
index e69de29bb..2f558afcb 100644
--- a/sources/shiboken6/shibokenmodule/nothing.h
+++ b/sources/shiboken6/shibokenmodule/nothing.h
@@ -0,0 +1,3 @@
+// This is a placeholder file for shiboken, because shiboken expects a header file listing the
+// header files whose bindings are to be created. This file is empty because shibokenmodule
+// functions are implemented directly inside the typesystem_shiboken.xml file through CPython code.
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 1bee3f543..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,116 +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="PyObject*">
- <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>
+ <add-function signature="getCppPointer(PyObject*)" return-type="PySequence*">
+ <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>
- </add-function>
+ <add-function signature="createdByPython(PyObject*)" return-type="bool">
+ <inject-code file="shibokenmodule.cpp" snippet="createdbypython"/>
+ </add-function>
- <add-function signature="dump(PyObject*)" return-type="PyObject*">
- <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>
+ <add-function signature="disassembleFrame(PyObject*)" return-type="PyObject">
+ <inject-code file="shibokenmodule.cpp" snippet="disassembleframe"/>
</add-function>
- <add-function signature="getAllValidWrappers(void)" return-type="PyObject*">
- <inject-code>
- std::set&lt;PyObject*&gt; setAll = Shiboken::BindingManager::instance().getAllPyObjects();
- PyObject* listAll = PyList_New(0);
- if (listAll == NULL)
- return NULL;
+ <add-function signature="dump(PyObject*)" return-type="const char *">
+ <inject-code file="shibokenmodule.cpp" snippet="dump"/>
+ </add-function>
- const std::set&lt;PyObject*&gt;::iterator end = setAll.end();
- for (std::set&lt;PyObject*&gt;::iterator iter = setAll.begin(); iter != end; ++iter) {
- if (*iter != NULL) {
- if (PyList_Append(listAll, *iter) != 0) {
- Py_DECREF(listAll);
- return NULL;
- }
- }
- }
- return listAll;
- </inject-code>
+ <add-function signature="getAllValidWrappers(void)" return-type="PySequence*">
+ <inject-code file="shibokenmodule.cpp" snippet="getallvalidwrappers"/>
</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="dumpTypeGraph(const char *@fileName@)" return-type="bool">
+ <inject-code file="shibokenmodule.cpp" snippet="dumptypegraph"/>
+ </add-function>
+
+ <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);
-
- Shiboken::initSignature(module);
- VoidPtr::addVoidPtrToModule(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 bfa92e229..05f6e9e60 100644
--- a/sources/shiboken6/tests/CMakeLists.txt
+++ b/sources/shiboken6/tests/CMakeLists.txt
@@ -1,4 +1,7 @@
-cmake_minimum_required(VERSION 3.16)
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
if(BUILD_TESTS)
find_package(Qt${QT_MAJOR_VERSION}Test 6.0 REQUIRED)
@@ -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)
@@ -39,7 +45,21 @@ list(SORT TEST_FILES)
set(test_blacklist "")
-find_package(PythonInterp REQUIRED)
+if(SHIBOKEN_IS_CROSS_BUILD)
+ # 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(
+ Python
+ ${USE_PYTHON_VERSION}
+ REQUIRED
+ COMPONENTS Interpreter Development
+ )
+endif()
+
if(NOT CTEST_TESTING_TIMEOUT)
set(CTEST_TESTING_TIMEOUT 60)
endif()
@@ -51,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)
@@ -59,7 +79,10 @@ foreach(test_file ${TEST_FILES})
endif()
endforeach()
-add_subdirectory(dumpcodemodel)
+# dumpcodemodel depends on apiextractor which is not cross-built.
+if(SHIBOKEN_BUILD_TOOLS)
+ add_subdirectory(dumpcodemodel)
+endif()
# FIXME Skipped until add an option to choose the generator
# add_subdirectory(test_generator)
diff --git a/sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt b/sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt
index 5c5e2c7b0..e7dbef961 100644
--- a/sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt
+++ b/sources/shiboken6/tests/dumpcodemodel/CMakeLists.txt
@@ -1,6 +1,16 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
add_executable(dumpcodemodel main.cpp)
target_include_directories(dumpcodemodel
- PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${apiextractor_SOURCE_DIR})
+ PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../ApiExtractor
+)
-target_link_libraries(dumpcodemodel PUBLIC apiextractor Qt${QT_MAJOR_VERSION}::Core)
+target_link_libraries(dumpcodemodel
+ PRIVATE
+ apiextractor
+ Qt::Core
+)
diff --git a/sources/shiboken6/tests/dumpcodemodel/main.cpp b/sources/shiboken6/tests/dumpcodemodel/main.cpp
index 527a81262..eb876634c 100644
--- a/sources/shiboken6/tests/dumpcodemodel/main.cpp
+++ b/sources/shiboken6/tests/dumpcodemodel/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <abstractmetabuilder_p.h>
#include <parser/codemodel.h>
@@ -37,6 +12,7 @@
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
+#include <QtCore/QLibraryInfo>
#include <QtCore/QVersionNumber>
#include <QtCore/QXmlStreamWriter>
@@ -44,13 +20,15 @@
#include <algorithm>
#include <iterator>
+using namespace Qt::StringLiterals;
+
static bool optJoinNamespaces = false;
static inline QString languageLevelDescription()
{
- return QLatin1String("C++ Language level (c++11..c++17, default=")
- + QLatin1String(clang::languageLevelOption(clang::emulatedCompilerLanguageLevel()))
- + QLatin1Char(')');
+ return u"C++ Language level (c++11..c++20, default="_s
+ + QLatin1StringView(clang::languageLevelOption(clang::emulatedCompilerLanguageLevel()))
+ + u')';
}
static void formatDebugOutput(const FileModelItem &dom, bool verbose)
@@ -60,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';
}
@@ -70,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(QStringLiteral("enum-type"));
- writer.writeAttribute(nameAttribute(), en->name());
+ writer.writeStartElement(u"enum-type"_s);
+ writer.writeAttribute(nameAttribute, en->name());
writer.writeEndElement();
}
@@ -117,9 +95,9 @@ static void formatXmlClass(QXmlStreamWriter &writer, const ClassModelItem &klass
const bool isValueType = std::any_of(functions.cbegin(), functions.cend(),
isPublicCopyConstructor);
formatXmlLocationComment(writer, klass);
- writer.writeStartElement(isValueType ? QStringLiteral("value-type")
- : QStringLiteral("object-type"));
- writer.writeAttribute(nameAttribute(), klass->name());
+ writer.writeStartElement(isValueType ? u"value-type"_s
+ : u"object-type"_s);
+ writer.writeAttribute(nameAttribute, klass->name());
formatXmlScopeMembers(writer, klass);
writer.writeEndElement();
}
@@ -139,14 +117,14 @@ static bool hasMembers(const NamespaceModelItem &nsp)
static void startXmlNamespace(QXmlStreamWriter &writer, const NamespaceModelItem &nsp)
{
formatXmlLocationComment(writer, nsp);
- writer.writeStartElement(QStringLiteral("namespace-type"));
- writer.writeAttribute(nameAttribute(), nsp->name());
+ writer.writeStartElement(u"namespace-type"_s);
+ writer.writeAttribute(nameAttribute, nsp->name());
}
static void formatXmlNamespaceMembers(QXmlStreamWriter &writer, const NamespaceModelItem &nsp)
{
auto nestedNamespaces = nsp->namespaces();
- for (int i = nestedNamespaces.size() - 1; i >= 0; --i) {
+ for (auto i = nestedNamespaces.size() - 1; i >= 0; --i) {
if (!hasMembers(nestedNamespaces.at(i)))
nestedNamespaces.removeAt(i);
}
@@ -157,7 +135,7 @@ static void formatXmlNamespaceMembers(QXmlStreamWriter &writer, const NamespaceM
if (optJoinNamespaces) {
// Write out members of identical namespaces and remove
const QString name = current->name();
- for (int i = 0; i < nestedNamespaces.size(); ) {
+ for (qsizetype i = 0; i < nestedNamespaces.size(); ) {
if (nestedNamespaces.at(i)->name() == name) {
formatXmlNamespaceMembers(writer, nestedNamespaces.at(i));
nestedNamespaces.removeAt(i);
@@ -171,9 +149,9 @@ static void formatXmlNamespaceMembers(QXmlStreamWriter &writer, const NamespaceM
for (const auto &func : nsp->functions()) {
const QString signature = func->typeSystemSignature();
- if (!signature.contains(QLatin1String("operator"))) { // Skip free operators
- writer.writeStartElement(QStringLiteral("function"));
- writer.writeAttribute(QStringLiteral("signature"), signature);
+ if (!signature.contains(u"operator")) { // Skip free operators
+ writer.writeStartElement(u"function"_s);
+ writer.writeAttribute(u"signature"_s, signature);
writer.writeEndElement();
}
}
@@ -186,13 +164,13 @@ static void formatXmlOutput(const FileModelItem &dom)
QXmlStreamWriter writer(&output);
writer.setAutoFormatting(true);
writer.writeStartDocument();
- writer.writeStartElement(QStringLiteral("typesystem"));
- writer.writeAttribute(QStringLiteral("package"), QStringLiteral("insert_name"));
- writer.writeComment(QStringLiteral("Auto-generated ") +
+ writer.writeStartElement(u"typesystem"_s);
+ writer.writeAttribute(u"package"_s, u"insert_name"_s);
+ writer.writeComment(u"Auto-generated "_s +
QDateTime::currentDateTime().toString(Qt::ISODate));
for (auto p : primitiveTypes) {
- writer.writeStartElement(QStringLiteral("primitive-type"));
- writer.writeAttribute(nameAttribute(), QLatin1String(p));
+ writer.writeStartElement(u"primitive-type"_s);
+ writer.writeAttribute(nameAttribute, QLatin1StringView(p));
writer.writeEndElement();
}
formatXmlNamespaceMembers(writer, dom);
@@ -220,29 +198,29 @@ int main(int argc, char **argv)
parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments);
const QString description =
- QString::fromLatin1(descriptionFormat).arg(QLatin1String(qVersion()),
+ QString::fromLatin1(descriptionFormat).arg(QLatin1StringView(qVersion()),
clang::libClangVersion().toString());
parser.setApplicationDescription(description);
parser.addHelpOption();
parser.addVersionOption();
- QCommandLineOption verboseOption(QStringLiteral("verbose"),
- QStringLiteral("Display verbose output about types"));
+ QCommandLineOption verboseOption(u"verbose"_s,
+ u"Display verbose output about types"_s);
parser.addOption(verboseOption);
- QCommandLineOption debugOption(QStringLiteral("debug"),
- QStringLiteral("Display debug output"));
+ QCommandLineOption debugOption(u"debug"_s,
+ u"Display debug output"_s);
parser.addOption(debugOption);
- QCommandLineOption joinNamespacesOption({QStringLiteral("j"), QStringLiteral("join-namespaces")},
- QStringLiteral("Join namespaces"));
+ QCommandLineOption joinNamespacesOption({u"j"_s, u"join-namespaces"_s},
+ u"Join namespaces"_s);
parser.addOption(joinNamespacesOption);
- QCommandLineOption languageLevelOption(QStringLiteral("std"),
+ QCommandLineOption languageLevelOption(u"std"_s,
languageLevelDescription(),
- QStringLiteral("level"));
+ u"level"_s);
parser.addOption(languageLevelOption);
- parser.addPositionalArgument(QStringLiteral("argument"),
- QStringLiteral("C++ compiler argument"),
- QStringLiteral("argument(s)"));
+ parser.addPositionalArgument(u"argument"_s,
+ u"C++ compiler argument"_s,
+ u"argument(s)"_s);
parser.process(app);
const QStringList &positionalArguments = parser.positionalArguments();
@@ -267,8 +245,8 @@ int main(int argc, char **argv)
optJoinNamespaces = parser.isSet(joinNamespacesOption);
const FileModelItem dom = AbstractMetaBuilderPrivate::buildDom(arguments, true, level, 0);
- if (dom.isNull()) {
- QString message = QLatin1String("Unable to parse ") + positionalArguments.join(QLatin1Char(' '));
+ 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 99ff667db..099c1f1de 100644
--- a/sources/shiboken6/tests/libminimal/libminimalmacros.h
+++ b/sources/shiboken6/tests/libminimal/libminimalmacros.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef LIBMINIMALMACROS_H
#define LIBMINIMALMACROS_H
@@ -47,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 6a0230d60..93c399542 100644
--- a/sources/shiboken6/tests/libminimal/listuser.cpp
+++ b/sources/shiboken6/tests/libminimal/listuser.cpp
@@ -1,54 +1,35 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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);
@@ -56,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)
@@ -65,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)
@@ -74,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);
@@ -92,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)
@@ -101,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)
@@ -110,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)
@@ -133,3 +106,28 @@ const std::list<int> &ListUser::getConstIntList() const
{
return m_stdIntList;
}
+
+int ListUser::modifyIntListPtr(std::list<int> *list) const
+{
+ const int oldSize = int(list->size());
+ list->push_back(42);
+ return oldSize;
+}
+
+std::list<int> *ListUser::returnIntListByPtr() const
+{
+ return nullptr;
+}
+
+int ListUser::callReturnIntListByPtr() const
+{
+ auto *list = returnIntListByPtr();
+ return list != nullptr ? int(list->size()) : 0;
+}
+
+int ListUser::modifyDoubleListPtr(std::list<double> *list) const
+{
+ const int oldSize = int(list->size());
+ list->push_back(42);
+ return oldSize;
+}
diff --git a/sources/shiboken6/tests/libminimal/listuser.h b/sources/shiboken6/tests/libminimal/listuser.h
index 0eae69ae1..9904ef27d 100644
--- a/sources/shiboken6/tests/libminimal/listuser.h
+++ b/sources/shiboken6/tests/libminimal/listuser.h
@@ -1,44 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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);
@@ -46,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); }
@@ -74,6 +57,14 @@ struct LIBMINIMAL_API ListUser
std::list<int> &getIntList();
const std::list<int> &getConstIntList() const;
+ int modifyIntListPtr(std::list<int> *list) const;
+
+ virtual std::list<int> *returnIntListByPtr() const;
+
+ int callReturnIntListByPtr() const;
+
+ int modifyDoubleListPtr(std::list<double> *list) const;
+
std::list<int> m_stdIntList;
};
diff --git a/sources/shiboken6/tests/libminimal/minbool.h b/sources/shiboken6/tests/libminimal/minbool.h
index 72a2cbabe..e460f466b 100644
--- a/sources/shiboken6/tests/libminimal/minbool.h
+++ b/sources/shiboken6/tests/libminimal/minbool.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef MINBOOL_H
#define MINBOOL_H
@@ -38,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;
};
@@ -55,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 eb7af3a74..a63a9c3c9 100644
--- a/sources/shiboken6/tests/libminimal/obj.cpp
+++ b/sources/shiboken6/tests/libminimal/obj.cpp
@@ -1,41 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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 b868bbcbf..be0bfb52b 100644
--- a/sources/shiboken6/tests/libminimal/obj.h
+++ b/sources/shiboken6/tests/libminimal/obj.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OBJ_H
#define OBJ_H
@@ -34,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; }
@@ -50,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/typedef.cpp b/sources/shiboken6/tests/libminimal/typedef.cpp
index e0886d982..115b7be0a 100644
--- a/sources/shiboken6/tests/libminimal/typedef.cpp
+++ b/sources/shiboken6/tests/libminimal/typedef.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "typedef.h"
diff --git a/sources/shiboken6/tests/libminimal/typedef.h b/sources/shiboken6/tests/libminimal/typedef.h
index b8d6faacd..7116db1b8 100644
--- a/sources/shiboken6/tests/libminimal/typedef.h
+++ b/sources/shiboken6/tests/libminimal/typedef.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TYPEDEF_H
#define TYPEDEF_H
diff --git a/sources/shiboken6/tests/libminimal/val.h b/sources/shiboken6/tests/libminimal/val.h
index c43302317..50f090a7d 100644
--- a/sources/shiboken6/tests/libminimal/val.h
+++ b/sources/shiboken6/tests/libminimal/val.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef VAL_H
#define VAL_H
@@ -34,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 e1bcf0961..36d503fe8 100644
--- a/sources/shiboken6/tests/libother/extendsnoimplicitconversion.h
+++ b/sources/shiboken6/tests/libother/extendsnoimplicitconversion.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef EXTENDSNOIMPLICITCONVERSION_H
#define EXTENDSNOIMPLICITCONVERSION_H
@@ -38,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/libothermacros.h b/sources/shiboken6/tests/libother/libothermacros.h
index e5207064f..567757abd 100644
--- a/sources/shiboken6/tests/libother/libothermacros.h
+++ b/sources/shiboken6/tests/libother/libothermacros.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef LIBOTHERMACROS_H
#define LIBOTHERMACROS_H
diff --git a/sources/shiboken6/tests/libother/number.cpp b/sources/shiboken6/tests/libother/number.cpp
index bc97de6a6..fbf50dc4a 100644
--- a/sources/shiboken6/tests/libother/number.cpp
+++ b/sources/shiboken6/tests/libother/number.cpp
@@ -1,59 +1,28 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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 222c6e1a6..2c480e7f2 100644
--- a/sources/shiboken6/tests/libother/number.h
+++ b/sources/shiboken6/tests/libother/number.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef NUMBER_H
#define NUMBER_H
@@ -43,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);
@@ -52,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 d23f6ad23..93a18876e 100644
--- a/sources/shiboken6/tests/libother/otherderived.cpp
+++ b/sources/shiboken6/tests/libother/otherderived.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "otherderived.h"
@@ -32,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 72e1e2302..d6bde8808 100644
--- a/sources/shiboken6/tests/libother/otherderived.h
+++ b/sources/shiboken6/tests/libother/otherderived.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OTHERDERIVED_H
#define OTHERDERIVED_H
@@ -43,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 e7ee4f96d..cfbbfb2c2 100644
--- a/sources/shiboken6/tests/libother/othermultiplederived.cpp
+++ b/sources/shiboken6/tests/libother/othermultiplederived.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "othermultiplederived.h"
@@ -33,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 84a426ac9..9f90c43a7 100644
--- a/sources/shiboken6/tests/libother/othermultiplederived.h
+++ b/sources/shiboken6/tests/libother/othermultiplederived.h
@@ -1,46 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OTHERMULTIPLEDERIVED_H
#define OTHERMULTIPLEDERIVED_H
#include "libothermacros.h"
#include "multiple_derived.h"
+#include "objecttype.h"
#include "virtualmethods.h"
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 c7778e7c9..eaaa231be 100644
--- a/sources/shiboken6/tests/libother/otherobjecttype.cpp
+++ b/sources/shiboken6/tests/libother/otherobjecttype.cpp
@@ -1,37 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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 a9362c370..844795118 100644
--- a/sources/shiboken6/tests/libother/otherobjecttype.h
+++ b/sources/shiboken6/tests/libother/otherobjecttype.h
@@ -1,44 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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:
@@ -46,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/othertypesystypedef.cpp b/sources/shiboken6/tests/libother/othertypesystypedef.cpp
index 7e6e1ff64..1a50c4edf 100644
--- a/sources/shiboken6/tests/libother/othertypesystypedef.cpp
+++ b/sources/shiboken6/tests/libother/othertypesystypedef.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "othertypesystypedef.h"
diff --git a/sources/shiboken6/tests/libother/othertypesystypedef.h b/sources/shiboken6/tests/libother/othertypesystypedef.h
index e3f434613..999b71fd3 100644
--- a/sources/shiboken6/tests/libother/othertypesystypedef.h
+++ b/sources/shiboken6/tests/libother/othertypesystypedef.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OTHERTYPESYSTYPEDEF_H
#define OTHERTYPESYSTYPEDEF_H
diff --git a/sources/shiboken6/tests/libother/smartptrtester.cpp b/sources/shiboken6/tests/libother/smartptrtester.cpp
index 9636c7521..1c6496b1a 100644
--- a/sources/shiboken6/tests/libother/smartptrtester.cpp
+++ b/sources/shiboken6/tests/libother/smartptrtester.cpp
@@ -1,36 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "smartptrtester.h"
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/libother/smartptrtester.h b/sources/shiboken6/tests/libother/smartptrtester.h
index a560bcf2f..6d7991c06 100644
--- a/sources/shiboken6/tests/libother/smartptrtester.h
+++ b/sources/shiboken6/tests/libother/smartptrtester.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SMARTPTRTESTER_H
#define SMARTPTRTESTER_H
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 3b2b1ef0a..0d67d8630 100644
--- a/sources/shiboken6/tests/libsample/abstract.cpp
+++ b/sources/shiboken6/tests/libsample/abstract.cpp
@@ -1,89 +1,64 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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)
@@ -91,7 +66,6 @@ void Abstract::callVirtualGettingEnum(PrintFormat p)
virtualGettingAEnum(p);
}
-void Abstract::virtualGettingAEnum(Abstract::PrintFormat p)
+void Abstract::virtualGettingAEnum(Abstract::PrintFormat)
{
}
-
diff --git a/sources/shiboken6/tests/libsample/abstract.h b/sources/shiboken6/tests/libsample/abstract.h
index 746107c71..4c1b98d90 100644
--- a/sources/shiboken6/tests/libsample/abstract.h
+++ b/sources/shiboken6/tests/libsample/abstract.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ABSTRACT_H
#define ABSTRACT_H
@@ -49,6 +24,8 @@ private:
PrivValue2 = PrivValue1 + 2
};
public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Abstract)
+
enum PrintFormat {
Short,
Verbose,
@@ -63,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;
@@ -92,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;
@@ -107,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 425476672..2ac435d3d 100644
--- a/sources/shiboken6/tests/libsample/blackbox.cpp
+++ b/sources/shiboken6/tests/libsample/blackbox.cpp
@@ -1,129 +1,81 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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 629a217cc..9d32670dd 100644
--- a/sources/shiboken6/tests/libsample/blackbox.h
+++ b/sources/shiboken6/tests/libsample/blackbox.h
@@ -1,54 +1,32 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef BLACKBOX_H
#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();
@@ -60,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 91e546d6e..cafd382a9 100644
--- a/sources/shiboken6/tests/libsample/bucket.cpp
+++ b/sources/shiboken6/tests/libsample/bucket.cpp
@@ -1,49 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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);
@@ -53,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();
}
@@ -69,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()
@@ -83,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 09f933863..73e8edd78 100644
--- a/sources/shiboken6/tests/libsample/bucket.h
+++ b/sources/shiboken6/tests/libsample/bucket.h
@@ -1,36 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef BUCKET_H
#define BUCKET_H
#include "libsamplemacros.h"
#include "objecttype.h"
+
#include <list>
class ObjectType;
@@ -38,7 +14,7 @@ class ObjectType;
class LIBSAMPLE_API Bucket : public ObjectType
{
public:
- Bucket();
+ Bucket() = default;
void push(int);
int pop();
bool empty();
@@ -52,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 021d2a079..78d5162b0 100644
--- a/sources/shiboken6/tests/libsample/bytearray.cpp
+++ b/sources/shiboken6/tests/libsample/bytearray.cpp
@@ -1,38 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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)
@@ -42,48 +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';
}
-ByteArray::ByteArray(const ByteArray& other)
-{
- m_data = std::vector<char>(other.size() + 1);
- memcpy(&m_data[0], &other.m_data[0], other.size());
- m_data[other.size()] = '\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);
@@ -91,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])
@@ -130,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 5dfb63fd5..35ff22367 100644
--- a/sources/shiboken6/tests/libsample/bytearray.h
+++ b/sources/shiboken6/tests/libsample/bytearray.h
@@ -1,89 +1,64 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef BYTEARRAY_H
#define BYTEARRAY_H
#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);
- ByteArray(const ByteArray& other);
+ 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 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 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 aca24e355..579239bcb 100644
--- a/sources/shiboken6/tests/libsample/collector.cpp
+++ b/sources/shiboken6/tests/libsample/collector.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "collector.h"
@@ -33,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;
@@ -50,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 bc10a7481..26766847a 100644
--- a/sources/shiboken6/tests/libsample/collector.h
+++ b/sources/shiboken6/tests/libsample/collector.h
@@ -1,64 +1,37 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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 a9b7f03c3..e3bec9aae 100644
--- a/sources/shiboken6/tests/libsample/complex.cpp
+++ b/sources/shiboken6/tests/libsample/complex.cpp
@@ -1,43 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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());
@@ -45,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 d0f6c1408..168fe5c44 100644
--- a/sources/shiboken6/tests/libsample/complex.h
+++ b/sources/shiboken6/tests/libsample/complex.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef COMPLEX_H
#define COMPLEX_H
@@ -34,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 ceab8d6dc..a5411b749 100644
--- a/sources/shiboken6/tests/libsample/ctorconvrule.h
+++ b/sources/shiboken6/tests/libsample/ctorconvrule.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CTORCONVRULE_H
#define CTORCONVRULE_H
@@ -34,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/ctparam.cpp b/sources/shiboken6/tests/libsample/ctparam.cpp
index 89d4dd744..9bbbcfc3f 100644
--- a/sources/shiboken6/tests/libsample/ctparam.cpp
+++ b/sources/shiboken6/tests/libsample/ctparam.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "ctparam.h"
diff --git a/sources/shiboken6/tests/libsample/ctparam.h b/sources/shiboken6/tests/libsample/ctparam.h
index 8acf14aaf..fa241b587 100644
--- a/sources/shiboken6/tests/libsample/ctparam.h
+++ b/sources/shiboken6/tests/libsample/ctparam.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CTPARAM_H
#define CTPARAM_H
diff --git a/sources/shiboken6/tests/libsample/cvlist.h b/sources/shiboken6/tests/libsample/cvlist.h
index 50ad8bfe8..e09c7d943 100644
--- a/sources/shiboken6/tests/libsample/cvlist.h
+++ b/sources/shiboken6/tests/libsample/cvlist.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef CONSTVALUELIST_H
#define CONSTVALUELIST_H
@@ -37,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
@@ -46,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 0dc026876..d20880431 100644
--- a/sources/shiboken6/tests/libsample/derived.cpp
+++ b/sources/shiboken6/tests/libsample/derived.cpp
@@ -1,69 +1,36 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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;
}
@@ -74,40 +41,36 @@ Derived::defaultValue(int n)
return ((double) n) + 0.1;
}
-OverloadedFuncEnum
-Derived::overloaded(int i, int d)
+OverloadedFuncEnum Derived::overloaded(int, int)
{
return OverloadedFunc_ii;
}
-OverloadedFuncEnum
-Derived::overloaded(double n)
+OverloadedFuncEnum Derived::overloaded(double)
{
return OverloadedFunc_d;
}
-Derived::OtherOverloadedFuncEnum
-Derived::otherOverloaded(int a, int b, bool c, double d)
+Derived::OtherOverloadedFuncEnum Derived::otherOverloaded(int, int, bool, double)
{
return OtherOverloadedFunc_iibd;
}
-Derived::OtherOverloadedFuncEnum
-Derived::otherOverloaded(int a, double b)
+Derived::OtherOverloadedFuncEnum Derived::otherOverloaded(int, double)
{
return OtherOverloadedFunc_id;
}
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;
}
@@ -115,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 783a6dc50..cf95cb601 100644
--- a/sources/shiboken6/tests/libsample/derived.h
+++ b/sources/shiboken6/tests/libsample/derived.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef DERIVED_H
#define DERIVED_H
@@ -40,6 +15,8 @@ enum OverloadedFuncEnum {
class LIBSAMPLE_API Derived : public Abstract
{
public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Derived)
+
enum OtherOverloadedFuncEnum {
OtherOverloadedFunc_iibd,
OtherOverloadedFunc_id
@@ -48,21 +25,21 @@ public:
class SomeInnerClass {
public:
void uselessMethod() {}
- SomeInnerClass operator+(const SomeInnerClass& other) { return other; }
- bool operator==(const SomeInnerClass& other) { 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);
@@ -78,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/derivedusingct.cpp b/sources/shiboken6/tests/libsample/derivedusingct.cpp
index 3ee5f2cb4..720d0ed96 100644
--- a/sources/shiboken6/tests/libsample/derivedusingct.cpp
+++ b/sources/shiboken6/tests/libsample/derivedusingct.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "derivedusingct.h"
diff --git a/sources/shiboken6/tests/libsample/derivedusingct.h b/sources/shiboken6/tests/libsample/derivedusingct.h
index ae0682cfd..6bc026d08 100644
--- a/sources/shiboken6/tests/libsample/derivedusingct.h
+++ b/sources/shiboken6/tests/libsample/derivedusingct.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef DERIVEDUSINGCT_H
#define DERIVEDUSINGCT_H
diff --git a/sources/shiboken6/tests/libsample/echo.cpp b/sources/shiboken6/tests/libsample/echo.cpp
index 55e2a461e..7fa8433d3 100644
--- a/sources/shiboken6/tests/libsample/echo.cpp
+++ b/sources/shiboken6/tests/libsample/echo.cpp
@@ -1,29 +1,4 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "echo.h"
diff --git a/sources/shiboken6/tests/libsample/echo.h b/sources/shiboken6/tests/libsample/echo.h
index 3f645694a..01b11a4a6 100644
--- a/sources/shiboken6/tests/libsample/echo.h
+++ b/sources/shiboken6/tests/libsample/echo.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ECHO_H
#define ECHO_H
@@ -37,19 +12,49 @@ class ObjectType;
class Echo
{
public:
- Echo(){}
- ~Echo(){}
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Echo)
- void doNothingWithConstBool(const bool hi) {}
- void methodWithNamedArg(const Str& string = Str("")) {}
+ Echo() noexcept = default;
+ ~Echo() = default;
- Str operator()(const Str& s, const int i) { return s + i; }
+ void doNothingWithConstBool(const bool hi);
+ void methodWithNamedArg(const Str &string = Str{});
+
+ 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) { return *this; }
- Echo& operator<<(signed int item) { return *this; }
- Echo& operator<<(const ObjectType* item) { return *this; }
- Echo& operator<<(Str str) { return *this; }
+ Echo &operator<<(unsigned int item);
+ Echo &operator<<(signed int item);
+ Echo &operator<<(const ObjectType *item);
+ Echo &operator<<(Str str);
};
-#endif
+inline void Echo::doNothingWithConstBool(const bool)
+{
+}
+
+inline void Echo::methodWithNamedArg(const Str &)
+{
+}
+
+inline Echo &Echo::operator<<(unsigned int)
+{
+ return *this;
+}
+
+inline Echo &Echo::operator<<(signed int)
+{
+ return *this;
+}
+
+inline Echo &Echo::operator<<(const ObjectType *)
+{
+ return *this;
+}
+
+inline Echo &Echo::operator<<(Str)
+{
+ return *this;
+}
+
+#endif // ECHO_H
diff --git a/sources/shiboken6/tests/libsample/exceptiontest.cpp b/sources/shiboken6/tests/libsample/exceptiontest.cpp
index 1302a8e43..56144e086 100644
--- a/sources/shiboken6/tests/libsample/exceptiontest.cpp
+++ b/sources/shiboken6/tests/libsample/exceptiontest.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "exceptiontest.h"
@@ -62,3 +37,10 @@ void ExceptionTest::voidThrowInt(bool doThrow)
if (doThrow)
throw 42;
}
+
+ExceptionTest *ExceptionTest::create(bool doThrow)
+{
+ if (doThrow)
+ throw TestException();
+ return new ExceptionTest;
+}
diff --git a/sources/shiboken6/tests/libsample/exceptiontest.h b/sources/shiboken6/tests/libsample/exceptiontest.h
index 8ab3e2b67..b5812a090 100644
--- a/sources/shiboken6/tests/libsample/exceptiontest.h
+++ b/sources/shiboken6/tests/libsample/exceptiontest.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef EXCEPTIONTEST_H
#define EXCEPTIONTEST_H
@@ -43,6 +18,8 @@ class LIBSAMPLE_API ExceptionTest
int intThrowInt(bool doThrow);
void voidThrowInt(bool doThrow);
+
+ static ExceptionTest *create(bool doThrow);
};
#endif // EXCEPTIONTEST_H
diff --git a/sources/shiboken6/tests/libsample/expression.cpp b/sources/shiboken6/tests/libsample/expression.cpp
index 0b0bcdefe..6f3c5fdc5 100644
--- a/sources/shiboken6/tests/libsample/expression.cpp
+++ b/sources/shiboken6/tests/libsample/expression.cpp
@@ -1,139 +1,79 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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 3add5572e..e7c5b7306 100644
--- a/sources/shiboken6/tests/libsample/expression.h
+++ b/sources/shiboken6/tests/libsample/expression.h
@@ -1,64 +1,40 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef EXPRESSION_H
#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 f862babd2..950847985 100644
--- a/sources/shiboken6/tests/libsample/filter.cpp
+++ b/sources/shiboken6/tests/libsample/filter.cpp
@@ -1,69 +1,34 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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);
}
-Union::Union(const Union& filter)
-{
- m_filters = filter.filters();
-}
-
-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::Intersection(const Intersection& filter)
-{
- m_filters = filter.filters();
-}
-
-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 e318cba20..d82d38eb8 100644
--- a/sources/shiboken6/tests/libsample/filter.h
+++ b/sources/shiboken6/tests/libsample/filter.h
@@ -1,39 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef FILTER_H
#define FILTER_H
+#include "libsamplemacros.h"
+
#include <string>
#include <list>
-#include "libsamplemacros.h"
-
class Intersection;
class LIBSAMPLE_API Filter
@@ -42,7 +17,6 @@ class LIBSAMPLE_API Filter
class LIBSAMPLE_API Data : public Filter
{
-
public:
enum Field {
Name,
@@ -50,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; }
@@ -64,13 +38,12 @@ class LIBSAMPLE_API Union : public Filter
{
public:
- Union(const Data&);
- Union(const Intersection&);
- Union() {};
- Union(const Union&);
+ 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;
@@ -79,20 +52,18 @@ private:
class LIBSAMPLE_API Intersection : public Filter
{
public:
-
- Intersection(const Data&);
- Intersection(const Union&);
- Intersection() {};
- Intersection(const Intersection&);
+ 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 ffa3722b7..ad2f4dd5a 100644
--- a/sources/shiboken6/tests/libsample/functions.cpp
+++ b/sources/shiboken6/tests/libsample/functions.cpp
@@ -1,63 +1,34 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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());
@@ -66,135 +37,114 @@ 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__;
}
-GlobalOverloadFuncEnum
-overloadedFunc(int val)
+GlobalOverloadFuncEnum overloadedFunc(int)
{
return GlobalOverloadFunc_i;
}
-GlobalOverloadFuncEnum
-overloadedFunc(double val)
+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;
}
@@ -229,9 +179,7 @@ double sumDoubleMatrix(double m[2][3])
return result;
}
-ArrayModifyTest::ArrayModifyTest()
-{
-}
+ArrayModifyTest::ArrayModifyTest() = default;
int ArrayModifyTest::sumIntArray(int n, int *array)
{
@@ -254,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;
}
@@ -263,3 +211,22 @@ std::wstring addStdWStrings(const std::wstring &s1, const std::wstring &s2)
{
return s1 + s2;
}
+
+void testNullPtrT(std::nullptr_t)
+{
+ 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 46ccd196c..b745aed6b 100644
--- a/sources/shiboken6/tests/libsample/functions.h
+++ b/sources/shiboken6/tests/libsample/functions.h
@@ -1,41 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef FUNCTIONS_H
#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,
@@ -55,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);
@@ -73,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]);
@@ -89,6 +68,11 @@ LIBSAMPLE_API double sumDoubleMatrix(double m[2][3]);
LIBSAMPLE_API std::string addStdStrings(const std::string &s1, const std::string &s2);
LIBSAMPLE_API std::wstring addStdWStrings(const std::wstring &s1, const std::wstring &s2);
+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 643eac458..93c2abe47 100644
--- a/sources/shiboken6/tests/libsample/handle.cpp
+++ b/sources/shiboken6/tests/libsample/handle.cpp
@@ -1,44 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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 824c28b9a..07fc89d15 100644
--- a/sources/shiboken6/tests/libsample/handle.h
+++ b/sources/shiboken6/tests/libsample/handle.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef HANDLE_H
#define HANDLE_H
@@ -33,35 +8,41 @@
/* 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) {}
- inline void set(HANDLE ptr) { HANDLE tmp; tmp = m_handle; m_handle = tmp; }
- 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(SAMPLE_HANDLE)
+{
+ SAMPLE_HANDLE tmp = m_handle;
+ m_handle = tmp;
+}
+
struct LIBSAMPLE_API PrimitiveStruct {};
using PrimitiveStructPtr = struct PrimitiveStruct *;
struct LIBSAMPLE_API PrimitiveStructPointerHolder
diff --git a/sources/shiboken6/tests/libsample/implicitconv.cpp b/sources/shiboken6/tests/libsample/implicitconv.cpp
index 88af0d936..887fa6b1c 100644
--- a/sources/shiboken6/tests/libsample/implicitconv.cpp
+++ b/sources/shiboken6/tests/libsample/implicitconv.cpp
@@ -1,66 +1,39 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "implicitconv.h"
-ImplicitConv
-ImplicitConv::implicitConvCommon(ImplicitConv implicit)
+ImplicitConv::ImplicitConv(const Null &) :
+ m_ctorEnum(CtorPrimitiveType)
+{
+}
+
+ImplicitConv ImplicitConv::implicitConvCommon(ImplicitConv implicit)
{
return implicit;
}
-ImplicitConv
-ImplicitConv::implicitConvDefault(ImplicitConv implicit)
+ImplicitConv ImplicitConv::implicitConvDefault(ImplicitConv implicit)
{
return implicit;
}
-ImplicitConv::ICOverloadedFuncEnum
-ImplicitConv::implicitConvOverloading(ImplicitConv implicit, int dummyArg)
+ImplicitConv::ICOverloadedFuncEnum ImplicitConv::implicitConvOverloading(ImplicitConv, int)
{
return ImplicitConv::OverFunc_Ii;
}
-ImplicitConv::ICOverloadedFuncEnum
-ImplicitConv::implicitConvOverloading(ImplicitConv implicit, bool dummyArg)
+ImplicitConv::ICOverloadedFuncEnum ImplicitConv::implicitConvOverloading(ImplicitConv, bool)
{
return ImplicitConv::OverFunc_Ib;
}
-ImplicitConv::ICOverloadedFuncEnum
-ImplicitConv::implicitConvOverloading(int dummyArg)
+ImplicitConv::ICOverloadedFuncEnum ImplicitConv::implicitConvOverloading(int)
{
return ImplicitConv::OverFunc_i;
}
-ImplicitConv::ICOverloadedFuncEnum
-ImplicitConv::implicitConvOverloading(CtorEnum dummyArg)
+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 ea859a1a6..5d69eb487 100644
--- a/sources/shiboken6/tests/libsample/implicitconv.h
+++ b/sources/shiboken6/tests/libsample/implicitconv.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef IMPLICITCONV_H
#define IMPLICITCONV_H
@@ -37,6 +12,8 @@ class ObjectType;
class LIBSAMPLE_API ImplicitConv
{
public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ImplicitConv)
+
enum CtorEnum {
CtorNone,
CtorOne,
@@ -53,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) : m_ctorEnum(CtorPrimitiveType) {}
- ~ImplicitConv() {}
+ ImplicitConv(const Null &null);
+ ~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);
@@ -75,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 b1cf2d26b..707d14ed8 100644
--- a/sources/shiboken6/tests/libsample/injectcode.cpp
+++ b/sources/shiboken6/tests/libsample/injectcode.cpp
@@ -1,46 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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;
@@ -48,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);
}
@@ -95,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 927721f8f..74046dad5 100644
--- a/sources/shiboken6/tests/libsample/injectcode.h
+++ b/sources/shiboken6/tests/libsample/injectcode.h
@@ -1,56 +1,35 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef INJECTCODE_H
#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
@@ -58,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/intwrapper.cpp b/sources/shiboken6/tests/libsample/intwrapper.cpp
index aa1a22874..0eaf30465 100644
--- a/sources/shiboken6/tests/libsample/intwrapper.cpp
+++ b/sources/shiboken6/tests/libsample/intwrapper.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "intwrapper.h"
diff --git a/sources/shiboken6/tests/libsample/intwrapper.h b/sources/shiboken6/tests/libsample/intwrapper.h
index 158cff8e1..cfda5adc7 100644
--- a/sources/shiboken6/tests/libsample/intwrapper.h
+++ b/sources/shiboken6/tests/libsample/intwrapper.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef INTWRAPPER_H
#define INTWRAPPER_H
diff --git a/sources/shiboken6/tests/libsample/libsamplemacros.h b/sources/shiboken6/tests/libsample/libsamplemacros.h
index e85b0fd5b..93e549bfb 100644
--- a/sources/shiboken6/tests/libsample/libsamplemacros.h
+++ b/sources/shiboken6/tests/libsample/libsamplemacros.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef LIBSAMPLEMACROS_H
#define LIBSAMPLEMACROS_H
diff --git a/sources/shiboken6/tests/libsample/list.h b/sources/shiboken6/tests/libsample/list.h
index f4970d947..5e06d2a66 100644
--- a/sources/shiboken6/tests/libsample/list.h
+++ b/sources/shiboken6/tests/libsample/list.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef LIST_H
#define LIST_H
@@ -43,6 +18,8 @@ class List : public std::list<T>
class IntList : public List<int>
{
public:
+ LIBMINIMAL_DEFAULT_MOVE(IntList)
+
enum CtorEnum {
NoParamsCtor,
IntCtor,
@@ -50,10 +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 IntList& lst) : List<int>(lst), m_ctorUsed(CopyCtor) {}
- 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 &operator=(const IntList &) = default;
inline void append(int v) { insert(end(), v); }
CtorEnum constructorUsed() { return m_ctorUsed; }
@@ -64,6 +44,8 @@ private:
class PointValueList : public List<Point>
{
public:
+ LIBMINIMAL_DEFAULT_MOVE(PointValueList)
+
enum CtorEnum {
NoParamsCtor,
PointCtor,
@@ -71,10 +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 PointValueList& lst) : List<Point>(lst), m_ctorUsed(CopyCtor) {}
- 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 &operator=(const PointValueList &) = default;
+ ~PointValueList() = default;
inline void append(Point v) { insert(end(), v); }
CtorEnum constructorUsed() { return m_ctorUsed; }
@@ -85,6 +70,8 @@ private:
class ObjectTypePtrList : public List<ObjectType*>
{
public:
+ LIBMINIMAL_DEFAULT_MOVE(ObjectTypePtrList)
+
enum CtorEnum {
NoParamsCtor,
ObjectTypeCtor,
@@ -92,15 +79,21 @@ public:
ListOfObjectTypePtrCtor
};
- inline ObjectTypePtrList() : m_ctorUsed(NoParamsCtor) {}
- inline explicit ObjectTypePtrList(ObjectType* val) : m_ctorUsed(ObjectTypeCtor) { push_back(val); }
- inline ObjectTypePtrList(const ObjectTypePtrList& lst) : List<ObjectType*>(lst), m_ctorUsed(CopyCtor) {}
- 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;
+
+ ObjectTypePtrList &operator=(const 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 995220b6f..9bb7f7798 100644
--- a/sources/shiboken6/tests/libsample/listuser.cpp
+++ b/sources/shiboken6/tests/libsample/listuser.cpp
@@ -1,45 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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();
}
-std::list<int>
-ListUser::createList()
+ListUser::ListUser() = default;
+ListUser::ListUser(const ListUser &other) = default;
+ListUser::ListUser(ListUser &&other) noexcept = default;
+ListUser &ListUser::operator=(const ListUser &other) = default;
+ListUser &ListUser::operator=(ListUser &&other) noexcept = default;
+ListUser::~ListUser() = default;
+
+std::list<int> ListUser::createList()
{
std::list<int> retval;
for (int i = 0; i < 4; i++)
@@ -47,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);
@@ -56,36 +34,30 @@ 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);
}
-ListUser::ListOfSomething
-ListUser::listOfPoints(const std::list<Point>& pointlist)
+ListUser::ListOfSomething ListUser::listOfPoints(const std::list<Point> &)
{
return ListOfPoint;
}
-ListUser::ListOfSomething
-ListUser::listOfPoints(const std::list<PointF>& pointlist)
+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 7e67039d9..96781ed16 100644
--- a/sources/shiboken6/tests/libsample/listuser.h
+++ b/sources/shiboken6/tests/libsample/listuser.h
@@ -1,41 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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:
@@ -46,9 +22,12 @@ public:
ListOfPointF
};
- ListUser() {}
- ListUser(const ListUser& other) : m_lst(other.m_lst) {}
- virtual ~ListUser() {}
+ ListUser();
+ ListUser(const ListUser &other);
+ ListUser(ListUser &&other) noexcept;
+ ListUser &operator=(const ListUser &other);
+ ListUser &operator=(ListUser &&other) noexcept;
+ virtual ~ListUser();
virtual std::list<int> createList();
std::list<int> callCreateList();
@@ -58,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 336551ea2..1b44642ae 100644
--- a/sources/shiboken6/tests/libsample/main.cpp
+++ b/sources/shiboken6/tests/libsample/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 <list>
@@ -37,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 e2a0f7181..40059bbcd 100644
--- a/sources/shiboken6/tests/libsample/mapuser.cpp
+++ b/sources/shiboken6/tests/libsample/mapuser.cpp
@@ -1,69 +1,44 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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)
+{
+ 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> *)
+{
+}
+
+void MapUser::referenceToMap(std::map<std::string, std::string> &)
{
- cout << __FUNCTION__ << endl;
- for (auto it = mapping.begin(), end = mapping.end(); it != end; ++it)
- cout << (*it).first << " => " << (*it).second << endl;
}
std::map<int, std::list<std::list<double> > > MapUser::foo() const
diff --git a/sources/shiboken6/tests/libsample/mapuser.h b/sources/shiboken6/tests/libsample/mapuser.h
index ad434b957..1677a4bfb 100644
--- a/sources/shiboken6/tests/libsample/mapuser.h
+++ b/sources/shiboken6/tests/libsample/mapuser.h
@@ -1,48 +1,26 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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();
@@ -53,10 +31,10 @@ public:
inline std::map<std::string, std::list<int> > getMap() { return m_map; }
// Compile test
- static void pointerToMap(std::map<std::string, std::string>* arg) {}
- static void referenceToMap(std::map<std::string, std::string>& arg) {}
+ 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 dd3ddc089..48e1b7de3 100644
--- a/sources/shiboken6/tests/libsample/modelindex.h
+++ b/sources/shiboken6/tests/libsample/modelindex.h
@@ -1,57 +1,33 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef MODELINDEX_H
#define MODELINDEX_H
-#include "libsamplemacros.h"
-
class ModelIndex
{
public:
- ModelIndex() : m_value(0) {}
- ModelIndex(const ModelIndex& other) { m_value = other.m_value; }
+ ModelIndex() = default;
+
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;
+ int m_value = 0;
};
class ReferentModelIndex
{
public:
- ReferentModelIndex() {}
- ReferentModelIndex(const ModelIndex& index) : m_index(index) {}
- ReferentModelIndex(const ReferentModelIndex& other) { m_index = other.m_index; }
+ ReferentModelIndex() = default;
+
+ 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;
};
@@ -59,14 +35,16 @@ private:
class PersistentModelIndex
{
public:
- PersistentModelIndex() {}
- PersistentModelIndex(const ModelIndex& index) : m_index(index) {}
- PersistentModelIndex(const PersistentModelIndex& other) { m_index = other.m_index; }
+ PersistentModelIndex() = default;
+
+ 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 627d17b45..6d627c4c1 100644
--- a/sources/shiboken6/tests/libsample/modifications.cpp
+++ b/sources/shiboken6/tests/libsample/modifications.cpp
@@ -1,40 +1,14 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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");
}
@@ -43,30 +17,87 @@ Modifications::~Modifications()
delete m_object;
}
-std::pair<double, double>
-Modifications::pointToPair(Point pt, bool* ok)
+Modifications::OverloadedModFunc Modifications::overloaded(int, bool, Point, Point)
+{
+ return Overloaded_ibPP;
+}
+
+Modifications::OverloadedModFunc Modifications::overloaded(int, bool, int, int)
+{
+ return Overloaded_ibii;
+}
+
+Modifications::OverloadedModFunc Modifications::overloaded(int, bool, int, Point)
+{
+ return Overloaded_ibiP;
+}
+
+Modifications::OverloadedModFunc Modifications::overloaded(int, bool, int, bool)
+{
+ return Overloaded_ibib;
+}
+
+Modifications::OverloadedModFunc Modifications::overloaded(int, bool, int, double)
+{
+ return Overloaded_ibid;
+}
+
+void Modifications::argRemoval0(int, bool, int, int)
+{
+}
+
+void Modifications::argRemoval0(int, bool, int, bool)
+{
+}
+
+void Modifications::argRemoval1(int, bool, Point, Point, int)
+{
+}
+
+void Modifications::argRemoval1(int, bool, int, bool)
+{
+}
+
+void Modifications::argRemoval2(int, bool, Point, Point, int)
+{
+}
+
+void Modifications::argRemoval3(int, Point, bool, Point, int)
+{
+}
+
+void Modifications::argRemoval4(int, Point, bool, Point, int)
+{
+}
+
+void Modifications::argRemoval5(int, bool, Point, Point, int)
+{
+}
+
+void Modifications::argRemoval5(int, bool, int, bool)
+{
+}
+
+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;
@@ -76,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)
@@ -115,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;
@@ -142,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 888c66d18..5bd1bac47 100644
--- a/sources/shiboken6/tests/libsample/modifications.h
+++ b/sources/shiboken6/tests/libsample/modifications.h
@@ -1,44 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef MODIFICATIONS_H
#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();
@@ -58,34 +36,38 @@ public:
// those overloaded methods should be heavily modified
// to push the overload decisor to its limits
- inline OverloadedModFunc overloaded(int a0, bool b0, int c0, double d0) { return Overloaded_ibid; }
- inline OverloadedModFunc overloaded(int a1, bool b1, int c1, bool d1) { return Overloaded_ibib; }
- inline OverloadedModFunc overloaded(int a2, bool b2, int c2, Point d2) { return Overloaded_ibiP; }
- inline OverloadedModFunc overloaded(int a3, bool b3, int c3 = 123, int d3 = 456) { return Overloaded_ibii; }
- inline OverloadedModFunc overloaded(int a4, bool b4, Point c4, Point d4) { return Overloaded_ibPP; }
+ OverloadedModFunc overloaded(int a0, bool b0, int c0, double d0);
+ OverloadedModFunc overloaded(int a1, bool b1, int c1, bool d1);
+ OverloadedModFunc overloaded(int a2, bool b2, int c2, Point d2);
+ OverloadedModFunc overloaded(int a3, bool b3, int c3 = 123, int d3 = 456);
+ OverloadedModFunc overloaded(int a4, bool b4, Point c4, Point d4);
- inline void argRemoval0(int a0, bool a1, int a2 = 123, int a3 = 456) {}
- inline void argRemoval0(int a0, bool a1, int a2, bool a3) {}
+ void argRemoval0(int a0, bool a1, int a2 = 123, int a3 = 456);
+ void argRemoval0(int a0, bool a1, int a2, bool a3);
- inline void argRemoval1(int a0, bool a1, Point a2 = Point(1, 2), Point a3 = Point(3, 4), int a4 = 333) {}
- inline void argRemoval1(int a0, bool a1, int a2, bool a3) {}
+ void argRemoval1(int a0, bool a1, Point a2 = Point(1, 2), Point a3 = Point(3, 4),
+ int a4 = 333);
+ void argRemoval1(int a0, bool a1, int a2, bool a3);
- inline void argRemoval2(int a0, bool a1, Point a2 = Point(1, 2), Point a3 = Point(3, 4), int a4 = 333) {}
+ void argRemoval2(int a0, bool a1, Point a2 = Point(1, 2), Point a3 = Point(3, 4),
+ int a4 = 333);
- inline void argRemoval3(int a0, Point a1 = Point(1, 2), bool a2 = true, Point a3 = Point(3, 4), int a4 = 333) {}
+ void argRemoval3(int a0, Point a1 = Point(1, 2), bool a2 = true, Point a3 = Point(3, 4),
+ int a4 = 333);
- inline void argRemoval4(int a0, Point a1, bool a2, Point a3 = Point(3, 4), int a4 = 333) {}
+ void argRemoval4(int a0, Point a1, bool a2, Point a3 = Point(3, 4), int a4 = 333);
- inline void argRemoval5(int a0, bool a1, Point a2 = Point(1, 2), Point a3 = Point(3, 4), int a4 = 333) {}
- inline void argRemoval5(int a0, bool a1, int a2, bool a3) {}
+ void argRemoval5(int a0, bool a1, Point a2 = Point(1, 2), Point a3 = Point(3, 4),
+ int a4 = 333);
+ void argRemoval5(int a0, bool a1, int a2, bool a3);
// '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);
@@ -106,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; }
@@ -139,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;
@@ -148,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 015cf4e80..c39c97738 100644
--- a/sources/shiboken6/tests/libsample/modified_constructor.cpp
+++ b/sources/shiboken6/tests/libsample/modified_constructor.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "modified_constructor.h"
@@ -33,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 ccf23a1a3..a27899f3f 100644
--- a/sources/shiboken6/tests/libsample/modified_constructor.h
+++ b/sources/shiboken6/tests/libsample/modified_constructor.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef MODIFIEDCONSTRUCTOR_H
#define MODIFIEDCONSTRUCTOR_H
@@ -35,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 2c6a0b8bb..be535c62f 100644
--- a/sources/shiboken6/tests/libsample/multiple_derived.cpp
+++ b/sources/shiboken6/tests/libsample/multiple_derived.cpp
@@ -1,64 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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 b551eda74..8c2143ed6 100644
--- a/sources/shiboken6/tests/libsample/multiple_derived.h
+++ b/sources/shiboken6/tests/libsample/multiple_derived.h
@@ -1,99 +1,90 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef MDERIVED_H
#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;
};
@@ -101,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;
};
@@ -182,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 3173f4609..a0b91380b 100644
--- a/sources/shiboken6/tests/libsample/noimplicitconversion.h
+++ b/sources/shiboken6/tests/libsample/noimplicitconversion.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef NOIMPLICITCONVERSION_H
#define NOIMPLICITCONVERSION_H
@@ -38,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 bfdcbcf5b..fa97b8859 100644
--- a/sources/shiboken6/tests/libsample/nondefaultctor.h
+++ b/sources/shiboken6/tests/libsample/nondefaultctor.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef NONDEFAULTCTOR_H
#define NONDEFAULTCTOR_H
@@ -33,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;
}
@@ -69,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 5a9e670c6..e41c21604 100644
--- a/sources/shiboken6/tests/libsample/nontypetemplate.h
+++ b/sources/shiboken6/tests/libsample/nontypetemplate.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2018 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef NONTYPETEMPLATE_H
#define NONTYPETEMPLATE_H
@@ -46,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 ea34ff5a0..945a89fa2 100644
--- a/sources/shiboken6/tests/libsample/null.h
+++ b/sources/shiboken6/tests/libsample/null.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef NULL_H
#define NULL_H
@@ -33,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 c92fb2ec2..56ed86577 100644
--- a/sources/shiboken6/tests/libsample/objectmodel.cpp
+++ b/sources/shiboken6/tests/libsample/objectmodel.cpp
@@ -1,42 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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;
}
+ObjectModel::MethodCalled ObjectModel::receivesObjectTypeFamily(const ObjectModel &)
+{
+ return ObjectModel::ObjectModelCalled;
+}
+
+ObjectModel::MethodCalled ObjectModel::receivesObjectTypeFamily(const ObjectType &)
+{
+ return ObjectModel::ObjectTypeCalled;
+}
diff --git a/sources/shiboken6/tests/libsample/objectmodel.h b/sources/shiboken6/tests/libsample/objectmodel.h
index 1890ac47f..6d2f97aee 100644
--- a/sources/shiboken6/tests/libsample/objectmodel.h
+++ b/sources/shiboken6/tests/libsample/objectmodel.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OBJECTMODEL_H
#define OBJECTMODEL_H
@@ -36,23 +11,21 @@ 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]
enum MethodCalled { ObjectTypeCalled, ObjectModelCalled };
- static MethodCalled receivesObjectTypeFamily(const ObjectType& object) { return ObjectModel::ObjectTypeCalled; }
- static MethodCalled receivesObjectTypeFamily(const ObjectModel& object) { return ObjectModel::ObjectModelCalled; }
+ static MethodCalled receivesObjectTypeFamily(const ObjectType &object);
+ static MethodCalled receivesObjectTypeFamily(const ObjectModel &object);
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 e5926d0c2..fa3e7357c 100644
--- a/sources/shiboken6/tests/libsample/objecttype.cpp
+++ b/sources/shiboken6/tests/libsample/objecttype.cpp
@@ -1,71 +1,38 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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;
@@ -77,8 +44,7 @@ ObjectType::removeChild(ObjectType* child)
}
}
-ObjectType*
-ObjectType::takeChild(ObjectType* child)
+ObjectType *ObjectType::takeChild(ObjectType *child)
{
if (!child)
return nullptr;
@@ -92,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));
@@ -107,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()) {
@@ -125,8 +88,7 @@ ObjectType::killChild(const Str& name)
}
}
-void
-ObjectType::setParent(ObjectType* parent)
+void ObjectType::setParent(ObjectType *parent)
{
if (m_parent == parent)
return;
@@ -139,33 +101,28 @@ 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);
}
-bool
-ObjectType::event(Event* event)
+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) {
@@ -173,38 +130,43 @@ ObjectType::processEvent(ObjectTypeList objects, Event *event)
});
}
-void
-ObjectType::callInvalidateEvent(Event* event)
+void ObjectType::callInvalidateEvent(Event *event)
{
invalidateEvent(event);
}
-void
-ObjectType::setLayout(ObjectTypeLayout* l)
+void ObjectType::invalidateEvent(Event *)
+{
+}
+
+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;
@@ -214,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;
@@ -224,39 +186,35 @@ 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& prefix, Event::EventType type, unsigned char value){
- return value*value;
+unsigned char ObjectType::callWithEnum(const Str &, Event::EventType, unsigned char value)
+{
+ return value * value;
}
-unsigned char
-ObjectType::callWithEnum(const Str& prefix, unsigned char value) {
+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);
}
@@ -276,37 +234,31 @@ 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* event)
+bool ObjectTypeDerived::event(Event *)
{
return true;
}
diff --git a/sources/shiboken6/tests/libsample/objecttype.h b/sources/shiboken6/tests/libsample/objecttype.h
index 5863d5f2d..498556459 100644
--- a/sources/shiboken6/tests/libsample/objecttype.h
+++ b/sources/shiboken6/tests/libsample/objecttype.h
@@ -1,41 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OBJECTTYPE_H
#define OBJECTTYPE_H
-#include <list>
#include "str.h"
#include "null.h"
#include "libsamplemacros.h"
-#include <stddef.h>
+#include <list>
struct Event
{
@@ -51,11 +25,12 @@ 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; }
+ void setEventTypeByConstPtr(const EventType *etPtr) { m_eventType = *etPtr; }
private:
EventType m_eventType;
@@ -73,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);
- virtual void invalidateEvent(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;
@@ -148,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 64fa78c83..7b12ff945 100644
--- a/sources/shiboken6/tests/libsample/objecttypebyvalue.h
+++ b/sources/shiboken6/tests/libsample/objecttypebyvalue.h
@@ -1,46 +1,31 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OBJECTTYPEBYVALUE_H
#define OBJECTTYPEBYVALUE_H
-#include <list>
+
#include "protected.h"
+#include <list>
+
class ObjectTypeByValue
{
public:
- ObjectTypeByValue returnSomeKindOfMe() { return ObjectTypeByValue(); }
- void acceptKindOfMeAsValue(ObjectTypeByValue kindOfMe) {}
+ ObjectTypeByValue returnSomeKindOfMe() { return {}; }
+ void acceptKindOfMeAsValue(ObjectTypeByValue kindOfMe);
- void acceptListOfObjectTypeByValue(std::list<ObjectTypeByValue> listOfMe) {}
+ void acceptListOfObjectTypeByValue(std::list<ObjectTypeByValue> listOfMe);
// prop used to check for segfaults
ProtectedProperty prop;
};
-#endif
+inline void ObjectTypeByValue::acceptKindOfMeAsValue(ObjectTypeByValue)
+{
+}
+
+inline void ObjectTypeByValue::acceptListOfObjectTypeByValue(std::list<ObjectTypeByValue>)
+{
+}
+
+#endif // OBJECTTYPEBYVALUE_H
diff --git a/sources/shiboken6/tests/libsample/objecttypeholder.cpp b/sources/shiboken6/tests/libsample/objecttypeholder.cpp
index be225a0d2..c0950d09c 100644
--- a/sources/shiboken6/tests/libsample/objecttypeholder.cpp
+++ b/sources/shiboken6/tests/libsample/objecttypeholder.cpp
@@ -1,41 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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)
{
}
@@ -45,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 7558b11ee..190664608 100644
--- a/sources/shiboken6/tests/libsample/objecttypeholder.h
+++ b/sources/shiboken6/tests/libsample/objecttypeholder.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OBJECTTYPEHOLDER_H
#define OBJECTTYPEHOLDER_H
@@ -36,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 f06ede758..3fa02917c 100644
--- a/sources/shiboken6/tests/libsample/objecttypelayout.cpp
+++ b/sources/shiboken6/tests/libsample/objecttypelayout.cpp
@@ -1,43 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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;
}
@@ -50,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())
@@ -64,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 eb099313c..0aa9fad6e 100644
--- a/sources/shiboken6/tests/libsample/objecttypelayout.h
+++ b/sources/shiboken6/tests/libsample/objecttypelayout.h
@@ -1,36 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OBJECTTYPELAYOUT_H
#define OBJECTTYPELAYOUT_H
#include "libsamplemacros.h"
#include "objecttype.h"
+
#include <list>
class ObjectType;
@@ -38,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 dc5243f2e..c78387a3e 100644
--- a/sources/shiboken6/tests/libsample/objecttypeoperators.cpp
+++ b/sources/shiboken6/tests/libsample/objecttypeoperators.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "objecttypeoperators.h"
@@ -32,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 6bb54d600..6144952ca 100644
--- a/sources/shiboken6/tests/libsample/objecttypeoperators.h
+++ b/sources/shiboken6/tests/libsample/objecttypeoperators.h
@@ -1,61 +1,36 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OBJECTTYPEOPERATORS_H
#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 d640c406e..1b727f88c 100644
--- a/sources/shiboken6/tests/libsample/objectview.cpp
+++ b/sources/shiboken6/tests/libsample/objectview.cpp
@@ -1,54 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "objectview.h"
#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 b68d031e9..2567deee5 100644
--- a/sources/shiboken6/tests/libsample/objectview.h
+++ b/sources/shiboken6/tests/libsample/objectview.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OBJECTVIEW_H
#define OBJECTVIEW_H
@@ -38,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 4f491dd96..bc1ee833f 100644
--- a/sources/shiboken6/tests/libsample/oddbool.cpp
+++ b/sources/shiboken6/tests/libsample/oddbool.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "oddbool.h"
@@ -32,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;
@@ -46,3 +21,7 @@ int ComparisonTester::compare(const ComparisonTester &rhs) const
return 1;
return 0;
}
+
+SpaceshipComparisonTester::SpaceshipComparisonTester(int v) : m_value(v)
+{
+}
diff --git a/sources/shiboken6/tests/libsample/oddbool.h b/sources/shiboken6/tests/libsample/oddbool.h
index f7d77c0b3..dd2d32604 100644
--- a/sources/shiboken6/tests/libsample/oddbool.h
+++ b/sources/shiboken6/tests/libsample/oddbool.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ODDBOOL_H
#define ODDBOOL_H
@@ -33,11 +8,15 @@
#include <type_traits>
+#if __cplusplus >= 202002 || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002)
+# include <compare>
+#endif
+
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); }
@@ -56,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; }
@@ -73,7 +54,7 @@ public:
return invertedOddBool();
}
- static inline OddBool getOddBool(const OddBoolUser& oddBoolUser)
+ static inline OddBool getOddBool(const OddBoolUser &oddBoolUser)
{
return oddBoolUser.m_oddbool;
}
@@ -105,4 +86,21 @@ inline std::enable_if<std::is_assignable<ComparisonTester, int>::value, bool>::t
operator!=(const ComparisonTester &c1, const ComparisonTester &c2)
{ return c1.compare(c2) != 0; }
+class LIBSAMPLE_API SpaceshipComparisonTester
+{
+public:
+ explicit SpaceshipComparisonTester(int v);
+
+#if __cplusplus >= 202002 || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002)
+ auto operator<=>(const SpaceshipComparisonTester &rhs) const = default;
+
+ enum Enabled { HasSpaceshipOperator = 1 };
+#else
+ enum Enabled { HasSpaceshipOperator = 0 };
+#endif // C++ 20
+
+private:
+ int m_value;
+};
+
#endif // ODDBOOL_H
diff --git a/sources/shiboken6/tests/libsample/onlycopy.cpp b/sources/shiboken6/tests/libsample/onlycopy.cpp
index cfc7c9d99..981ea88a4 100644
--- a/sources/shiboken6/tests/libsample/onlycopy.cpp
+++ b/sources/shiboken6/tests/libsample/onlycopy.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "onlycopy.h"
@@ -36,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 84a32a951..7dc3e0069 100644
--- a/sources/shiboken6/tests/libsample/onlycopy.h
+++ b/sources/shiboken6/tests/libsample/onlycopy.h
@@ -1,36 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef ONLYCOPYCLASS_H
#define ONLYCOPYCLASS_H
#include "libsamplemacros.h"
+
#include <list>
+#include <memory>
// These classes simulate a situation found in QWebEngineHistoryItem.
@@ -39,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
@@ -60,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 ebf19586e..34da28e03 100644
--- a/sources/shiboken6/tests/libsample/overload.cpp
+++ b/sources/shiboken6/tests/libsample/overload.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "overload.h"
@@ -33,18 +8,196 @@ Overload::FunctionEnum Overload::overloaded()
return Function0;
}
-Overload::FunctionEnum Overload::overloaded(Size* size)
+Overload::FunctionEnum Overload::overloaded(Size *)
{
return Function1;
}
-Overload::FunctionEnum Overload::overloaded(Point* point, ParamEnum param)
+Overload::FunctionEnum Overload::overloaded(Point *, ParamEnum)
{
return Function2;
}
-Overload::FunctionEnum Overload::overloaded(const Point& point)
+Overload::FunctionEnum Overload::overloaded(const Point &)
{
return Function3;
}
+void Overload::differentReturnTypes(ParamEnum)
+{
+
+}
+
+int Overload::differentReturnTypes(ParamEnum, int val)
+{
+ return val;
+}
+
+int Overload::intOverloads(const Point &, double)
+{
+ return 1;
+}
+
+int Overload::intOverloads(int, int)
+{
+ return 2;
+}
+
+int Overload::intOverloads(int, int, double)
+{
+ return 3;
+}
+
+Overload::FunctionEnum Overload::intDoubleOverloads(double, double) const
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::intDoubleOverloads(int, int) const
+{
+ return Function0;
+}
+
+void Overload::singleOverload(Point *)
+{
+}
+
+Overload::FunctionEnum Overload::wrapperIntIntOverloads(const Polygon &, int, int)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::wrapperIntIntOverloads(const Point &, int, int)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::strBufferOverloads(const Str &, const char *, bool)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::strBufferOverloads(unsigned char *, int)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::drawText(const PointF &, const Str &)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::drawText(const Point &, const Str &)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::drawText(const RectF &, const Str &, const Echo &)
+{
+ return Function4;
+}
+
+Overload::FunctionEnum Overload::drawText(const RectF &, int, const Str &)
+{
+ return Function3;
+}
+
+Overload::FunctionEnum Overload::drawText(const Rect &, int, const Str &)
+{
+ return Function2;
+}
+
+Overload::FunctionEnum Overload::drawText(int, int, const Str &)
+{
+ return Function5;
+}
+
+Overload::FunctionEnum Overload::drawText(int, int, int, int, int, const Str &)
+{
+ return Function6;
+}
+
+Overload::FunctionEnum Overload::drawText2(const PointF &, const Str &)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::drawText2(const Point &, const Str &)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::drawText2(int, int, const Str &)
+{
+ return Function5;
+}
+
+Overload::FunctionEnum Overload::drawText2(const RectF &, const Str &, const Echo &)
+{
+ return Function4;
+}
+
+Overload::FunctionEnum Overload::drawText2(const RectF &, int, const Str &)
+{
+ return Function3;
+}
+
+Overload::FunctionEnum Overload::drawText2(const Rect &, int, const Str &)
+{
+ return Function2;
+}
+
+Overload::FunctionEnum Overload::drawText2(int, int, int, int, int, const Str &)
+{
+ return Function6;
+}
+
+Overload::FunctionEnum Overload::drawText3(const Str &, const Str &, const Str &)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::drawText3(int, int, int, int, int)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::drawText4(int, int, int)
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::drawText4(int, int, int, int, int)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::acceptSequence()
+{
+ return Function0;
+}
+
+Overload::FunctionEnum Overload::acceptSequence(const Str &, ParamEnum)
+{
+ return Function2;
+}
+
+Overload::FunctionEnum Overload::acceptSequence(int, int)
+{
+ return Function1;
+}
+
+Overload::FunctionEnum Overload::acceptSequence(void *)
+{
+ return Function5;
+}
+
+Overload::FunctionEnum Overload::acceptSequence(const char *const[])
+{
+ return Function4;
+}
+
+Overload::FunctionEnum Overload::acceptSequence(const Size &)
+{
+ return Function3;
+}
diff --git a/sources/shiboken6/tests/libsample/overload.h b/sources/shiboken6/tests/libsample/overload.h
index aa2572d50..b640bf7c7 100644
--- a/sources/shiboken6/tests/libsample/overload.h
+++ b/sources/shiboken6/tests/libsample/overload.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OVERLOAD_H
#define OVERLOAD_H
@@ -42,6 +17,8 @@
class LIBSAMPLE_API Overload
{
public:
+ LIBMINIMAL_DISABLE_COPY_MOVE(Overload)
+
enum FunctionEnum {
Function0,
Function1,
@@ -57,69 +34,71 @@ 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);
- inline void differentReturnTypes(ParamEnum param = Param0) {}
- inline int differentReturnTypes(ParamEnum param, int val) { return val; }
+ void differentReturnTypes(ParamEnum param = Param0);
+ int differentReturnTypes(ParamEnum param, int val);
- inline int intOverloads(const Point& p, double d) { return 1; }
- inline int intOverloads(int i, int i2) { return 2; }
- inline int intOverloads(int i, int removedArg, double d) { return 3; }
+ int intOverloads(const Point &p, double d);
+ int intOverloads(int i, int i2);
+ int intOverloads(int i, int removedArg, double d);
- inline FunctionEnum intDoubleOverloads(int a0, int a1) const { return Function0; }
- inline FunctionEnum intDoubleOverloads(double a0, double a1) const { return Function1; }
+ FunctionEnum intDoubleOverloads(int a0, int a1) const;
+ FunctionEnum intDoubleOverloads(double a0, double a1) const;
- void singleOverload(Point* x) {}
- Point* singleOverload() {return new Point();}
+ void singleOverload(Point *x);
+ 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) { return Function0; }
- FunctionEnum wrapperIntIntOverloads(const Polygon& arg0, int arg1, int arg2) { return Function1; }
+ FunctionEnum wrapperIntIntOverloads(const Point &arg0, int arg1, int arg2);
+ FunctionEnum wrapperIntIntOverloads(const Polygon &arg0, int arg1, int arg2);
// Similar to QImage constructor
- FunctionEnum strBufferOverloads(const Str &arg0, const char *arg1 = nullptr, bool arg2 = true) { return Function0; }
- FunctionEnum strBufferOverloads(unsigned char* arg0, int arg1) { return Function1; }
+ FunctionEnum strBufferOverloads(const Str &arg0, const char *arg1 = nullptr,
+ bool arg2 = true);
+ FunctionEnum strBufferOverloads(unsigned char *arg0, int arg1);
FunctionEnum strBufferOverloads() { return Function2; }
// Similar to QPainter::drawText(...)
- FunctionEnum drawText(const Point& a0, const Str& a1) { return Function0; }
- FunctionEnum drawText(const PointF& a0, const Str& a1) { return Function1; }
- FunctionEnum drawText(const Rect& a0, int a1, const Str& a2) { return Function2; }
- FunctionEnum drawText(const RectF& a0, int a1, const Str& a2) { return Function3; }
- FunctionEnum drawText(const RectF& a0, const Str& a1, const Echo& a2 = Echo()) { return Function4; }
- FunctionEnum drawText(int a0, int a1, const Str& a2) { return Function5; }
- FunctionEnum drawText(int a0, int a1, int a2, int a3, int a4, const Str& a5) { return Function6; }
+ FunctionEnum drawText(const Point &a0, const Str &a1);
+ FunctionEnum drawText(const PointF &a0, const Str &a1);
+ FunctionEnum drawText(const Rect &a0, int a1, const Str &a2);
+ FunctionEnum drawText(const RectF &a0, int a1, const Str &a2);
+ FunctionEnum drawText(const RectF &a0, const Str &a1, const Echo &a2 = Echo());
+ FunctionEnum drawText(int a0, int a1, const Str &a2);
+ FunctionEnum drawText(int a0, int a1, int a2, int a3, int a4, const Str &a5);
// A variant of the one similar to QPainter::drawText(...)
- FunctionEnum drawText2(const Point& a0, const Str& a1) { return Function0; }
- FunctionEnum drawText2(const PointF& a0, const Str& a1) { return Function1; }
- FunctionEnum drawText2(const Rect& a0, int a1, const Str& a2) { return Function2; }
- FunctionEnum drawText2(const RectF& a0, int a1, const Str& a2) { return Function3; }
- FunctionEnum drawText2(const RectF& a0, const Str& a1, const Echo& a2 = Echo()) { return Function4; }
- FunctionEnum drawText2(int a0, int a1, const Str& a2) { return Function5; }
- FunctionEnum drawText2(int a0, int a1, int a2, int a3 = 0, int a4 = 0, const Str& a5 = Str()) { return Function6; }
+ FunctionEnum drawText2(const Point &a0, const Str &a1);
+ FunctionEnum drawText2(const PointF &a0, const Str &a1);
+ FunctionEnum drawText2(const Rect &a0, int a1, const Str &a2);
+ FunctionEnum drawText2(const RectF &a0, int a1, const Str &a2);
+ FunctionEnum drawText2(const RectF &a0, const Str &a1, const Echo &a2 = Echo());
+ FunctionEnum drawText2(int a0, int a1, const Str &a2);
+ FunctionEnum drawText2(int a0, int a1, int a2, int a3 = 0, int a4 = 0,
+ const Str &a5 = Str());
// A simpler variant of the one similar to QPainter::drawText(...)
- FunctionEnum drawText3(const Str& a0, const Str& a1, const Str& a2) { return Function0; }
- FunctionEnum drawText3(int a0, int a1, int a2, int a3, int a4) { return Function1; }
+ FunctionEnum drawText3(const Str &a0, const Str &a1, const Str &a2);
+ FunctionEnum drawText3(int a0, int a1, int a2, int a3, int a4);
// Another simpler variant of the one similar to QPainter::drawText(...)
- FunctionEnum drawText4(int a0, int a1, int a2) { return Function0; }
- FunctionEnum drawText4(int a0, int a1, int a2, int a3, int a4) { return Function1; }
+ FunctionEnum drawText4(int a0, int a1, int a2);
+ FunctionEnum drawText4(int a0, int a1, int a2, int a3, int a4);
- FunctionEnum acceptSequence() { return Function0; }
- FunctionEnum acceptSequence(int a0, int a1) { return Function1; }
- FunctionEnum acceptSequence(const Str& a0, ParamEnum a1 = Param0) { return Function2; }
- FunctionEnum acceptSequence(const Size& a0) { return Function3; }
+ FunctionEnum acceptSequence();
+ FunctionEnum acceptSequence(int a0, int a1);
+ 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[]) { return Function4; }
- FunctionEnum acceptSequence(void* a0) { return Function5; }
+ FunctionEnum acceptSequence(const char *const a0[]);
+ FunctionEnum acceptSequence(void *a0);
};
class LIBSAMPLE_API Overload2 : public Overload
@@ -140,4 +119,3 @@ private:
};
#endif // OVERLOAD_H
-
diff --git a/sources/shiboken6/tests/libsample/overloadsort.cpp b/sources/shiboken6/tests/libsample/overloadsort.cpp
index 8534ef0f1..a9b4b0972 100644
--- a/sources/shiboken6/tests/libsample/overloadsort.cpp
+++ b/sources/shiboken6/tests/libsample/overloadsort.cpp
@@ -1,33 +1,43 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "overloadsort.h"
+const char *SortedOverload::overload(int)
+{
+ return "int";
+}
+
+const char *SortedOverload::overload(double)
+{
+ return "double";
+}
+
+const char *SortedOverload::overload(ImplicitBase)
+{
+ return "ImplicitBase";
+}
+
+const char *SortedOverload::overload(ImplicitTarget)
+{
+ return "ImplicitTarget";
+}
+
+const char *SortedOverload::overload(const std::list<ImplicitBase> &)
+{
+ return "list(ImplicitBase)";
+}
+
+int SortedOverload::implicit_overload(const ImplicitBase &)
+{
+ return 1;
+}
+
+const char *SortedOverload::overloadDeep(int, ImplicitBase &)
+{
+ return "ImplicitBase";
+}
+
int CustomOverloadSequence::overload(short v) const
{
return v + int(sizeof(v));
diff --git a/sources/shiboken6/tests/libsample/overloadsort.h b/sources/shiboken6/tests/libsample/overloadsort.h
index ad720222c..ee269cc21 100644
--- a/sources/shiboken6/tests/libsample/overloadsort.h
+++ b/sources/shiboken6/tests/libsample/overloadsort.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef OVERLOADSORT_H
#define OVERLOADSORT_H
@@ -36,52 +11,37 @@
class ImplicitTarget
{
public:
- ImplicitTarget(){}
+ ImplicitTarget() = default;
};
class ImplicitBase
{
public:
- ImplicitBase(){}
- ImplicitBase(const ImplicitTarget &b){}
+ ImplicitBase() = default;
+ ImplicitBase(const ImplicitTarget &b);
};
-class SortedOverload
+inline ImplicitBase::ImplicitBase(const ImplicitTarget &)
{
-public:
-
- inline const char *overload(int x) {
- return "int";
- }
-
- inline const char *overload(double x) {
- return "double";
- }
-
- inline const char *overload(ImplicitBase x) {
- return "ImplicitBase";
- }
-
- inline const char *overload(ImplicitTarget x) {
- return "ImplicitTarget";
- }
+}
- inline const char *overload(const std::list<ImplicitBase> &x) {
- return "list(ImplicitBase)";
- }
-
- inline int implicit_overload(const ImplicitBase &x) {
- return 1;
- }
+class LIBSAMPLE_API SortedOverload
+{
+public:
- inline const char *overloadDeep(int x, ImplicitBase &y) {
- return "ImplicitBase";
- }
+ const char *overload(int x);
+ const char *overload(double x);
+ const char *overload(ImplicitBase x);
+ const char *overload(ImplicitTarget x);
+ const char *overload(const std::list<ImplicitBase> &x);
+ int implicit_overload(const ImplicitBase &x);
- inline const char* pyObjOverload(int, int) { return "int,int"; }
- inline const char* pyObjOverload(unsigned char*, int) { return "PyObject,int"; }
+ 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"; }
};
class LIBSAMPLE_API CustomOverloadSequence
@@ -92,4 +52,3 @@ public:
};
#endif // OVERLOADSORT_H
-
diff --git a/sources/shiboken6/tests/libsample/pairuser.cpp b/sources/shiboken6/tests/libsample/pairuser.cpp
index 661988445..5b7eb4d8c 100644
--- a/sources/shiboken6/tests/libsample/pairuser.cpp
+++ b/sources/shiboken6/tests/libsample/pairuser.cpp
@@ -1,57 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 37219f724..ee51d818e 100644
--- a/sources/shiboken6/tests/libsample/pairuser.h
+++ b/sources/shiboken6/tests/libsample/pairuser.h
@@ -1,44 +1,21 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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();
@@ -51,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 b5c9356d6..76473a264 100644
--- a/sources/shiboken6/tests/libsample/pen.cpp
+++ b/sources/shiboken6/tests/libsample/pen.cpp
@@ -1,38 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "pen.h"
-Color::Color(SampleNamespace::InValue arg) : m_null(false)
+Color::Color(SampleNamespace::InValue) : m_null(false)
{
}
-Color::Color(unsigned int arg) : m_null(false)
+Color::Color(unsigned int) : m_null(false)
{
}
@@ -70,28 +45,30 @@ void Brush::setColor(const Color &newColor)
m_color = newColor;
}
-Pen::Pen() : m_ctor(EmptyCtor)
-{
-}
+Pen::Pen() = default;
-Pen::Pen(SampleNamespace::Option option) : m_ctor(EnumCtor)
+Pen::Pen(SampleNamespace::Option) : m_ctor(EnumCtor)
{
}
-Pen::Pen(const Color& color) : m_ctor(ColorCtor)
+Pen::Pen(const Color &) : m_ctor(ColorCtor)
{
}
-Pen::Pen(const Pen& pen) : m_ctor(CopyCtor)
+Pen::Pen(const Pen &) : m_ctor(CopyCtor)
{
}
+Pen::Pen(Pen &&) noexcept = default;
+Pen &Pen::operator=(const Pen &pen) = default;
+Pen &Pen::operator=(Pen &&) noexcept = default;
+
int Pen::ctorType()
{
return m_ctor;
}
-void Pen::drawLine(int x1, int y1, int x2, int y2, RenderHints renderHints)
+void Pen::drawLine(int, int, int, int, RenderHints)
{
}
diff --git a/sources/shiboken6/tests/libsample/pen.h b/sources/shiboken6/tests/libsample/pen.h
index 3e4fe5dd8..6f528f0f9 100644
--- a/sources/shiboken6/tests/libsample/pen.h
+++ b/sources/shiboken6/tests/libsample/pen.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef PEN_H
#define PEN_H
@@ -40,6 +15,7 @@ public:
Color(unsigned int arg);
bool isNull() const;
+
private:
bool m_null = true;
};
@@ -73,8 +49,12 @@ public:
Pen();
Pen(SampleNamespace::Option option);
- Pen(const Color& color);
- Pen(const Pen& pen);
+ Pen(const Color &color);
+ Pen(const Pen &pen);
+ Pen(Pen &&) noexcept;
+ Pen &operator=(const Pen &pen);
+ Pen &operator=(Pen &&) noexcept;
+ ~Pen() = default;
// PYSIDE-1325, default initializer
void drawLine(int x1, int y1, int x2, int y2, RenderHints renderHints = {});
@@ -85,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 e61fd5969..2a7f20e33 100644
--- a/sources/shiboken6/tests/libsample/photon.cpp
+++ b/sources/shiboken6/tests/libsample/photon.cpp
@@ -1,50 +1,31 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "photon.h"
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 1dcb4f83e..2debe47d1 100644
--- a/sources/shiboken6/tests/libsample/photon.h
+++ b/sources/shiboken6/tests/libsample/photon.h
@@ -1,37 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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.
@@ -47,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; }
@@ -67,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()
{
@@ -82,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;
@@ -96,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 75e015e07..0a28e877f 100644
--- a/sources/shiboken6/tests/libsample/point.cpp
+++ b/sources/shiboken6/tests/libsample/point.cpp
@@ -1,46 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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;
@@ -48,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 579bcd515..7e5d128ab 100644
--- a/sources/shiboken6/tests/libsample/point.h
+++ b/sources/shiboken6/tests/libsample/point.h
@@ -1,45 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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; }
@@ -52,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 b872ceb5c..26f1cf0a6 100644
--- a/sources/shiboken6/tests/libsample/pointerholder.h
+++ b/sources/shiboken6/tests/libsample/pointerholder.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef POINTERHOLDER_H
#define POINTERHOLDER_H
@@ -34,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 fadf3e591..736a5c6b5 100644
--- a/sources/shiboken6/tests/libsample/pointf.cpp
+++ b/sources/shiboken6/tests/libsample/pointf.cpp
@@ -1,46 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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;
@@ -48,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 f90125c8a..49e009467 100644
--- a/sources/shiboken6/tests/libsample/pointf.h
+++ b/sources/shiboken6/tests/libsample/pointf.h
@@ -1,45 +1,22 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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; }
@@ -50,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 a86bf6483..6af597192 100644
--- a/sources/shiboken6/tests/libsample/polygon.cpp
+++ b/sources/shiboken6/tests/libsample/polygon.cpp
@@ -1,59 +1,26 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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())
@@ -61,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 728332d1a..2424ddd51 100644
--- a/sources/shiboken6/tests/libsample/polygon.h
+++ b/sources/shiboken6/tests/libsample/polygon.h
@@ -1,66 +1,39 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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 f168fdacd..3b38414f8 100644
--- a/sources/shiboken6/tests/libsample/privatector.h
+++ b/sources/shiboken6/tests/libsample/privatector.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef PRIVATECTOR_H
#define PRIVATECTOR_H
@@ -34,22 +9,34 @@
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;
};
-#endif
+class DeletedDefaultCtor
+{
+public:
+ DeletedDefaultCtor() = delete;
+
+ DeletedDefaultCtor(const DeletedDefaultCtor &) = default;
+ DeletedDefaultCtor(DeletedDefaultCtor &&) = default;
+ DeletedDefaultCtor &operator=(const DeletedDefaultCtor &) = default;
+ DeletedDefaultCtor &operator=(DeletedDefaultCtor &&) = default;
+ ~DeletedDefaultCtor() = default;
+};
+
+#endif // PRIVATECTOR_H
diff --git a/sources/shiboken6/tests/libsample/privatedtor.h b/sources/shiboken6/tests/libsample/privatedtor.h
index 64b8652f6..05f18ea53 100644
--- a/sources/shiboken6/tests/libsample/privatedtor.h
+++ b/sources/shiboken6/tests/libsample/privatedtor.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef PRIVATEDTOR_H
#define PRIVATEDTOR_H
@@ -34,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.cpp b/sources/shiboken6/tests/libsample/protected.cpp
index b0f3f1cdc..7ab52d22b 100644
--- a/sources/shiboken6/tests/libsample/protected.cpp
+++ b/sources/shiboken6/tests/libsample/protected.cpp
@@ -1,32 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "protected.h"
int ProtectedVirtualDestructor::dtor_called = 0;
+const char *ProtectedNonPolymorphic::dataTypeName(void *) const
+{
+ return "pointer";
+}
+
+const char *ProtectedNonPolymorphic::dataTypeName(int) const
+{
+ return "integer";
+}
diff --git a/sources/shiboken6/tests/libsample/protected.h b/sources/shiboken6/tests/libsample/protected.h
index 0f4fbf299..059cced5d 100644
--- a/sources/shiboken6/tests/libsample/protected.h
+++ b/sources/shiboken6/tests/libsample/protected.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef PROTECTED_H
#define PROTECTED_H
@@ -32,26 +7,30 @@
#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 const char* dataTypeName(void *data = nullptr) const { return "pointer"; }
- inline const char* dataTypeName(int data) const { return "integer"; }
+ inline static const char *protectedStatic() { return "protectedStatic"; }
+ const char *dataTypeName(void *data = nullptr) const;
+ const char *dataTypeName(int data) const;
private:
std::string m_name;
@@ -60,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;
@@ -77,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:
@@ -104,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
@@ -115,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 1897a8dce..53296d26c 100644
--- a/sources/shiboken6/tests/libsample/rect.h
+++ b/sources/shiboken6/tests/libsample/rect.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef RECT_H
#define RECT_H
@@ -34,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 37ce1a590..29dcfc054 100644
--- a/sources/shiboken6/tests/libsample/reference.cpp
+++ b/sources/shiboken6/tests/libsample/reference.cpp
@@ -1,78 +1,53 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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
+{
+ std::cout << "Reference.objId: " << m_objId << ", address: " << this;
+}
-void
-Reference::show() const
+Reference &Reference::returnMySecondArg(int, Reference &ref)
{
- cout << "Reference.objId: " << m_objId << ", address: " << this;
+ 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)
{
+ return ref;
}
diff --git a/sources/shiboken6/tests/libsample/reference.h b/sources/shiboken6/tests/libsample/reference.h
index 2c0498c6f..52818d9ea 100644
--- a/sources/shiboken6/tests/libsample/reference.h
+++ b/sources/shiboken6/tests/libsample/reference.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef REFERENCE_H
#define REFERENCE_H
@@ -34,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) { return 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;
};
@@ -69,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& returnMySecondArg(int a, ObjTypeReference& ref) { return ref; }
- virtual ObjTypeReference& justAPureVirtualFunc(ObjTypeReference& ref) = 0;
+
+ virtual ObjTypeReference &returnMyFirstArg(ObjTypeReference &ref) { return ref; }
+ virtual ObjTypeReference &returnMySecondArg(int a, ObjTypeReference &ref);
+ 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 47c18c049..669f2ebf0 100644
--- a/sources/shiboken6/tests/libsample/removednamespaces.h
+++ b/sources/shiboken6/tests/libsample/removednamespaces.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef REMOVEDNAMESPACE_H
#define REMOVEDNAMESPACE_H
@@ -71,4 +46,3 @@ namespace RemovedNamespace3
} // namespace UnremovedNamespace
#endif // REMOVEDNAMESPACE_H
-
diff --git a/sources/shiboken6/tests/libsample/renaming.cpp b/sources/shiboken6/tests/libsample/renaming.cpp
index 30586e1db..d67b42a51 100644
--- a/sources/shiboken6/tests/libsample/renaming.cpp
+++ b/sources/shiboken6/tests/libsample/renaming.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "renaming.h"
diff --git a/sources/shiboken6/tests/libsample/renaming.h b/sources/shiboken6/tests/libsample/renaming.h
index cd88b36bf..787ccc2f7 100644
--- a/sources/shiboken6/tests/libsample/renaming.h
+++ b/sources/shiboken6/tests/libsample/renaming.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef RENAMING_H
#define RENAMING_H
diff --git a/sources/shiboken6/tests/libsample/sample.cpp b/sources/shiboken6/tests/libsample/sample.cpp
index 638413fd2..5b5f8588b 100644
--- a/sources/shiboken6/tests/libsample/sample.cpp
+++ b/sources/shiboken6/tests/libsample/sample.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "sample.h"
@@ -40,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 a6a0ff154..27909571a 100644
--- a/sources/shiboken6/tests/libsample/sample.h
+++ b/sources/shiboken6/tests/libsample/sample.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SAMPLE_H
#define SAMPLE_H
@@ -45,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 b3ef96f5a..eae5af2d2 100644
--- a/sources/shiboken6/tests/libsample/samplenamespace.cpp
+++ b/sources/shiboken6/tests/libsample/samplenamespace.cpp
@@ -1,37 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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
{
@@ -43,91 +17,81 @@ 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;
}
-void
-doSomethingWithArray(const unsigned char* data, unsigned int size, const char* format)
+void doSomethingWithArray(const unsigned char *, unsigned int, const char *)
{
// This function does nothing in fact.
// It is here as a dummy copy of QPixmap.loadFromData method
// to check compilation issues, i.e. if it compiles, it's ok.
}
-int
-enumItemAsDefaultValueToIntArgument(int value)
+int enumItemAsDefaultValueToIntArgument(int value)
{
return value;
}
-void
-forceDecisorSideA(ObjectType* object)
+void forceDecisorSideA(ObjectType *)
{
}
-void
-forceDecisorSideA(const Point& pt, const Str& text, ObjectType* object)
+void forceDecisorSideA(const Point &, const Str &, ObjectType *)
{
}
-void
-forceDecisorSideB(int a, ObjectType* object)
+void forceDecisorSideB(int, ObjectType *)
{
}
-void
-forceDecisorSideB(int a, const Point& pt, const Str& text, ObjectType* object)
+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 5fe269c5e..99a0787ee 100644
--- a/sources/shiboken6/tests/libsample/samplenamespace.h
+++ b/sources/shiboken6/tests/libsample/samplenamespace.h
@@ -1,40 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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,
@@ -44,6 +20,25 @@ enum {
namespace SampleNamespace
{
+inline namespace InlineNamespace
+{
+ enum EnumWithinInlineNamespace { EWIN_Value0, EWIN_Value1 };
+
+ class LIBSAMPLE_API ClassWithinInlineNamespace {
+ public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(ClassWithinInlineNamespace)
+
+ ClassWithinInlineNamespace() noexcept = default;
+ ~ClassWithinInlineNamespace() = default;
+
+ void setValue(EnumWithinInlineNamespace v) { m_value = v; }
+ EnumWithinInlineNamespace value() const { return m_value; }
+
+ private:
+ EnumWithinInlineNamespace m_value = EWIN_Value0;
+ };
+} // inline ns
+
enum Option {
None_,
RandomNumber,
@@ -80,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);
@@ -95,7 +91,10 @@ public:
class OkThisIsRecursiveEnough
{
public:
- virtual ~OkThisIsRecursiveEnough() {}
+ LIBMINIMAL_DISABLE_COPY_MOVE(OkThisIsRecursiveEnough)
+
+ OkThisIsRecursiveEnough() noexcept = default;
+ virtual ~OkThisIsRecursiveEnough() = default;
enum NiceEnum {
NiceValue1, NiceValue2
};
@@ -104,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 {
@@ -125,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
{
@@ -134,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.cpp b/sources/shiboken6/tests/libsample/sbkdate.cpp
index 8ba18af43..fd408f637 100644
--- a/sources/shiboken6/tests/libsample/sbkdate.cpp
+++ b/sources/shiboken6/tests/libsample/sbkdate.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "sbkdate.h"
diff --git a/sources/shiboken6/tests/libsample/sbkdate.h b/sources/shiboken6/tests/libsample/sbkdate.h
index bbe3d3ca8..5e1dd0b84 100644
--- a/sources/shiboken6/tests/libsample/sbkdate.h
+++ b/sources/shiboken6/tests/libsample/sbkdate.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SBKDATE_H
#define SBKDATE_H
@@ -34,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;
@@ -47,4 +22,3 @@ private:
};
#endif // SBKDATE_H
-
diff --git a/sources/shiboken6/tests/libsample/simplefile.cpp b/sources/shiboken6/tests/libsample/simplefile.cpp
index 3b68e02c3..e51b14088 100644
--- a/sources/shiboken6/tests/libsample/simplefile.cpp
+++ b/sources/shiboken6/tests/libsample/simplefile.cpp
@@ -1,108 +1,73 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 7a437a99d..e4612c944 100644
--- a/sources/shiboken6/tests/libsample/simplefile.h
+++ b/sources/shiboken6/tests/libsample/simplefile.h
@@ -1,56 +1,34 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SIMPLEFILE_H
#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 4c195161e..0291d6e86 100644
--- a/sources/shiboken6/tests/libsample/size.cpp
+++ b/sources/shiboken6/tests/libsample/size.cpp
@@ -1,39 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 76502b416..2d194e96b 100644
--- a/sources/shiboken6/tests/libsample/size.h
+++ b/sources/shiboken6/tests/libsample/size.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SIZE_H
#define SIZE_H
@@ -34,28 +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)
- {
- return m_width == other.m_width && m_height == other.m_height;
- }
-
- 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
@@ -67,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();
@@ -75,7 +48,7 @@ public:
return a <= b;
}
- inline bool operator>=(const Size& other)
+ inline bool operator>=(const Size &other)
{
return calculateArea() >= other.calculateArea();
}
@@ -86,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;
@@ -117,12 +90,13 @@ public:
// TODO: add ++size, size++, --size, size--
// 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&);
@@ -137,65 +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<(double area, const Size& s)
+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)
{
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;
@@ -203,4 +183,3 @@ private:
};
#endif // SIZE_H
-
diff --git a/sources/shiboken6/tests/libsample/snakecasetest.cpp b/sources/shiboken6/tests/libsample/snakecasetest.cpp
index d82984e6f..8240308b4 100644
--- a/sources/shiboken6/tests/libsample/snakecasetest.cpp
+++ b/sources/shiboken6/tests/libsample/snakecasetest.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "snakecasetest.h"
diff --git a/sources/shiboken6/tests/libsample/snakecasetest.h b/sources/shiboken6/tests/libsample/snakecasetest.h
index 8900c2eec..757dd23b2 100644
--- a/sources/shiboken6/tests/libsample/snakecasetest.h
+++ b/sources/shiboken6/tests/libsample/snakecasetest.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SNAKECASETEST_H
#define SNAKECASETEST_H
diff --git a/sources/shiboken6/tests/libsample/sometime.cpp b/sources/shiboken6/tests/libsample/sometime.cpp
index 851b3b913..ad9a0d81c 100644
--- a/sources/shiboken6/tests/libsample/sometime.cpp
+++ b/sources/shiboken6/tests/libsample/sometime.cpp
@@ -1,36 +1,11 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "sometime.h"
-#include <stdio.h>
-void
-Time::setTime()
+#include <cstdio>
+
+void Time::setTime()
{
m_hour = 0;
m_minute = 0;
@@ -39,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;
@@ -49,15 +23,12 @@ Time::setTime(int h, int m, int s, int ms)
m_is_null = false;
}
-
-Time::NumArgs
-Time::somethingCompletelyDifferent()
+Time::NumArgs Time::somethingCompletelyDifferent()
{
return ZeroArgs;
}
-Time::NumArgs
-Time::somethingCompletelyDifferent(int h, int m, ImplicitConv ic, ObjectType* type)
+Time::NumArgs Time::somethingCompletelyDifferent(int, int, ImplicitConv ic, ObjectType *type)
{
if (type)
return FourArgs;
@@ -66,18 +37,17 @@ Time::somethingCompletelyDifferent(int h, int m, ImplicitConv ic, ObjectType* ty
return ThreeArgs;
}
-Str
-Time::toString() const
+Str Time::toString() const
{
if (m_is_null)
return Str();
char buffer[13];
- sprintf(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
@@ -86,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);
}
@@ -96,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 ef16efa29..575d4b136 100644
--- a/sources/shiboken6/tests/libsample/sometime.h
+++ b/sources/shiboken6/tests/libsample/sometime.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SOMETIME_H
#define SOMETIME_H
@@ -37,6 +12,8 @@
class LIBSAMPLE_API Time
{
public:
+ LIBMINIMAL_DEFAULT_COPY_MOVE(Time)
+
enum NumArgs {
ZeroArgs,
TwoArgs,
@@ -44,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; }
@@ -73,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 0411569b2..742c0bb01 100644
--- a/sources/shiboken6/tests/libsample/str.cpp
+++ b/sources/shiboken6/tests/libsample/str.cpp
@@ -1,117 +1,74 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "str.h"
+
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
-using namespace std;
-
-Str::Str(const Str& s)
-{
- init(s.cstring());
-}
-
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()
-{
-}
-
-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)
@@ -119,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;
@@ -140,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 2f7cee8c3..6b3386cef 100644
--- a/sources/shiboken6/tests/libsample/str.h
+++ b/sources/shiboken6/tests/libsample/str.h
@@ -1,51 +1,25 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef STR_H
#define STR_H
-#include <string>
#include "libsamplemacros.h"
+#include <string>
+
class LIBSAMPLE_API Str
{
public:
- Str(const Str& s);
Str(char c);
- Str(const char* cstr = "");
- ~Str();
+ 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);
@@ -53,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 f3e8ac96b..5840a0516 100644
--- a/sources/shiboken6/tests/libsample/strlist.cpp
+++ b/sources/shiboken6/tests/libsample/strlist.cpp
@@ -1,44 +1,17 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "strlist.h"
#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 43aa15390..01865a5b4 100644
--- a/sources/shiboken6/tests/libsample/strlist.h
+++ b/sources/shiboken6/tests/libsample/strlist.h
@@ -1,38 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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>
{
@@ -44,20 +19,29 @@ public:
ListOfStrCtor
};
- inline StrList() : m_ctorUsed(NoParamsCtor) {}
- 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 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) {}
+
+ 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.cpp b/sources/shiboken6/tests/libsample/templateptr.cpp
index fa5bb8206..a73f78417 100644
--- a/sources/shiboken6/tests/libsample/templateptr.cpp
+++ b/sources/shiboken6/tests/libsample/templateptr.cpp
@@ -1,33 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "templateptr.h"
-void TemplatePtr::dummy(std::list<std::pair<BlackBox *, BlackBox *> > & items)
+void TemplatePtr::dummy(std::list<std::pair<BlackBox *, BlackBox *> > &)
{
-} \ No newline at end of file
+}
diff --git a/sources/shiboken6/tests/libsample/templateptr.h b/sources/shiboken6/tests/libsample/templateptr.h
index 584b64185..bf230c363 100644
--- a/sources/shiboken6/tests/libsample/templateptr.h
+++ b/sources/shiboken6/tests/libsample/templateptr.h
@@ -1,43 +1,19 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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 840f1feac..5ccf5d1ed 100644
--- a/sources/shiboken6/tests/libsample/transform.cpp
+++ b/sources/shiboken6/tests/libsample/transform.cpp
@@ -1,65 +1,28 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2013 Kitware, Inc.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2013 Kitware, Inc.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#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 d9ec98dd4..34ebf40d3 100644
--- a/sources/shiboken6/tests/libsample/transform.h
+++ b/sources/shiboken6/tests/libsample/transform.h
@@ -1,31 +1,6 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2013 Kitware, Inc.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2013 Kitware, Inc.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TRANSFORM_H
#define TRANSFORM_H
@@ -34,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/typesystypedef.cpp b/sources/shiboken6/tests/libsample/typesystypedef.cpp
index 16777bf32..d9c9a92fc 100644
--- a/sources/shiboken6/tests/libsample/typesystypedef.cpp
+++ b/sources/shiboken6/tests/libsample/typesystypedef.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "typesystypedef.h"
diff --git a/sources/shiboken6/tests/libsample/typesystypedef.h b/sources/shiboken6/tests/libsample/typesystypedef.h
index 228381c5f..be42fbefe 100644
--- a/sources/shiboken6/tests/libsample/typesystypedef.h
+++ b/sources/shiboken6/tests/libsample/typesystypedef.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef TYPESYSTYPEDEF_H
#define TYPESYSTYPEDEF_H
diff --git a/sources/shiboken6/tests/libsample/valueandvirtual.h b/sources/shiboken6/tests/libsample/valueandvirtual.h
index 34a6788e2..799e11e40 100644
--- a/sources/shiboken6/tests/libsample/valueandvirtual.h
+++ b/sources/shiboken6/tests/libsample/valueandvirtual.h
@@ -1,47 +1,25 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef VALUEANDVIRTUAL_H
#define VALUEANDVIRTUAL_H
+#include "libsamplemacros.h"
+
class ValueAndVirtual
{
public:
- ValueAndVirtual(int id) : m_id(id) {}
- ValueAndVirtual(const ValueAndVirtual &other) { m_id = other.m_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 705835c0b..515564664 100644
--- a/sources/shiboken6/tests/libsample/virtualmethods.cpp
+++ b/sources/shiboken6/tests/libsample/virtualmethods.cpp
@@ -1,43 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "virtualmethods.h"
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;
@@ -48,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;
@@ -57,6 +29,11 @@ VirtualMethods::getMargins(int* left, int* top, int* right, int* bottom) const
*bottom = m_bottom;
}
+int VirtualMethods::recursionOnModifiedVirtual(Str) const
+{
+ return 0;
+}
+
const Str & VirtualMethods::returnConstRef() const
{
static const Str result;
diff --git a/sources/shiboken6/tests/libsample/virtualmethods.h b/sources/shiboken6/tests/libsample/virtualmethods.h
index 577f6919e..b7172ad0d 100644
--- a/sources/shiboken6/tests/libsample/virtualmethods.h
+++ b/sources/shiboken6/tests/libsample/virtualmethods.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef VIRTUALMETHODS_H
#define VIRTUALMETHODS_H
@@ -42,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)
@@ -86,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)
{
@@ -100,16 +76,16 @@ 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);
}
- virtual int recursionOnModifiedVirtual(Str arg) const { return 0; }
+ 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;
@@ -119,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
@@ -153,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; }
@@ -165,4 +143,3 @@ private:
};
#endif // VIRTUALMETHODS_H
-
diff --git a/sources/shiboken6/tests/libsample/voidholder.h b/sources/shiboken6/tests/libsample/voidholder.h
index 367e99ddf..3f0f4d973 100644
--- a/sources/shiboken6/tests/libsample/voidholder.h
+++ b/sources/shiboken6/tests/libsample/voidholder.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef VOIDHOLDER_H
#define VOIDHOLDER_H
@@ -34,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 152c57f25..95f0cffd6 100644
--- a/sources/shiboken6/tests/libsmart/CMakeLists.txt
+++ b/sources/shiboken6/tests/libsmart/CMakeLists.txt
@@ -1,7 +1,19 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
project(libsmart)
set(libsmart_SRC
-smart.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/libsmartmacros.h b/sources/shiboken6/tests/libsmart/libsmartmacros.h
index 03edab049..c1f229b6c 100644
--- a/sources/shiboken6/tests/libsmart/libsmartmacros.h
+++ b/sources/shiboken6/tests/libsmart/libsmartmacros.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef LIB_SMART_MACROS_H
#define LIB_SMART_MACROS_H
diff --git a/sources/shiboken6/tests/libsmart/smart.cpp b/sources/shiboken6/tests/libsmart/smart.cpp
index 81fa30c7e..2273040f9 100644
--- a/sources/shiboken6/tests/libsmart/smart.cpp
+++ b/sources/shiboken6/tests/libsmart/smart.cpp
@@ -1,75 +1,53 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "smart.h"
#include <algorithm>
#include <iostream>
-static inline bool shouldPrint()
+static inline bool verbose()
{
- return Registry::getInstance()->shouldPrint();
+ return Registry::getInstance()->verbose();
}
-void SharedPtrBase::logDefaultConstructor(const void *t)
+void SharedPtrBase::logDefaultConstructor(const char *instantiation, const void *t)
{
- if (shouldPrint())
- std::cout << "shared_ptr default constructor " << t << '\n';
+ if (verbose())
+ std::cout << "SharedPtr<" << instantiation << "> default constructor " << t << '\n';
}
-void SharedPtrBase::logConstructor(const void *t, const void *pointee)
+void SharedPtrBase::logConstructor(const char *instantiation, const void *t,
+ const void *pointee)
{
- if (shouldPrint()) {
- std::cout << "shared_ptr constructor " << t << " with pointer "
- << pointee << '\n';
+ if (verbose()) {
+ std::cout << "SharedPtr<" << instantiation << "> constructor "
+ << t << " with pointer " << pointee << '\n';
}
}
-void SharedPtrBase::logCopyConstructor(const void *t, const void *refData)
+void SharedPtrBase::logCopyConstructor(const char *instantiation, const void *t,
+ const void *refData)
{
- if (shouldPrint()) {
- std::cout << "shared_ptr copy constructor " << t << " with pointer "
- << refData << '\n';
+ if (verbose()) {
+ std::cout << "SharedPtr<" << instantiation << ">) copy constructor "
+ << t << " with pointer " << refData << '\n';
}
}
-void SharedPtrBase::logAssignment(const void *t, const void *refData)
+void SharedPtrBase::logAssignment(const char *instantiation, const void *t, const void *refData)
{
- if (shouldPrint()) {
- std::cout << "shared_ptr assignment operator " << t << " with pointer "
- << refData << "\n";
+ if (verbose()) {
+ std::cout << "SharedPtr<" << instantiation << ">::operator= " << t
+ << " with pointer " << refData << "\n";
}
}
-void SharedPtrBase::logDestructor(const void *t, int remainingRefCount)
+void SharedPtrBase::logDestructor(const char *instantiation, const void *t,
+ int remainingRefCount)
{
- if (shouldPrint()) {
- std::cout << "shared_ptr destructor " << t << " remaining refcount "
+ if (verbose()) {
+ std::cout << "~SharedPtr<" << instantiation << "> " << t << ", remaining refcount "
<< remainingRefCount << '\n';
}
}
@@ -77,49 +55,49 @@ void SharedPtrBase::logDestructor(const void *t, int remainingRefCount)
Obj::Obj() : m_integer(123), m_internalInteger(new Integer)
{
Registry::getInstance()->add(this);
- if (shouldPrint())
- std::cout << "Object constructor " << this << '\n';
+ if (verbose())
+ std::cout << "Obj constructor " << this << '\n';
}
Obj::~Obj()
{
Registry::getInstance()->remove(this);
delete m_internalInteger;
- if (shouldPrint())
- std::cout << "Object destructor " << this << '\n';
+ if (verbose())
+ std::cout << "~Obj " << this << '\n';
}
void Obj::printObj() {
- if (shouldPrint()) {
- std::cout << "integer value: " << m_integer
+ if (verbose()) {
+ std::cout << "Obj::printObj(): integer value: " << m_integer
<< " internal integer value: " << m_internalInteger->value() << '\n';
}
}
-SharedPtr<Obj> Obj::giveSharedPtrToObj()
+SharedPtr<Obj> Obj::createSharedPtrObj()
{
SharedPtr<Obj> o(new Obj);
return o;
}
-std::vector<SharedPtr<Obj> > Obj::giveSharedPtrToObjList(int size)
+std::vector<SharedPtr<Obj> > Obj::createSharedPtrObjList(int size)
{
std::vector<SharedPtr<Obj> > r;
for (int i=0; i < size; i++)
- r.push_back(giveSharedPtrToObj());
+ r.push_back(createSharedPtrObj());
return r;
}
-SharedPtr<Integer> Obj::giveSharedPtrToInteger()
+SharedPtr<Integer> Obj::createSharedPtrInteger()
{
SharedPtr<Integer> o(new Integer);
return o;
}
-SharedPtr<Smart::Integer2> Obj::giveSharedPtrToInteger2()
+SharedPtr<Smart::Integer2> Obj::createSharedPtrInteger2()
{
SharedPtr<Smart::Integer2> o(new Smart::Integer2);
return o;
@@ -133,11 +111,37 @@ int Obj::takeSharedPtrToObj(SharedPtr<Obj> pObj)
int Obj::takeSharedPtrToInteger(SharedPtr<Integer> pInt)
{
+ if (pInt.isNull()) {
+ std::cout << "SharedPtr<Integer>(nullptr) passed!\n";
+ return -1;
+ }
pInt->printInteger();
return pInt->value();
}
-SharedPtr<const Integer> Obj::giveSharedPtrToConstInteger()
+int Obj::takeSharedPtrToIntegerByConstRef(const SharedPtr<Integer> &pInt)
+{
+ if (pInt.isNull()) {
+ std::cout << "SharedPtr<Integer>(nullptr) passed!\n";
+ return -1;
+ }
+ pInt->printInteger();
+ return pInt->value();
+}
+
+SharedPtr<Integer> Obj::createSharedPtrInteger(int value)
+{
+ auto *i = new Integer;
+ i->setValue(value);
+ return SharedPtr<Integer>(i);
+}
+
+SharedPtr<Integer> Obj::createNullSharedPtrInteger()
+{
+ return {};
+}
+
+SharedPtr<const Integer> Obj::createSharedPtrConstInteger()
{
SharedPtr<const Integer> co(new Integer);
return co;
@@ -156,14 +160,14 @@ Integer Obj::takeInteger(Integer val)
Integer::Integer() : m_int(456)
{
Registry::getInstance()->add(this);
- if (shouldPrint())
+ if (verbose())
std::cout << "Integer constructor " << this << '\n';
}
Integer::Integer(const Integer &other)
{
Registry::getInstance()->add(this);
- if (shouldPrint())
+ if (verbose())
std::cout << "Integer copy constructor " << this << '\n';
m_int = other.m_int;
}
@@ -171,7 +175,7 @@ Integer::Integer(const Integer &other)
Integer &Integer::operator=(const Integer &other)
{
Registry::getInstance()->add(this);
- if (shouldPrint())
+ if (verbose())
std::cout << "Integer operator= " << this << '\n';
m_int = other.m_int;
return *this;
@@ -180,8 +184,8 @@ Integer &Integer::operator=(const Integer &other)
Integer::~Integer()
{
Registry::getInstance()->remove(this);
- if (shouldPrint())
- std::cout << "Integer destructor " << this << '\n';
+ if (verbose())
+ std::cout << "~Integer " << this << " (" << m_int << ")\n";
}
int Integer::value() const
@@ -192,11 +196,20 @@ int Integer::value() const
void Integer::setValue(int v)
{
m_int = v;
+ if (verbose())
+ std::cout << "Integer::setValue(" << v << ") " << this << '\n';
+}
+
+int Integer::compare(const Integer &rhs) const
+{
+ if (m_int < rhs.m_int)
+ return -1;
+ return m_int > rhs.m_int ? 1 : 0;
}
void Integer::printInteger() const
{
- if (shouldPrint())
+ if (verbose())
std::cout << "Integer value for object " << this << " is " << m_int << '\n';
}
@@ -240,14 +253,14 @@ int Registry::countIntegers() const
return static_cast<int>(m_integers.size());
}
-bool Registry::shouldPrint() const
+bool Registry::verbose() const
{
- return m_printStuff;
+ return m_verbose;
}
-void Registry::setShouldPrint(bool flag)
+void Registry::setVerbose(bool flag)
{
- m_printStuff = flag;
+ m_verbose = flag;
}
Smart::Integer2::Integer2()
@@ -255,7 +268,5 @@ Smart::Integer2::Integer2()
{
}
-Smart::Integer2::Integer2(const Smart::Integer2 &other)
- : Integer (other)
-{
-}
+Smart::Integer2::Integer2(const Smart::Integer2 &) = default;
+Smart::Integer2 &Smart::Integer2::operator=(const Integer2 &) = default;
diff --git a/sources/shiboken6/tests/libsmart/smart.h b/sources/shiboken6/tests/libsmart/smart.h
index 6238f27d5..1f610b302 100644
--- a/sources/shiboken6/tests/libsmart/smart.h
+++ b/sources/shiboken6/tests/libsmart/smart.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SMART_H
#define SMART_H
@@ -33,5 +8,9 @@
#include "smart_integer.h"
#include "smart_obj.h"
#include "smart_registry.h"
+#include "smart_test.h"
+#include "stdsharedptrtestbench.h"
+#include "stdoptionaltestbench.h"
+#include "stduniqueptrtestbench.h"
#endif // SMART_H
diff --git a/sources/shiboken6/tests/libsmart/smart_integer.h b/sources/shiboken6/tests/libsmart/smart_integer.h
index 126894120..42a441a00 100644
--- a/sources/shiboken6/tests/libsmart/smart_integer.h
+++ b/sources/shiboken6/tests/libsmart/smart_integer.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SMART_INTEGER_H
#define SMART_INTEGER_H
@@ -36,20 +11,58 @@ 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;
int value() const;
void setValue(int v);
+ int compare(const Integer &rhs) const;
+
int m_int; // public for testing member field access.
};
+inline bool operator==(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) == 0;
+}
+
+inline bool operator!=(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) != 0;
+}
+
+inline bool operator<(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) < 0;
+}
+
+inline bool operator<=(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) <= 0;
+}
+
+inline bool operator>(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) > 0;
+}
+
+inline bool operator>=(const Integer &lhs, const Integer &rhs)
+{
+ return lhs.compare(rhs) >= 0;
+}
+
namespace Smart {
class LIB_SMART_API Integer2 : public Integer {
public:
Integer2();
- Integer2(const Integer2 &other);
+ 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 8fe45993f..9f4f8425d 100644
--- a/sources/shiboken6/tests/libsmart/smart_obj.h
+++ b/sources/shiboken6/tests/libsmart/smart_obj.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SMART_OBJ_H
#define SMART_OBJ_H
@@ -42,18 +17,26 @@ 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();
Integer takeInteger(Integer val);
- SharedPtr<Obj> giveSharedPtrToObj();
- std::vector<SharedPtr<Obj> > giveSharedPtrToObjList(int size);
- virtual SharedPtr<Integer> giveSharedPtrToInteger(); // virtual for PYSIDE-1188
- SharedPtr<const Integer> giveSharedPtrToConstInteger();
+ static SharedPtr<Obj> createSharedPtrObj();
+ std::vector<SharedPtr<Obj> > createSharedPtrObjList(int size);
+ virtual SharedPtr<Integer> createSharedPtrInteger(); // virtual for PYSIDE-1188
+ SharedPtr<const Integer> createSharedPtrConstInteger();
int takeSharedPtrToConstInteger(SharedPtr<const Integer> pInt);
- SharedPtr<Smart::Integer2> giveSharedPtrToInteger2();
+ SharedPtr<Smart::Integer2> createSharedPtrInteger2();
int takeSharedPtrToObj(SharedPtr<Obj> pObj);
int takeSharedPtrToInteger(SharedPtr<Integer> pInt);
+ int takeSharedPtrToIntegerByConstRef(const SharedPtr<Integer> &pInt);
+
+ static SharedPtr<Integer> createSharedPtrInteger(int value);
+ static SharedPtr<Integer> createNullSharedPtrInteger();
int m_integer; // public for testing member field access.
Integer *m_internalInteger;
diff --git a/sources/shiboken6/tests/libsmart/smart_registry.h b/sources/shiboken6/tests/libsmart/smart_registry.h
index 6171ddb59..abf7edc84 100644
--- a/sources/shiboken6/tests/libsmart/smart_registry.h
+++ b/sources/shiboken6/tests/libsmart/smart_registry.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SMART_REGISTRY_H
#define SMART_REGISTRY_H
@@ -53,8 +28,8 @@ public:
void remove(Integer *p);
int countObjects() const;
int countIntegers() const;
- bool shouldPrint() const;
- void setShouldPrint(bool flag);
+ bool verbose() const;
+ void setVerbose(bool flag);
protected:
Registry();
@@ -62,7 +37,7 @@ protected:
private:
std::vector<Obj *> m_objects;
std::vector<Integer *> m_integers;
- bool m_printStuff = false;
+ bool m_verbose = false;
};
#endif // SMART_REGISTRY_H
diff --git a/sources/shiboken6/tests/libsmart/smart_sharedptr.h b/sources/shiboken6/tests/libsmart/smart_sharedptr.h
index 65a489c68..dc665810a 100644
--- a/sources/shiboken6/tests/libsmart/smart_sharedptr.h
+++ b/sources/shiboken6/tests/libsmart/smart_sharedptr.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef SMART_SHARED_PTR_H
#define SMART_SHARED_PTR_H
@@ -35,37 +10,40 @@
struct SharedPtrBase
{
- LIB_SMART_API static void logDefaultConstructor(const void *t);
- LIB_SMART_API static void logConstructor(const void *t, const void *pointee);
- LIB_SMART_API static void logCopyConstructor(const void *t, const void *refData);
- LIB_SMART_API static void logAssignment(const void *t, const void *refData);
- LIB_SMART_API static void logDestructor(const void *t, int remainingRefCount);
+ LIB_SMART_API static void logDefaultConstructor(const char *instantiation, const void *t);
+ LIB_SMART_API static void logConstructor(const char *instantiation, const void *t, const void *pointee);
+ LIB_SMART_API static void logCopyConstructor(const char *instantiation, const void *t, const void *refData);
+ LIB_SMART_API static void logAssignment(const char *instantiation, const void *t, const void *refData);
+ LIB_SMART_API static void logDestructor(const char *instantiation, const void *t, int remainingRefCount);
};
template <class T>
class SharedPtr : public SharedPtrBase {
public:
- SharedPtr() { logDefaultConstructor(this); }
+ LIBMINIMAL_DEFAULT_MOVE(SharedPtr)
+
+ SharedPtr() { logDefaultConstructor(typeid(T).name(), this); }
SharedPtr(T *v) : mPtr(v)
{
- logConstructor(this, v);
+ logConstructor(typeid(T).name(), this, v);
}
SharedPtr(const SharedPtr<T> &other) : mPtr(other.mPtr)
{
- logCopyConstructor(this, data());
+ logCopyConstructor(typeid(T).name(), this, data());
}
template<class X>
SharedPtr(const SharedPtr<X> &other) : mPtr(other.mPtr)
{
- logCopyConstructor(this, data());
+ 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;
}
@@ -107,7 +85,7 @@ public:
~SharedPtr()
{
if (mPtr.use_count() >= 1)
- logDestructor(this, mPtr.use_count() - 1);
+ logDestructor(typeid(T).name(), this, mPtr.use_count() - 1);
}
std::shared_ptr<T> mPtr;
diff --git a/sources/shiboken6/tests/libsmart/smart_test.h b/sources/shiboken6/tests/libsmart/smart_test.h
new file mode 100644
index 000000000..89d8cbc7c
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/smart_test.h
@@ -0,0 +1,13 @@
+// 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 SMART_TEST_H
+#define SMART_TEST_H
+
+namespace Test {
+
+enum DummyEnum { Dummy1, Dummy2 };
+
+}
+
+#endif // SMART_TEST_H
diff --git a/sources/shiboken6/tests/libsmart/stdoptionaltestbench.cpp b/sources/shiboken6/tests/libsmart/stdoptionaltestbench.cpp
new file mode 100644
index 000000000..69100720c
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stdoptionaltestbench.cpp
@@ -0,0 +1,58 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "stdoptionaltestbench.h"
+
+#include <iostream>
+
+std::ostream &operator<<(std::ostream &str, const Integer &i)
+{
+ str << i.value();
+ return str;
+}
+
+template <class T>
+std::ostream &operator<<(std::ostream &str, const std::optional<T> &o)
+{
+ if (o.has_value())
+ str << o.value();
+ else
+ str << "nullopt";
+ return str;
+}
+
+StdOptionalTestBench::StdOptionalTestBench() = default;
+
+std::optional<int> StdOptionalTestBench::optionalInt() const
+{
+ return m_optionalInt;
+}
+
+void StdOptionalTestBench::setOptionalInt(const std::optional<int> &i)
+{
+ std::cout << __FUNCTION__ << ' ' << i << '\n';
+ m_optionalInt = i;
+}
+
+void StdOptionalTestBench::setOptionalIntValue(int i)
+{
+ std::cout << __FUNCTION__ << ' ' << i << '\n';
+ m_optionalInt.emplace(i);
+}
+
+std::optional<Integer> StdOptionalTestBench::optionalInteger() const
+{
+ return m_optionalInteger;
+}
+
+void StdOptionalTestBench::setOptionalInteger(const std::optional<Integer> &s)
+{
+ std::cout << __FUNCTION__ << ' ' << s << '\n';
+ m_optionalInteger = s;
+}
+
+void StdOptionalTestBench::setOptionalIntegerValue(Integer &s)
+{
+ std::cout << __FUNCTION__ << ' ' << s << '\n';
+ m_optionalInteger.emplace(s);
+}
diff --git a/sources/shiboken6/tests/libsmart/stdoptionaltestbench.h b/sources/shiboken6/tests/libsmart/stdoptionaltestbench.h
new file mode 100644
index 000000000..baa709821
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stdoptionaltestbench.h
@@ -0,0 +1,30 @@
+// 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 OPTIONALTEST_H
+#define OPTIONALTEST_H
+
+#include "libsmartmacros.h"
+#include "smart_integer.h"
+
+#include <optional>
+
+class LIB_SMART_API StdOptionalTestBench
+{
+public:
+ StdOptionalTestBench();
+
+ std::optional<int> optionalInt() const;
+ void setOptionalInt(const std::optional<int> &i);
+ void setOptionalIntValue(int i);
+
+ std::optional<Integer> optionalInteger() const;
+ void setOptionalInteger(const std::optional<Integer> &s);
+ void setOptionalIntegerValue(Integer &s);
+
+private:
+ std::optional<int> m_optionalInt;
+ std::optional<Integer> m_optionalInteger;
+};
+
+#endif // OPTIONALTEST_H
diff --git a/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp
new file mode 100644
index 000000000..472f807f2
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.cpp
@@ -0,0 +1,106 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "stdsharedptrtestbench.h"
+#include "smart_integer.h"
+
+#include <iostream>
+
+StdSharedPtrTestBench::StdSharedPtrTestBench() = default;
+StdSharedPtrTestBench::~StdSharedPtrTestBench() = default;
+
+std::shared_ptr<Integer> StdSharedPtrTestBench::createInteger(int v)
+{
+ auto result = std::make_shared<Integer>();
+ result->setValue(v);
+ return result;
+}
+
+std::shared_ptr<Integer> StdSharedPtrTestBench::createNullInteger()
+{
+ return {};
+}
+
+void StdSharedPtrTestBench::printInteger(const std::shared_ptr<Integer> &p)
+{
+ std::cerr << __FUNCTION__ << ' ';
+ if (p.get())
+ std::cerr << p->value();
+ else
+ std::cerr << "nullptr";
+ std::cerr << '\n';
+}
+
+std::shared_ptr<int> StdSharedPtrTestBench::createInt(int v)
+{
+ return std::make_shared<int>(v);
+}
+
+std::shared_ptr<int> StdSharedPtrTestBench::createNullInt()
+{
+ return {};
+}
+
+void StdSharedPtrTestBench::printInt(const std::shared_ptr<int> &p)
+{
+ std::cerr << __FUNCTION__ << ' ';
+ if (p.get())
+ std::cerr << *p;
+ else
+ std::cerr << "nullptr";
+ std::cerr << '\n';
+}
+
+std::shared_ptr<double> StdSharedPtrTestBench::createDouble(double v)
+{
+ return std::make_shared<double>(v);
+}
+
+std::shared_ptr<double> StdSharedPtrTestBench::createNullDouble()
+{
+ return {};
+}
+
+void StdSharedPtrTestBench::printDouble(const std::shared_ptr<double> &p)
+{
+ std::cerr << __FUNCTION__ << ' ';
+ if (p.get())
+ std::cerr << *p;
+ else
+ std::cerr << "nullptr";
+ 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;
+
+std::shared_ptr<Integer> StdSharedPtrVirtualMethodTester::callModifyInteger(const std::shared_ptr<Integer> &p)
+{
+ return doModifyInteger(p);
+}
+
+std::shared_ptr<Integer> StdSharedPtrVirtualMethodTester::doModifyInteger(std::shared_ptr<Integer> p)
+{
+ p->setValue(p->value() + 1);
+ return p;
+}
diff --git a/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h
new file mode 100644
index 000000000..9d4c207b5
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stdsharedptrtestbench.h
@@ -0,0 +1,49 @@
+// 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 STDSHAREDPTRTESTBENCH_H
+#define STDSHAREDPTRTESTBENCH_H
+
+#include "libsmartmacros.h"
+
+#include <memory>
+#include <string>
+
+class Integer;
+
+class LIB_SMART_API StdSharedPtrTestBench
+{
+public:
+ StdSharedPtrTestBench();
+ ~StdSharedPtrTestBench();
+
+ static std::shared_ptr<Integer> createInteger(int v = 42);
+ static std::shared_ptr<Integer> createNullInteger();
+ static void printInteger(const std::shared_ptr<Integer> &);
+
+ 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<double> createDouble(double v = 42);
+ static std::shared_ptr<double> createNullDouble();
+ static void printDouble(const std::shared_ptr<double> &);
+
+ 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
+{
+public:
+ StdSharedPtrVirtualMethodTester();
+ virtual ~StdSharedPtrVirtualMethodTester();
+
+ std::shared_ptr<Integer> callModifyInteger(const std::shared_ptr<Integer> &p);
+
+protected:
+ virtual std::shared_ptr<Integer> doModifyInteger(std::shared_ptr<Integer> p);
+};
+
+#endif // STDSHAREDPTRTESTBENCH_H
diff --git a/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.cpp b/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.cpp
new file mode 100644
index 000000000..df4b566fa
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.cpp
@@ -0,0 +1,133 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "stduniqueptrtestbench.h"
+#include "smart_integer.h"
+
+#include <iostream>
+
+std::ostream &operator<<(std::ostream &str, const std::unique_ptr<Integer> &p)
+{
+ str << "unique_ptr<Integer>(";
+ if (p.get())
+ str << p->value();
+ else
+ str << "nullptr";
+ str << ')';
+ return str;
+}
+
+std::ostream &operator<<(std::ostream &str, const std::unique_ptr<Smart::Integer2> &p)
+{
+ str << "unique_ptr<Integer>(";
+ if (p.get())
+ str << p->value();
+ else
+ str << "nullptr";
+ str << ')';
+ return str;
+}
+
+std::ostream &operator<<(std::ostream &str, const std::unique_ptr<int> &p)
+{
+ str << "unique_ptr<int>(";
+ if (p.get())
+ str << *p;
+ else
+ str << "nullptr";
+ str << ')';
+ return str;
+}
+
+StdUniquePtrTestBench::StdUniquePtrTestBench() = default;
+StdUniquePtrTestBench::~StdUniquePtrTestBench() = default;
+
+std::unique_ptr<Integer> StdUniquePtrTestBench::createInteger(int v)
+{
+ auto result = std::make_unique<Integer>();
+ result->setValue(v);
+ return result;
+}
+
+std::unique_ptr<Integer> StdUniquePtrTestBench::createNullInteger()
+{
+ return {};
+}
+
+void StdUniquePtrTestBench::printInteger(const std::unique_ptr<Integer> &p)
+{
+ std::cerr << __FUNCTION__ << ' ' << p << '\n';
+}
+
+void StdUniquePtrTestBench::takeInteger(std::unique_ptr<Integer> p)
+{
+ std::cerr << __FUNCTION__ << ' ' << p << '\n';
+}
+
+std::unique_ptr<int> StdUniquePtrTestBench::createInt(int v)
+{
+ return std::make_unique<int>(v);
+}
+
+std::unique_ptr<int> StdUniquePtrTestBench::createNullInt()
+{
+ return {};
+}
+
+void StdUniquePtrTestBench::printInt(const std::unique_ptr<int> &p)
+{
+ std::cerr << __FUNCTION__ << ' ' << p << '\n';
+}
+
+void StdUniquePtrTestBench::takeInt(std::unique_ptr<int> p)
+{
+ std::cerr << __FUNCTION__ << ' ' << p << '\n';
+}
+
+StdUniquePtrVirtualMethodTester::StdUniquePtrVirtualMethodTester() = default;
+
+StdUniquePtrVirtualMethodTester::~StdUniquePtrVirtualMethodTester() = default;
+
+bool StdUniquePtrVirtualMethodTester::testModifyIntegerByRef(int value, int expectedValue)
+{
+ auto p = std::make_unique<Integer>();
+ p->setValue(value);
+ const int actualValue = doModifyIntegerByRef(p);
+ return p.get() != nullptr && actualValue == expectedValue;
+}
+
+bool StdUniquePtrVirtualMethodTester::testModifyIntegerValue(int value, int expectedValue)
+{
+ auto p = std::make_unique<Integer>();
+ p->setValue(value);
+ const int actualValue = doModifyIntegerByValue(std::move(p));
+ return p.get() == nullptr && actualValue == expectedValue;
+}
+
+bool StdUniquePtrVirtualMethodTester::testCreateInteger(int value, int expectedValue)
+{
+ auto p = doCreateInteger(value);
+ return p.get() != nullptr && p->value() == expectedValue;
+}
+
+std::unique_ptr<Integer> StdUniquePtrVirtualMethodTester::doCreateInteger(int v)
+{
+ auto result = std::make_unique<Integer>();
+ result->setValue(v);
+ return result;
+}
+
+int StdUniquePtrVirtualMethodTester::doModifyIntegerByRef(const std::unique_ptr<Integer> &p)
+{
+ return p->value() + 1;
+}
+
+int StdUniquePtrVirtualMethodTester::doModifyIntegerByValue(std::unique_ptr<Integer> p)
+{
+ return p->value() + 1;
+}
+
+void StdUniquePtrTestBench::printInteger2(const std::unique_ptr<Smart::Integer2> &p)
+{
+ std::cerr << __FUNCTION__ << ' ' << p << '\n';
+}
diff --git a/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.h b/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.h
new file mode 100644
index 000000000..868c6d08c
--- /dev/null
+++ b/sources/shiboken6/tests/libsmart/stduniqueptrtestbench.h
@@ -0,0 +1,50 @@
+// 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 STDUNIQUEPTRTESTBENCH_H
+#define STDUNIQUEPTRTESTBENCH_H
+
+#include "libsmartmacros.h"
+
+#include <memory>
+
+class Integer;
+namespace Smart {
+class Integer2;
+}
+
+class LIB_SMART_API StdUniquePtrTestBench
+{
+public:
+ StdUniquePtrTestBench();
+ ~StdUniquePtrTestBench();
+
+ static std::unique_ptr<Integer> createInteger(int v = 42);
+ static std::unique_ptr<Integer> createNullInteger();
+ static void printInteger2(const std::unique_ptr<Smart::Integer2> &p);
+ static void printInteger(const std::unique_ptr<Integer> &p);
+ static void takeInteger(std::unique_ptr<Integer> p); // Call with std::move()
+
+ static std::unique_ptr<int> createInt(int v = 42);
+ static std::unique_ptr<int> createNullInt();
+ static void printInt(const std::unique_ptr<int> &p);
+ static void takeInt(std::unique_ptr<int> p); // Call with std::move()
+};
+
+class LIB_SMART_API StdUniquePtrVirtualMethodTester
+{
+public:
+ StdUniquePtrVirtualMethodTester();
+ virtual ~StdUniquePtrVirtualMethodTester();
+
+ bool testModifyIntegerByRef(int value, int expectedValue);
+ bool testModifyIntegerValue(int value, int expectedValue);
+ bool testCreateInteger(int value, int expectedValue);
+
+protected:
+ virtual std::unique_ptr<Integer> doCreateInteger(int v);
+ virtual int doModifyIntegerByRef(const std::unique_ptr<Integer> &p);
+ virtual int doModifyIntegerByValue(std::unique_ptr<Integer> p);
+};
+
+#endif // STDUNIQUEPTRTESTBENCH_H
diff --git a/sources/shiboken6/tests/minimalbinding/CMakeLists.txt b/sources/shiboken6/tests/minimalbinding/CMakeLists.txt
index 63ad8a577..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,22 +9,30 @@ ${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
)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/minimal-binding.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/minimal-binding.txt" @ONLY)
+shiboken_get_tool_shell_wrapper(shiboken tool_wrapper)
+
add_custom_command(
-OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
-BYPRODUCTS ${minimal_SRC}
-COMMAND shiboken6 --project-file=${CMAKE_CURRENT_BINARY_DIR}/minimal-binding.txt ${GENERATOR_EXTRA_FLAGS}
-DEPENDS ${minimal_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h shiboken6
-WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-COMMENT "Running generator for 'minimal' test binding..."
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+ BYPRODUCTS ${minimal_SRC}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Shiboken6::shiboken6>
+ --project-file=${CMAKE_CURRENT_BINARY_DIR}/minimal-binding.txt
+ ${GENERATOR_EXTRA_FLAGS}
+ DEPENDS ${minimal_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h Shiboken6::shiboken6
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Running generator for 'minimal' test binding..."
)
add_library(minimal MODULE ${minimal_SRC})
diff --git a/sources/shiboken6/tests/minimalbinding/brace_pattern_test.py b/sources/shiboken6/tests/minimalbinding/brace_pattern_test.py
index e036eafb9..946a869db 100644
--- a/sources/shiboken6/tests/minimalbinding/brace_pattern_test.py
+++ b/sources/shiboken6/tests/minimalbinding/brace_pattern_test.py
@@ -1,41 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:LGPL$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU Lesser General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU Lesser
-## General Public License version 3 as published by the Free Software
-## Foundation and appearing in the file LICENSE.LGPL3 included in the
-## packaging of this file. Please review the following information to
-## ensure the GNU Lesser General Public License version 3 requirements
-## will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 2.0 or (at your option) the GNU General
-## Public license version 3 or any later version approved by the KDE Free
-## Qt Foundation. The licenses are as published by the Free Software
-## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-2.0.html and
-## https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
import os
import re
@@ -47,8 +11,7 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from shiboken6 import Shiboken
-_init_pyside_extension() # trigger bootstrap
+from shiboken6 import Shiboken # noqa: F401
from shibokensupport.signature.lib.tool import build_brace_pattern
@@ -58,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
@@ -78,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 1b06245c4..fc5c59a26 100644
--- a/sources/shiboken6/tests/minimalbinding/global.h
+++ b/sources/shiboken6/tests/minimalbinding/global.h
@@ -1,33 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "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 a1fc48c08..b30bb653a 100644
--- a/sources/shiboken6/tests/minimalbinding/listuser_test.py
+++ b/sources/shiboken6/tests/minimalbinding/listuser_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
@@ -44,7 +17,10 @@ from minimal import ListUser, Val, Obj, StdIntList
class ExtListUser(ListUser):
def __init__(self):
- ListUser.__init__(self)
+ super().__init__()
+ self._stdIntList = StdIntList()
+ self._stdIntList.append(1)
+ self._stdIntList.append(2)
def createIntList(self, num):
return list(range(0, num * 2, 2))
@@ -56,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)]
@@ -78,6 +54,9 @@ class ExtListUser(ListUser):
def sumListOfIntLists(self, intListList):
return sum([sum(line) for line in intListList]) * 2
+ def returnIntListByPtr(self):
+ return self._stdIntList
+
class IntListConversionTest(unittest.TestCase):
@@ -116,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()
@@ -318,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)
@@ -346,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)
@@ -356,7 +343,34 @@ class ListOfIntListConversionTest(unittest.TestCase):
self.assertEqual(len(const_l), 4)
self.assertRaises(TypeError, const_l.append, 6)
+ def testListByPtrOpaque(self):
+ """Test a function taking C++ list by pointer for which an opaque
+ container exists."""
+ lu = ListUser()
+ python_list = [1, 2]
+ self.assertEqual(lu.modifyIntListPtr(python_list), 2)
+
+ # Pass an opaque container and verify whether it is modified by C++
+ cpp_list = StdIntList()
+ cpp_list.append(1)
+ cpp_list.append(2)
+ self.assertEqual(lu.modifyIntListPtr(cpp_list), 2)
+ self.assertEqual(len(cpp_list), 3)
+
+ def testListByPtr(self):
+ """Test a function taking C++ list by pointer for which no opaque
+ container exists."""
+ lu = ListUser()
+ python_list = [1.1, 22.2]
+ self.assertEqual(lu.modifyDoubleListPtr(python_list), 2)
+
+ def testReturnListByPtr(self):
+ """Test that a virtual function returning a list by pointer can be
+ reimplemented by a Python function returning an opaque container."""
+ lu = ExtListUser()
+ size = lu.callReturnIntListByPtr() # Call virtual from C++
+ self.assertEqual(size, 2)
+
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/minimalbinding/minbool_test.py b/sources/shiboken6/tests/minimalbinding/minbool_test.py
index 789803371..d9ce0eac0 100644
--- a/sources/shiboken6/tests/minimalbinding/minbool_test.py
+++ b/sources/shiboken6/tests/minimalbinding/minbool_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -40,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/minimal-binding.txt.in b/sources/shiboken6/tests/minimalbinding/minimal-binding.txt.in
index 85b139676..101567070 100644
--- a/sources/shiboken6/tests/minimalbinding/minimal-binding.txt.in
+++ b/sources/shiboken6/tests/minimalbinding/minimal-binding.txt.in
@@ -13,3 +13,4 @@ typesystem-path = @CMAKE_CURRENT_SOURCE_DIR@
enable-parent-ctor-heuristic
use-isnull-as-nb_nonzero
+lean-headers
diff --git a/sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject b/sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject
new file mode 100644
index 000000000..ab19dc443
--- /dev/null
+++ b/sources/shiboken6/tests/minimalbinding/minimalbinding.pyproject
@@ -0,0 +1,10 @@
+{
+ "files": ["brace_pattern_test.py",
+ "containeruser_test.py",
+ "listuser_test.py",
+ "minbool_test.py",
+ "obj_test.py",
+ "typedef_test.py",
+ "val_test.py",
+ "typesystem_minimal.xml"]
+}
diff --git a/sources/shiboken6/tests/minimalbinding/obj_test.py b/sources/shiboken6/tests/minimalbinding/obj_test.py
index 1abd6e04c..e873845de 100644
--- a/sources/shiboken6/tests/minimalbinding/obj_test.py
+++ b/sources/shiboken6/tests/minimalbinding/obj_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -39,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)
@@ -118,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 9076cbe5e..c2fc8fc12 100644
--- a/sources/shiboken6/tests/minimalbinding/typedef_test.py
+++ b/sources/shiboken6/tests/minimalbinding/typedef_test.py
@@ -1,35 +1,7 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-from functools import reduce
+# 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 os
import sys
import unittest
@@ -38,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
@@ -58,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 = ()
@@ -89,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 9bb7e7b7e..e18bf8686 100644
--- a/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml
+++ b/sources/shiboken6/tests/minimalbinding/typesystem_minimal.xml
@@ -15,32 +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>
- 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) {
- %INTYPE_0 cppItem(*it);
- PyList_SET_ITEM(%out, idx, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
- }
- return %out;
- </native-to-target>
- <target-to-native>
- <add-conversion type="PySequence">
- Shiboken::AutoDecRef seq(PySequence_Fast(%in, 0));
- const Py_ssize_t size = PySequence_Fast_GET_SIZE(seq.object());
- for (Py_ssize_t i = 0; i &lt; size; ++i) {
- PyObject* pyItem = PySequence_Fast_GET_ITEM(seq.object(), i);
- %OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
- %out.push_back(cppItem);
- }
- </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">
@@ -59,34 +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"/>
- <container-type name="std::vector" type="vector">
- <include file-name="vector" location="global"/>
- <conversion-rule>
- <native-to-target>
- %INTYPE::size_type vectorSize = %in.size();
- PyObject* %out = PyList_New(Py_ssize_t(vectorSize));
- for (%INTYPE::size_type idx = 0; idx &lt; vectorSize; ++idx) {
- %INTYPE_0 cppItem(%in[idx]);
- PyList_SET_ITEM(%out, idx, %CONVERTTOPYTHON[%INTYPE_0](cppItem));
- }
- return %out;
- </native-to-target>
- <target-to-native>
- <add-conversion type="PySequence">
- Shiboken::AutoDecRef seq(PySequence_Fast(%in, 0));
- const Py_ssize_t vectorSize = PySequence_Fast_GET_SIZE(seq.object());
- %out.reserve(vectorSize);
- for (Py_ssize_t idx = 0; idx &lt; vectorSize; ++idx ) {
- PyObject* pyItem = PySequence_Fast_GET_ITEM(seq.object(), idx);
- %OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
- %out.push_back(cppItem);
- }
- </add-conversion>
- </target-to-native>
- </conversion-rule>
- </container-type>
+ <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 63d2cf300..b8225a247 100644
--- a/sources/shiboken6/tests/minimalbinding/val_test.py
+++ b/sources/shiboken6/tests/minimalbinding/val_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -119,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 7c8562abc..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
@@ -22,13 +25,19 @@ ${CMAKE_CURRENT_BINARY_DIR}/other/valuewithunitintmillimeter_wrapper.cpp
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/other-binding.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/other-binding.txt" @ONLY)
+shiboken_get_tool_shell_wrapper(shiboken tool_wrapper)
+
add_custom_command(
-OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
-BYPRODUCTS ${other_SRC}
-COMMAND shiboken6 --project-file=${CMAKE_CURRENT_BINARY_DIR}/other-binding.txt ${GENERATOR_EXTRA_FLAGS}
-DEPENDS ${other_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h shiboken6
-WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-COMMENT "Running generator for 'other' test binding..."
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+ BYPRODUCTS ${other_SRC}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Shiboken6::shiboken6>
+ --project-file=${CMAKE_CURRENT_BINARY_DIR}/other-binding.txt
+ ${GENERATOR_EXTRA_FLAGS}
+ DEPENDS ${other_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h Shiboken6::shiboken6
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Running generator for 'other' test binding..."
)
add_library(other MODULE ${other_SRC})
diff --git a/sources/shiboken6/tests/otherbinding/collector_external_operator_test.py b/sources/shiboken6/tests/otherbinding/collector_external_operator_test.py
index b059335de..2ba21653d 100644
--- a/sources/shiboken6/tests/otherbinding/collector_external_operator_test.py
+++ b/sources/shiboken6/tests/otherbinding/collector_external_operator_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 Collector shift operators defined in other modules.'''
@@ -43,6 +16,7 @@ init_paths()
from sample import Collector, ObjectType
from other import OtherObjectType
+
class CollectorOtherObjectType(unittest.TestCase):
'''Test cases for Collector << OtherObjectType'''
@@ -60,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 79ae9de18..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
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 NoImplicitConversion using a ExtendsNoImplicitConversion parameter,
being that the latter defines a new conversion operator for the former, and this one
@@ -45,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.'''
@@ -54,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 e54e38e77..abbef6231 100644
--- a/sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py
+++ b/sources/shiboken6/tests/otherbinding/extended_multiply_operator_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 libsample's Point multiply operator defined in libother module.'''
@@ -43,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.'''
@@ -66,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/global.h b/sources/shiboken6/tests/otherbinding/global.h
index 702fb9287..af796734a 100644
--- a/sources/shiboken6/tests/otherbinding/global.h
+++ b/sources/shiboken6/tests/otherbinding/global.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "../samplebinding/global.h"
#include "extendsnoimplicitconversion.h"
diff --git a/sources/shiboken6/tests/otherbinding/module_reload_test.py b/sources/shiboken6/tests/otherbinding/module_reload_test.py
index fe3a83533..bde2f5236 100644
--- a/sources/shiboken6/tests/otherbinding/module_reload_test.py
+++ b/sources/shiboken6/tests/otherbinding/module_reload_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 importlib import reload
import os
@@ -48,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):
@@ -59,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 c3a12d7ad..d6c356436 100644
--- a/sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py
+++ b/sources/shiboken6/tests/otherbinding/new_ctor_operator_test.py
@@ -1,35 +1,9 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-'''Tests calling Str constructor using a Number parameter, being that number defines a cast operator to Str.'''
+# 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.'''
import os
import sys
@@ -43,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.'''
@@ -56,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 36c27b35d..d2cd7de5b 100644
--- a/sources/shiboken6/tests/otherbinding/objtypehashes_test.py
+++ b/sources/shiboken6/tests/otherbinding/objtypehashes_test.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -34,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):
@@ -55,6 +30,5 @@ class TestHashFuncs (unittest.TestCase):
self.assertEqual(hash1_2, hash1)
-
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/otherbinding/other-binding.txt.in b/sources/shiboken6/tests/otherbinding/other-binding.txt.in
index dbe935a9f..d85f6030a 100644
--- a/sources/shiboken6/tests/otherbinding/other-binding.txt.in
+++ b/sources/shiboken6/tests/otherbinding/other-binding.txt.in
@@ -17,4 +17,4 @@ typesystem-path = @sample_SOURCE_DIR@
typesystem-path = @smart_SOURCE_DIR@
enable-parent-ctor-heuristic
-
+lean-headers
diff --git a/sources/shiboken6/tests/otherbinding/otherbinding.pyproject b/sources/shiboken6/tests/otherbinding/otherbinding.pyproject
new file mode 100644
index 000000000..d1bbee11e
--- /dev/null
+++ b/sources/shiboken6/tests/otherbinding/otherbinding.pyproject
@@ -0,0 +1,17 @@
+{
+ "files": ["collector_external_operator_test.py",
+ "conversion_operator_for_class_without_implicit_conversions_test.py",
+ "extended_multiply_operator_test.py",
+ "module_reload_test.py",
+ "new_ctor_operator_test.py",
+ "objtypehashes_test.py",
+ "otherderived_test.py",
+ "othertypesystypedef_test.py",
+ "signature_test.py",
+ "smartptr_test.py",
+ "test_module_template.py",
+ "typediscovery_test.py",
+ "usersprimitivefromothermodule_test.py",
+ "wrongctor_test.py",
+ "typesystem_other.xml"]
+}
diff --git a/sources/shiboken6/tests/otherbinding/otherderived_test.py b/sources/shiboken6/tests/otherbinding/otherderived_test.py
index 9a68e2ad4..459f474f1 100644
--- a/sources/shiboken6/tests/otherbinding/otherderived_test.py
+++ b/sources/shiboken6/tests/otherbinding/otherderived_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 OtherDerived class'''
+import gc
import os
import sys
import unittest
@@ -43,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)
@@ -51,6 +26,7 @@ class Multiple(Derived, Number):
def testCall(self):
return True
+
class OtherDeviant(OtherDerived):
def __init__(self):
OtherDerived.__init__(self)
@@ -66,6 +42,7 @@ class OtherDeviant(OtherDerived):
def className(self):
return 'OtherDeviant'
+
class MultipleTest(unittest.TestCase):
'''Test case for Multiple derived class'''
@@ -75,6 +52,8 @@ class MultipleTest(unittest.TestCase):
self.assertTrue(isinstance(o, Number))
self.assertTrue(isinstance(o, Derived))
del o
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
def testMethodCall(self):
o = Multiple()
@@ -82,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'''
@@ -92,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)
@@ -110,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')
@@ -121,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 05ac50c89..198c71693 100644
--- a/sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py
+++ b/sources/shiboken6/tests/otherbinding/othertypesystypedef_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2020 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 a class that holds a void pointer.'''
@@ -40,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 9f94edd34..8db3e566b 100644
--- a/sources/shiboken6/tests/otherbinding/signature_test.py
+++ b/sources/shiboken6/tests/otherbinding/signature_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 functions signature'''
@@ -43,13 +16,19 @@ init_paths()
from other import OtherObjectType
from shiboken_test_helper import objectFullname
+from shibokensupport.signature import get_signature
+
+
class SignatureTest(unittest.TestCase):
- # Check if the argument of 'OtherObjectType::enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value)'
+ # Check if the argument of
+ # 'OtherObjectType::enumAsInt(SampleNamespace::SomeClass::PublicScopedEnum value)'
# has the correct representation
def testNamespaceFromOtherModule(self):
- argType = OtherObjectType.enumAsInt.__signature__.parameters['value'].annotation
- self.assertEqual(objectFullname(argType), 'sample.SampleNamespace.SomeClass.PublicScopedEnum')
+ argType = get_signature(OtherObjectType.enumAsInt).parameters["value"].annotation
+ self.assertEqual(objectFullname(argType),
+ "sample.SampleNamespace.SomeClass.PublicScopedEnum")
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/otherbinding/smartptr_test.py b/sources/shiboken6/tests/otherbinding/smartptr_test.py
index a3a764629..fd5c7fa09 100644
--- a/sources/shiboken6/tests/otherbinding/smartptr_test.py
+++ b/sources/shiboken6/tests/otherbinding/smartptr_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2020 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 the SmartPtrTester class'''
@@ -40,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 5d08944f3..36ab43ae3 100644
--- a/sources/shiboken6/tests/otherbinding/test_module_template.py
+++ b/sources/shiboken6/tests/otherbinding/test_module_template.py
@@ -1,38 +1,22 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-from other import *
-from sample import *
+# 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 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 fee4734ae..39dc5cf0f 100644
--- a/sources/shiboken6/tests/otherbinding/typediscovery_test.py
+++ b/sources/shiboken6/tests/otherbinding/typediscovery_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 type discovery'''
@@ -40,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):
@@ -56,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 ec9e81080..15a988326 100644
--- a/sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py
+++ b/sources/shiboken6/tests/otherbinding/usersprimitivefromothermodule_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 user defined primitive type from a required module.'''
@@ -41,6 +14,7 @@ from shiboken_paths import init_paths
init_paths()
from other import Number
+
class UserDefinedPrimitiveTypeFromRequiredModuleTest(unittest.TestCase):
def testUsersPrimitiveFromRequiredModuleAsArgument(self):
@@ -55,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 1813671d7..b9251b428 100644
--- a/sources/shiboken6/tests/otherbinding/wrongctor_test.py
+++ b/sources/shiboken6/tests/otherbinding/wrongctor_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -37,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
new file mode 100644
index 000000000..11b22f038
--- /dev/null
+++ b/sources/shiboken6/tests/qtxmltosphinx/CMakeLists.txt
@@ -0,0 +1,32 @@
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
+
+# Standalone-buildable
+
+project(qtxmltosphinx)
+
+set(CMAKE_AUTOMOC ON)
+
+find_package(Qt6 COMPONENTS Core)
+
+set(generator_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../generator)
+set(api_extractor_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../ApiExtractor)
+
+set(qtxmltosphinx_SRC
+ ${generator_src_dir}/qtdoc/qtxmltosphinx.cpp
+ ${api_extractor_src_dir}/codesniphelpers.cpp
+ ${api_extractor_src_dir}/textstream.cpp
+ main.cpp)
+
+add_executable(qtxmltosphinx ${qtxmltosphinx_SRC})
+
+target_include_directories(qtxmltosphinx PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR}
+ ${api_extractor_src_dir}
+ ${generator_src_dir}
+ ${generator_src_dir}/shiboken
+ ${generator_src_dir}/qtdoc)
+
+target_link_libraries(qtxmltosphinx PRIVATE Qt::Core)
diff --git a/sources/shiboken6/tests/qtxmltosphinx/main.cpp b/sources/shiboken6/tests/qtxmltosphinx/main.cpp
new file mode 100644
index 000000000..5b0624376
--- /dev/null
+++ b/sources/shiboken6/tests/qtxmltosphinx/main.cpp
@@ -0,0 +1,115 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "qtxmltosphinxinterface.h"
+#include "qtxmltosphinx.h"
+
+#include <QtCore/QCommandLineParser>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QLoggingCategory>
+
+#include <exception>
+#include <iostream>
+
+using namespace Qt::StringLiterals;
+
+static const char help[] = R"(QtXmlToSphinx WebXML to rst converter
+
+A manual test for converting WebXML files to rst files for checking
+formatting.
+)";
+
+Q_LOGGING_CATEGORY(lcQtXmlToSphinx, "qt.xmltosphinx");
+
+static std::ostream &operator<<(std::ostream &str, const QString &s)
+{
+ str << s.toUtf8().constData();
+ return str;
+}
+
+class QtXmlToSphinxDocGenerator : public QtXmlToSphinxDocGeneratorInterface
+{
+public:
+ QtXmlToSphinxDocGenerator() = default;
+
+ QString expandFunction(const QString &) const override;
+ QString expandClass(const QString &, const QString &) const override;
+ QString resolveContextForMethod(const QString &,
+ const QString &) const override;
+ const QLoggingCategory &loggingCategory() const override;
+ QtXmlToSphinxLink resolveLink(const QtXmlToSphinxLink &link) const override;
+ Image resolveImage(const QString &href, const QString &) const;
+};
+
+// QtXmlToSphinxDocGeneratorInterface
+QString QtXmlToSphinxDocGenerator::expandFunction(const QString &) const
+{
+ return {};
+}
+
+QString QtXmlToSphinxDocGenerator::expandClass(const QString &, const QString &) const
+{
+ return {};
+}
+
+QString QtXmlToSphinxDocGenerator::resolveContextForMethod(const QString &, const QString &) const
+{
+ return {};
+}
+
+const QLoggingCategory &QtXmlToSphinxDocGenerator::loggingCategory() const
+{
+ return lcQtXmlToSphinx();
+}
+
+QtXmlToSphinxLink
+ QtXmlToSphinxDocGenerator::resolveLink(const QtXmlToSphinxLink &link) const
+{
+ return link;
+}
+
+QtXmlToSphinxDocGeneratorInterface::Image
+ QtXmlToSphinxDocGenerator::resolveImage(const QString &href, const QString &) const
+{
+ return {href, href};
+}
+
+static bool run(const QString &fileName)
+{
+ QtXmlToSphinxDocGenerator generator;
+ QtXmlToSphinxParameters parameters;
+
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ std::cerr << "Cannot open " << fileName << ": " << file.errorString() << '\n';
+ return false;
+ }
+ const QString xml = QString::fromUtf8(file.readAll());
+ file.close();
+ std::cout << QtXmlToSphinx(&generator, parameters, xml).result();
+ return true;
+}
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+
+ QCommandLineParser commandLineParser;
+ commandLineParser.setApplicationDescription(QString::fromLatin1(help));
+ commandLineParser.addHelpOption();
+ commandLineParser.addPositionalArgument(u"[file]"_s, u"WebXML file to process."_s);
+ commandLineParser.process(QCoreApplication::arguments());
+ if (commandLineParser.positionalArguments().isEmpty())
+ commandLineParser.showHelp(0); // quits
+
+ int exitCode = 1;
+ try {
+ if (run(commandLineParser.positionalArguments().constFirst()))
+ exitCode = 0;
+ } catch (const std::exception &e) {
+ std::cerr << "An exception occurred: " << e.what() << '\n';
+ }
+ return exitCode;
+}
diff --git a/sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt b/sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt
index 940a171b5..25074e716 100644
--- a/sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt
+++ b/sources/shiboken6/tests/qtxmltosphinxtest/CMakeLists.txt
@@ -1,4 +1,7 @@
-cmake_minimum_required(VERSION 3.16)
+# 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 ea60d36b5..3ba77196f 100644
--- a/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp
+++ b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.cpp
@@ -1,38 +1,16 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "qtxmltosphinxtest.h"
#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
@@ -61,6 +39,12 @@ QtXmlToSphinxLink QtXmlToSphinxTest::resolveLink(const QtXmlToSphinxLink &link)
return link;
}
+QtXmlToSphinxDocGeneratorInterface::Image
+ QtXmlToSphinxTest::resolveImage(const QString &href, const QString &) const
+{
+ return {href, href};
+}
+
QString QtXmlToSphinxTest::transformXml(const QString &xml) const
{
return QtXmlToSphinx(this, m_parameters, xml).result();
@@ -74,285 +58,322 @@ void QtXmlToSphinxTest::testTable_data()
QTest::newRow("emptyString") << QString() << QString();
// testSimpleTable
- const char *xml = "\
-<table>\
- <header>\
- <item>\
- <para>Header 1</para>\
- </item>\
- <item>\
- <para>Header 2</para>\
- </item>\
- </header>\
- <row>\
- <item>\
- <para>1 1</para>\
- </item>\
- <item>\
- <para>1 2</para>\
- </item>\
- </row>\
- <row>\
- <item>\
- <para>2 1</para>\
- </item>\
- <item>\
- <para>2 2</para>\
- </item>\
- </row>\
-</table>";
-
- const char *expected = "\n\
- +--------+--------+\n\
- |Header 1|Header 2|\n\
- +--------+--------+\n\
- |1 1 |1 2 |\n\
- +--------+--------+\n\
- |2 1 |2 2 |\n\
- +--------+--------+\n\
-\n";
+ const char *xml = R"(<table>
+ <header>
+ <item>
+ <para>Header 1</para>
+ </item>
+ <item>
+ <para>Header 2</para>
+ </item>
+ </header>
+ <row>
+ <item>
+ <para>1 1</para>
+ </item>
+ <item>
+ <para>1 2</para>
+ </item>
+ </row>
+ <row>
+ <item>
+ <para>2 1</para>
+ </item>
+ <item>
+ <para>2 2</para>
+ </item>
+ </row>
+</table>)";
+
+ const char *expected = R"(
+ +--------+--------+
+ |Header 1|Header 2|
+ +========+========+
+ |1 1 |1 2 |
+ +--------+--------+
+ |2 1 |2 2 |
+ +--------+--------+
+
+)";
QTest::newRow("testSimpleTable")
<< QString::fromLatin1(xml) << QString::fromLatin1(expected);
// testRowSpan
- xml = "\
-<table>\
- <header>\
- <item>\
- <para>Header 1</para>\
- </item>\
- <item>\
- <para>Header 2</para>\
- </item>\
- </header>\
- <row>\
- <item colspan=\"2\">\
- <para>I'm a big text!</para>\
- </item>\
- </row>\
- <row>\
- <item>\
- <para>2 1</para>\
- </item>\
- <item>\
- <para>2 2</para>\
- </item>\
- </row>\
-</table>";
-
- expected = "\n\
- +---------------+--------+\n\
- |Header 1 |Header 2|\n\
- +---------------+--------+\n\
- |I'm a big text! |\n\
- +---------------+--------+\n\
- |2 1 |2 2 |\n\
- +---------------+--------+\n\
-\n";
+ xml = R"(<table>
+ <header>
+ <item>
+ <para>Header 1</para>
+ </item>
+ <item>
+ <para>Header 2</para>
+ </item>
+ </header>
+ <row>
+ <item colspan="2">
+ <para>I'm a big text!</para>
+ </item>
+ </row>
+ <row>
+ <item>
+ <para>2 1</para>
+ </item>
+ <item>
+ <para>2 2</para>
+ </item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +---------------+--------+
+ |Header 1 |Header 2|
+ +===============+========+
+ |I'm a big text! |
+ +---------------+--------+
+ |2 1 |2 2 |
+ +---------------+--------+
+
+)";
QTest::newRow("testColSpan")
<< QString::fromLatin1(xml) << QString::fromLatin1(expected);
// testRowSpan
- xml = "\
-<table>\
- <header>\
- <item>\
- <para>Header 1</para>\
- </item>\
- <item>\
- <para>Header 2</para>\
- </item>\
- </header>\
- <row>\
- <item rowspan=\"2\">\
- <para>1.1</para>\
- </item>\
- <item>\
- <para>1.2</para>\
- </item>\
- </row>\
- <row>\
- <item>\
- <para>2 2</para>\
- </item>\
- </row>\
-</table>";
-
- expected = "\n\
- +--------+--------+\n\
- |Header 1|Header 2|\n\
- +--------+--------+\n\
- |1.1 |1.2 |\n\
- + +--------+\n\
- | |2 2 |\n\
- +--------+--------+\n\
-\n";
+ xml = R"(<table>
+ <header>
+ <item>
+ <para>Header 1</para>
+ </item>
+ <item>
+ <para>Header 2</para>
+ </item>
+ </header>
+ <row>
+ <item rowspan="2">
+ <para>1.1</para>
+ </item>
+ <item>
+ <para>1.2</para>
+ </item>
+ </row>
+ <row>
+ <item>
+ <para>2 2</para>
+ </item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +--------+--------+
+ |Header 1|Header 2|
+ +========+========+
+ |1.1 |1.2 |
+ + +--------+
+ | |2 2 |
+ +--------+--------+
+
+)";
QTest::newRow("testRowSpan")
<< QString::fromLatin1(xml) << QString::fromLatin1(expected);
// testComplexTable
- xml = "\
-<table>\
- <header>\
- <item>\
- <para>Header 1</para>\
- </item>\
- <item>\
- <para>Header 2</para>\
- </item>\
- <item>\
- <para>Header 3</para>\
- </item>\
- </header>\
- <row>\
- <item rowspan=\"2\">\
- <para>1.1</para>\
- </item>\
- <item colspan=\"2\">\
- <para>1.2</para>\
- </item>\
- </row>\
- <row>\
- <item>\
- <para>2 2</para>\
- </item>\
- <item>\
- <para>2 3</para>\
- </item>\
- </row>\
-</table>";
-
- expected = "\n\
- +--------+--------+--------+\n\
- |Header 1|Header 2|Header 3|\n\
- +--------+--------+--------+\n\
- |1.1 |1.2 |\n\
- + +--------+--------+\n\
- | |2 2 |2 3 |\n\
- +--------+--------+--------+\n\
-\n";
+ xml = R"(<table>
+ <header>
+ <item>
+ <para>Header 1</para>
+ </item>
+ <item>
+ <para>Header 2</para>
+ </item>
+ <item>
+ <para>Header 3</para>
+ </item>
+ </header>
+ <row>
+ <item rowspan="2">
+ <para>1.1</para>
+ </item>
+ <item colspan="2">
+ <para>1.2</para>
+ </item>
+ </row>
+ <row>
+ <item>
+ <para>2 2</para>
+ </item>
+ <item>
+ <para>2 3</para>
+ </item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +--------+--------+--------+
+ |Header 1|Header 2|Header 3|
+ +========+========+========+
+ |1.1 |1.2 |
+ + +--------+--------+
+ | |2 2 |2 3 |
+ +--------+--------+--------+
+
+)";
QTest::newRow("testComplexTable")
<< QString::fromLatin1(xml) << QString::fromLatin1(expected);
// testRowSpan2
- xml = "\
-<table>\
- <header>\
- <item><para>h1</para></item>\
- <item><para>h2</para></item>\
- <item><para>h3</para></item>\
- <item><para>h4</para></item>\
- </header>\
- <row>\
- <item rowspan=\"6\"><para>A</para></item>\
- <item rowspan=\"6\"><para>B</para></item>\
- <item><para>C</para></item>\
- <item><para>D</para></item>\
- </row>\
- <row>\
- <item><para>E</para></item>\
- <item><para>F</para></item>\
- </row>\
- <row>\
- <item><para>E</para></item>\
- <item><para>F</para></item>\
- </row>\
- <row>\
- <item><para>E</para></item>\
- <item><para>F</para></item>\
- </row>\
- <row>\
- <item><para>E</para></item>\
- <item><para>F</para></item>\
- </row>\
- <row>\
- <item><para>E</para></item>\
- <item><para>F</para></item>\
- </row>\
-</table>";
-
- expected = "\n\
- +--+--+--+--+\n\
- |h1|h2|h3|h4|\n\
- +--+--+--+--+\n\
- |A |B |C |D |\n\
- + + +--+--+\n\
- | | |E |F |\n\
- + + +--+--+\n\
- | | |E |F |\n\
- + + +--+--+\n\
- | | |E |F |\n\
- + + +--+--+\n\
- | | |E |F |\n\
- + + +--+--+\n\
- | | |E |F |\n\
- +--+--+--+--+\n\
-\n";
+ xml = R"(<table>
+ <header>
+ <item><para>h1</para></item>
+ <item><para>h2</para></item>
+ <item><para>h3</para></item>
+ <item><para>h4</para></item>
+ </header>
+ <row>
+ <item rowspan="6"><para>A</para></item>
+ <item rowspan="6"><para>B</para></item>
+ <item><para>C</para></item>
+ <item><para>D</para></item>
+ </row>
+ <row>
+ <item><para>E</para></item>
+ <item><para>F</para></item>
+ </row>
+ <row>
+ <item><para>E</para></item>
+ <item><para>F</para></item>
+ </row>
+ <row>
+ <item><para>E</para></item>
+ <item><para>F</para></item>
+ </row>
+ <row>
+ <item><para>E</para></item>
+ <item><para>F</para></item>
+ </row>
+ <row>
+ <item><para>E</para></item>
+ <item><para>F</para></item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +--+--+--+--+
+ |h1|h2|h3|h4|
+ +==+==+==+==+
+ |A |B |C |D |
+ + + +--+--+
+ | | |E |F |
+ + + +--+--+
+ | | |E |F |
+ + + +--+--+
+ | | |E |F |
+ + + +--+--+
+ | | |E |F |
+ + + +--+--+
+ | | |E |F |
+ +--+--+--+--+
+
+)";
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 = "\
-<table>\
- <header>\
- <item>\
- <para>Header 1</para>\
- </item>\
- <item>\
- <para>Header 2</para>\
- </item>\
- </header>\
- <row>\
- <item>\
- <para>1.1</para>\
- </item>\
- <item>\
- <para>1.2</para>\
- </item>\
- </row>\
- <row>\
- <item colspan=\"2\">\
- <para>2 2</para>\
- </item>\
- <item>\
- <para>2 3</para>\
- </item>\
- <item>\
- <para>2 4</para>\
- </item>\
- <item>\
- <para>2 5</para>\
- </item>\
- </row>\
- <row>\
- <item>\
- <para>3 1</para>\
- </item>\
- <item>\
- <para>3 2</para>\
- </item>\
- <item>\
- <para>3 3</para>\
- </item>\
- </row>\
-</table>";
-
- expected = "\n\
- +--------+------------+\n\
- |Header 1|Header 2 |\n\
- +--------+------------+\n\
- |1.1 |1.2 |\n\
- +--------+------------+\n\
- |2 2 2 3 2 4 2 5|\n\
- +--------+------------+\n\
- |3 1 |3 2 3 3 |\n\
- +--------+------------+\n\
-\n";
+ xml = R"(<table>
+ <header>
+ <item>
+ <para>Header 1</para>
+ </item>
+ <item>
+ <para>Header 2</para>
+ </item>
+ </header>
+ <row>
+ <item>
+ <para>1.1</para>
+ </item>
+ <item>
+ <para>1.2</para>
+ </item>
+ </row>
+ <row>
+ <item colspan="2">
+ <para>2 2</para>
+ </item>
+ <item>
+ <para>2 3</para>
+ </item>
+ <item>
+ <para>2 4</para>
+ </item>
+ <item>
+ <para>2 5</para>
+ </item>
+ </row>
+ <row>
+ <item>
+ <para>3 1</para>
+ </item>
+ <item>
+ <para>3 2</para>
+ </item>
+ <item>
+ <para>3 3</para>
+ </item>
+ </row>
+</table>)";
+
+ expected = R"(
+ +--------+------------+
+ |Header 1|Header 2 |
+ +========+============+
+ |1.1 |1.2 |
+ +--------+------------+
+ |2 2 2 3 2 4 2 5|
+ +--------+------------+
+ |3 1 |3 2 3 3 |
+ +--------+------------+
+
+)";
QTest::newRow("testBrokenTable")
<< QString::fromLatin1(xml) << QString::fromLatin1(expected);
@@ -369,26 +390,20 @@ void QtXmlToSphinxTest::testTable()
QCOMPARE(actual, expected);
}
-using TablePtr = QSharedPointer<QtXmlToSphinx::Table>;
+using TablePtr = std::shared_ptr<QtXmlToSphinx::Table>;
Q_DECLARE_METATYPE(TablePtr);
void QtXmlToSphinxTest::testTableFormatting_data()
{
- using TableRow = QtXmlToSphinx::TableRow;
using TableCell = QtXmlToSphinx::TableCell;
QTest::addColumn<TablePtr>("table");
QTest::addColumn<QString>("expected");
TablePtr table(new QtXmlToSphinx::Table);
- TableRow row;
- row << TableCell("item11") << TableCell("item12");
- table->appendRow(row);
- row.clear();
- row << TableCell("") << TableCell("item22");
- table->appendRow(row);
- row.clear();
+ table->appendRow({TableCell("item11"), TableCell("item12")});
+ table->appendRow({TableCell(""), TableCell("item22")});
table->normalize();
const char *expected = R"(+------+------+
@@ -402,12 +417,8 @@ void QtXmlToSphinxTest::testTableFormatting_data()
QTest::newRow("normal") << table << QString::fromLatin1(expected);
table.reset(new QtXmlToSphinx::Table);
- row << TableCell("item11") << TableCell("item12\nline2");
- table->appendRow(row);
- row.clear();
- row << TableCell("") << TableCell("item22\nline2\nline3");
- table->appendRow(row);
- row.clear();
+ table->appendRow({TableCell("item11"), TableCell("item12\nline2")});
+ table->appendRow({TableCell(""), TableCell("item22\nline2\nline3")});
table->normalize();
expected = R"(+------+------+
@@ -456,4 +467,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 8f74baaf5..5108ef452 100644
--- a/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h
+++ b/sources/shiboken6/tests/qtxmltosphinxtest/qtxmltosphinxtest.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef QTXMLTOSPHINXTEST_H
#define QTXMLTOSPHINXTEST_H
@@ -44,6 +19,7 @@ public:
const QString &) const override;
const QLoggingCategory &loggingCategory() const override;
QtXmlToSphinxLink resolveLink(const QtXmlToSphinxLink &link) const override;
+ Image resolveImage(const QString &href, const QString &context) const override;
private slots:
void testTable_data();
@@ -52,6 +28,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 558140279..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
@@ -27,6 +30,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/customoverloadsequence_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/cvlistuser_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/cvvaluetype_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sbkdate_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/deleteddefaultctor_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/derived_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/derivedusingct_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/derived_someinnerclass_wrapper.cpp
@@ -106,17 +110,20 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/sample_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sample_sample_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_ctparam_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_inlinenamespace_classwithininlinenamespace_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_someclass_someinnerclass_okthisisrecursiveenough_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/samplenamespace_someclass_someinnerclass_wrapper.cpp
${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
${CMAKE_CURRENT_BINARY_DIR}/sample/snakecasetest_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/snakecasederivedtest_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/sonofmderived1_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/sample/spaceshipcomparisontester_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/str_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/strlist_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/sample/time_wrapper.cpp
@@ -141,13 +148,19 @@ ${CMAKE_CURRENT_BINARY_DIR}/sample/union_wrapper.cpp
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/sample-binding.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt" @ONLY)
+shiboken_get_tool_shell_wrapper(shiboken tool_wrapper)
+
add_custom_command(
-OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
-BYPRODUCTS ${sample_SRC}
-COMMAND shiboken6 --project-file=${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt ${GENERATOR_EXTRA_FLAGS}
-DEPENDS ${sample_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h shiboken6
-WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-COMMENT "Running generator for 'sample' test binding..."
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+ BYPRODUCTS ${sample_SRC}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Shiboken6::shiboken6>
+ --project-file=${CMAKE_CURRENT_BINARY_DIR}/sample-binding.txt
+ ${GENERATOR_EXTRA_FLAGS}
+ DEPENDS ${sample_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h Shiboken6::shiboken6
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Running generator for 'sample' test binding..."
)
add_library(sample MODULE ${sample_SRC})
diff --git a/sources/shiboken6/tests/samplebinding/__del___test.py b/sources/shiboken6/tests/samplebinding/__del___test.py
index 146e6e409..456886614 100644
--- a/sources/shiboken6/tests/samplebinding/__del___test.py
+++ b/sources/shiboken6/tests/samplebinding/__del___test.py
@@ -1,34 +1,8 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
@@ -42,17 +16,21 @@ import sample
delCalled = False
+
class MyObject(sample.ObjectType):
def __del__(self):
global delCalled
delCalled = True
+
class TestDel(unittest.TestCase):
def testIt(self):
a = MyObject()
del a
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ 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 7fa0a0012..89e87be1d 100644
--- a/sources/shiboken6/tests/samplebinding/abstract_test.py
+++ b/sources/shiboken6/tests/samplebinding/abstract_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 Abstract class'''
@@ -42,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)
@@ -87,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++.'''
@@ -112,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 134e73c55..0b5680143 100644
--- a/sources/shiboken6/tests/samplebinding/addedfunction_test.py
+++ b/sources/shiboken6/tests/samplebinding/addedfunction_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 added functions.'''
@@ -41,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.'''
@@ -65,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 570d3ddd9..2a739033b 100644
--- a/sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_test.py
+++ b/sources/shiboken6/tests/samplebinding/addedfunction_with_container_args_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 added functions with nested and multi-argument container types.'''
@@ -41,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 86d0a4731..b0ca56a6d 100644
--- a/sources/shiboken6/tests/samplebinding/argumentmodifications_test.py
+++ b/sources/shiboken6/tests/samplebinding/argumentmodifications_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 method arguments modifications performed as described on typesystem.'''
+import gc
import os
import sys
import unittest
@@ -42,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.'''
@@ -50,6 +25,8 @@ class ArgumentModificationsTest(unittest.TestCase):
def tearDown(self):
del self.mods
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
def testArgRemoval0(self):
'''Tests argument removal modifications on Modifications.argRemoval0.'''
@@ -64,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))
@@ -75,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))
@@ -83,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))
@@ -92,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)
@@ -112,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 c3d438a88..0d73bca1c 100644
--- a/sources/shiboken6/tests/samplebinding/array_numpy_test.py
+++ b/sources/shiboken6/tests/samplebinding/array_numpy_test.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2017 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 NumPy Array types.'''
@@ -48,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 e39c2733c..ad65d58db 100644
--- a/sources/shiboken6/tests/samplebinding/array_sequence_test.py
+++ b/sources/shiboken6/tests/samplebinding/array_sequence_test.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2017 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 Array types (PySequence).'''
@@ -40,6 +14,7 @@ from shiboken_paths import init_paths
init_paths()
import sample
+
class ArrayTester(unittest.TestCase):
'''Test case for arrays.'''
@@ -56,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 f3950af9c..a7e7a7210 100644
--- a/sources/shiboken6/tests/samplebinding/bug_554_test.py
+++ b/sources/shiboken6/tests/samplebinding/bug_554_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
'''Unit test for bug#554'''
@@ -38,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 365941b46..c470fe723 100644
--- a/sources/shiboken6/tests/samplebinding/bug_704_test.py
+++ b/sources/shiboken6/tests/samplebinding/bug_704_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -52,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 bcf61a2d5..e51a899fa 100644
--- a/sources/shiboken6/tests/samplebinding/bytearray_test.py
+++ b/sources/shiboken6/tests/samplebinding/bytearray_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -61,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)
@@ -107,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 4b9a18e7b..f0ac70626 100644
--- a/sources/shiboken6/tests/samplebinding/child_return_test.py
+++ b/sources/shiboken6/tests/samplebinding/child_return_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
'''The BlackBox class has cases of ownership transference between C++ and Python.'''
+import gc
import os
import sys
import unittest
@@ -40,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.'''
@@ -50,6 +25,8 @@ class ReturnOfChildTest(unittest.TestCase):
o1 = ObjectType.createWithChild()
child = o1.children()[0]
del o1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertRaises(RuntimeError, child.objectName)
def testKillParentKeepingChild2(self):
@@ -57,8 +34,10 @@ class ReturnOfChildTest(unittest.TestCase):
o1 = ObjectType.createWithChild()
child = o1.findChild("child")
del o1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ 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 44d32ce39..1eeb3d446 100644
--- a/sources/shiboken6/tests/samplebinding/class_fields_test.py
+++ b/sources/shiboken6/tests/samplebinding/class_fields_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
'''Simple test case for accessing the exposed C++ class fields.'''
@@ -42,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.'''
@@ -63,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.'''
@@ -99,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.'''
@@ -107,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)
@@ -119,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.'''
@@ -138,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):
@@ -182,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)
@@ -192,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 c68230474..4caebc62a 100644
--- a/sources/shiboken6/tests/samplebinding/collector_test.py
+++ b/sources/shiboken6/tests/samplebinding/collector_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 Collector class' shift operators.'''
@@ -60,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'''
@@ -84,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 272eee357..454aff100 100644
--- a/sources/shiboken6/tests/samplebinding/complex_test.py
+++ b/sources/shiboken6/tests/samplebinding/complex_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 Complex class'''
@@ -43,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'''
@@ -74,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')
@@ -87,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 eb802f43b..7e76245b1 100644
--- a/sources/shiboken6/tests/samplebinding/conversion_operator_test.py
+++ b/sources/shiboken6/tests/samplebinding/conversion_operator_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 implicit conversion generated by conversion operator.'''
@@ -42,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()
@@ -57,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 63d9163ba..db539d1b9 100644
--- a/sources/shiboken6/tests/samplebinding/copy_test.py
+++ b/sources/shiboken6/tests/samplebinding/copy_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 deep copy of objects'''
@@ -90,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 be8e11bc4..5e2695d72 100644
--- a/sources/shiboken6/tests/samplebinding/ctorconvrule_test.py
+++ b/sources/shiboken6/tests/samplebinding/ctorconvrule_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 proper generation of constructor altered by conversion-rule tag.'''
@@ -42,6 +15,7 @@ init_paths()
from sample import CtorConvRule
+
class TestCtorConvRule(unittest.TestCase):
'''Simple test case for CtorConvRule'''
@@ -51,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 5a20216b6..4e4ae2603 100644
--- a/sources/shiboken6/tests/samplebinding/cyclic_test.py
+++ b/sources/shiboken6/tests/samplebinding/cyclic_test.py
@@ -1,34 +1,8 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
@@ -42,7 +16,6 @@ from sample import ObjectView
from sample import ObjectModel
-
class ObjTest(unittest.TestCase):
def test_cyclic_dependency_withParent(self):
@@ -50,8 +23,6 @@ class ObjTest(unittest.TestCase):
only be removed by the garbage collector, and then invoke the
garbage collector in a different thread.
"""
- import gc
-
class CyclicChildObject(ObjectType):
def __init__(self, parent):
super(CyclicChildObject, self).__init__(parent)
@@ -65,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
@@ -74,7 +45,9 @@ class ObjTest(unittest.TestCase):
cycle = CyclicObject()
self.assertTrue(alive())
del cycle
- self.assertTrue(alive())
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: the semantics of gc.enable/gc.disable is different for PyPy
+ self.assertTrue(alive())
gc.collect()
self.assertFalse(alive())
@@ -83,8 +56,6 @@ class ObjTest(unittest.TestCase):
only be removed by the garbage collector, and then invoke the
garbage collector in a different thread.
"""
- import gc
-
class CyclicChildObject(ObjectView):
def __init__(self, model):
super(CyclicChildObject, self).__init__(None)
@@ -98,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
@@ -107,10 +78,12 @@ class ObjTest(unittest.TestCase):
cycle = CyclicObject()
self.assertTrue(alive())
del cycle
- self.assertTrue(alive())
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: the semantics of gc.enable/gc.disable is different for PyPy
+ self.assertTrue(alive())
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 ad1419391..2b6efcf18 100644
--- a/sources/shiboken6/tests/samplebinding/date_test.py
+++ b/sources/shiboken6/tests/samplebinding/date_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 python conversions types '''
@@ -43,6 +16,7 @@ from datetime import date
from sample import SbkDate
+
class DateConversionTest(unittest.TestCase):
def testConstructorWithDateObject(self):
@@ -59,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 128b3c913..0d39c5f96 100644
--- a/sources/shiboken6/tests/samplebinding/decisor_test.py
+++ b/sources/shiboken6/tests/samplebinding/decisor_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 the method overload decisor.'''
@@ -42,6 +15,7 @@ init_paths()
from sample import SampleNamespace, Point, ObjectType, ObjectModel
+
class DecisorTest(unittest.TestCase):
'''Test cases for the method overload decisor.'''
@@ -64,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 8fb663eb1..57a792ae2 100644
--- a/sources/shiboken6/tests/samplebinding/delete_test.py
+++ b/sources/shiboken6/tests/samplebinding/delete_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -41,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 8a1d37cfc..c371df94f 100644
--- a/sources/shiboken6/tests/samplebinding/deprecated_test.py
+++ b/sources/shiboken6/tests/samplebinding/deprecated_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -41,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 8bdb051a8..346f29136 100644
--- a/sources/shiboken6/tests/samplebinding/derived_test.py
+++ b/sources/shiboken6/tests/samplebinding/derived_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 Derived class'''
@@ -43,6 +16,7 @@ init_paths()
import sample
from sample import Abstract, Derived, DerivedUsingCt, OverloadedFuncEnum
+
class Deviant(Derived):
def __init__(self):
Derived.__init__(self)
@@ -58,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'''
@@ -67,22 +51,6 @@ class DerivedTest(unittest.TestCase):
'id_', 'pureVirtual', 'unpureVirtual'])
self.assertTrue(inherited_methods.issubset(dir(Derived)))
- 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()
@@ -100,21 +68,23 @@ class DerivedTest(unittest.TestCase):
derived = Derived()
result = derived.overloaded(1.1, 2.2)
self.assertEqual(type(result), OverloadedFuncEnum)
- 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)
@@ -126,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')
@@ -150,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)
@@ -159,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 9b0d7a9ff..aa21a0f7e 100644
--- a/sources/shiboken6/tests/samplebinding/duck_punching_test.py
+++ b/sources/shiboken6/tests/samplebinding/duck_punching_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 virtual methods.'''
@@ -43,6 +16,7 @@ init_paths()
from sample import VirtualMethods, SimpleFile, Point
+
def MethodTypeCompat(func, instance):
return types.MethodType(func, instance)
@@ -51,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").'''
@@ -83,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
@@ -93,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
@@ -112,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
@@ -177,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 67be482f2..f1859260e 100644
--- a/sources/shiboken6/tests/samplebinding/echo_test.py
+++ b/sources/shiboken6/tests/samplebinding/echo_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 <add-function> with const char* as argument'''
@@ -42,6 +15,7 @@ init_paths()
from sample import Echo
+
class TestEcho(unittest.TestCase):
'''Simple test case for Echo.echo'''
@@ -53,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 66d7daf5b..276b8d894 100644
--- a/sources/shiboken6/tests/samplebinding/enum_test.py
+++ b/sources/shiboken6/tests/samplebinding/enum_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2021 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 Python representation of C++ enums.'''
@@ -40,33 +13,27 @@ 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
+
def createTempFile():
import tempfile
return tempfile.SpooledTemporaryFile(mode='rw')
+
class EnumTest(unittest.TestCase):
'''Test case for Python representation of C++ enums.'''
- 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.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)
@@ -92,16 +59,18 @@ 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.'''
- self.assertRaises(TypeError, SampleNamespace.InValue, '1')
+ self.assertRaises((TypeError, ValueError), SampleNamespace.InValue, '1')
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):
@@ -126,49 +95,26 @@ class EnumTest(unittest.TestCase):
self.assertEqual(event.eventType(), Event.BASIC_EVENT)
event.setEventTypeByConstRef(Event.SOME_EVENT)
self.assertEqual(event.eventType(), Event.SOME_EVENT)
-
- 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))
+ event.setEventTypeByConstPtr(Event.BASIC_EVENT)
+ self.assertEqual(event.eventType(), Event.BASIC_EVENT)
def testEnumArgumentWithDefaultValue(self):
'''Option enumArgumentWithDefaultValue(Option opt = UnixTime);'''
self.assertEqual(SampleNamespace.enumArgumentWithDefaultValue(), SampleNamespace.UnixTime)
- self.assertEqual(SampleNamespace.enumArgumentWithDefaultValue(SampleNamespace.RandomNumber), SampleNamespace.RandomNumber)
-
- 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(klass.__signature__, None)
- # The base class must be Enum
- self.assertNotEqual(base.__signature__, None)
- # It contains an int annotation.
- param = base.__signature__.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(999))
+ Event.__init__(self, Event.EventType(3))
+
class OutOfBoundsTest(unittest.TestCase):
def testValue(self):
e = MyEvent()
- self.assertEqual(repr(e.eventType()), 'sample.Event.EventType(999)')
+ self.assertEqual(repr(e.eventType()), "<EventType.ANY_EVENT: 3>")
- def testNoneName(self):
- e = MyEvent()
- t = e.eventType()
- self.assertEqual(t.name, None)
class EnumOverloadTest(unittest.TestCase):
'''Test case for overloads involving enums'''
@@ -180,6 +126,7 @@ class EnumOverloadTest(unittest.TestCase):
self.assertEqual(o.callWithEnum('', Event.ANY_EVENT, 9), 81)
self.assertEqual(o.callWithEnum('', 9), 9)
+
class EnumOperators(unittest.TestCase):
'''Test case for operations on enums'''
@@ -189,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 72705c4c4..42ae23961 100644
--- a/sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py
+++ b/sources/shiboken6/tests/samplebinding/enumfromremovednamespace_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -41,15 +14,10 @@ init_paths()
import sample
from shiboken_test_helper import objectFullname
+from shibokensupport.signature import get_signature
+
class TestEnumFromRemovedNamespace(unittest.TestCase):
- 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
@@ -59,10 +27,10 @@ class TestEnumFromRemovedNamespace(unittest.TestCase):
"sample.ObjectOnInvisibleNamespace")
# Function arguments
- signature = sample.ObjectOnInvisibleNamespace.toInt.__signature__
+ signature = get_signature(sample.ObjectOnInvisibleNamespace.toInt)
self.assertEqual(objectFullname(signature.parameters['e'].annotation),
"sample.RemovedNamespace1_Enum")
- signature = sample.ObjectOnInvisibleNamespace.consume.__signature__
+ signature = get_signature(sample.ObjectOnInvisibleNamespace.consume)
self.assertEqual(objectFullname(signature.parameters['other'].annotation),
"sample.ObjectOnInvisibleNamespace")
@@ -76,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 54ad28ff3..8e13d5d46 100644
--- a/sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py
+++ b/sources/shiboken6/tests/samplebinding/event_loop_call_virtual_test.py
@@ -1,45 +1,17 @@
#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
'''Simple event loop dispatcher test.'''
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
@@ -67,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 12410ed88..8b854fca6 100644
--- a/sources/shiboken6/tests/samplebinding/event_loop_thread_test.py
+++ b/sources/shiboken6/tests/samplebinding/event_loop_thread_test.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
from random import random
@@ -90,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 96c389aa8..d9e6b377f 100644
--- a/sources/shiboken6/tests/samplebinding/exception_test.py
+++ b/sources/shiboken6/tests/samplebinding/exception_test.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-#
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -39,6 +13,7 @@ init_paths()
from sample import ExceptionTest
+
class CppExceptionTest(unittest.TestCase):
def testVoid(self):
@@ -49,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)
@@ -65,21 +40,32 @@ 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)
+ def testModifications(self):
+ """PYSIDE-1995, test whether exceptions are propagated
+ when return ownership modifications are generated."""
+ exceptionCount = 0
+ try:
+ et = ExceptionTest.create(True) # noqa: F841
+ except: # noqa: E722
+ exceptionCount += 1
+ self.assertEqual(exceptionCount, 1)
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/filter_test.py b/sources/shiboken6/tests/samplebinding/filter_test.py
index e9c2d5ccc..df805093f 100644
--- a/sources/shiboken6/tests/samplebinding/filter_test.py
+++ b/sources/shiboken6/tests/samplebinding/filter_test.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -37,6 +12,7 @@ init_paths()
from sample import Data, Intersection, Union
+
class TestFilters(unittest.TestCase):
def testAnd(self):
@@ -48,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 dd24f274b..64806417a 100644
--- a/sources/shiboken6/tests/samplebinding/global.h
+++ b/sources/shiboken6/tests/samplebinding/global.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "abstract.h"
#include "blackbox.h"
@@ -81,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 c1879e3e9..af22328c5 100644
--- a/sources/shiboken6/tests/samplebinding/handleholder_test.py
+++ b/sources/shiboken6/tests/samplebinding/handleholder_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 a class that holds a unknown handle object.
Test case for BUG #1105.
@@ -44,6 +17,7 @@ init_paths()
from sample import HandleHolder
+
class HandleHolderTest(unittest.TestCase):
def testCreation(self):
holder = HandleHolder(HandleHolder.createHandle())
@@ -60,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 fae9c724d..c41f5cc06 100644
--- a/sources/shiboken6/tests/samplebinding/hashabletype_test.py
+++ b/sources/shiboken6/tests/samplebinding/hashabletype_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 __hash__'''
@@ -40,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):
@@ -56,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 5bd497e43..feb78d045 100644
--- a/sources/shiboken6/tests/samplebinding/ignorederefop_test.py
+++ b/sources/shiboken6/tests/samplebinding/ignorederefop_test.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -34,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 0e3e99d64..081666281 100644
--- a/sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py
+++ b/sources/shiboken6/tests/samplebinding/implicitconv_numerical_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 inplicit converting C++ numeric types.'''
@@ -54,9 +27,15 @@ if is64bitArchitecture and sys.platform != 'win32':
cLongMin = -9223372036854775808
cLongMax = 9223372036854775807
+
class NumericTester(unittest.TestCase):
'''Helper class for numeric comparison testing'''
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ return super().assertRaises(*args, **kwds)
+
def check_value(self, source, expected, callback, desired_type=None):
result = callback(source)
self.assertEqual(result, expected)
diff --git a/sources/shiboken6/tests/samplebinding/implicitconv_test.py b/sources/shiboken6/tests/samplebinding/implicitconv_test.py
index 782ddba2b..ebafe0c52 100644
--- a/sources/shiboken6/tests/samplebinding/implicitconv_test.py
+++ b/sources/shiboken6/tests/samplebinding/implicitconv_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 implicit conversions'''
@@ -42,6 +15,7 @@ init_paths()
from sample import ImplicitConv, ObjectType
+
class ImplicitConvTest(unittest.TestCase):
'''Test case for implicit conversions'''
@@ -70,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 5d1bde31d..28d62486a 100644
--- a/sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py
+++ b/sources/shiboken6/tests/samplebinding/inheritanceandscope_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 finding scope in cases involving inheritance.'''
@@ -42,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 a6fb7a5ef..f673a7807 100644
--- a/sources/shiboken6/tests/samplebinding/injectcode_test.py
+++ b/sources/shiboken6/tests/samplebinding/injectcode_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 std::list container conversions'''
@@ -41,6 +14,7 @@ from shiboken_paths import init_paths
init_paths()
from sample import InjectCode
+
class MyInjectCode(InjectCode):
def __init__(self):
InjectCode.__init__(self)
@@ -49,8 +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")
def testTypeNativeBeginning_TypeTargetBeginning(self):
ic = InjectCode()
self.assertEqual(str(ic), "Hi! I'm the inject code dummy class.")
@@ -96,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):
@@ -135,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 6e5b23aa7..721f33483 100644
--- a/sources/shiboken6/tests/samplebinding/innerclass_test.py
+++ b/sources/shiboken6/tests/samplebinding/innerclass_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -40,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 58e519d00..defa9ca71 100644
--- a/sources/shiboken6/tests/samplebinding/intlist_test.py
+++ b/sources/shiboken6/tests/samplebinding/intlist_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -40,6 +13,7 @@ init_paths()
from sample import IntList
+
class IntListTest(unittest.TestCase):
def testAutoFunctionsToBaseList(self):
@@ -101,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 a2fabf87f..d883adf47 100644
--- a/sources/shiboken6/tests/samplebinding/intwrapper_test.py
+++ b/sources/shiboken6/tests/samplebinding/intwrapper_test.py
@@ -1,32 +1,5 @@
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2021 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -43,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)
@@ -56,6 +29,11 @@ class IntWrapperTest(unittest.TestCase):
i -= ten2
self.assertTrue(i == ten1)
+ def testAddPyMethodDef(self):
+ """Test of added free function (PYSIDE-1905)."""
+ i = IntWrapper(10)
+ self.assertEqual(i.add_ints(10, 20), 30)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py b/sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py
index 1456f5e7a..bb35b2bb1 100644
--- a/sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py
+++ b/sources/shiboken6/tests/samplebinding/invalid_virtual_return_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 returning invalid types in a virtual function'''
@@ -65,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 8e900489d..10591fec6 100644
--- a/sources/shiboken6/tests/samplebinding/keep_reference_test.py
+++ b/sources/shiboken6/tests/samplebinding/keep_reference_test.py
@@ -1,35 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-'''Test case for objects that keep references to other object without owning them (e.g. model/view relationships).'''
+# 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 os
import sys
@@ -42,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):
@@ -75,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 b7257a320..b668bfd90 100644
--- a/sources/shiboken6/tests/samplebinding/list_test.py
+++ b/sources/shiboken6/tests/samplebinding/list_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 std::list container conversions'''
@@ -42,6 +15,7 @@ init_paths()
from sample import ListUser, Point, PointF
+
class ExtendedListUser(ListUser):
def __init__(self):
ListUser.__init__(self)
@@ -51,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'''
@@ -96,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)
@@ -123,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 eaaf4ca05..acd47634a 100644
--- a/sources/shiboken6/tests/samplebinding/lock_test.py
+++ b/sources/shiboken6/tests/samplebinding/lock_test.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
'''Simple test with a blocking C++ method that should allow python
threads to run.'''
@@ -89,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)
@@ -98,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 205075bc3..fa99ad2e7 100644
--- a/sources/shiboken6/tests/samplebinding/map_test.py
+++ b/sources/shiboken6/tests/samplebinding/map_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 std::map container conversions'''
@@ -42,6 +15,7 @@ init_paths()
from sample import MapUser
+
class ExtendedMapUser(MapUser):
def __init__(self):
MapUser.__init__(self)
@@ -49,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'''
@@ -71,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_)
@@ -79,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 ed07626a0..4d7eeda96 100644
--- a/sources/shiboken6/tests/samplebinding/metaclass_test.py
+++ b/sources/shiboken6/tests/samplebinding/metaclass_test.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -35,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/mi_virtual_methods_test.py b/sources/shiboken6/tests/samplebinding/mi_virtual_methods_test.py
index ba92bdb85..8d324db59 100644
--- a/sources/shiboken6/tests/samplebinding/mi_virtual_methods_test.py
+++ b/sources/shiboken6/tests/samplebinding/mi_virtual_methods_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 virtual methods in multiple inheritance scenarios'''
diff --git a/sources/shiboken6/tests/samplebinding/mixed_mi_test.py b/sources/shiboken6/tests/samplebinding/mixed_mi_test.py
index f303ea0db..fa8481600 100644
--- a/sources/shiboken6/tests/samplebinding/mixed_mi_test.py
+++ b/sources/shiboken6/tests/samplebinding/mixed_mi_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 multiple inheritance in mixed Python/C++ scenarios'''
@@ -79,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 1a4ed2407..e23503eff 100644
--- a/sources/shiboken6/tests/samplebinding/modelindex_test.py
+++ b/sources/shiboken6/tests/samplebinding/modelindex_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -40,6 +13,7 @@ init_paths()
from sample import ModelIndex, ReferentModelIndex, PersistentModelIndex
+
class TestCastOperator(unittest.TestCase):
def testCastOperatorReturningValue(self):
@@ -57,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 dff7b68fb..b5663a04e 100644
--- a/sources/shiboken6/tests/samplebinding/modelview_test.py
+++ b/sources/shiboken6/tests/samplebinding/modelview_test.py
@@ -1,35 +1,9 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-'''Test case for objects that keep references to other object without owning them (e.g. model/view relationships).'''
+# 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
@@ -44,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)
@@ -56,6 +32,7 @@ class ListModelKeepsReference(ObjectModel):
def data(self):
return self.obj
+
class ListModelDoesntKeepsReference(ObjectModel):
def data(self):
obj = MyObject()
@@ -82,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 3429ccd0f..dced14396 100644
--- a/sources/shiboken6/tests/samplebinding/modifications_test.py
+++ b/sources/shiboken6/tests/samplebinding/modifications_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 method modifications performed as described on type system. '''
+import gc
import os
import sys
import unittest
@@ -42,6 +16,7 @@ init_paths()
from sample import Modifications, Point, ByteArray
+
class ExtModifications(Modifications):
def __init__(self):
Modifications.__init__(self)
@@ -64,25 +39,18 @@ class ModificationsTest(unittest.TestCase):
def tearDown(self):
del self.mods
-
- 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)))
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
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')
@@ -103,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);
@@ -117,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)
@@ -133,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)
@@ -147,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 63cec6556..9791a3491 100644
--- a/sources/shiboken6/tests/samplebinding/modified_constructor_test.py
+++ b/sources/shiboken6/tests/samplebinding/modified_constructor_test.py
@@ -1,37 +1,9 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 cases for ConstructorWithModifiedArgument class.'''
-import sys
import os
import sys
import unittest
@@ -41,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):
@@ -51,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 b59e64a00..dcb487f1a 100644
--- a/sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py
+++ b/sources/shiboken6/tests/samplebinding/modifiedvirtualmethods_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 modified virtual methods.'''
+import gc
import os
import sys
import unittest
@@ -42,6 +16,7 @@ init_paths()
from sample import VirtualMethods, Str
+
class ExtendedVirtualMethods(VirtualMethods):
def __init__(self):
VirtualMethods.__init__(self)
@@ -87,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):
@@ -100,6 +75,8 @@ class VirtualMethodsTest(unittest.TestCase):
def tearDown(self):
del self.vm
del self.evm
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
def testModifiedVirtualMethod0(self):
'''Renamed virtual method.'''
@@ -209,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):
@@ -241,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 c522d0e38..fc6b26c3f 100644
--- a/sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py
+++ b/sources/shiboken6/tests/samplebinding/multi_cpp_inheritance_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 multiple inheritance'''
@@ -40,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 0c40a4fd1..7497714a8 100644
--- a/sources/shiboken6/tests/samplebinding/multiple_derived_test.py
+++ b/sources/shiboken6/tests/samplebinding/multiple_derived_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 multiple inheritance'''
@@ -40,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'''
@@ -67,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))
@@ -87,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()
@@ -107,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()
@@ -122,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()
@@ -143,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()
@@ -162,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()
@@ -193,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()
@@ -206,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()
@@ -219,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()
@@ -230,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 3dc79fa96..64a6792ac 100644
--- a/sources/shiboken6/tests/samplebinding/namespace_test.py
+++ b/sources/shiboken6/tests/samplebinding/namespace_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 std::map container conversions'''
@@ -40,9 +13,10 @@ 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 shibokensupport.signature import get_signature
# For tests of invisible namespaces, see
# enumfromremovednamespace_test.py / removednamespaces.h
@@ -50,17 +24,17 @@ from shiboken_test_helper import objectFullname
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()
+ 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)
@@ -68,21 +42,26 @@ 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),
- "<class 'sample.SampleNamespace.SomeClass.ProtectedEnum'>")
+ "<enum 'ProtectedEnum'>")
self.assertEqual(str(SampleNamespace.SomeClass.SomeInnerClass.ProtectedEnum),
- "<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),
- "<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(SampleNamespace.enumInEnumOut.__signature__.parameters['in_'].annotation),
- "sample.SampleNamespace.InValue")
- self.assertEqual(objectFullname(SampleNamespace.enumAsInt.__signature__.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()
+ cls.setValue(SampleNamespace.EWIN_Value1)
+ self.assertEqual(cls.value(), SampleNamespace.EWIN_Value1)
if __name__ == '__main__':
diff --git a/sources/shiboken6/tests/samplebinding/newdivision_test.py b/sources/shiboken6/tests/samplebinding/newdivision_test.py
index a9152f4a1..0e7dfbee1 100644
--- a/sources/shiboken6/tests/samplebinding/newdivision_test.py
+++ b/sources/shiboken6/tests/samplebinding/newdivision_test.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -35,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 31a51995e..bc8d29e50 100644
--- a/sources/shiboken6/tests/samplebinding/nondefaultctor_test.py
+++ b/sources/shiboken6/tests/samplebinding/nondefaultctor_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 ...'''
@@ -42,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):
@@ -70,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 b329f5672..a10547728 100644
--- a/sources/shiboken6/tests/samplebinding/nontypetemplate_test.py
+++ b/sources/shiboken6/tests/samplebinding/nontypetemplate_test.py
@@ -1,32 +1,6 @@
#!/usr/bin/env python
-#
-#############################################################################
-##
-## Copyright (C) 2018 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
hasNumPy = False
@@ -47,6 +21,7 @@ init_paths()
from sample import IntArray2, IntArray3
+
class NonTypeTemplateTest(unittest.TestCase):
def testNonTypeTemplate(self):
@@ -58,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 16f675547..7be239fc4 100644
--- a/sources/shiboken6/tests/samplebinding/nonzero_test.py
+++ b/sources/shiboken6/tests/samplebinding/nonzero_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -40,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 5512a2de6..f714a4fc8 100644
--- a/sources/shiboken6/tests/samplebinding/numericaltypedef_test.py
+++ b/sources/shiboken6/tests/samplebinding/numericaltypedef_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -40,6 +13,7 @@ init_paths()
from sample import SizeF
+
class NumericalTypedefTest(unittest.TestCase):
def testNumericalTypedefExact(self):
@@ -59,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 61f8c7103..42094a463 100644
--- a/sources/shiboken6/tests/samplebinding/numpy_test.py
+++ b/sources/shiboken6/tests/samplebinding/numpy_test.py
@@ -1,39 +1,14 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 sys
try:
- from distutils import sysconfig
+ import sysconfig
if bool(sysconfig.get_config_var('Py_DEBUG')):
sys.exit(0)
import numpy
-except:
+except: # noqa: E722
sys.exit(0)
import os
@@ -46,6 +21,7 @@ from shiboken_paths import init_paths
init_paths()
from sample import PointF
+
class TestNumpyTypes(unittest.TestCase):
def testNumpyConverted(self):
@@ -60,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 58036a458..ead68ba13 100644
--- a/sources/shiboken6/tests/samplebinding/objecttype_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttype_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 ObjectType class of object-type with privates copy constructor and = operator.'''
@@ -95,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)
@@ -129,11 +102,9 @@ class ObjectTypeTest(unittest.TestCase):
def testInvalidProperty(self):
o = ObjectType()
- try:
+ with self.assertRaises(AttributeError):
o.typo
- self.assertFail()
- except AttributeError as error:
- self.assertEqual(error.args[0], "'sample.ObjectType' object has no attribute '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 f9944e61b..285e2313b 100644
--- a/sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttype_with_named_args_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -40,6 +13,7 @@ init_paths()
from sample import ObjectType
+
class NamedArgsTest(unittest.TestCase):
def testOneArgument(self):
@@ -62,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 52253f241..8f74af3ab 100644
--- a/sources/shiboken6/tests/samplebinding/objecttypebyvalue_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttypebyvalue_test.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -35,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):
@@ -47,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 10b2f0ca9..677b89281 100644
--- a/sources/shiboken6/tests/samplebinding/objecttypelayout_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttypelayout_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 cases for ObjectTypeLayout class.'''
+import gc
import os
import sys
import unittest
@@ -40,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):
@@ -48,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()
@@ -83,7 +56,9 @@ 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()
self.assertRaises(RuntimeError, c1.objectName)
self.assertRaises(RuntimeError, c2.objectName)
@@ -105,7 +80,9 @@ 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()
self.assertRaises(RuntimeError, c1.objectName)
self.assertRaises(RuntimeError, c2.objectName)
@@ -113,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()
@@ -165,6 +143,8 @@ class ObjectTypeLayoutTest(unittest.TestCase):
self.assertEqual(l2.parent(), l1)
del p1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertRaises(RuntimeError, c1.objectName)
self.assertRaises(RuntimeError, c2.objectName)
@@ -174,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()
@@ -201,6 +182,8 @@ class ObjectTypeLayoutTest(unittest.TestCase):
self.assertEqual(l2.parent(), l1)
del p1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertRaises(RuntimeError, c1.objectName)
self.assertRaises(RuntimeError, c2.objectName)
@@ -210,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()
@@ -239,6 +223,8 @@ class ObjectTypeLayoutTest(unittest.TestCase):
p2.setLayout(l1)
del p1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(c1.parent(), p2)
self.assertEqual(c2.parent(), p2)
@@ -248,6 +234,8 @@ class ObjectTypeLayoutTest(unittest.TestCase):
self.assertEqual(l2.parent(), l1)
del p2
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertRaises(RuntimeError, c1.objectName)
self.assertRaises(RuntimeError, c2.objectName)
@@ -257,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()
@@ -287,6 +275,8 @@ class ObjectTypeLayoutTest(unittest.TestCase):
p2.setLayout(l1)
del p1
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(c1.parent(), p2)
self.assertEqual(c2.parent(), p2)
@@ -296,6 +286,8 @@ class ObjectTypeLayoutTest(unittest.TestCase):
self.assertEqual(l2.parent(), l1)
del p2
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertRaises(RuntimeError, c1.objectName)
self.assertRaises(RuntimeError, c2.objectName)
@@ -304,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 a82c54b7e..ceeee6c8d 100644
--- a/sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttypeoperators_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -37,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):
@@ -53,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)
@@ -63,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 cb270c69b..5fa6f824e 100644
--- a/sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py
+++ b/sources/shiboken6/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -39,6 +12,7 @@ from shiboken_paths import init_paths
init_paths()
from sample import ObjectTypeHolder
+
class TestObjectTypeReferenceAsVirtualMethodArgument(unittest.TestCase):
def testBasic(self):
@@ -52,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 a65b1228c..87a8cdb1f 100644
--- a/sources/shiboken6/tests/samplebinding/oddbool_test.py
+++ b/sources/shiboken6/tests/samplebinding/oddbool_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 OddBool user's primitive type conversion.'''
@@ -40,13 +13,15 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
-from sample import OddBoolUser, ComparisonTester
+from sample import OddBoolUser, ComparisonTester, SpaceshipComparisonTester
+
class DerivedOddBoolUser (OddBoolUser):
def returnMyselfVirtual(self):
return OddBoolUser()
pass
+
class OddBoolTest(unittest.TestCase):
def testOddBoolUser(self):
@@ -57,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()
@@ -86,6 +61,19 @@ class OddBoolTest(unittest.TestCase):
t2 = ComparisonTester(42)
self.assertEqual(t1, t2)
+ def testSpaceshipOperator(self):
+ if not SpaceshipComparisonTester.HasSpaceshipOperator:
+ print("Skipping Spaceship Operator test")
+ return
+ t1 = SpaceshipComparisonTester(42)
+ t2 = SpaceshipComparisonTester(42)
+ self.assertEqual(t1, t2)
+ self.assertTrue(t1 <= t2)
+ self.assertTrue(t1 >= t2)
+ t2 = SpaceshipComparisonTester(43)
+ self.assertTrue(t1 < t2)
+ self.assertFalse(t1 > t2)
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/samplebinding/onlycopyclass_test.py b/sources/shiboken6/tests/samplebinding/onlycopyclass_test.py
index 65ec14cd7..bcb154c52 100644
--- a/sources/shiboken6/tests/samplebinding/onlycopyclass_test.py
+++ b/sources/shiboken6/tests/samplebinding/onlycopyclass_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -40,6 +13,7 @@ init_paths()
from sample import OnlyCopy, FriendOfOnlyCopy
+
class ClassWithOnlyCopyCtorTest(unittest.TestCase):
def testGetOne(self):
obj = FriendOfOnlyCopy.createOnlyCopy(123)
@@ -61,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 5635eeed2..84442306a 100644
--- a/sources/shiboken6/tests/samplebinding/overflow_test.py
+++ b/sources/shiboken6/tests/samplebinding/overflow_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 overflowing C++ numeric types.'''
@@ -40,21 +13,29 @@ 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):
'''Test case for overflowing C++ numeric types.'''
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ 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)
@@ -63,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)
@@ -81,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 ff941e016..060d91510 100644
--- a/sources/shiboken6/tests/samplebinding/overload_sorting_test.py
+++ b/sources/shiboken6/tests/samplebinding/overload_sorting_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 overload sorting'''
@@ -40,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):
@@ -90,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 50f587eec..62fa8d8d2 100644
--- a/sources/shiboken6/tests/samplebinding/overload_test.py
+++ b/sources/shiboken6/tests/samplebinding/overload_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 Overload class'''
@@ -48,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
@@ -205,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 9d8b0aeab..269b97299 100644
--- a/sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py
+++ b/sources/shiboken6/tests/samplebinding/overloadwithdefault_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -66,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 3b5ae5c8e..8a55d3ab8 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_argument_invalidation_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
'''Wrapper validity tests for arguments.'''
@@ -42,6 +15,7 @@ init_paths()
from sample import Polygon, Point
+
class WrapperValidityOfArgumentsTest(unittest.TestCase):
'''Wrapper validity tests for arguments.'''
@@ -52,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 be010c84b..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
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 for destroy a child object in C++'''
@@ -57,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 10535f272..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
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 for deleting a child object in python'''
+import gc
import os
import random
import string
@@ -56,8 +30,11 @@ class DeleteChildInPython(unittest.TestCase):
child.setObjectName(name)
del child
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
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 310bf08ee..8f654639c 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_delete_parent_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 for destroying the parent'''
+import gc
import os
import sys
import unittest
@@ -56,8 +30,10 @@ class DeleteParentTest(unittest.TestCase):
refcount_before = sys.getrefcount(child)
del parent
+ # 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):
@@ -69,6 +45,8 @@ class DeleteParentTest(unittest.TestCase):
child.setParent(parent)
del parent
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
for i, child in enumerate(children):
self.assertRaises(RuntimeError, child.objectName)
self.assertEqual(sys.getrefcount(child), 4)
@@ -81,6 +59,8 @@ class DeleteParentTest(unittest.TestCase):
grandchild = ObjectType(child)
del parent
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertRaises(RuntimeError, child.objectName)
self.assertEqual(sys.getrefcount(child), 2)
self.assertRaises(RuntimeError, grandchild.objectName)
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 e4a59426e..37b7591e4 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_after_use_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
'''Ownership tests for cases of invalidation of Python wrapper after use.'''
@@ -48,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__()
@@ -62,7 +37,7 @@ class MyObjectType (ObjectType):
self.callInvalidateEvent(ev)
try:
ev.eventType()
- except:
+ except: # noqa: E722
self.fail = True
raise
return True
@@ -70,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)
@@ -111,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 6ffa6629b..77b7c576c 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_child_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 for invalidating a C++ created child that was already on the care of a parent.'''
+import gc
import os
import sys
import unittest
@@ -67,10 +41,14 @@ class InvalidateChildTest(unittest.TestCase):
self.assertEqual(parent.children(), [])
del parent
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ # PYSIDE-535: Why do I need to do it twice, here?
+ gc.collect()
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 efc3afd38..8cbefc30c 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
'''The BlackBox class has cases of ownership transference between Python and C++.'''
@@ -42,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++.'''
@@ -54,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 d34eeedd2..c721a212c 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_invalidate_parent_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 for invalidating a parent of other objects.'''
@@ -61,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
@@ -70,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 0a5718429..304223063 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_reparenting_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 for object reparenting.'''
@@ -43,6 +16,7 @@ import sys
from sample import ObjectType
+
class ExtObjectType(ObjectType):
def __init__(self):
ObjectType.__init__(self)
@@ -135,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 9d9492e29..0e9f08b72 100644
--- a/sources/shiboken6/tests/samplebinding/ownership_transference_test.py
+++ b/sources/shiboken6/tests/samplebinding/ownership_transference_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
'''The BlackBox class has cases of ownership transference between C++ and Python.'''
+import gc
import os
import sys
import unittest
@@ -42,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.'''
@@ -55,16 +30,19 @@ 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)
del bb
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertRaises(RuntimeError, o1.objectName)
self.assertEqual(str(o2.objectName()), 'object2')
self.assertEqual(sys.getrefcount(o2), o2_refcnt)
@@ -72,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)
@@ -83,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 559f15ba2..4bd5c697c 100644
--- a/sources/shiboken6/tests/samplebinding/pair_test.py
+++ b/sources/shiboken6/tests/samplebinding/pair_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 std::pair container conversions'''
@@ -42,6 +15,7 @@ init_paths()
from sample import PairUser
+
class ExtendedPairUser(PairUser):
def __init__(self):
PairUser.__init__(self)
@@ -51,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'''
@@ -75,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)
@@ -98,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)
@@ -106,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 9cd1be2f6..106f3bd61 100644
--- a/sources/shiboken6/tests/samplebinding/pen_test.py
+++ b/sources/shiboken6/tests/samplebinding/pen_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 <add-function> with const char* as argument'''
@@ -42,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 457df0c16..f86c0f423 100644
--- a/sources/shiboken6/tests/samplebinding/point_test.py
+++ b/sources/shiboken6/tests/samplebinding/point_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 Point class'''
@@ -42,9 +15,15 @@ init_paths()
from sample import Point
+
class PointTest(unittest.TestCase):
'''Test case for Point class, including operator overloads.'''
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ return super().assertRaises(*args, **kwds)
+
def testConstructor(self):
'''Test Point class constructor.'''
pt = Point(5.0, 2.3)
@@ -114,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 d34ee7355..633525a9c 100644
--- a/sources/shiboken6/tests/samplebinding/pointerholder_test.py
+++ b/sources/shiboken6/tests/samplebinding/pointerholder_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 class that holds an arbitraty pointer and is modified to hold an PyObject.'''
@@ -42,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')
@@ -58,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 ad3bd899a..4da1a89c6 100644
--- a/sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py
+++ b/sources/shiboken6/tests/samplebinding/pointerprimitivetype_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
"""
pointerprimitivetype_test.py
@@ -54,8 +27,8 @@ from shiboken_paths import init_paths
init_paths()
from sample import IntArray2, VirtualMethods
-import shiboken6
-_init_pyside_extension() # trigger init, which does not happen in tests
+from shibokensupport.signature import get_signature
+
import typing
@@ -64,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
@@ -75,7 +48,7 @@ class PointerPrimitiveTypeTest(unittest.TestCase):
def testReturnVarSignature(self):
# signature="getMargins(int*,int*,int*,int*)const">
- ann = VirtualMethods.getMargins.__signature__.return_annotation
+ ann = get_signature(VirtualMethods.getMargins).return_annotation
self.assertEqual(ann, typing.Tuple[int, int, int, int])
diff --git a/sources/shiboken6/tests/samplebinding/pointf_test.py b/sources/shiboken6/tests/samplebinding/pointf_test.py
index 3b8285b0b..91c58eb1d 100644
--- a/sources/shiboken6/tests/samplebinding/pointf_test.py
+++ b/sources/shiboken6/tests/samplebinding/pointf_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 PointF class'''
@@ -42,6 +15,7 @@ init_paths()
from sample import PointF
+
class PointFTest(unittest.TestCase):
'''Test case for PointF class, including operator overloads.'''
@@ -72,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 26dd3046b..0b9fe2249 100644
--- a/sources/shiboken6/tests/samplebinding/primitivereferenceargument_test.py
+++ b/sources/shiboken6/tests/samplebinding/primitivereferenceargument_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -39,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)
@@ -52,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 b06c65944..63040388d 100644
--- a/sources/shiboken6/tests/samplebinding/privatector_test.py
+++ b/sources/shiboken6/tests/samplebinding/privatector_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 class with only a private constructor.'''
@@ -47,6 +20,11 @@ from sample import PrivateCtor
class PrivateCtorTest(unittest.TestCase):
'''Test case for PrivateCtor class'''
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ return super().assertRaises(*args, **kwds)
+
def testPrivateCtorInstanciation(self):
'''Test if instanciation of class with a private constructor raises an exception.'''
self.assertRaises(TypeError, PrivateCtor)
@@ -86,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 2f3b28069..651f63b15 100644
--- a/sources/shiboken6/tests/samplebinding/privatedtor_test.py
+++ b/sources/shiboken6/tests/samplebinding/privatedtor_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 class with a private destructor.'''
@@ -48,6 +21,11 @@ from sample import PrivateDtor
class PrivateDtorTest(unittest.TestCase):
'''Test case for PrivateDtor class'''
+ def assertRaises(self, *args, **kwds):
+ if not hasattr(sys, "pypy_version_info"):
+ # PYSIDE-535: PyPy complains "Fatal RPython error: NotImplementedError"
+ return super().assertRaises(*args, **kwds)
+
def testPrivateDtorInstanciation(self):
'''Test if instanciation of class with a private destructor raises an exception.'''
self.assertRaises(TypeError, PrivateDtor)
@@ -102,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 096eb615d..e4ccf721d 100644
--- a/sources/shiboken6/tests/samplebinding/protected_test.py
+++ b/sources/shiboken6/tests/samplebinding/protected_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 protected methods.'''
+import gc
import os
import sys
import unittest
@@ -42,46 +16,57 @@ 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.'''
def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(cacheSize(), 0)
def testProtectedCall(self):
@@ -105,10 +90,13 @@ 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.'''
def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(cacheSize(), 0)
def testProtectedCall(self):
@@ -132,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.'''
@@ -156,6 +146,8 @@ class ProtectedPolymorphicGrandDaugherTest(unittest.TestCase):
another with protected virtual methods.'''
def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(cacheSize(), 0)
def testProtectedCallWithInstanceCreatedOnCpp(self):
@@ -173,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.'''
@@ -180,6 +173,8 @@ class ProtectedVirtualDtorTest(unittest.TestCase):
ProtectedVirtualDestructor.resetDtorCounter()
def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(cacheSize(), 0)
def testVirtualProtectedDtor(self):
@@ -187,7 +182,11 @@ class ProtectedVirtualDtorTest(unittest.TestCase):
dtor_called = ProtectedVirtualDestructor.dtorCalled()
for i in range(1, 10):
pvd = ProtectedVirtualDestructor()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
del pvd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(ProtectedVirtualDestructor.dtorCalled(), dtor_called + i)
def testVirtualProtectedDtorOnCppCreatedObject(self):
@@ -196,6 +195,8 @@ class ProtectedVirtualDtorTest(unittest.TestCase):
for i in range(1, 10):
pvd = ProtectedVirtualDestructor.create()
del pvd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(ProtectedVirtualDestructor.dtorCalled(), dtor_called + i)
def testProtectedDtorOnDerivedClass(self):
@@ -204,25 +205,32 @@ class ProtectedVirtualDtorTest(unittest.TestCase):
for i in range(1, 10):
pvd = ExtendedProtectedVirtualDestructor()
del pvd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(ExtendedProtectedVirtualDestructor.dtorCalled(), dtor_called + i)
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.'''
def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(cacheSize(), 0)
def testProtectedMethodWithProtectedEnumArgument(self):
@@ -231,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):
@@ -282,6 +309,8 @@ class ProtectedPropertyTest(unittest.TestCase):
def tearDown(self):
del self.obj
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(cacheSize(), 0)
def testProtectedProperty(self):
@@ -323,6 +352,8 @@ class ProtectedPropertyTest(unittest.TestCase):
pointProperty = obj.protectedValueTypeProperty
self.assertTrue(obj.protectedValueTypeProperty is pointProperty)
del obj, point, pointProperty
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(cacheSize(), cache_size)
def testProtectedValueTypePointerProperty(self):
@@ -334,18 +365,24 @@ class ProtectedPropertyTest(unittest.TestCase):
self.assertEqual(self.obj.protectedValueTypePointerProperty, pt2)
self.assertTrue(self.obj.protectedValueTypePointerProperty is pt1)
self.assertFalse(self.obj.protectedValueTypePointerProperty is pt2)
+ # PYSIDE-535: Need to assign None to break the cycle
+ self.obj.protectedValueTypePointerProperty = None
def testProtectedObjectTypeProperty(self):
'''Writes and reads a protected object type property.'''
obj = ObjectType()
self.obj.protectedObjectTypeProperty = obj
self.assertEqual(self.obj.protectedObjectTypeProperty, obj)
+ # PYSIDE-535: Need to assign None to break the cycle
+ self.obj.protectedObjectTypeProperty = None
class PrivateDtorProtectedMethodTest(unittest.TestCase):
'''Test cases for classes with private destructors and protected methods.'''
def tearDown(self):
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(cacheSize(), 0)
def testProtectedMethod(self):
@@ -359,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 2d2ae5942..d60f9cf35 100644
--- a/sources/shiboken6/tests/samplebinding/pstrlist_test.py
+++ b/sources/shiboken6/tests/samplebinding/pstrlist_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -39,6 +12,7 @@ from shiboken_paths import init_paths
init_paths()
import sample
+
class PStrListTest(unittest.TestCase):
def testPStrList(self):
@@ -53,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 d19715e7c..ec64c1e31 100644
--- a/sources/shiboken6/tests/samplebinding/pystr_test.py
+++ b/sources/shiboken6/tests/samplebinding/pystr_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 definition of __str__ method.'''
@@ -42,6 +15,7 @@ init_paths()
from sample import Point
+
class PyStrTest(unittest.TestCase):
'''Test case for definition of __str__ method.'''
@@ -50,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 7b5b773e8..65398b5c6 100644
--- a/sources/shiboken6/tests/samplebinding/python_thread_test.py
+++ b/sources/shiboken6/tests/samplebinding/python_thread_test.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#!/usr/bin/env python
@@ -61,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}')
@@ -91,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'''
@@ -116,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 f8519165b..1d19de941 100644
--- a/sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py
+++ b/sources/shiboken6/tests/samplebinding/receive_null_cstring_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 a function that could receive a NULL pointer in a '[const] char*' parameter.'''
@@ -42,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.'''
@@ -56,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 4255f1921..1b6dd3a7a 100644
--- a/sources/shiboken6/tests/samplebinding/reference_test.py
+++ b/sources/shiboken6/tests/samplebinding/reference_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 methods that receive references to objects.'''
@@ -40,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):
@@ -75,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.'''
@@ -84,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)
@@ -115,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)
@@ -123,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 48893173b..942c7ea29 100644
--- a/sources/shiboken6/tests/samplebinding/referencetopointer_test.py
+++ b/sources/shiboken6/tests/samplebinding/referencetopointer_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 reference to pointer argument type.'''
@@ -42,6 +15,7 @@ init_paths()
from sample import VirtualMethods, Str
+
class ExtendedVirtualMethods(VirtualMethods):
def __init__(self):
VirtualMethods.__init__(self)
@@ -99,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 a31dceb35..b08438ef3 100644
--- a/sources/shiboken6/tests/samplebinding/renaming_test.py
+++ b/sources/shiboken6/tests/samplebinding/renaming_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 renaming using target-lang-name attribute.'''
@@ -43,6 +16,9 @@ init_paths()
from sample import RenamedValue, RenamedUser
+from shibokensupport.signature import get_signature
+
+
class RenamingTest(unittest.TestCase):
def test(self):
'''Tests whether the C++ class ToBeRenamedValue renamed via attribute
@@ -54,11 +30,10 @@ class RenamingTest(unittest.TestCase):
"<class 'sample.RenamedValue'>")
rename_user = RenamedUser()
rename_user.useRenamedValue(renamed_value)
- actual_signature = str(rename_user.useRenamedValue.__signature__)
+ actual_signature = str(get_signature(rename_user.useRenamedValue))
self.assertTrue(re.match(r"^\(self,\s*?v:\s*?sample.RenamedValue\)\s*?->\s*?None$",
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 3ca3f2731..2c4f07c65 100644
--- a/sources/shiboken6/tests/samplebinding/return_null_test.py
+++ b/sources/shiboken6/tests/samplebinding/return_null_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 functions that could return a NULL pointer.'''
@@ -40,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.'''
@@ -60,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 5a5fab646..3146d0faf 100644
--- a/sources/shiboken6/tests/samplebinding/richcompare_test.py
+++ b/sources/shiboken6/tests/samplebinding/richcompare_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -38,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):
@@ -49,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-binding.txt.in b/sources/shiboken6/tests/samplebinding/sample-binding.txt.in
index 317f76f09..bcf9de90f 100644
--- a/sources/shiboken6/tests/samplebinding/sample-binding.txt.in
+++ b/sources/shiboken6/tests/samplebinding/sample-binding.txt.in
@@ -13,3 +13,4 @@ typesystem-path = @CMAKE_CURRENT_SOURCE_DIR@
enable-parent-ctor-heuristic
use-isnull-as-nb_nonzero
+lean-headers
diff --git a/sources/shiboken6/tests/samplebinding/sample_test.py b/sources/shiboken6/tests/samplebinding/sample_test.py
index ec97658c8..19b2f708d 100644
--- a/sources/shiboken6/tests/samplebinding/sample_test.py
+++ b/sources/shiboken6/tests/samplebinding/sample_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 libsample bindings module'''
@@ -42,32 +15,10 @@ init_paths()
import sample
+
class ModuleTest(unittest.TestCase):
'''Test case for module and global functions'''
- 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)))
-
- 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)))
-
- 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'
@@ -80,6 +31,11 @@ class ModuleTest(unittest.TestCase):
self.assertEqual(sample.countVarargs(1, 2), 1)
self.assertEqual(sample.countVarargs(1, 2, 3, 'a', 'b', 4, (5, 6)), 6)
+ def testSampleComparisonOpInNamespace(self):
+ s1 = sample.sample.sample(10)
+ s2 = sample.sample.sample(10)
+ self.assertEqual(s1, s2)
+
def testConstant(self):
self.assertEqual(sample.sample.INT_CONSTANT, 42)
@@ -91,7 +47,30 @@ class ModuleTest(unittest.TestCase):
self.assertEqual(sample.addStdStrings(t1, t1), expected)
self.assertEqual(sample.addStdWStrings(t1, t1), expected)
+ def testNullPtrT(self):
+ 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/samplebinding.pyproject b/sources/shiboken6/tests/samplebinding/samplebinding.pyproject
new file mode 100644
index 000000000..ba6ba6f8f
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/samplebinding.pyproject
@@ -0,0 +1,131 @@
+{
+ "files": ["__del___test.py",
+ "abstract_test.py",
+ "addedfunction_test.py",
+ "addedfunction_with_container_args_test.py",
+ "argumentmodifications_test.py",
+ "array_numpy_test.py",
+ "array_sequence_test.py",
+ "bug_554_test.py",
+ "bug_704_test.py",
+ "bytearray_test.py",
+ "child_return_test.py",
+ "class_fields_test.py",
+ "collector_test.py",
+ "complex_test.py",
+ "conversion_operator_test.py",
+ "copy_test.py",
+ "ctorconvrule_test.py",
+ "cyclic_test.py",
+ "date_test.py",
+ "decisor_test.py",
+ "delete_test.py",
+ "deprecated_test.py",
+ "derived_test.py",
+ "duck_punching_test.py",
+ "echo_test.py",
+ "enum_test.py",
+ "enumfromremovednamespace_test.py",
+ "event_loop_call_virtual_test.py",
+ "event_loop_thread_test.py",
+ "exception_test.py",
+ "filter_test.py",
+ "handleholder_test.py",
+ "hashabletype_test.py",
+ "ignorederefop_test.py",
+ "implicitconv_numerical_test.py",
+ "implicitconv_test.py",
+ "inheritanceandscope_test.py",
+ "injectcode_test.py",
+ "innerclass_test.py",
+ "intlist_test.py",
+ "intwrapper_test.py",
+ "invalid_virtual_return_test.py",
+ "keep_reference_test.py",
+ "list_test.py",
+ "lock_test.py",
+ "map_test.py",
+ "metaclass_test.py",
+ "mi_virtual_methods_test.py",
+ "mixed_mi_test.py",
+ "modelindex_test.py",
+ "modelview_test.py",
+ "modifications_test.py",
+ "modified_constructor_test.py",
+ "modifiedvirtualmethods_test.py",
+ "multi_cpp_inheritance_test.py",
+ "multiple_derived_test.py",
+ "namespace_test.py",
+ "newdivision_test.py",
+ "nondefaultctor_test.py",
+ "nontypetemplate_test.py",
+ "nonzero_test.py",
+ "numericaltypedef_test.py",
+ "numpy_test.py",
+ "objecttype_test.py",
+ "objecttype_with_named_args_test.py",
+ "objecttypebyvalue_test.py",
+ "objecttypelayout_test.py",
+ "objecttypeoperators_test.py",
+ "objecttypereferenceasvirtualmethodargument_test.py",
+ "oddbool_test.py",
+ "onlycopyclass_test.py",
+ "overflow_test.py",
+ "overload_sorting_test.py",
+ "overload_test.py",
+ "overloadwithdefault_test.py",
+ "ownership_argument_invalidation_test.py",
+ "ownership_delete_child_in_cpp_test.py",
+ "ownership_delete_child_in_python_test.py",
+ "ownership_delete_parent_test.py",
+ "ownership_invalidate_after_use_test.py",
+ "ownership_invalidate_child_test.py",
+ "ownership_invalidate_nonpolymorphic_test.py",
+ "ownership_invalidate_parent_test.py",
+ "ownership_reparenting_test.py",
+ "ownership_transference_test.py",
+ "pair_test.py",
+ "pen_test.py",
+ "point_test.py",
+ "pointerholder_test.py",
+ "pointerprimitivetype_test.py",
+ "pointf_test.py",
+ "primitivereferenceargument_test.py",
+ "privatector_test.py",
+ "privatedtor_test.py",
+ "protected_test.py",
+ "pstrlist_test.py",
+ "pystr_test.py",
+ "python_thread_test.py",
+ "receive_null_cstring_test.py",
+ "reference_test.py",
+ "referencetopointer_test.py",
+ "renaming_test.py",
+ "return_null_test.py",
+ "richcompare_test.py",
+ "sample_test.py",
+ "samplesnippets.cpp",
+ "simplefile_glue.cpp",
+ "simplefile_test.py",
+ "size_test.py",
+ "snakecase_test.py",
+ "static_nonstatic_methods_test.py",
+ "str_test.py",
+ "strlist_test.py",
+ "templateinheritingclass_test.py",
+ "time_test.py",
+ "transform_test.py",
+ "typeconverters_test.py",
+ "typedealloc_test.py",
+ "typedtordoublefree_test.py",
+ "typesystypedef_test.py",
+ "unsafe_parent_test.py",
+ "useraddedctor_test.py",
+ "virtualdtor_test.py",
+ "virtualmethods_test.py",
+ "visibilitychange_test.py",
+ "voidholder_test.py",
+ "weakref_test.py",
+ "writableclassdict_test.py",
+ "typesystem_sample.xml"]
+}
diff --git a/sources/shiboken6/tests/samplebinding/samplesnippets.cpp b/sources/shiboken6/tests/samplebinding/samplesnippets.cpp
new file mode 100644
index 000000000..43e6b08de
--- /dev/null
+++ b/sources/shiboken6/tests/samplebinding/samplesnippets.cpp
@@ -0,0 +1,54 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+// @snippet intwrapper_add_ints
+extern "C" {
+static PyObject *Sbk_IntWrapper_add_ints(PyObject * /* self */, PyObject *args)
+{
+ PyObject *result = nullptr;
+ if (PyTuple_Check(args) != 0 && PyTuple_Size(args) == 2) {
+ PyObject *arg1 = PyTuple_GetItem(args, 0);
+ PyObject *arg2 = PyTuple_GetItem(args, 1);
+ if (PyLong_Check(arg1) != 0 && PyLong_Check(arg2) != 0)
+ result = PyLong_FromLong(PyLong_AsLong(arg1) + PyLong_AsLong(arg2));
+ }
+ if (result == nullptr)
+ PyErr_SetString(PyExc_TypeError, "expecting 2 ints");
+ return result;
+}
+}
+// @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_glue.cpp b/sources/shiboken6/tests/samplebinding/simplefile_glue.cpp
index bccd51534..76c0cfaf2 100644
--- a/sources/shiboken6/tests/samplebinding/simplefile_glue.cpp
+++ b/sources/shiboken6/tests/samplebinding/simplefile_glue.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
if (!%CPPSELF.%FUNCTION_NAME()) {
PyObject* error_msg = PyBytes_FromFormat(
diff --git a/sources/shiboken6/tests/samplebinding/simplefile_test.py b/sources/shiboken6/tests/samplebinding/simplefile_test.py
index 1f5561f77..55c894a35 100644
--- a/sources/shiboken6/tests/samplebinding/simplefile_test.py
+++ b/sources/shiboken6/tests/samplebinding/simplefile_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 SimpleFile class'''
@@ -42,6 +15,7 @@ init_paths()
from sample import SimpleFile
+
class SimpleFileTest(unittest.TestCase):
'''Test cases for SimpleFile class.'''
@@ -81,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 4df438e2b..069ce59b3 100644
--- a/sources/shiboken6/tests/samplebinding/size_test.py
+++ b/sources/shiboken6/tests/samplebinding/size_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 operator overloads on Size class'''
@@ -42,6 +15,7 @@ init_paths()
from sample import Size
+
class PointTest(unittest.TestCase):
'''Test case for Size class, including operator overloads.'''
@@ -121,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/snakecase_test.py b/sources/shiboken6/tests/samplebinding/snakecase_test.py
index 2147b2c5b..a1538796a 100644
--- a/sources/shiboken6/tests/samplebinding/snakecase_test.py
+++ b/sources/shiboken6/tests/samplebinding/snakecase_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2020 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 snake case generation'''
diff --git a/sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py b/sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py
index 200b0e4c0..cf0889299 100644
--- a/sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py
+++ b/sources/shiboken6/tests/samplebinding/static_nonstatic_methods_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 overloads involving static and non-static versions of a method.'''
@@ -42,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.'''
@@ -106,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 a2c092bb8..c06fd6428 100644
--- a/sources/shiboken6/tests/samplebinding/str_test.py
+++ b/sources/shiboken6/tests/samplebinding/str_test.py
@@ -1,35 +1,9 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
-
-'''Test cases for a method that receives a reference to class that is implicitly convertible from a Python native type.'''
+# 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.'''
import os
import sys
@@ -42,6 +16,7 @@ init_paths()
from sample import Str
+
class StrTest(unittest.TestCase):
'''Test cases for thr Str class.'''
@@ -58,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))
@@ -117,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 c3eb02b8e..2bfb80b67 100644
--- a/sources/shiboken6/tests/samplebinding/strlist_test.py
+++ b/sources/shiboken6/tests/samplebinding/strlist_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 StrList class that inherits from std::list<Str>.'''
@@ -42,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>.'''
@@ -115,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 f0bb1f762..11279c7ec 100644
--- a/sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py
+++ b/sources/shiboken6/tests/samplebinding/templateinheritingclass_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -41,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):
@@ -84,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 5fa36621d..6283a6744 100644
--- a/sources/shiboken6/tests/samplebinding/time_test.py
+++ b/sources/shiboken6/tests/samplebinding/time_test.py
@@ -1,37 +1,9 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 constructor and method signature decisor on Time class.'''
-import sys
import os
import sys
import unittest
@@ -44,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
@@ -142,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 5d55d9d77..7dfd18a4a 100644
--- a/sources/shiboken6/tests/samplebinding/transform_test.py
+++ b/sources/shiboken6/tests/samplebinding/transform_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 argument modification with more than nine arguments.'''
@@ -42,6 +15,7 @@ init_paths()
from sample import Point, applyHomogeneousTransform
+
class TransformTest(unittest.TestCase):
'''Test cases for modifying a function with > 9 arguments.'''
@@ -59,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 141da0860..987ba6dfd 100644
--- a/sources/shiboken6/tests/samplebinding/typeconverters_test.py
+++ b/sources/shiboken6/tests/samplebinding/typeconverters_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 various usages of the type converters.'''
@@ -42,6 +15,7 @@ init_paths()
import sample
+
class GetPythonTypeByNameTest(unittest.TestCase):
'''Uses an added function with inject code that uses the libshiboken
@@ -186,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 32a15e300..ce881e802 100644
--- a/sources/shiboken6/tests/samplebinding/typedealloc_test.py
+++ b/sources/shiboken6/tests/samplebinding/typedealloc_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 deallocation of type extended in Python.'''
@@ -52,18 +25,24 @@ class TypeDeallocTest(unittest.TestCase):
def tearDown(self):
del self.called
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
def callback(self, *args):
self.called = True
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)
@@ -71,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)
@@ -79,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 983633a7f..ab8e535b5 100644
--- a/sources/shiboken6/tests/samplebinding/typedtordoublefree_test.py
+++ b/sources/shiboken6/tests/samplebinding/typedtordoublefree_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -39,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.'''
@@ -49,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 aa3c60975..e315e599e 100644
--- a/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
+++ b/sources/shiboken6/tests/samplebinding/typesystem_sample.xml
@@ -1,11 +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>
@@ -73,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>
@@ -83,6 +81,7 @@
</native-to-target>
<target-to-native>
<add-conversion type="PyNone">
+ SBK_UNUSED(%in)
%out = 0;
</add-conversion>
<add-conversion check="checkPyCapsuleOrPyCObject(%in)" type="PyObject">
@@ -151,6 +150,9 @@
<add-function signature="operator==(const ComparisonTester&amp;)" return-type="bool"/>
<add-function signature="operator!=(const ComparisonTester&amp;)" return-type="bool"/>
</value-type>
+ <value-type name="SpaceshipComparisonTester">
+ <enum-type name="Enabled"/>
+ </value-type>
<primitive-type name="PStr">
<include file-name="str.h" location="global"/>
@@ -164,6 +166,7 @@
%out = %OUTTYPE(str);
</add-conversion>
<add-conversion type="Py_None">
+ SBK_UNUSED(%in)
%out = %OUTTYPE();
</add-conversion>
</target-to-native>
@@ -252,6 +255,7 @@
<add-function signature="getPythonType(const char*)" return-type="PyObject">
<inject-code class="target" position="beginning">
+ SBK_UNUSED(self)
%PYARG_0 = (PyObject*) Shiboken::Conversions::getPythonTypeObject(%1);
if (!%PYARG_0)
%PYARG_0 = Py_None;
@@ -347,24 +351,7 @@
</inject-code>
</add-function>
- <container-type name="std::pair" type="pair">
- <include file-name="utility" location="global"/>
- <conversion-rule>
- <native-to-target>
- PyObject* %out = PyTuple_New(2);
- PyTuple_SET_ITEM(%out, 0, %CONVERTTOPYTHON[%INTYPE_0](%in.first));
- PyTuple_SET_ITEM(%out, 1, %CONVERTTOPYTHON[%INTYPE_1](%in.second));
- return %out;
- </native-to-target>
- <target-to-native>
- <add-conversion type="PySequence">
- %out.first = %CONVERTTOCPP[%OUTTYPE_0](PySequence_Fast_GET_ITEM(%in, 0));
- %out.second = %CONVERTTOCPP[%OUTTYPE_1](PySequence_Fast_GET_ITEM(%in, 1));
- </add-conversion>
- </target-to-native>
- </conversion-rule>
- </container-type>
- <template name="cpplist_to_pylist_convertion">
+ <template name="cpp_indexed_list_to_pylist_conversion">
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) {
@@ -373,70 +360,19 @@
}
return %out;
</template>
- <template name="pyseq_to_cpplist_convertion">
- Shiboken::AutoDecRef seq(PySequence_Fast(%in, 0));
- const Py_ssize_t size = PySequence_Fast_GET_SIZE(seq.object());
- for (Py_ssize_t i = 0; i &lt; size; ++i) {
- PyObject* pyItem = PySequence_Fast_GET_ITEM(seq.object(), i);
- %OUTTYPE_0 cppItem = %CONVERTTOCPP[%OUTTYPE_0](pyItem);
- %out.push_back(cppItem);
- }
- </template>
- <container-type name="std::list" type="list">
- <include file-name="list" location="global"/>
- <conversion-rule>
- <native-to-target>
- <insert-template name="cpplist_to_pylist_convertion"/>
- </native-to-target>
- <target-to-native>
- <add-conversion type="PySequence">
- <insert-template name="pyseq_to_cpplist_convertion"/>
- </add-conversion>
- </target-to-native>
- </conversion-rule>
- </container-type>
<container-type name="List" type="list">
<include file-name="list" location="global"/>
<conversion-rule>
<native-to-target>
- <insert-template name="cpplist_to_pylist_convertion"/>
+ <insert-template name="cpp_indexed_list_to_pylist_conversion"/>
</native-to-target>
<target-to-native>
<add-conversion type="PySequence">
- <insert-template name="pyseq_to_cpplist_convertion"/>
+ <insert-template name="shiboken_conversion_pyiterable_to_cppsequentialcontainer"/>
</add-conversion>
</target-to-native>
</conversion-rule>
</container-type>
- <container-type name="std::map" type="map">
- <include file-name="map" location="global"/>
- <conversion-rule>
- <native-to-target>
- PyObject* %out = PyDict_New();
- for (auto it = %in.cbegin(), end = %in.cend(); it != 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({cppKey, cppValue});
- }
- </add-conversion>
- </target-to-native>
- </conversion-rule>
- </container-type>
-
<add-function signature="cacheSize()" return-type="int">
<inject-code class="target">
%RETURN_TYPE %0 = Shiboken::BindingManager::instance().getAllPyObjects().size();
@@ -461,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)" />
@@ -481,6 +418,9 @@
<function signature="overloadedFunc(int)" />
<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*)">
@@ -489,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"/>
@@ -517,6 +457,10 @@
<enum-type identified-by-value="AnonymousGlobalEnum_Value0"/>
<namespace-type name="SampleNamespace">
+ <namespace-type name="InlineNamespace">
+ <value-type name="ClassWithinInlineNamespace"/>
+ <enum-type name="EnumWithinInlineNamespace"/>
+ </namespace-type>
<enum-type name="Option"/>
<enum-type name="InValue"/>
<enum-type name="OutValue"/>
@@ -541,8 +485,12 @@
<modify-function signature="doSomethingWithArray(const unsigned char*, unsigned int, const char*)">
<modify-argument index="1">
<replace-type modified-type="const char*"/>
- <conversion-rule class="native">
- const unsigned char* %out = reinterpret_cast&lt;const unsigned char*>(Shiboken::String::toCString(%PYARG_1));
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion>
+ const unsigned char* %out = reinterpret_cast&lt;const unsigned char*>(Shiboken::String::toCString(%PYARG_1));
+ </add-conversion>
+ </target-to-native>
</conversion-rule>
</modify-argument>
<modify-argument index="2">
@@ -623,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">
@@ -644,7 +600,7 @@
</modify-function>
</object-type>
- <object-type name="ObjectType" hash-function="objectTypeHash">
+ <object-type name="ObjectType" hash-function="objectTypeHash" parent-management="yes">
<modify-function signature="deprecatedFunction()" deprecated="yes" />
<!-- rename function to avoid Python signature conflit -->
<modify-function signature="setObject(const Null&amp;)" rename="setNullObject" />
@@ -685,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
@@ -773,7 +729,7 @@
</modify-function>
</object-type>
- <value-type name="ObjectTypeHolder"/>
+ <object-type name="ObjectTypeHolder"/>
<value-type name="OnlyCopy"/>
<value-type name="FriendOfOnlyCopy"/>
@@ -1166,14 +1122,14 @@
<modify-argument index="1">
<remove-argument/>
<conversion-rule class="native">
- int %out = PySequence_Size(%PYARG_1);
+ const auto %out = PySequence_Size(%PYARG_1);
</conversion-rule>
</modify-argument>
<modify-argument index="2">
<replace-type modified-type="PySequence" />
<conversion-rule class="native">
Shiboken::AutoArrayPointer&lt;Point&gt; %out(%1);
- for (int i = 0; i &lt; %1; ++i)
+ for (Py_ssize_t i = 0; i &lt; %1; ++i)
%out[i] = %CONVERTTOCPP[Point](PySequence_Fast_GET_ITEM(%PYARG_1, i));
</conversion-rule>
</modify-argument>
@@ -1216,14 +1172,18 @@
</modify-argument>
<modify-argument index="return">
<replace-type modified-type="PySequence"/>
- <conversion-rule class="native">
- Shiboken::AutoDecRef _py_ok_(PySequence_GetItem(%PYARG_0, 0));
- Shiboken::AutoDecRef _py_ret_(PySequence_GetItem(%PYARG_0, 1));
- *%2 = %CONVERTTOCPP[bool](_py_ok_);
- %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](_py_ret_);
- </conversion-rule>
- <conversion-rule class="target">
- <insert-template name="differenceOfPointCoordinates_returnTarget"/>
+ <conversion-rule>
+ <target-to-native>
+ <add-conversion>
+ Shiboken::AutoDecRef _py_ok_(PySequence_GetItem(%PYARG_0, 0));
+ Shiboken::AutoDecRef _py_ret_(PySequence_GetItem(%PYARG_0, 1));
+ *%2 = %CONVERTTOCPP[bool](_py_ok_);
+ %RETURN_TYPE %out = %CONVERTTOCPP[%RETURN_TYPE](_py_ret_);
+ </add-conversion>
+ </target-to-native>
+ <native-to-target>
+ <insert-template name="differenceOfPointCoordinates_returnTarget"/>
+ </native-to-target>
</conversion-rule>
</modify-argument>
</modify-function>
@@ -1440,7 +1400,7 @@
}
</template>
<modify-function signature="getMargins(int*,int*,int*,int*)const">
- <modify-argument index="0">
+ <modify-argument index="return" pyi-type="Tuple[int, int, int, int]">
<replace-type modified-type="PyObject" />
</modify-argument>
<modify-argument index="1">
@@ -1617,15 +1577,15 @@
<modify-argument index="1">
<remove-argument/>
<conversion-rule class="native">
- int %out = PySequence_Size(%PYARG_1);
+ const auto %out = PySequence_Size(%PYARG_1);
</conversion-rule>
</modify-argument>
<modify-argument index="2">
<replace-type modified-type="PySequence"/>
<conversion-rule class="native">
- int numItems = PySequence_Size(%PYARG_1);
+ const auto numItems = PySequence_Size(%PYARG_1);
Shiboken::AutoArrayPointer&lt;int&gt; %out(numItems);
- for (int i = 0; i &lt; numItems; ++i) {
+ for (Py_ssize_t i = 0; i &lt; numItems; ++i) {
if (%CHECKTYPE[int](PySequence_Fast_GET_ITEM(%PYARG_1, i)))
%out[i] = %CONVERTTOCPP[int](PySequence_Fast_GET_ITEM(%PYARG_1, i));
else if (%ISCONVERTIBLE[int](PySequence_Fast_GET_ITEM(%PYARG_1, i)))
@@ -1942,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"/>
@@ -1999,6 +1959,9 @@
}
}
}
+ // PySIDE-1735: Enums are now implemented in Python, so we need to avoid asserts.
+ if (PyErr_Occurred())
+ break;
const char** %out = 0;
</conversion-rule>
</modify-argument>
@@ -2047,7 +2010,12 @@
<object-type name="Collector" stream="yes"/>
- <value-type name="IntWrapper" />
+ <value-type name="IntWrapper">
+ <inject-code class="native" position="beginning"
+ file="samplesnippets.cpp" snippet="intwrapper_add_ints"/>
+ <add-pymethoddef name="add_ints" function="Sbk_IntWrapper_add_ints"
+ flags="METH_VARARGS"/>
+ </value-type>
<value-type name="Str" hash-function="strHash">
<add-function signature="__str__" return-type="PyObject*">
@@ -2105,6 +2073,7 @@
<conversion-rule>
<target-to-native>
<add-conversion type="Py_None">
+ SBK_UNUSED(%in)
%out = %OUTTYPE();
</add-conversion>
<add-conversion type="PyObject" check="Shiboken::String::check(%in) || PyBytes_Check(%in)">
@@ -2256,19 +2225,20 @@
</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" />
<object-type name="PrivateCtor" />
<object-type name="PrivateDtor" />
+ <value-type name="DeletedDefaultCtor"/>
<object-type name="Base1"/>
<object-type name="Base2"/>
@@ -2409,15 +2379,24 @@
<value-type name="Expression" />
- <object-type name="ExceptionTest" exception-handling="auto-on"/>
-
- <value-type name="ModelIndex" />
- <value-type name="ReferentModelIndex">
- <modify-function signature="operator const ModelIndex&amp;()const">
+ <object-type name="ExceptionTest" exception-handling="auto-on">
+ <modify-function signature="create(bool)">
<modify-argument index="return">
<define-ownership owner="c++"/>
</modify-argument>
+ <inject-code class="target" position="end">
+ // Test comment
+ </inject-code>
</modify-function>
+ </object-type>
+
+ <value-type name="ModelIndex" />
+ <value-type name="ReferentModelIndex">
+ <modify-function signature="operator const ModelIndex&amp;()const">
+ <modify-argument index="return">
+ <define-ownership owner="c++"/>
+ </modify-argument>
+ </modify-function>
</value-type>
<value-type name="PersistentModelIndex" />
@@ -2430,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>
@@ -2445,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 70c22f657..f7f5342ee 100644
--- a/sources/shiboken6/tests/samplebinding/typesystypedef_test.py
+++ b/sources/shiboken6/tests/samplebinding/typesystypedef_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2020 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 a class that holds a void pointer.'''
@@ -40,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 ab9895f1f..2a7e5cac7 100644
--- a/sources/shiboken6/tests/samplebinding/unsafe_parent_test.py
+++ b/sources/shiboken6/tests/samplebinding/unsafe_parent_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 ...'''
@@ -42,6 +15,7 @@ init_paths()
from sample import ObjectType
+
class DerivedObjectType(ObjectType):
def isPython(self):
return True
@@ -49,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 910037cd5..45d4095b6 100644
--- a/sources/shiboken6/tests/samplebinding/useraddedctor_test.py
+++ b/sources/shiboken6/tests/samplebinding/useraddedctor_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 user added constructors'''
@@ -39,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 8f29eca3c..6be870269 100644
--- a/sources/shiboken6/tests/samplebinding/virtualdtor_test.py
+++ b/sources/shiboken6/tests/samplebinding/virtualdtor_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 virtual destructor.'''
+import gc
import os
import sys
import unittest
@@ -42,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.'''
@@ -58,6 +34,8 @@ class VirtualDtorTest(unittest.TestCase):
for i in range(1, 10):
vd = VirtualDtor()
del vd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(VirtualDtor.dtorCalled(), dtor_called + i)
def testVirtualDtorOnCppCreatedObject(self):
@@ -66,6 +44,8 @@ class VirtualDtorTest(unittest.TestCase):
for i in range(1, 10):
vd = VirtualDtor.create()
del vd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(VirtualDtor.dtorCalled(), dtor_called + i)
def testDtorOnDerivedClass(self):
@@ -74,9 +54,10 @@ class VirtualDtorTest(unittest.TestCase):
for i in range(1, 10):
evd = ExtendedVirtualDtor()
del evd
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(ExtendedVirtualDtor.dtorCalled(), dtor_called + i)
if __name__ == '__main__':
unittest.main()
-
diff --git a/sources/shiboken6/tests/samplebinding/virtualmethods_test.py b/sources/shiboken6/tests/samplebinding/virtualmethods_test.py
index 1c842993c..52dc66c90 100644
--- a/sources/shiboken6/tests/samplebinding/virtualmethods_test.py
+++ b/sources/shiboken6/tests/samplebinding/virtualmethods_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 virtual methods.'''
+import gc
import os
import sys
import unittest
@@ -40,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)
@@ -62,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)
@@ -71,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)
@@ -80,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'''
@@ -88,9 +66,12 @@ class VirtualMethodsTest(unittest.TestCase):
def tearDown(self):
del self.prefix_from_codeinjection
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ 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)
@@ -144,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 918d957b2..becdf7423 100644
--- a/sources/shiboken6/tests/samplebinding/visibilitychange_test.py
+++ b/sources/shiboken6/tests/samplebinding/visibilitychange_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -38,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 da4042a98..186cb473e 100644
--- a/sources/shiboken6/tests/samplebinding/voidholder_test.py
+++ b/sources/shiboken6/tests/samplebinding/voidholder_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 a class that holds a void pointer.'''
@@ -43,6 +16,7 @@ init_paths()
from sample import VoidHolder, Point
from shiboken6 import Shiboken
+
class VoidHolderTest(unittest.TestCase):
'''Test case for void pointer manipulation.'''
@@ -71,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 6ca031c0d..01c6d58d5 100644
--- a/sources/shiboken6/tests/samplebinding/weakref_test.py
+++ b/sources/shiboken6/tests/samplebinding/weakref_test.py
@@ -1,36 +1,10 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 weakref support'''
+import gc
import os
import sys
import unittest
@@ -56,15 +30,19 @@ 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()
self.assertTrue(self.called)
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()
self.assertTrue(self.called)
diff --git a/sources/shiboken6/tests/samplebinding/writableclassdict_test.py b/sources/shiboken6/tests/samplebinding/writableclassdict_test.py
index b7668e497..dfc962db9 100644
--- a/sources/shiboken6/tests/samplebinding/writableclassdict_test.py
+++ b/sources/shiboken6/tests/samplebinding/writableclassdict_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -40,7 +13,10 @@ init_paths()
from sample import Point
-class ExtPoint(Point): pass
+
+class ExtPoint(Point):
+ pass
+
class TestWritableClassDict(unittest.TestCase):
def testSetattrOnClass(self):
@@ -56,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/shiboken_paths.py b/sources/shiboken6/tests/shiboken_paths.py
index c829c0ab9..3ec940f2e 100644
--- a/sources/shiboken6/tests/shiboken_paths.py
+++ b/sources/shiboken6/tests/shiboken_paths.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2020 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
diff --git a/sources/shiboken6/tests/shiboken_test_helper.py b/sources/shiboken6/tests/shiboken_test_helper.py
index 793baf4ad..14fe6a2d1 100644
--- a/sources/shiboken6/tests/shiboken_test_helper.py
+++ b/sources/shiboken6/tests/shiboken_test_helper.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2019 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
def objectFullname(t):
diff --git a/sources/shiboken6/tests/shibokenmodule/module_test.py b/sources/shiboken6/tests/shibokenmodule/module_test.py
index f75d28c3b..9f9f8f5a4 100644
--- a/sources/shiboken6/tests/shibokenmodule/module_test.py
+++ b/sources/shiboken6/tests/shibokenmodule/module_test.py
@@ -1,30 +1,5 @@
-#############################################################################
-##
-## Copyright (C) 2016 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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 os
import sys
@@ -32,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()))
@@ -68,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))
@@ -80,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)
@@ -94,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 637420651..594744840 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
@@ -13,18 +16,40 @@ ${CMAKE_CURRENT_BINARY_DIR}/smart/sharedptr_integer_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/registry_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/smart_integer2_wrapper.cpp
${CMAKE_CURRENT_BINARY_DIR}/smart/sharedptr_integer2_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/stdsharedptrtestbench_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/stdsharedptrvirtualmethodtester_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_shared_ptr_double_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
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_unique_ptr_integer_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_unique_ptr_integer2_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/std_unique_ptr_int_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/stdoptionaltestbench_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/stduniqueptrtestbench_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/stduniqueptrvirtualmethodtester_wrapper.cpp
+${CMAKE_CURRENT_BINARY_DIR}/smart/test_wrapper.cpp
)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/smart-binding.txt.in"
"${CMAKE_CURRENT_BINARY_DIR}/smart-binding.txt" @ONLY)
+shiboken_get_tool_shell_wrapper(shiboken tool_wrapper)
+
add_custom_command(
-OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
-BYPRODUCTS ${smart_SRC}
-COMMAND shiboken6 --project-file=${CMAKE_CURRENT_BINARY_DIR}/smart-binding.txt ${GENERATOR_EXTRA_FLAGS}
-DEPENDS ${smart_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h shiboken6
-WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-COMMENT "Running generator for 'smart' test binding..."
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log"
+ BYPRODUCTS ${smart_SRC}
+ COMMAND
+ ${tool_wrapper}
+ $<TARGET_FILE:Shiboken6::shiboken6>
+ --project-file=${CMAKE_CURRENT_BINARY_DIR}/smart-binding.txt
+ ${GENERATOR_EXTRA_FLAGS}
+ DEPENDS ${smart_TYPESYSTEM} ${CMAKE_CURRENT_SOURCE_DIR}/global.h Shiboken6::shiboken6
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ COMMENT "Running generator for 'smart' test binding..."
)
add_library(smart MODULE ${smart_SRC})
diff --git a/sources/shiboken6/tests/smartbinding/global.h b/sources/shiboken6/tests/smartbinding/global.h
index 959859b40..5bec15063 100644
--- a/sources/shiboken6/tests/smartbinding/global.h
+++ b/sources/shiboken6/tests/smartbinding/global.h
@@ -1,29 +1,4 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include "smart.h"
diff --git a/sources/shiboken6/tests/smartbinding/smart-binding.txt.in b/sources/shiboken6/tests/smartbinding/smart-binding.txt.in
index 699f0bfe6..a2c73c6bf 100644
--- a/sources/shiboken6/tests/smartbinding/smart-binding.txt.in
+++ b/sources/shiboken6/tests/smartbinding/smart-binding.txt.in
@@ -13,3 +13,4 @@ typesystem-path = @CMAKE_CURRENT_SOURCE_DIR@
enable-parent-ctor-heuristic
use-isnull-as-nb_nonzero
+lean-headers
diff --git a/sources/shiboken6/tests/smartbinding/smart_pointer_test.py b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py
index 1bdce333e..8d4272558 100644
--- a/sources/shiboken6/tests/smartbinding/smart_pointer_test.py
+++ b/sources/shiboken6/tests/smartbinding/smart_pointer_test.py
@@ -1,33 +1,6 @@
#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#############################################################################
-##
-## Copyright (C) 2017 The Qt Company Ltd.
-## Contact: https://www.qt.io/licensing/
-##
-## This file is part of the test suite of Qt for Python.
-##
-## $QT_BEGIN_LICENSE:GPL-EXCEPT$
-## Commercial License Usage
-## Licensees holding valid commercial Qt licenses may use this file in
-## accordance with the commercial license agreement provided with the
-## Software or, alternatively, in accordance with the terms contained in
-## a written agreement between you and The Qt Company. For licensing terms
-## and conditions see https://www.qt.io/terms-conditions. For further
-## information use the contact form at https://www.qt.io/contact-us.
-##
-## GNU General Public License Usage
-## Alternatively, this file may be used under the terms of the GNU
-## General Public License version 3 as published by the Free Software
-## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-## included in the packaging of this file. Please review the following
-## information to ensure the GNU General Public License requirements will
-## be met: https://www.gnu.org/licenses/gpl-3.0.html.
-##
-## $QT_END_LICENSE$
-##
-#############################################################################
+# 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
@@ -39,32 +12,49 @@ sys.path.append(os.fspath(Path(__file__).resolve().parents[1]))
from shiboken_paths import init_paths
init_paths()
from copy import copy
-from smart import Obj, Registry, Integer
+from smart import (Obj, Registry, Integer, SharedPtr_Integer, std)
+
def objCount():
return Registry.getInstance().countObjects()
+
def integerCount():
return Registry.getInstance().countIntegers()
+
+def integerFromValue(v):
+ result = Integer()
+ result.setValue(v)
+ return result
+
+
class SmartPointerTests(unittest.TestCase):
- def testObjSmartPointer(self):
- # Uncomment to see more debug info about creation of objects and ref counts.
- # Registry.getInstance().setShouldPrint(True)
+ def setUp(self):
+ super().setUp()
+ if os.environ.get("VERBOSE"):
+ Registry.getInstance().setVerbose(True)
+
+ def testObjSmartPointer(self):
# Create Obj.
o = Obj()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(objCount(), 1)
# Create a shared pointer to an Obj together with an Obj.
- ptrToObj = o.giveSharedPtrToObj()
+ ptrToObj = o.createSharedPtrObj()
self.assertEqual(objCount(), 2)
# Delete the old Obj.
o = None
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(objCount(), 1)
- # Get a wrapper to the Obj inside of the shared pointer, object count should not change.
+ # Get a wrapper to the Obj inside of the shared pointer, object count
+ # should not change.
obj = ptrToObj.data()
self.assertEqual(objCount(), 1)
obj.m_integer = 50
@@ -74,12 +64,13 @@ class SmartPointerTests(unittest.TestCase):
ptrToObj.m_integer = 100
self.assertEqual(ptrToObj.m_integer, 100)
- # Get inner PyObject via shared pointer (like operator->) and set value in it.
+ # Get inner PyObject via shared pointer (like operator->) and set
+ # value in it.
ptrToObj.m_internalInteger.m_int = 200
self.assertEqual(ptrToObj.m_internalInteger.m_int, 200)
- # Pass smart pointer as argument to a method, return value is the value of m_integer of
- # passed Obj inside the smart pointer.
+ # Pass smart pointer as argument to a method, return value is the value
+ # of m_integer of passed Obj inside the smart pointer.
result = ptrToObj.takeSharedPtrToObj(ptrToObj)
self.assertEqual(result, 100)
@@ -89,38 +80,42 @@ class SmartPointerTests(unittest.TestCase):
result = None
if integerCount() > 1:
gc.collect()
- print('Running garbage collector for reference test', file=sys.stderr)
+ print('Running garbage collector for reference test',
+ file=sys.stderr)
self.assertEqual(integerCount(), 1)
# Make a copy of the shared pointer, object count should not change.
ptrToObj2 = copy(ptrToObj)
self.assertEqual(objCount(), 1)
- # Delete the first shared pointer, object count should not change because the second
- # one still has a reference.
+ # Delete the first shared pointer, object count should not change
+ # because the second one still has a reference.
del ptrToObj
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(objCount(), 1)
# Delete the second smart pointer, object should be deleted.
del ptrToObj2
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(objCount(), 0)
self.assertEqual(integerCount(), 0)
def testIntegerSmartPointer(self):
- # Uncomment to see more debug info about creation of objects and ref counts.
- # Registry.getInstance().setShouldPrint(True)
-
# Create Obj.
o = Obj()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(objCount(), 1)
# Create a shared pointer to an Integer together with an Integer.
- ptrToInteger = o.giveSharedPtrToInteger()
+ ptrToInteger = o.createSharedPtrInteger()
self.assertEqual(objCount(), 1)
self.assertEqual(integerCount(), 2)
- # Get a wrapper to the Integer inside of the shared pointer, integer count should not
- # change.
+ # Get a wrapper to the Integer inside of the shared pointer, integer
+ # count should not change.
integer = ptrToInteger.data()
self.assertEqual(integerCount(), 2)
integer.m_int = 50
@@ -134,8 +129,8 @@ class SmartPointerTests(unittest.TestCase):
ptrToInteger.m_int = 100
self.assertEqual(ptrToInteger.m_int, 100)
- # Pass smart pointer as argument to a method, return value is the value of m_int of
- # passed Integer inside the smart pointer.
+ # Pass smart pointer as argument to a method, return value is the
+ # value of m_int of passed Integer inside the smart pointer.
result = o.takeSharedPtrToInteger(ptrToInteger)
self.assertEqual(result, 100)
@@ -143,28 +138,31 @@ class SmartPointerTests(unittest.TestCase):
ptrToInteger2 = copy(ptrToInteger)
self.assertEqual(integerCount(), 2)
- # Delete the first shared pointer, integer count should not change because the second
- # one still has a reference.
+ # Delete the first shared pointer, integer count should not change
+ # because the second one still has a reference.
del ptrToInteger
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(integerCount(), 2)
# Delete the second smart pointer, integer should be deleted.
del ptrToInteger2
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(objCount(), 1)
self.assertEqual(integerCount(), 1)
# Delete the original object which was used to create the integer.
del o
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(objCount(), 0)
self.assertEqual(integerCount(), 0)
def testConstIntegerSmartPointer(self):
- # Uncomment to see more debug info about creation of objects and ref counts.
- # Registry.getInstance().setShouldPrint(True)
-
# Create Obj.
o = Obj()
- ptrToConstInteger = o.giveSharedPtrToConstInteger()
+ ptrToConstInteger = o.createSharedPtrConstInteger()
self.assertEqual(ptrToConstInteger.m_int, 456)
result = o.takeSharedPtrToConstInteger(ptrToConstInteger)
self.assertEqual(result, 456)
@@ -173,10 +171,12 @@ class SmartPointerTests(unittest.TestCase):
def testSmartPointersWithNamespace(self):
# Create the main object
o = Obj()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(objCount(), 1)
# Create a shared pointer to an Integer together with an Integer.
- ptrToInteger = o.giveSharedPtrToInteger2()
+ ptrToInteger = o.createSharedPtrInteger2()
self.assertEqual(objCount(), 1)
self.assertEqual(integerCount(), 2)
@@ -188,17 +188,25 @@ class SmartPointerTests(unittest.TestCase):
o = Obj()
# Create a list of shared objects
- ptrToObjList = o.giveSharedPtrToObjList(10)
+ ptrToObjList = o.createSharedPtrObjList(10)
self.assertEqual(len(ptrToObjList), 10)
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(objCount(), 11)
# Remove one from the list
ptrToObjList.pop()
self.assertEqual(len(ptrToObjList), 9)
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
+ # PYSIDE-535: Why do I need to do it twice, here?
+ gc.collect()
self.assertEqual(objCount(), 10)
# clear and delete all objects in the list
del ptrToObjList[:] # Python 2.7 lists have no clear method
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(len(ptrToObjList), 0)
self.assertEqual(objCount(), 1)
@@ -206,7 +214,7 @@ class SmartPointerTests(unittest.TestCase):
# Create Obj.
o = Obj()
# Create a shared pointer to an Obj together with an Obj.
- ptrToObj = o.giveSharedPtrToObj()
+ ptrToObj = o.createSharedPtrObj()
try:
ptrToObj.typo
self.assertFail()
@@ -216,16 +224,79 @@ class SmartPointerTests(unittest.TestCase):
def testSmartPointerConversions(self):
# Create Obj.
o = Obj()
+ # PYSIDE-535: Need to collect garbage in PyPy to trigger deletion
+ gc.collect()
self.assertEqual(objCount(), 1)
self.assertEqual(integerCount(), 1)
# Create a shared pointer to an Integer2
- integer2 = o.giveSharedPtrToInteger2()
+ integer2 = o.createSharedPtrInteger2()
+ # User defined name
+ self.assertEqual(type(integer2).__name__, "SmartInteger2Ptr")
+ self.assertTrue("smart.Test.SmartInteger2Ptr" in repr(type(integer2)))
self.assertEqual(integer2.value(), 456)
# pass Smart<Integer2> to a function that accepts Smart<Integer>
r = o.takeSharedPtrToInteger(integer2)
self.assertEqual(r, integer2.value())
+ def testSmartPointerValueComparison(self):
+ """Test a pointee class with comparison operators."""
+ four = Obj.createSharedPtrInteger(4)
+ four2 = Obj.createSharedPtrInteger(4)
+ five = Obj.createSharedPtrInteger(5)
+ self.assertTrue(four == four)
+ self.assertTrue(four == four2)
+ self.assertFalse(four != four)
+ self.assertFalse(four != four2)
+ self.assertFalse(four < four)
+ self.assertTrue(four <= four)
+ self.assertFalse(four > four)
+ self.assertTrue(four >= four)
+ self.assertFalse(four == five)
+ self.assertTrue(four != five)
+ self.assertTrue(four < five)
+ self.assertTrue(four <= five)
+ self.assertFalse(four > five)
+ self.assertFalse(four >= five)
+ self.assertTrue(five > four)
+
+ self.assertRaises(NotImplementedError,
+ lambda: Obj.createNullSharedPtrInteger() == four)
+
+ def testSmartPointerObjectComparison(self):
+ """Test a pointee class without comparison operators."""
+ o1 = Obj.createSharedPtrObj()
+ o2 = Obj.createSharedPtrObj()
+ self.assertTrue(o1 == o1)
+ self.assertFalse(o1 != o1)
+ self.assertFalse(o1 == o2)
+ self.assertTrue(o1 != o2)
+
+ def testOperatorNbBool(self):
+ null_ptr = Obj.createNullSharedPtrInteger()
+ self.assertFalse(null_ptr)
+ zero = Obj.createSharedPtrInteger(0)
+ self.assertTrue(zero)
+
+ def testParameterNone(self):
+ o = Obj()
+ null_ptr = Obj.createNullSharedPtrInteger()
+ o.takeSharedPtrToInteger(null_ptr)
+ o.takeSharedPtrToIntegerByConstRef(null_ptr)
+ o.takeSharedPtrToInteger(None)
+ o.takeSharedPtrToIntegerByConstRef(None)
+
+ def testConstruction(self):
+ p1 = SharedPtr_Integer(integerFromValue(42))
+ self.assertEqual(p1.value(), 42)
+
+ p2 = std.shared_ptr_Integer(integerFromValue(42))
+ self.assertEqual(p2.value(), 42)
+ p2.reset(integerFromValue(43))
+ self.assertEqual(p2.value(), 43)
+ gc.collect()
+
+
if __name__ == '__main__':
unittest.main()
diff --git a/sources/shiboken6/tests/smartbinding/smartbinding.pyproject b/sources/shiboken6/tests/smartbinding/smartbinding.pyproject
new file mode 100644
index 000000000..d0855ef82
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/smartbinding.pyproject
@@ -0,0 +1,7 @@
+{
+ "files": ["smart_pointer_test.py",
+ "std_optional_test.py",
+ "std_shared_ptr_test.py",
+ "std_unique_ptr_test.py",
+ "typesystem_smart.xml"]
+}
diff --git a/sources/shiboken6/tests/smartbinding/std_optional_test.py b/sources/shiboken6/tests/smartbinding/std_optional_test.py
new file mode 100644
index 000000000..bee573548
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/std_optional_test.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+# 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 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 smart import Integer, StdOptionalTestBench, std
+
+
+def call_func_on_optional(o):
+ o.printInteger()
+
+
+def integer_from_value(v):
+ result = Integer()
+ result.setValue(v)
+ return result
+
+
+class StdOptionalTests(unittest.TestCase):
+
+ def testCInt(self):
+ b = StdOptionalTestBench()
+ ci = b.optionalInt()
+ self.assertFalse(ci.has_value())
+ b.setOptionalIntValue(42)
+ ci = b.optionalInt()
+ self.assertTrue(ci.has_value())
+ self.assertEqual(ci.value(), 42)
+ b.setOptionalInt(ci)
+ ci = b.optionalInt()
+ self.assertTrue(ci.has_value())
+ self.assertEqual(ci.value(), 42)
+
+ ci = std.optional_int(43)
+ self.assertEqual(ci.value(), 43)
+
+ def testInteger(self):
+ b = StdOptionalTestBench()
+ i = b.optionalInteger()
+ self.assertFalse(i.has_value())
+ self.assertFalse(i)
+ # Must not throw a C++ exception
+ self.assertRaises(AttributeError, call_func_on_optional, i)
+
+ b.setOptionalIntegerValue(integer_from_value(42))
+ i = b.optionalInteger()
+ self.assertTrue(i.has_value())
+ self.assertEqual(i.value().value(), 42)
+ i.printInteger()
+ print(i)
+ b.setOptionalInteger(i)
+ i = b.optionalInteger()
+ self.assertTrue(i.has_value())
+ self.assertEqual(i.value().value(), 42)
+ call_func_on_optional(i)
+
+ i = std.optional_Integer(integer_from_value(43))
+ self.assertEqual(i.value().value(), 43)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py b/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py
new file mode 100644
index 000000000..a37a307a5
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/std_shared_ptr_test.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# 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 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 smart import Integer, StdDoublePtr, StdSharedPtrTestBench, StdSharedPtrVirtualMethodTester, std
+
+
+def call_func_on_ptr(ptr):
+ ptr.printInteger()
+
+
+class VirtualTester(StdSharedPtrVirtualMethodTester):
+
+ def doModifyInteger(self, p):
+ p.setValue(p.value() * 2)
+ return p
+
+
+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)
+
+ np = StdSharedPtrTestBench.createNullInteger()
+ StdSharedPtrTestBench.printInteger(np)
+ self.assertFalse(np)
+ self.assertRaises(AttributeError, call_func_on_ptr, np)
+
+ iv = Integer()
+ iv.setValue(42)
+ np = std.shared_ptr_Integer(iv)
+ self.assertEqual(np.value(), 42)
+
+ def testInt(self):
+ np = StdSharedPtrTestBench.createNullInt()
+ StdSharedPtrTestBench.printInt(np)
+ self.assertFalse(np)
+ p = StdSharedPtrTestBench.createInt()
+ StdSharedPtrTestBench.printInt(p)
+ ip = std.StdIntPtr(42)
+ StdSharedPtrTestBench.printInt(ip)
+
+ def testDouble(self):
+ np = StdSharedPtrTestBench.createNullDouble()
+ StdSharedPtrTestBench.printDouble(np)
+ self.assertFalse(np)
+ p = StdSharedPtrTestBench.createDouble(67)
+ StdSharedPtrTestBench.printDouble(p)
+ dp = StdDoublePtr(42)
+ StdSharedPtrTestBench.printDouble(dp)
+
+ 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
+ correctly."""
+ p = StdSharedPtrTestBench.createInteger()
+ p.setValue(42)
+ v = StdSharedPtrVirtualMethodTester()
+ r = v.callModifyInteger(p) # Base implementation increments
+ self.assertEqual(r.value(), 43)
+
+ p.setValue(42)
+ v = VirtualTester()
+ r = v.callModifyInteger(p) # Derived implementation doubles
+ self.assertEqual(r.value(), 84)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py b/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py
new file mode 100644
index 000000000..9c7ef2f01
--- /dev/null
+++ b/sources/shiboken6/tests/smartbinding/std_unique_ptr_test.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python
+# 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 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 smart import Integer, Integer2, StdUniquePtrTestBench, StdUniquePtrVirtualMethodTester, std
+
+
+def call_func_on_ptr(ptr):
+ ptr.printInteger()
+
+
+class VirtualTester(StdUniquePtrVirtualMethodTester):
+
+ def doCreateInteger(self, v):
+ iv = Integer() # Construct from pointee
+ iv.setValue(2 * v)
+ return std.unique_ptr_Integer(iv)
+
+ def doModifyIntegerByRef(self, p):
+ return 2 * p.value()
+
+ def doModifyIntegerByValue(self, p):
+ return 2 * p.value()
+
+
+class StdUniquePtrTests(unittest.TestCase):
+ def testInteger(self):
+ p = StdUniquePtrTestBench.createInteger()
+ StdUniquePtrTestBench.printInteger(p) # unique_ptr by ref
+ self.assertTrue(p)
+
+ call_func_on_ptr(p)
+ self.assertTrue(p)
+
+ StdUniquePtrTestBench.takeInteger(p) # unique_ptr by value, takes pointee
+ self.assertFalse(p)
+
+ np = StdUniquePtrTestBench.createNullInteger()
+ StdUniquePtrTestBench.printInteger(np)
+ self.assertFalse(np)
+ self.assertRaises(AttributeError, call_func_on_ptr, np)
+
+ iv = Integer() # Construct from pointee
+ iv.setValue(42)
+ np = std.unique_ptr_Integer(iv)
+ self.assertEqual(np.value(), 42)
+
+ def test_derived(self):
+ iv2 = Integer2() # Construct from pointee
+ iv2.setValue(42)
+ p = std.unique_ptr_Smart_Integer2(iv2)
+ self.assertEqual(p.value(), 42)
+ StdUniquePtrTestBench.printInteger2(p) # unique_ptr by ref
+ self.assertTrue(p)
+ StdUniquePtrTestBench.printInteger(p) # conversion
+ # FIXME: This fails, pointer is moved in value conversion
+ # self.assertTrue(p)
+
+ def testInt(self):
+ p = StdUniquePtrTestBench.createInt() # unique_ptr by ref
+ StdUniquePtrTestBench.printInt(p)
+ StdUniquePtrTestBench.takeInt(p) # unique_ptr by value, takes pointee
+ self.assertFalse(p)
+
+ np = StdUniquePtrTestBench.createNullInt()
+ StdUniquePtrTestBench.printInt(np)
+ self.assertFalse(np)
+
+ def testVirtuals(self):
+ """Test whether code generating virtual function overrides is generated
+ correctly."""
+ p = StdUniquePtrTestBench.createInteger()
+ p.setValue(42)
+ v = StdUniquePtrVirtualMethodTester()
+ self.assertTrue(v.testCreateInteger(42, 42))
+ self.assertTrue(v.testModifyIntegerByRef(42, 43)) # Default implementation increments
+ self.assertTrue(v.testModifyIntegerValue(42, 43))
+
+ v = VirtualTester() # Reimplemented methods double values
+ self.assertTrue(v.testCreateInteger(42, 84))
+ self.assertTrue(v.testModifyIntegerByRef(42, 84))
+ self.assertTrue(v.testModifyIntegerValue(42, 84))
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/sources/shiboken6/tests/smartbinding/typesystem_smart.xml b/sources/shiboken6/tests/smartbinding/typesystem_smart.xml
index f651161c5..e479e4ddf 100644
--- a/sources/shiboken6/tests/smartbinding/typesystem_smart.xml
+++ b/sources/shiboken6/tests/smartbinding/typesystem_smart.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<typesystem package="smart">
+ <rejection class="*" argument-type="^std::nullptr_t&amp;?$"/>
<template name="cpplist_to_pylist_convertion">
PyObject *%out = PyList_New(int(%in.size()));
@@ -16,21 +17,6 @@
%out.push_back(cppItem);
}
</template>
- <container-type name="std::vector" type="list">
- <include file-name="list" location="global"/>
- <conversion-rule>
- <native-to-target>
- <insert-template name="cpplist_to_pylist_convertion"/>
- </native-to-target>
- <target-to-native>
- <add-conversion type="PySequence">
- <insert-template name="pyseq_to_cpplist_convertion"/>
- </add-conversion>
- </target-to-native>
- </conversion-rule>
- </container-type>
-
- <custom-type name="std::shared_ptr" />
<!-- Used in tests to check what C++ objects are allocated. -->
<object-type name="Registry" />
@@ -41,7 +27,8 @@
won't work.
-->
<smart-pointer-type name="SharedPtr" type="shared" getter="data" ref-count-method="useCount"
- instantiations="Integer,Smart::Integer2,Obj"/>
+ null-check-method="isNull"
+ instantiations="Integer,Smart::Integer2=Test::SmartInteger2Ptr,Obj"/>
<object-type name="Obj" />
<value-type name="Integer" />
@@ -50,4 +37,45 @@
</namespace-type>
<!-- Just used to silence the warnings that shiboken doens't know what to do with this type -->
<custom-type name="RefData" />
+
+ <value-type name="StdOptionalTestBench"/>
+
+ <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"
+ value-check-method="operator bool"
+ ref-count-method="use_count"
+ reset-method="reset"
+ instantiations="Integer,int=StdIntPtr,double=::StdDoublePtr,std::string">
+ <include file-name="memory" location="global"/>
+ </smart-pointer-type>
+
+ <smart-pointer-type name="unique_ptr" type="unique" getter="get"
+ value-check-method="operator bool"
+ reset-method="reset"
+ instantiations="Integer,Smart::Integer2,int">
+ <include file-name="memory" location="global"/>
+ </smart-pointer-type>
+
+ <smart-pointer-type name="optional" type="value-handle" getter="value"
+ value-check-method="has_value"
+ instantiations="Integer,int">
+ <include file-name="optional" location="global"/>
+ </smart-pointer-type>
+
+ </namespace-type>
+ <object-type name="StdSharedPtrTestBench"/>
+ <object-type name="StdSharedPtrVirtualMethodTester"/>
+
+ <object-type name="StdUniquePtrTestBench"/>
+ <object-type name="StdUniquePtrVirtualMethodTester"/>
+
+ <namespace-type name="Test">
+ <enum-type name="DummyEnum"/>
+ </namespace-type>
+
</typesystem>
diff --git a/sources/shiboken6/tests/test_generator/CMakeLists.txt b/sources/shiboken6/tests/test_generator/CMakeLists.txt
index b48ae37da..e1d078894 100644
--- a/sources/shiboken6/tests/test_generator/CMakeLists.txt
+++ b/sources/shiboken6/tests/test_generator/CMakeLists.txt
@@ -1,4 +1,7 @@
-cmake_minimum_required(VERSION 3.16)
+# Copyright (C) 2023 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.18)
project(test_generator)
set(dummy_generator_SRC dummygenerator.cpp)
diff --git a/sources/shiboken6/tests/test_generator/dummygenerator.cpp b/sources/shiboken6/tests/test_generator/dummygenerator.cpp
index 826791bfc..8a5079820 100644
--- a/sources/shiboken6/tests/test_generator/dummygenerator.cpp
+++ b/sources/shiboken6/tests/test_generator/dummygenerator.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "dummygenerator.h"
diff --git a/sources/shiboken6/tests/test_generator/dummygenerator.h b/sources/shiboken6/tests/test_generator/dummygenerator.h
index e768e7643..d17206809 100644
--- a/sources/shiboken6/tests/test_generator/dummygenerator.h
+++ b/sources/shiboken6/tests/test_generator/dummygenerator.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef DUMMYGENERATOR_H
#define DUMMYGENERATOR_H
diff --git a/sources/shiboken6/tests/test_generator/dummygentest.cpp b/sources/shiboken6/tests/test_generator/dummygentest.cpp
index 40ca6c7c5..d439e3d8c 100644
--- a/sources/shiboken6/tests/test_generator/dummygentest.cpp
+++ b/sources/shiboken6/tests/test_generator/dummygentest.cpp
@@ -1,37 +1,13 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 "dummygentest.h"
#include "dummygenerator.h"
#include "dummygentestconfig.h"
-#include <QTemporaryFile>
+
+#include <QtCore/QProcess>
+#include <QtCore/QTemporaryFile>
#include <QtTest/QTest>
-#include <QProcess>
#define GENERATED_CONTENTS "// Generated code for class: Dummy"
diff --git a/sources/shiboken6/tests/test_generator/dummygentest.h b/sources/shiboken6/tests/test_generator/dummygentest.h
index 78bae1d52..1b1143b0a 100644
--- a/sources/shiboken6/tests/test_generator/dummygentest.h
+++ b/sources/shiboken6/tests/test_generator/dummygentest.h
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#ifndef DUMMYGENTABLETEST_H
#define DUMMYGENTABLETEST_H
diff --git a/sources/shiboken6/tests/test_generator/main.cpp b/sources/shiboken6/tests/test_generator/main.cpp
index f928b4d2c..ba4440b2f 100644
--- a/sources/shiboken6/tests/test_generator/main.cpp
+++ b/sources/shiboken6/tests/test_generator/main.cpp
@@ -1,30 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the test suite of Qt for Python.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// 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 <QtCore>
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.