aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/ApiExtractor
diff options
context:
space:
mode:
Diffstat (limited to 'sources/shiboken6/ApiExtractor')
-rw-r--r--sources/shiboken6/ApiExtractor/CMakeLists.txt129
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaargument.cpp75
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaargument.h46
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp2033
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder.h94
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp202
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetabuilder_p.h237
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaenum.cpp200
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetaenum.h59
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafield.cpp58
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafield.h39
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.cpp617
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetafunction.h173
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.cpp841
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetalang.h182
-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.h42
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetatype.cpp491
-rw-r--r--sources/shiboken6/ApiExtractor/abstractmetatype.h107
-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.cpp745
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractor.h106
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorflags.h26
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorresult.cpp96
-rw-r--r--sources/shiboken6/ApiExtractor/apiextractorresult.h85
-rw-r--r--sources/shiboken6/ApiExtractor/arraytypeentry.h28
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangbuilder.cpp524
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangbuilder.h35
-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.cpp80
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/clangparser.h48
-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.cpp327
-rw-r--r--sources/shiboken6/ApiExtractor/clangparser/compilersupport.h55
-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.cpp153
-rw-r--r--sources/shiboken6/ApiExtractor/conditionalstreamreader.h56
-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.cpp58
-rw-r--r--sources/shiboken6/ApiExtractor/dotview.h14
-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.h55
-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.cpp525
-rw-r--r--sources/shiboken6/ApiExtractor/messages.h143
-rw-r--r--sources/shiboken6/ApiExtractor/modifications.cpp401
-rw-r--r--sources/shiboken6/ApiExtractor/modifications.h282
-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.cpp550
-rw-r--r--sources/shiboken6/ApiExtractor/parser/codemodel.h245
-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.cpp169
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h32
-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.cpp429
-rw-r--r--sources/shiboken6/ApiExtractor/tests/testenum.h34
-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.cpp1292
-rw-r--r--sources/shiboken6/ApiExtractor/typedatabase.h182
-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.cpp88
-rw-r--r--sources/shiboken6/ApiExtractor/typeparser.h31
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.cpp1309
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem.h678
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem_enums.h66
-rw-r--r--sources/shiboken6/ApiExtractor/typesystem_typedefs.h110
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.cpp2646
-rw-r--r--sources/shiboken6/ApiExtractor/typesystemparser.h285
-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
215 files changed, 16847 insertions, 12250 deletions
diff --git a/sources/shiboken6/ApiExtractor/CMakeLists.txt b/sources/shiboken6/ApiExtractor/CMakeLists.txt
index 040d85f54..7aa2fbd11 100644
--- a/sources/shiboken6/ApiExtractor/CMakeLists.txt
+++ b/sources/shiboken6/ApiExtractor/CMakeLists.txt
@@ -1,50 +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
-abstractmetaenum.cpp
-abstractmetafield.cpp
-abstractmetafunction.cpp
-abstractmetatype.cpp
-abstractmetalang.cpp
-codesniphelpers.cpp
-conditionalstreamreader.cpp
-documentation.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
+abstractmetaargument.cpp abstractmetaargument.h
+abstractmetabuilder.cpp abstractmetabuilder.h abstractmetabuilder_p.h
+abstractmetabuilder_helpers.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)
@@ -56,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
@@ -67,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)
@@ -80,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 366fc00a1..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:
@@ -39,11 +19,13 @@ public:
QString m_name;
AbstractMetaType m_type;
+ AbstractMetaType m_modifiedType;
bool m_hasName = false;
Documentation m_doc;
QString m_expression;
QString m_originalExpression;
int m_argumentIndex = 0;
+ bool m_modifiedRemoved = false;
};
AbstractMetaArgument::AbstractMetaArgument() : d(new AbstractMetaArgumentData)
@@ -56,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
{
@@ -68,7 +50,34 @@ const AbstractMetaType &AbstractMetaArgument::type() const
void AbstractMetaArgument::setType(const AbstractMetaType &type)
{
if (d->m_type != type)
- d->m_type = type;
+ d->m_type = d->m_modifiedType = type;
+}
+
+const AbstractMetaType &AbstractMetaArgument::modifiedType() const
+{
+ return d->m_modifiedType;
+}
+
+bool AbstractMetaArgument::isTypeModified() const
+{
+ return modifiedType() != type();
+}
+
+bool AbstractMetaArgument::isModifiedRemoved() const
+{
+ return d->m_modifiedRemoved;
+}
+
+void AbstractMetaArgument::setModifiedRemoved(bool v)
+{
+ if (d->m_modifiedRemoved != v)
+ d->m_modifiedRemoved = v;
+}
+
+void AbstractMetaArgument::setModifiedType(const AbstractMetaType &type)
+{
+ if (d->m_modifiedType != type)
+ d->m_modifiedType = type;
}
QString AbstractMetaArgument::name() const
@@ -144,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;
}
@@ -182,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 b5fe22db7..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,12 +19,17 @@ 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;
+
+ bool isModifiedRemoved() const;
+ void setModifiedRemoved(bool v);
QString name() const;
void setName(const QString &name, bool realName = true);
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder.cpp
index cac311626..89d636964 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,26 +53,51 @@
#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);
}
-bool AbstractMetaBuilderPrivate::m_useGlobalHeader = false;
+static void fixArgumentIndexes(AbstractMetaArgumentList *list)
+{
+ for (qsizetype i = 0, size = list->size(); i < size; ++i)
+ (*list)[i].setArgumentIndex(i);
+}
-AbstractMetaBuilderPrivate::AbstractMetaBuilderPrivate() :
- m_logDirectory(QLatin1String(".") + QDir::separator())
+bool operator<(const RejectEntry &re1, const RejectEntry &re2)
+{
+ return re1.reason != re2.reason
+ ? (re1.reason < re2.reason) : (re1.sortkey < re2.sortkey);
+}
+
+QTextStream &operator<<(QTextStream &str, const RejectEntry &re)
+{
+ str << re.signature;
+ if (!re.message.isEmpty())
+ str << ": " << re.message;
+ return str;
+}
+
+static void applyCachedFunctionModifications(AbstractMetaFunction *metaFunction,
+ const FunctionModificationList &functionMods)
{
+ for (const FunctionModification &mod : functionMods) {
+ if (mod.exceptionHandling() != TypeSystem::ExceptionHandling::Unspecified)
+ metaFunction->setExceptionHandlingModification(mod.exceptionHandling());
+ if (mod.allowThread() != TypeSystem::AllowThread::Unspecified)
+ metaFunction->setAllowThreadModification(mod.allowThread());
+ }
}
-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)
@@ -96,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;
@@ -116,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;
@@ -153,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());
}
}
@@ -174,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;
@@ -191,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())
@@ -214,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()));
}
@@ -229,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()
@@ -258,42 +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();
- 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;
}
+
+ AbstractMetaFunction *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, AbstractMetaFunctionCPtr(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)
@@ -310,21 +376,24 @@ bool AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem
return false;
// Strip first argument, since that is the containing object
- AbstractMetaArgumentList arguments = streamFunction->arguments();
- if (!streamClass->typeEntry()->generateCode())
- arguments.takeLast();
- else
- arguments.takeFirst();
+ AbstractMetaArgumentList arguments = streamFunction->arguments();
+ if (!streamClass->typeEntry()->generateCode()) {
+ arguments.takeLast();
+ } else {
+ arguments.takeFirst();
+ fixArgumentIndexes(&arguments);
+ }
streamFunction->setArguments(arguments);
- *streamFunction += AbstractMetaFunction::FinalInTargetLang;
streamFunction->setAccess(Access::Public);
- AbstractMetaClass *funcClass;
+ AbstractMetaClassPtr funcClass;
if (!streamClass->typeEntry()->generateCode()) {
- AbstractMetaArgumentList reverseArgs = reverseList(streamFunction->arguments());
+ AbstractMetaArgumentList reverseArgs = streamFunction->arguments();
+ std::reverse(reverseArgs.begin(), reverseArgs.end());
+ fixArgumentIndexes(&reverseArgs);
streamFunction->setArguments(reverseArgs);
streamFunction->setReverseOperator(true);
funcClass = streamedClass;
@@ -332,19 +401,19 @@ bool AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem
funcClass = streamClass;
}
- setupFunctionDefaults(streamFunction, funcClass);
- funcClass->addFunction(AbstractMetaFunctionCPtr(streamFunction));
+ AbstractMetaClass::addFunction(funcClass, AbstractMetaFunctionCPtr(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)
@@ -357,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;
@@ -367,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
@@ -384,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();
@@ -395,18 +464,35 @@ FileModelItem AbstractMetaBuilderPrivate::buildDom(QByteArrayList arguments,
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;
}
-void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
+// List of candidates for a mismatched added global function.
+static QStringList functionCandidates(const AbstractMetaFunctionCList &list,
+ const QString &signature)
+{
+ QString name = signature;
+ const auto parenPos = name.indexOf(u'(');
+ if (parenPos > 0)
+ name.truncate(parenPos);
+ QStringList result;
+ for (const auto &func : list) {
+ if (name == func->name())
+ result += func->minimalSignature();
+ }
+ return result;
+}
+
+void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom,
+ ApiExtractorFlags flags)
{
const TypeDatabase *types = TypeDatabase::instance();
@@ -415,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()) {
@@ -436,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();
@@ -462,10 +548,10 @@ 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;
@@ -479,14 +565,15 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
metaFunc->setTypeEntry(funcEntry);
applyFunctionModifications(metaFunc);
+ metaFunc->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);
@@ -498,22 +585,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 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())
@@ -523,25 +616,27 @@ 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;
}
}
if (!ok) {
+ const QStringList candidates = functionCandidates(m_globalFunctions,
+ signatures.constFirst());
qCWarning(lcShiboken, "%s",
- qPrintable(msgGlobalFunctionNotDefined(fte, signature)));
+ qPrintable(msgGlobalFunctionNotDefined(fte, signature, candidates)));
}
}
} 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()
@@ -558,7 +653,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);
}
@@ -581,16 +676,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
@@ -600,6 +694,8 @@ void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom)
cls->setInnerClasses(classesTopologicalSorted(cls->innerClasses()));
}
+ fixSmartPointers();
+
dumpLog();
sortLists();
@@ -612,25 +708,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;
}
@@ -642,7 +742,7 @@ void AbstractMetaBuilder::setLogDirectory(const QString &logDir)
d->m_logDirectory.append(QDir::separator());
}
-void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls,
+void AbstractMetaBuilderPrivate::addAbstractMetaClass(const AbstractMetaClassPtr &cls,
const _CodeModelItem *item)
{
m_itemToClass.insert(item, cls);
@@ -656,23 +756,27 @@ void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls,
}
}
-AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModelItem &dom,
- const NamespaceModelItem &namespaceItem)
+AbstractMetaClassPtr
+ AbstractMetaBuilderPrivate::traverseNamespace(const FileModelItem &dom,
+ const NamespaceModelItem &namespaceItem)
{
- QString namespaceName = currentScope()->qualifiedName().join(colonColon());
+ QString namespaceName = currentScope()->qualifiedName().join(u"::"_s);
if (!namespaceName.isEmpty())
- namespaceName.append(colonColon());
+ namespaceName.append(u"::"_s);
namespaceName.append(namespaceItem->name());
if (TypeDatabase::instance()->isClassRejected(namespaceName)) {
- m_rejectedClasses.insert(namespaceName, AbstractMetaBuilder::GenerationDisabled);
- return nullptr;
+ m_rejectedClasses.insert({AbstractMetaBuilder::GenerationDisabled,
+ namespaceName, namespaceName, QString{}});
+ return {};
}
auto type = TypeDatabase::instance()->findNamespaceType(namespaceName, namespaceItem->fileName());
if (!type) {
- qCWarning(lcShiboken, "%s",
- qPrintable(msgNamespaceNoTypeEntry(namespaceItem, namespaceName)));
+ const QString rejectReason = msgNamespaceNoTypeEntry(namespaceItem, namespaceName);
+ qCWarning(lcShiboken, "%s", qPrintable(rejectReason));
+ m_rejectedClasses.insert({AbstractMetaBuilder::GenerationDisabled,
+ namespaceName, namespaceName, rejectReason});
return nullptr;
}
@@ -682,22 +786,22 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
}
// Continue populating namespace?
- AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, type);
+ AbstractMetaClassPtr metaClass = AbstractMetaClass::findClass(m_metaClasses, type);
if (!metaClass) {
- metaClass = new AbstractMetaClass;
+ metaClass.reset(new AbstractMetaClass);
metaClass->setTypeEntry(type);
- addAbstractMetaClass(metaClass, namespaceItem.data());
+ addAbstractMetaClass(metaClass, namespaceItem.get());
if (auto extendsType = type->extends()) {
- AbstractMetaClass *extended = AbstractMetaClass::findClass(m_metaClasses, extendsType);
+ const auto extended = AbstractMetaClass::findClass(m_metaClasses, extendsType);
if (!extended) {
qCWarning(lcShiboken, "%s",
qPrintable(msgNamespaceToBeExtendedNotFound(extendsType->name(), extendsType->targetLangPackage())));
- return nullptr;
+ return {};
}
metaClass->setExtendedNamespace(extended);
}
} else {
- m_itemToClass.insert(namespaceItem.data(), metaClass);
+ m_itemToClass.insert(namespaceItem.get(), metaClass);
}
traverseEnums(namespaceItem, metaClass, namespaceItem->enumsDeclarations());
@@ -706,11 +810,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
const ClassList &classes = namespaceItem->classes();
for (const ClassModelItem &cls : classes) {
- AbstractMetaClass *mjc = traverseClass(dom, cls, metaClass);
+ const auto mjc = traverseClass(dom, cls, metaClass);
if (mjc) {
metaClass->addInnerClass(mjc);
mjc->setEnclosingClass(metaClass);
- addAbstractMetaClass(mjc, cls.data());
+ addAbstractMetaClass(mjc, cls.get());
}
}
@@ -718,20 +822,22 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModel
// specific typedefs to be used as classes.
const TypeDefList typeDefs = namespaceItem->typeDefs();
for (const TypeDefModelItem &typeDef : typeDefs) {
- AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, metaClass);
+ const auto cls = traverseTypeDef(dom, typeDef, metaClass);
if (cls) {
metaClass->addInnerClass(cls);
cls->setEnclosingClass(metaClass);
- addAbstractMetaClass(cls, typeDef.data());
+ addAbstractMetaClass(cls, typeDef.get());
}
}
// Traverse namespaces recursively
for (const NamespaceModelItem &ni : namespaceItem->namespaces()) {
- AbstractMetaClass *mjc = traverseNamespace(dom, ni);
+ const auto mjc = traverseNamespace(dom, ni);
if (mjc) {
metaClass->addInnerClass(mjc);
mjc->setEnclosingClass(metaClass);
+ m_classToItem.insert(mjc, ni.get()); // Add for enum lookup.
+ m_itemToClass.insert(ni.get(), mjc);
}
}
@@ -745,16 +851,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);
@@ -764,7 +870,7 @@ std::optional<AbstractMetaEnum>
for (const EnumeratorModelItem &enumValue : enums) {
tmpQualifiedName.removeLast();
tmpQualifiedName << enumValue->name();
- qualifiedName = tmpQualifiedName.join(colonColon());
+ qualifiedName = tmpQualifiedName.join(u"::"_s);
typeEntry = TypeDatabase::instance()->findType(qualifiedName);
if (typeEntry)
break;
@@ -781,65 +887,75 @@ std::optional<AbstractMetaEnum>
if (TypeDatabase::instance()->isEnumRejected(className, enumName, &rejectReason)) {
if (typeEntry)
typeEntry->setCodeGeneration(TypeEntry::GenerateNothing);
- m_rejectedEnums.insert(qualifiedName + rejectReason, AbstractMetaBuilder::GenerationDisabled);
+ m_rejectedEnums.insert({AbstractMetaBuilder::GenerationDisabled, qualifiedName,
+ qualifiedName, rejectReason});
return {};
}
const bool rejectionWarning = !enclosing || enclosing->typeEntry()->generateCode();
if (!typeEntry) {
+ const QString rejectReason = msgNoEnumTypeEntry(enumItem, className);
if (rejectionWarning)
- qCWarning(lcShiboken, "%s", qPrintable(msgNoEnumTypeEntry(enumItem, className)));
- m_rejectedEnums.insert(qualifiedName, AbstractMetaBuilder::NotInTypeSystem);
+ qCWarning(lcShiboken, "%s", qPrintable(rejectReason));
+ m_rejectedEnums.insert({AbstractMetaBuilder::NotInTypeSystem, qualifiedName,
+ qualifiedName, rejectReason});
return {};
}
if (!typeEntry->isEnum()) {
- if (rejectionWarning) {
- qCWarning(lcShiboken, "%s",
- qPrintable(msgNoEnumTypeConflict(enumItem, className, typeEntry)));
- }
- m_rejectedEnums.insert(qualifiedName, AbstractMetaBuilder::NotInTypeSystem);
+ const QString rejectReason = msgNoEnumTypeConflict(enumItem, className, typeEntry);
+ if (rejectionWarning)
+ qCWarning(lcShiboken, "%s", qPrintable(rejectReason));
+ m_rejectedEnums.insert({AbstractMetaBuilder::NotInTypeSystem, qualifiedName,
+ qualifiedName, rejectReason});
return {};
}
AbstractMetaEnum metaEnum;
metaEnum.setEnumKind(enumItem->enumKind());
+ metaEnum.setDeprecated(enumItem->isDeprecated());
+ metaEnum.setUnderlyingType(enumItem->underlyingType());
metaEnum.setSigned(enumItem->isSigned());
if (enumsDeclarations.contains(qualifiedName)
|| enumsDeclarations.contains(enumName)) {
metaEnum.setHasQEnumsDeclaration(true);
}
- auto *enumTypeEntry = 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);
@@ -851,9 +967,31 @@ std::optional<AbstractMetaEnum>
return metaEnum;
}
-AbstractMetaClass *AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelItem &,
- const TypeDefModelItem &typeDef,
- AbstractMetaClass *currentClass)
+AbstractMetaClassPtr
+ AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelItem &dom,
+ const TypeDefModelItem &typeDef,
+ const AbstractMetaClassPtr &currentClass)
+{
+ auto result = traverseTypeDefHelper(dom, typeDef, currentClass);
+ if (!result && typeDef->type().isPlain()) {
+ const auto &type = typeDef->type();
+ QString fullName;
+ if (currentClass)
+ fullName += currentClass->qualifiedCppName() + "::"_L1;
+ fullName += typeDef->name();
+ QString targetName = typeDef->type().toString();
+ m_typedefTargetToName.insert(targetName, fullName);
+ const QByteArray normalized = QMetaObject::normalizedType(targetName.toUtf8().constData());
+ if (targetName != QLatin1StringView(normalized))
+ m_typedefTargetToName.insert(QString::fromUtf8(normalized), fullName);
+ }
+ return result;
+}
+
+AbstractMetaClassPtr
+ AbstractMetaBuilderPrivate::traverseTypeDefHelper(const FileModelItem &,
+ const TypeDefModelItem &typeDef,
+ const AbstractMetaClassPtr &currentClass)
{
TypeDatabase *types = TypeDatabase::instance();
QString className = stripTemplateArgs(typeDef->name());
@@ -862,26 +1000,39 @@ 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();
+ const auto pTarget = targetNames.size() == 1
+ ? types->findPrimitiveType(targetNames.constFirst()) : PrimitiveTypeEntryPtr{};
if (ptype) {
- QString typeDefName = typeDef->type().qualifiedName()[0];
- ptype->setReferencedTypeEntry(types->findPrimitiveType(typeDefName));
+ ptype->setReferencedTypeEntry(pTarget);
return nullptr;
}
+ // It is a (nested?) global typedef to a primitive type
+ // (like size_t = unsigned)? Add it to the type DB.
+ if (pTarget && isCppPrimitive(basicReferencedNonBuiltinTypeEntry(pTarget))
+ && currentClass == nullptr) {
+ auto pte = std::make_shared<PrimitiveTypeEntry>(className, QVersionNumber{},
+ TypeEntryCPtr{});
+ pte->setReferencedTypeEntry(pTarget);
+ pte->setBuiltIn(true);
+ types->addType(pte);
+ return nullptr;
+ }
// 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()));
@@ -900,8 +1051,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()));
@@ -927,9 +1078,9 @@ void AbstractMetaBuilderPrivate::traverseTypesystemTypedefs()
}
}
-AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem &dom,
+AbstractMetaClassPtr AbstractMetaBuilderPrivate::traverseClass(const FileModelItem &dom,
const ClassModelItem &classItem,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
QString className = stripTemplateArgs(classItem->name());
QString fullClassName = className;
@@ -937,20 +1088,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;
}
@@ -959,11 +1114,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
QTextStream(&fullClassName) << "anonymous struct at " << classItem->fileName()
<< ':' << classItem->startLine();
}
- m_rejectedClasses.insert(fullClassName, reason);
+ m_rejectedClasses.insert({reason, fullClassName, fullClassName, QString{}});
return nullptr;
}
- auto *metaClass = new AbstractMetaClass;
+ auto metaClass = std::make_shared<AbstractMetaClass>();
metaClass->setSourceLocation(classItem->sourceLocation());
metaClass->setTypeEntry(type);
if ((type->typeFlags() & ComplexTypeEntry::ForceAbstract) != 0)
@@ -972,6 +1127,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) {
@@ -985,21 +1143,22 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
if (ReportHandler::isDebug(ReportHandler::MediumDebug)) {
const QString message = type->isContainer()
- ? QStringLiteral("container: '%1'").arg(fullClassName)
- : QStringLiteral("class: '%1'").arg(metaClass->fullName());
+ ? 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);
@@ -1011,11 +1170,11 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
{
const ClassList &innerClasses = classItem->classes();
for (const ClassModelItem &ci : innerClasses) {
- AbstractMetaClass *cl = traverseClass(dom, ci, metaClass);
+ const auto cl = traverseClass(dom, ci, metaClass);
if (cl) {
cl->setEnclosingClass(metaClass);
metaClass->addInnerClass(cl);
- addAbstractMetaClass(cl, ci.data());
+ addAbstractMetaClass(cl, ci.get());
}
}
@@ -1025,10 +1184,10 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
// specific typedefs to be used as classes.
const TypeDefList typeDefs = classItem->typeDefs();
for (const TypeDefModelItem &typeDef : typeDefs) {
- AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, metaClass);
+ const auto cls = traverseTypeDef(dom, typeDef, metaClass);
if (cls) {
cls->setEnclosingClass(metaClass);
- addAbstractMetaClass(cls, typeDef.data());
+ addAbstractMetaClass(cls, typeDef.get());
}
}
@@ -1040,7 +1199,7 @@ AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem
}
void AbstractMetaBuilderPrivate::traverseScopeMembers(const ScopeModelItem &item,
- AbstractMetaClass *metaClass)
+ const AbstractMetaClassPtr &metaClass)
{
// Classes/Namespace members
traverseFields(item, metaClass);
@@ -1054,28 +1213,25 @@ void AbstractMetaBuilderPrivate::traverseScopeMembers(const ScopeModelItem &item
void AbstractMetaBuilderPrivate::traverseClassMembers(const ClassModelItem &item)
{
- AbstractMetaClass *metaClass = m_itemToClass.value(item.data());
- if (!metaClass)
- return;
-
- // Class members
- traverseScopeMembers(item, metaClass);
+ const auto metaClass = m_itemToClass.value(item.get());
+ if (metaClass) // Class members
+ traverseScopeMembers(item, metaClass);
}
-void AbstractMetaBuilderPrivate::traverseUsingMembers(AbstractMetaClass *metaClass)
+void AbstractMetaBuilderPrivate::traverseUsingMembers(const AbstractMetaClassPtr &metaClass) const
{
const _CodeModelItem *item = m_classToItem.value(metaClass);
if (item == nullptr || item->kind() != _CodeModelItem::Kind_Class)
return;
- auto classItem = static_cast<const _ClassModelItem *>(item);
+ const auto *classItem = static_cast<const _ClassModelItem *>(item);
for (const auto &um : classItem->usingMembers()) {
QString className = um.className;
- int pos = className.indexOf(u'<'); // strip "QList<value>"
+ auto pos = className.indexOf(u'<'); // strip "QList<value>"
if (pos != -1)
className.truncate(pos);
- if (auto baseClass = metaClass->AbstractMetaClass::findBaseClass(className)) {
+ if (auto baseClass = findBaseClass(metaClass, className)) {
QString name = um.memberName;
- const int lastQualPos = name.lastIndexOf(colonColon());
+ const auto lastQualPos = name.lastIndexOf(u"::"_s);
if (lastQualPos != -1)
name.remove(0, lastQualPos + 2);
metaClass->addUsingMember({name, baseClass, um.access});
@@ -1089,7 +1245,7 @@ void AbstractMetaBuilderPrivate::traverseUsingMembers(AbstractMetaClass *metaCla
void AbstractMetaBuilderPrivate::traverseNamespaceMembers(const NamespaceModelItem &item)
{
- AbstractMetaClass *metaClass = m_itemToClass.value(item.data());
+ const auto metaClass = m_itemToClass.value(item.get());
if (!metaClass)
return;
@@ -1104,18 +1260,18 @@ void AbstractMetaBuilderPrivate::traverseNamespaceMembers(const NamespaceModelIt
static inline QString fieldSignatureWithType(const VariableModelItem &field)
{
- return field->name() + QStringLiteral(" -> ") + field->type().toString();
+ return field->name() + " -> "_L1 + field->type().toString();
}
static inline QString qualifiedFieldSignatureWithType(const QString &className,
const VariableModelItem &field)
{
- return className + colonColon() + fieldSignatureWithType(field);
+ return className + u"::"_s + fieldSignatureWithType(field);
}
std::optional<AbstractMetaField>
AbstractMetaBuilderPrivate::traverseField(const VariableModelItem &field,
- const AbstractMetaClass *cls)
+ const AbstractMetaClassCPtr &cls)
{
QString fieldName = field->name();
QString className = cls->typeEntry()->qualifiedCppName();
@@ -1129,8 +1285,9 @@ std::optional<AbstractMetaField>
QString rejectReason;
if (TypeDatabase::instance()->isFieldRejected(className, fieldName, &rejectReason)) {
- m_rejectedFields.insert(qualifiedFieldSignatureWithType(className, field) + rejectReason,
- AbstractMetaBuilder::GenerationDisabled);
+ const QString signature = qualifiedFieldSignatureWithType(className, field);
+ m_rejectedFields.insert({AbstractMetaBuilder::GenerationDisabled,
+ signature, signature, rejectReason});
return {};
}
@@ -1143,7 +1300,7 @@ std::optional<AbstractMetaField>
auto metaType = translateType(fieldType, cls);
if (!metaType.has_value()) {
- const QString type = TypeInfo::resolveType(fieldType, currentScope()).qualifiedName().join(colonColon());
+ const QString type = TypeInfo::resolveType(fieldType, currentScope()).qualifiedName().join(u"::"_s);
if (cls->typeEntry()->generateCode()) {
qCWarning(lcShiboken, "%s",
qPrintable(msgSkippingField(field, cls->name(), type)));
@@ -1178,7 +1335,7 @@ static bool applyFieldModifications(AbstractMetaField *f)
}
void AbstractMetaBuilderPrivate::traverseFields(const ScopeModelItem &scope_item,
- AbstractMetaClass *metaClass)
+ const AbstractMetaClassPtr &metaClass)
{
const VariableList &variables = scope_item->variables();
for (const VariableModelItem &field : variables) {
@@ -1191,37 +1348,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)
{
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;
@@ -1233,16 +1375,22 @@ void AbstractMetaBuilderPrivate::fixReturnTypeOfConversionOperator(AbstractMetaF
AbstractMetaFunctionRawPtrList
AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem,
AbstractMetaClass::Attributes *constructorAttributes,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
*constructorAttributes = {};
AbstractMetaFunctionRawPtrList 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())
@@ -1252,8 +1400,8 @@ AbstractMetaFunctionRawPtrList
return result;
}
-void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
- AbstractMetaClass *metaClass)
+void AbstractMetaBuilderPrivate::traverseFunctions(const ScopeModelItem& scopeItem,
+ const AbstractMetaClassPtr &metaClass)
{
AbstractMetaClass::Attributes constructorAttributes;
const AbstractMetaFunctionRawPtrList functions =
@@ -1262,7 +1410,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
for (AbstractMetaFunction *metaFunction : functions) {
if (metaClass->isNamespace())
- *metaFunction += AbstractMetaFunction::Static;
+ metaFunction->setCppAttribute(FunctionAttribute::Static);
const auto propertyFunction = metaClass->searchPropertyFunction(metaFunction->name());
if (propertyFunction.index >= 0) {
@@ -1295,34 +1443,31 @@ 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->isConversionOperator())
fixReturnTypeOfConversionOperator(metaFunction);
- metaClass->addFunction(AbstractMetaFunctionCPtr(metaFunction));
+ AbstractMetaClass::addFunction(metaClass, AbstractMetaFunctionCPtr(metaFunction));
applyFunctionModifications(metaFunction);
} else if (metaFunction->isDestructor()) {
metaClass->setHasPrivateDestructor(metaFunction->isPrivate());
@@ -1338,7 +1483,7 @@ void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem,
fillAddedFunctions(metaClass);
}
-void AbstractMetaBuilderPrivate::fillAddedFunctions(AbstractMetaClass *metaClass)
+void AbstractMetaBuilderPrivate::fillAddedFunctions(const AbstractMetaClassPtr &metaClass)
{
// Add the functions added by the typesystem
QString errorMessage;
@@ -1351,12 +1496,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) {
@@ -1402,26 +1547,17 @@ void AbstractMetaBuilderPrivate::applyFunctionModifications(AbstractMetaFunction
func->setOriginalName(func->name());
func->setName(mod.renamedToName());
} else if (mod.isAccessModifier()) {
- funcRef -= AbstractMetaFunction::Friendly;
-
if (mod.isPublic())
funcRef.modifyAccess(Access::Public);
else if (mod.isProtected())
funcRef.modifyAccess(Access::Protected);
else if (mod.isPrivate())
funcRef.modifyAccess(Access::Private);
- else if (mod.isFriendly())
- funcRef += AbstractMetaFunction::Friendly;
}
-
- if (mod.isFinal())
- funcRef += AbstractMetaFunction::FinalInTargetLang;
- else if (mod.isNonFinal())
- funcRef -= AbstractMetaFunction::FinalInTargetLang;
}
}
-bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass)
+bool AbstractMetaBuilderPrivate::setupInheritance(const AbstractMetaClassPtr &metaClass)
{
if (metaClass->inheritanceDone())
return true;
@@ -1431,10 +1567,11 @@ 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);
@@ -1454,15 +1591,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()) {
@@ -1491,7 +1628,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));
}
@@ -1501,7 +1638,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();
@@ -1549,7 +1686,7 @@ bool AbstractMetaBuilderPrivate::traverseAddedGlobalFunction(const AddedFunction
AbstractMetaFunction *
AbstractMetaBuilderPrivate::traverseAddedFunctionHelper(const AddedFunctionPtr &addedFunc,
- AbstractMetaClass *metaClass /* = nullptr */,
+ const AbstractMetaClassPtr &metaClass /* = {} */,
QString *errorMessage)
{
auto returnType = translateType(addedFunc->returnType(), metaClass, {}, errorMessage);
@@ -1561,13 +1698,17 @@ AbstractMetaFunction *
return nullptr;
}
- auto metaFunction = new AbstractMetaFunction(addedFunc);
+ auto *metaFunction = new AbstractMetaFunction(addedFunc);
metaFunction->setType(returnType.value());
metaFunction->setFunctionType(functionTypeFromName(addedFunc->name()));
const auto &args = addedFunc->arguments();
- for (int i = 0; i < args.count(); ++i) {
+ qsizetype argCount = args.size();
+ // Check "foo(void)"
+ if (argCount == 1 && args.constFirst().typeInfo.isVoid())
+ argCount = 0;
+ for (qsizetype i = 0; i < argCount; ++i) {
const AddedFunction::Argument &arg = args.at(i);
auto type = translateType(arg.typeInfo, metaClass, {}, errorMessage);
if (Q_UNLIKELY(!type.has_value())) {
@@ -1614,7 +1755,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
@@ -1629,7 +1771,7 @@ AbstractMetaFunction *
}
bool AbstractMetaBuilderPrivate::traverseAddedMemberFunction(const AddedFunctionPtr &addedFunc,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
QString *errorMessage)
{
AbstractMetaFunction *metaFunction =
@@ -1639,11 +1781,11 @@ bool AbstractMetaBuilderPrivate::traverseAddedMemberFunction(const AddedFunction
const AbstractMetaArgumentList fargs = metaFunction->arguments();
if (metaClass->isNamespace())
- *metaFunction += AbstractMetaFunction::Static;
+ metaFunction->setCppAttribute(FunctionAttribute::Static);
if (metaFunction->name() == metaClass->name()) {
metaFunction->setFunctionType(AbstractMetaFunction::ConstructorFunction);
if (fargs.size() == 1) {
- 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())
@@ -1653,7 +1795,7 @@ bool AbstractMetaBuilderPrivate::traverseAddedMemberFunction(const AddedFunction
metaFunction->setDeclaringClass(metaClass);
metaFunction->setImplementingClass(metaClass);
- metaClass->addFunction(AbstractMetaFunctionCPtr(metaFunction));
+ AbstractMetaClass::addFunction(metaClass, AbstractMetaFunctionCPtr(metaFunction));
metaClass->setHasNonPrivateConstructor(true);
return true;
}
@@ -1669,9 +1811,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);
}
}
@@ -1681,15 +1823,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;
}
@@ -1786,7 +1928,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();
@@ -1801,9 +1943,48 @@ static bool applyArrayArgumentModifications(const FunctionModificationList &func
return true;
}
+// Create the meta type for a view (std::string_view -> std::string)
+static AbstractMetaType createViewOnType(const AbstractMetaType &metaType,
+ const TypeEntryCPtr &viewOnTypeEntry)
+{
+ auto result = metaType;
+ result.setTypeEntry(viewOnTypeEntry);
+ if (!metaType.isContainer() || !viewOnTypeEntry->isContainer())
+ return result;
+ // For containers, when sth with several template parameters
+ // (std::span<T, int N>) is mapped onto a std::vector<T>,
+ // remove the superfluous template parameters and strip 'const'.
+ const auto vcte = std::static_pointer_cast<const ContainerTypeEntry>(viewOnTypeEntry);
+ const auto &instantiations = metaType.instantiations();
+ AbstractMetaTypeList viewInstantiations;
+ const auto size = std::min(vcte->templateParameterCount(), instantiations.size());
+ for (qsizetype i = 0; i < size; ++i) {
+ auto ins = instantiations.at(i);
+ ins.setConstant(false);
+ viewInstantiations.append(ins);
+ }
+ result.setInstantiations(viewInstantiations);
+ return result;
+}
+
+void AbstractMetaBuilderPrivate::rejectFunction(const FunctionModelItem &functionItem,
+ const AbstractMetaClassPtr &currentClass,
+ AbstractMetaBuilder::RejectReason reason,
+ const QString &rejectReason)
+{
+ QString sortKey;
+ if (currentClass)
+ sortKey += currentClass->typeEntry()->qualifiedCppName() + u"::"_s;
+ sortKey += functionSignature(functionItem); // Sort without return type
+ const QString signatureWithType = functionItem->type().toString() + u' ' + sortKey;
+ m_rejectedFunctions.insert({reason, signatureWithType, sortKey, rejectReason});
+}
+
AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem,
- AbstractMetaClass *currentClass)
+ const AbstractMetaClassPtr &currentClass)
{
+ const auto *tdb = TypeDatabase::instance();
+
if (!functionItem->templateParameters().isEmpty())
return nullptr;
@@ -1821,34 +2002,40 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
}
return nullptr;
}
- 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 nullptr;
+ }
+
// 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 nullptr;
+ }
+ if (functionName == u"metaObject" && className != u"QObject")
+ return nullptr;
}
- 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);
+ if (tdb->isFunctionRejected(className, functionName, &rejectReason)) {
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, rejectReason);
return nullptr;
}
- const QString &signature = functionSignature(functionItem);
- const bool rejected =
- TypeDatabase::instance()->isFunctionRejected(className, signature, &rejectReason);
- if (rejected) {
+ const QString &signature = functionSignature(functionItem);
+ if (tdb->isFunctionRejected(className, signature, &rejectReason)) {
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, rejectReason);
if (ReportHandler::isDebug(ReportHandler::MediumDebug)) {
qCInfo(lcShiboken, "%s::%s was rejected by the type database (%s).",
qPrintable(className), qPrintable(signature), qPrintable(rejectReason));
@@ -1859,47 +2046,30 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
if (functionItem->isFriend())
return nullptr;
- const bool deprecated = functionItem->isDeprecated();
+ const auto cppAttributes = functionItem->attributes();
+ const bool deprecated = cppAttributes.testFlag(FunctionAttribute::Deprecated);
if (deprecated && m_skipDeprecated) {
- m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + QLatin1String(" is deprecated."),
- AbstractMetaBuilder::GenerationDisabled);
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, u" is deprecated."_s);
return nullptr;
}
- auto *metaFunction = new AbstractMetaFunction;
+ AbstractMetaFunction::Flags flags;
+ auto *metaFunction = new AbstractMetaFunction(functionName);
+ metaFunction->setCppAttributes(cppAttributes);
+ const QByteArray cSignature = signature.toUtf8();
+ const QString unresolvedSignature =
+ QString::fromUtf8(QMetaObject::normalizedSignature(cSignature.constData()));
+ 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());
@@ -1909,25 +2079,30 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
metaFunction->setType(AbstractMetaType::createVoid());
break;
case AbstractMetaFunction::ConstructorFunction:
- metaFunction->setExplicit(functionItem->isExplicit());
metaFunction->setName(currentClass->name());
metaFunction->setType(AbstractMetaType::createVoid());
break;
default: {
TypeInfo returnType = functionItem->type();
- if (TypeDatabase::instance()->isReturnTypeRejected(className, returnType.toString(), &rejectReason)) {
- m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled);
+ if (tdb->isReturnTypeRejected(className, returnType.toString(), &rejectReason)) {
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, rejectReason);
delete metaFunction;
return nullptr;
}
- auto type = translateType(returnType, currentClass, {}, &errorMessage);
+ TranslateTypeFlags flags;
+ if (functionItem->scopeResolution())
+ flags.setFlag(AbstractMetaBuilder::NoClassScopeLookup);
+ auto type = translateType(returnType, currentClass, flags, &errorMessage);
if (!type.has_value()) {
const QString reason = msgUnmatchedReturnType(functionItem, errorMessage);
+ const QString signature = qualifiedFunctionSignatureWithType(functionItem, className);
qCWarning(lcShiboken, "%s",
- qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason)));
- m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn, AbstractMetaBuilder::UnmatchedReturnType);
+ qPrintable(msgSkippingFunction(functionItem, signature, reason)));
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::UnmatchedReturnType, reason);
delete metaFunction;
return nullptr;
}
@@ -1938,41 +2113,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);
+ if (tdb->isArgumentTypeRejected(className, arg->type().toString(), &rejectReason)) {
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::GenerationDisabled, rejectReason);
delete metaFunction;
return nullptr;
}
- auto metaTypeO = translateType(arg->type(), currentClass, {}, &errorMessage);
+ TranslateTypeFlags flags;
+ if (arg->scopeResolution())
+ flags.setFlag(AbstractMetaBuilder::NoClassScopeLookup);
+ auto metaTypeO = translateType(arg->type(), currentClass, flags, &errorMessage);
if (!metaTypeO.has_value()) {
// If an invalid argument has a default value, simply remove it
// unless the function is virtual (since the override in the
// wrapper can then not correctly be generated).
- if (arg->defaultValue() && !functionItem->isVirtual()) {
+ if (arg->defaultValue()
+ && !functionItem->attributes().testFlag(FunctionAttribute::Virtual)) {
if (!currentClass || currentClass->typeEntry()->generateCode()) {
+ const QString signature = qualifiedFunctionSignatureWithType(functionItem, className);
qCWarning(lcShiboken, "%s",
- qPrintable(msgStrippingArgument(functionItem, i, originalQualifiedSignatureWithReturn, arg)));
+ qPrintable(msgStrippingArgument(functionItem, i, signature,
+ arg, errorMessage)));
}
break;
}
const QString reason = msgUnmatchedParameterType(arg, i, errorMessage);
+ const QString signature = qualifiedFunctionSignatureWithType(functionItem, className);
qCWarning(lcShiboken, "%s",
- qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason)));
- const QString rejectedFunctionSignature = originalQualifiedSignatureWithReturn
- + QLatin1String(": ") + reason;
- m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedArgumentType);
+ qPrintable(msgSkippingFunction(functionItem, signature, reason)));
+ rejectFunction(functionItem, currentClass,
+ AbstractMetaBuilder::UnmatchedArgumentType, reason);
delete metaFunction;
return nullptr;
}
@@ -1983,10 +2173,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;
@@ -2002,20 +2190,15 @@ AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const Functio
? AbstractMetaFunction::findClassModifications(metaFunction, currentClass)
: AbstractMetaFunction::findGlobalModifications(metaFunction);
- for (const FunctionModification &mod : functionMods) {
- if (mod.exceptionHandling() != TypeSystem::ExceptionHandling::Unspecified)
- metaFunction->setExceptionHandlingModification(mod.exceptionHandling());
- 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);
@@ -2048,7 +2231,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);
@@ -2064,35 +2247,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};
}
@@ -2116,7 +2303,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};
}
@@ -2126,25 +2313,37 @@ 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)
-{
- const 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);
return {};
}
+ // 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()) {
+ const auto pte = std::static_pointer_cast<const PrimitiveTypeEntry>(e);
+ types[i] = basicReferencedNonBuiltinTypeEntry(pte);
+ }
+ }
+
if (types.size() == 1)
return types;
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;
});
@@ -2167,10 +2366,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;
@@ -2178,9 +2377,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)
{
@@ -2193,9 +2577,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)
@@ -2222,10 +2613,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;
}
@@ -2233,7 +2624,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 {};
}
@@ -2249,7 +2640,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
@@ -2273,13 +2664,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);
@@ -2292,8 +2683,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;
@@ -2304,7 +2696,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
@@ -2312,23 +2704,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;
@@ -2339,15 +2740,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);
}
}
@@ -2373,8 +2777,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()) {
@@ -2408,7 +2812,7 @@ std::optional<AbstractMetaType>
std::optional<AbstractMetaType>
AbstractMetaBuilder::translateType(const TypeInfo &_typei,
- AbstractMetaClass *currentClass,
+ const AbstractMetaClassPtr &currentClass,
TranslateTypeFlags flags,
QString *errorMessage)
{
@@ -2419,7 +2823,7 @@ std::optional<AbstractMetaType>
std::optional<AbstractMetaType>
AbstractMetaBuilder::translateType(const QString &t,
- AbstractMetaClass *currentClass,
+ const AbstractMetaClassPtr &currentClass,
TranslateTypeFlags flags,
QString *errorMessageIn)
{
@@ -2442,14 +2846,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;
@@ -2462,7 +2866,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;
@@ -2474,113 +2878,163 @@ qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringV
return 0;
}
-QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &item,
- const AbstractMetaType &type,
- const AbstractMetaClass *implementingClass,
- int /* argumentIndex */)
+// 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 AbstractMetaClassCPtr &klass) const
+{
+ return d->fixEnumDefault(type, expr, klass);
+}
+
+void AbstractMetaBuilder::setCodeModelTestMode(bool b)
+{
+ 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
{
- QString expr = item->defaultValueExpression();
- if (expr.isEmpty() || expr == u"{}")
+ expr.replace(u'\n', u' '); // breaks signature parser
+
+ if (AbstractMetaBuilder::dontFixDefaultValue(expr))
return expr;
- 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()) {
- bool isNumber;
- expr.toInt(&isNumber);
- if (!isNumber && expr.indexOf(colonColon()) < 0) {
- // Add the enum/flag scope to default value, making it usable
- // from other contexts beside its owner class hierarchy
- static const QRegularExpression typeRegEx(QStringLiteral("[^<]*[<]([^:]*::).*"));
- Q_ASSERT(typeRegEx.isValid());
- const QRegularExpressionMatch match = typeRegEx.match(type.minimalSignature());
- if (match.hasMatch())
- expr.prepend(match.captured(1));
- }
- } 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 (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;
@@ -2589,8 +3043,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;
@@ -2610,19 +3064,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;
@@ -2642,7 +3095,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.
@@ -2660,7 +3113,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 {};
@@ -2672,16 +3125,34 @@ 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,
+ InheritTemplateFlags flags)
+{
+ auto result = std::make_shared<AbstractMetaClass>();
+ result->setTypeDef(true);
+
+ result->setTypeEntry(te);
+ if (!AbstractMetaBuilderPrivate::inheritTemplate(result, templateClass,
+ templateTypes, flags)) {
+ return {};
+ }
+ AbstractMetaBuilderPrivate::inheritTemplateFunctions(result);
+ return result;
+}
+
+bool AbstractMetaBuilderPrivate::inheritTemplate(const AbstractMetaClassPtr &subclass,
+ const AbstractMetaClassCPtr &templateClass,
const TypeInfo &info)
{
AbstractMetaTypeList templateTypes;
for (const TypeInfo &i : info.instantiations()) {
- QString typeName = i.qualifiedName().join(colonColon());
+ QString typeName = i.qualifiedName().join(u"::"_s);
TypeDatabase *typeDb = TypeDatabase::instance();
- TypeEntry *t = nullptr;
+ 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
@@ -2689,18 +3160,18 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
if (isNumber(typeName)) {
t = typeDb->findType(typeName);
if (!t) {
- auto parent = subclass->typeEntry()->typeSystemTypeEntry();
+ auto parent = typeSystemTypeEntry(subclass->typeEntry());
t = TypeDatabase::instance()->addConstantValueTypeEntry(typeName, parent);
}
} else {
QStringList possibleNames;
- possibleNames << subclass->qualifiedCppName() + colonColon() + typeName;
- possibleNames << templateClass->qualifiedCppName() + colonColon() + typeName;
+ possibleNames << subclass->qualifiedCppName() + u"::"_s + typeName;
+ possibleNames << templateClass->qualifiedCppName() + u"::"_s + typeName;
if (subclass->enclosingClass())
- possibleNames << subclass->enclosingClass()->qualifiedCppName() + colonColon() + typeName;
+ possibleNames << subclass->enclosingClass()->qualifiedCppName() + u"::"_s + typeName;
possibleNames << typeName;
- for (const QString &possibleName : qAsConst(possibleNames)) {
+ for (const QString &possibleName : std::as_const(possibleNames)) {
t = typeDb->findType(possibleName);
if (t)
break;
@@ -2720,36 +3191,147 @@ bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass,
<< info.toString() << ". The corresponding type was not found in the typesystem.";
}
}
+ return inheritTemplate(subclass, templateClass, templateTypes);
+}
+bool AbstractMetaBuilderPrivate::inheritTemplate(const AbstractMetaClassPtr &subclass,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes,
+ InheritTemplateFlags flags)
+{
subclass->setTemplateBaseClass(templateClass);
+ if (flags.testFlag(InheritTemplateFlag::SetEnclosingClass))
+ subclass->setEnclosingClass(templateClass->enclosingClass());
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.get(),
+ &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());
@@ -2761,82 +3343,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());
- }
-
- 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 (doInheritTemplateFunction(function, existingSubclassFuncs,
+ templateClass, subclass)) {
+ AbstractMetaFunctionCPtr f = inheritTemplateMember(function, templateTypes,
+ templateClass, subclass);
+ if (f)
+ AbstractMetaClass::addFunction(subclass, f);
}
-
-
- 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
@@ -2845,8 +3358,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;
}
@@ -2861,7 +3373,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();
@@ -2872,7 +3384,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;
@@ -2901,63 +3413,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)));
@@ -2966,70 +3450,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;
@@ -3039,10 +3490,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)) {
@@ -3052,14 +3505,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();
@@ -3085,24 +3538,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
@@ -3116,8 +3589,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);
@@ -3127,21 +3600,6 @@ void AbstractMetaBuilderPrivate::pushScope(const NamespaceModelItem &item)
}
}
-AbstractMetaArgumentList AbstractMetaBuilderPrivate::reverseList(const AbstractMetaArgumentList &list)
-{
- AbstractMetaArgumentList ret;
-
- int index = list.size();
- for (const AbstractMetaArgument &a : list) {
- AbstractMetaArgument arg = a;
- arg.setArgumentIndex(index);
- ret.prepend(arg);
- index--;
- }
-
- return ret;
-}
-
void AbstractMetaBuilder::setGlobalHeaders(const QFileInfoList &globalHeaders)
{
d->m_globalHeaders = globalHeaders;
@@ -3165,13 +3623,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)
@@ -3181,13 +3644,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()) {
@@ -3235,9 +3698,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 97c324f51..cbd8c7034 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,23 +75,66 @@ 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,
+ InheritTemplateFlags flags = {});
+
+ /// 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 AbstractMetaClassCPtr &scope,
+ QStringView value);
+
+ static bool dontFixDefaultValue(QStringView expr);
+
+ // For testing purposes
+ 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;
#endif
diff --git a/sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp b/sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp
new file mode 100644
index 000000000..68eef737a
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/abstractmetabuilder_helpers.cpp
@@ -0,0 +1,202 @@
+// 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 "enumtypeentry.h"
+#include "flagstypeentry.h"
+
+using namespace Qt::StringLiterals;
+
+using QStringViewList = QList<QStringView>;
+
+// Return a prefix to fully qualify value, eg:
+// resolveScopePrefix("Class::NestedClass::Enum::Value1", "Enum::Value1")
+// -> "Class::NestedClass::")
+static QString resolveScopePrefixHelper(const QStringViewList &scopeList,
+ QStringView value)
+{
+ QString name;
+ for (qsizetype i = scopeList.size() - 1 ; i >= 0; --i) {
+ const QString prefix = scopeList.at(i).toString() + u"::"_s;
+ if (value.startsWith(prefix))
+ name.clear();
+ else
+ name.prepend(prefix);
+ }
+ return name;
+}
+
+QString AbstractMetaBuilder::resolveScopePrefix(const AbstractMetaClassCPtr &scope,
+ QStringView value)
+{
+ if (!scope)
+ return {};
+ const QString &qualifiedCppName = scope->qualifiedCppName();
+ const QStringViewList scopeList =
+ QStringView{qualifiedCppName}.split(u"::"_s, Qt::SkipEmptyParts);
+ return resolveScopePrefixHelper(scopeList, value);
+}
+
+// Return the scope for fully qualifying the enumeration value
+static QString resolveEnumValueScopePrefix(const AbstractMetaEnum &metaEnum,
+ QStringView value)
+{
+ 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"::"_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);
+}
+
+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 isIntegerConstant(const QStringView expr)
+{
+ bool isNumber;
+ auto n = expr.toInt(&isNumber, /* guess base: 0x or decimal */ 0);
+ Q_UNUSED(n);
+ 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 AbstractMetaClassCPtr &klass) const
+{
+ // QFlags construct from integers, do not fix that
+ if (isIntegerConstant(expr))
+ return expr;
+
+ const QString field = qualifyStaticField(klass, expr);
+ if (!field.isEmpty())
+ return field;
+
+ const auto typeEntry = type.typeEntry();
+ EnumTypeEntryCPtr enumTypeEntry;
+ FlagsTypeEntryCPtr flagsTypeEntry;
+ if (typeEntry->isFlags()) {
+ flagsTypeEntry = std::static_pointer_cast<const FlagsTypeEntry>(typeEntry);
+ enumTypeEntry = flagsTypeEntry->originator();
+ } else {
+ Q_ASSERT(typeEntry->isEnum());
+ enumTypeEntry = std::static_pointer_cast<const EnumTypeEntry>(typeEntry);
+ }
+ // Use the enum's qualified name (would otherwise be "QFlags<Enum>")
+ if (!enumTypeEntry->qualifiedCppName().contains(u"::"))
+ return expr; // Global enum, nothing to fix here
+
+ // This is a somehow scoped enum
+ AbstractMetaEnum metaEnum = m_enums.value(enumTypeEntry);
+
+ if (isQualifiedCppIdentifier(expr)) // A single enum value
+ return resolveEnumValueScopePrefix(metaEnum, expr) + expr;
+
+ QString result;
+ // Is this a cast from integer or other type ("Enum(-1)" or "Options(0x10|0x20)"?
+ // Prepend the scope (assuming enum and flags are in the same scope).
+ auto parenPos = expr.indexOf(u'(');
+ const bool typeCast = parenPos != -1 && expr.endsWith(u')')
+ && isQualifiedCppIdentifier(QStringView{expr}.left(parenPos));
+ if (typeCast) {
+ const QString prefix =
+ AbstractMetaBuilder::resolveScopePrefix(metaEnum.enclosingClass(), expr);
+ result += prefix;
+ parenPos += prefix.size();
+ }
+ result += expr;
+
+ // Extract "Option1 | Option2" from "Options(Option1 | Option2)"
+ QStringView innerExpression = typeCast
+ ? QStringView{result}.mid(parenPos + 1, result.size() - parenPos - 2)
+ : QStringView{result};
+
+ // Quick check for number "Options(0x4)"
+ if (isIntegerConstant(innerExpression))
+ return result;
+
+ // Quick check for single enum value "Options(Option1)"
+ if (isQualifiedCppIdentifier(innerExpression)) {
+ const QString prefix = resolveEnumValueScopePrefix(metaEnum, innerExpression);
+ result.insert(parenPos + 1, prefix);
+ return result;
+ }
+
+ // Tokenize simple "A | B" expressions and qualify the enum values therein.
+ // Anything more complicated is left as is ATM.
+ if (!innerExpression.contains(u'|') || innerExpression.contains(u'&')
+ || innerExpression.contains(u'^') || innerExpression.contains(u'(')
+ || innerExpression.contains(u'~')) {
+ return result;
+ }
+
+ const QList<QStringView> tokens = innerExpression.split(u'|', Qt::SkipEmptyParts);
+ QStringList qualifiedTokens;
+ qualifiedTokens.reserve(tokens.size());
+ for (const auto &tokenIn : tokens) {
+ const auto token = tokenIn.trimmed();
+ QString qualified = token.toString();
+ if (!isIntegerConstant(token) && isQualifiedCppIdentifier(token))
+ qualified.prepend(resolveEnumValueScopePrefix(metaEnum, token));
+ qualifiedTokens.append(qualified);
+ }
+ 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 bcfd7bc73..d7aaba5b0 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,88 @@ 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);
+ const AbstractMetaClassPtr &currentClass);
+ void traverseFunctions(const ScopeModelItem& item,
+ const AbstractMetaClassPtr &parent);
static void applyFunctionModifications(AbstractMetaFunction *func);
- void traverseFields(const ScopeModelItem &item, AbstractMetaClass *parent);
+ void traverseFields(const ScopeModelItem &item, const AbstractMetaClassPtr &parent);
bool traverseStreamOperator(const FunctionModelItem &functionItem,
- AbstractMetaClass *currentClass);
+ const AbstractMetaClassPtr &currentClass);
void traverseOperatorFunction(const FunctionModelItem &item,
- AbstractMetaClass *currentClass);
+ const AbstractMetaClassPtr &currentClass);
AbstractMetaFunction *traverseAddedFunctionHelper(const AddedFunctionPtr &addedFunc,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
QString *errorMessage);
bool traverseAddedGlobalFunction(const AddedFunctionPtr &addedFunc,
QString *errorMessage);
bool traverseAddedMemberFunction(const AddedFunctionPtr &addedFunc,
- AbstractMetaClass *metaClass,
+ const AbstractMetaClassPtr &metaClass,
QString *errorMessage);
- AbstractMetaFunction *traverseFunction(const FunctionModelItem &function,
- AbstractMetaClass *currentClass);
+ void rejectFunction(const FunctionModelItem &functionItem,
+ const AbstractMetaClassPtr &currentClass,
+ AbstractMetaBuilder::RejectReason reason,
+ const QString &rejectReason);
+ AbstractMetaFunction *traverseFunction(const FunctionModelItem &function,
+ const AbstractMetaClassPtr &currentClass);
std::optional<AbstractMetaField> traverseField(const VariableModelItem &field,
- const AbstractMetaClass *cls);
- void checkFunctionModifications();
+ const AbstractMetaClassCPtr &cls);
+ void checkFunctionModifications() const;
void registerHashFunction(const FunctionModelItem &functionItem,
- AbstractMetaClass *currentClass);
+ const AbstractMetaClassPtr &currentClass);
void registerToStringCapabilityIn(const NamespaceModelItem &namespaceItem);
void registerToStringCapability(const FunctionModelItem &functionItem,
- AbstractMetaClass *currentClass);
+ const AbstractMetaClassPtr &currentClass);
/**
* A conversion operator function should not have its owner class as
@@ -141,45 +144,67 @@ public:
*/
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);
-
- static QString fixDefaultValue(const ArgumentModelItem &item,
- const AbstractMetaType &type,
- const AbstractMetaClass *,
- int argumentIndex);
+ 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,
+ InheritTemplateFlags flags = {});
+
+ 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);
@@ -187,30 +212,31 @@ public:
static bool isEnum(const FileModelItem &dom, const QStringList &qualifiedName);
void sortLists();
- static AbstractMetaArgumentList reverseList(const AbstractMetaArgumentList &list);
- void setInclude(TypeEntry *te, const QString &path) const;
+ void setInclude(const TypeEntryPtr &te, const QString &path) const;
static void fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods);
- void fillAddedFunctions(AbstractMetaClass *metaClass);
- const AbstractMetaClass *resolveTypeSystemTypeDef(const AbstractMetaType &t) const;
+ void fillAddedFunctions(const AbstractMetaClassPtr &metaClass);
+ AbstractMetaClassCPtr resolveTypeSystemTypeDef(const AbstractMetaType &t) const;
+
+ void fixSmartPointers();
- AbstractMetaBuilder *q;
+ AbstractMetaBuilder *q = nullptr;
AbstractMetaClassList m_metaClasses;
AbstractMetaClassList m_templates;
AbstractMetaClassList m_smartPointers;
- QHash<const _CodeModelItem *, AbstractMetaClass *> m_itemToClass;
- QHash<const AbstractMetaClass *, const _CodeModelItem *> m_classToItem;
+ QHash<const _CodeModelItem *, AbstractMetaClassPtr > m_itemToClass;
+ QHash<AbstractMetaClassCPtr, const _CodeModelItem *> m_classToItem;
AbstractMetaFunctionCList m_globalFunctions;
AbstractMetaEnumList m_globalEnums;
- using RejectMap = QMap<QString, AbstractMetaBuilder::RejectReason>;
+ using RejectSet = std::set<RejectEntry>;
- RejectMap m_rejectedClasses;
- RejectMap m_rejectedEnums;
- RejectMap m_rejectedFunctions;
- RejectMap m_rejectedFields;
+ RejectSet m_rejectedClasses;
+ RejectSet m_rejectedEnums;
+ RejectSet m_rejectedFunctions;
+ RejectSet m_rejectedFields;
- QHash<const TypeEntry *, AbstractMetaEnum> m_enums;
+ QHash<TypeEntryCPtr, AbstractMetaEnum> m_enums;
QList<NamespaceModelItem> m_scopes;
@@ -218,9 +244,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 44e8ddc84..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) {
@@ -87,6 +67,16 @@ bool AbstractMetaField::isModifiedRemoved(int types) const
return false;
}
+bool AbstractMetaField::generateOpaqueContainer() const
+{
+ const FieldModificationList &mods = modifications();
+ for (const FieldModification &mod : mods) {
+ if (mod.isOpaqueContainer())
+ return true;
+ }
+ return false;
+}
+
const AbstractMetaType &AbstractMetaField::type() const
{
return d->m_type;
@@ -133,7 +123,7 @@ void AbstractMetaField::setStatic(bool s)
QString AbstractMetaField::qualifiedCppName() const
{
- return enclosingClass()->qualifiedCppName() + QLatin1String("::")
+ return enclosingClass()->qualifiedCppName() + u"::"_s
+ originalName();
}
@@ -212,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 e6435f68d..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,14 @@ 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;
void setType(const AbstractMetaType &type);
@@ -94,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 2199d7fe2..11a02f154 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetafunction.cpp
@@ -1,54 +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;
};
@@ -60,7 +48,6 @@ public:
AbstractMetaFunctionPrivate()
: m_constant(false),
m_reverse(false),
- m_explicit(false),
m_pointerOperator(false),
m_isCallOperator(false)
{
@@ -73,7 +60,10 @@ 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);
QString m_name;
QString m_originalName;
@@ -81,22 +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;
- const AbstractMetaClass *m_class = nullptr;
- const AbstractMetaClass *m_implementingClass = nullptr;
- const AbstractMetaClass *m_declaringClass = nullptr;
+ QString m_modifiedTypeName;
+ 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;
@@ -107,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);
@@ -122,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);
@@ -217,23 +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;
- auto *pte = static_cast<const PrimitiveTypeEntry *>(d->m_type.typeEntry());
- // Walk along typedefs
- while (auto *referencedPte = pte->referencedTypeEntry())
- pte =referencedPte;
- return pte->name() == u"bool";
+ return basicReferencedTypeEntry(d->m_type.typeEntry())->name() == u"bool";
}
bool AbstractMetaFunction::isOperatorBool() const
@@ -268,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())
@@ -283,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();
@@ -298,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;
}
@@ -327,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
@@ -358,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);
@@ -384,10 +413,39 @@ AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const Abstra
return result;
}
+// Is this the const overload of another function of equivalent return type?
+bool AbstractMetaFunction::isConstOverloadOf(const AbstractMetaFunction *other) const
+{
+ const auto argumentCount = d->m_arguments.size();
+ if (!isConstant() || other->isConstant() || name() != other->name()
+ || argumentCount != other->arguments().size()) {
+ return false;
+ }
+
+ // Match "const Foo &getFoo() const" / "Foo &getFoo()" / "Foo getFoo() const"
+ const auto otherType = other->type();
+ if (d->m_type.name() != otherType.name()
+ || d->m_type.indirectionsV() != otherType.indirectionsV()) {
+ return false;
+ }
+
+ const auto &otherArguments = other->arguments();
+ for (qsizetype a = 0; a < argumentCount; ++a) {
+ if (d->m_arguments.at(a).type() != otherArguments.at(a).type())
+ return false;
+ }
+ return true;
+}
+
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());
@@ -400,6 +458,7 @@ AbstractMetaFunction *AbstractMetaFunction::copy() const
cpy->setExceptionSpecification(d->m_exceptionSpecification);
cpy->setAllowThreadModification(d->m_allowThreadModification);
cpy->setExceptionHandlingModification(d->m_exceptionHandlingModification);
+ cpy->d->m_modifiedTypeName = d->m_modifiedTypeName;
cpy->d->m_addedFunction = d->m_addedFunction;
cpy->d->m_arguments = d->m_arguments;
@@ -423,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
@@ -459,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;
}
@@ -484,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;
@@ -496,31 +589,47 @@ 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
{
- AbstractMetaArgumentList arguments = this->arguments();
-
int count = 0;
- for (int i = 0; i < arguments.size(); ++i && ++count) {
- if (argumentRemoved(i + 1))
+ 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;
- else if (!arguments.at(i).defaultValueExpression().isEmpty())
+ else if (!arg.defaultValueExpression().isEmpty())
break;
}
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;
@@ -535,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()) {
@@ -564,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
{
@@ -579,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;
}
@@ -625,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
@@ -676,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
@@ -685,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
@@ -699,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;
}
@@ -737,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()) {
@@ -749,18 +896,22 @@ TypeSystem::Ownership AbstractMetaFunction::argumentTargetOwnership(const Abstra
return TypeSystem::UnspecifiedOwnership;
}
-QString AbstractMetaFunction::typeReplaced(int key) const
+const QString &AbstractMetaFunction::modifiedTypeName() const
{
- for (const auto &modification : modifications(declaringClass())) {
- for (const ArgumentModification &argumentModification : modification.argument_mods()) {
- if (argumentModification.index() == key
- && !argumentModification.modifiedType().isEmpty()) {
- return argumentModification.modifiedType();
- }
- }
- }
+ return d->m_modifiedTypeName;
+}
- return QString();
+bool AbstractMetaFunction::generateOpaqueContainerReturn() const
+{
+ 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
@@ -774,6 +925,56 @@ bool AbstractMetaFunction::isModifiedToArray(int argumentIndex) const
return false;
}
+// Note: The declaring class must be correctly set for this to work.
+bool AbstractMetaFunctionPrivate::applyTypeModification(const AbstractMetaFunction *q,
+ const QString &type,
+ int number, QString *errorMessage)
+{
+ if (number < 0 || number > m_arguments.size()) {
+ *errorMessage =
+ msgTypeModificationFailed(type, number, q,
+ msgArgumentOutOfRange(number, 0, m_arguments.size()));
+ return false;
+ }
+
+ // Modified return types may have unparseable types like Python tuples
+ if (number == 0) {
+ m_modifiedTypeName = type;
+ return true;
+ }
+
+ auto typeOpt = AbstractMetaType::fromString(type, errorMessage);
+ if (!typeOpt.has_value()) {
+ *errorMessage = msgTypeModificationFailed(type, number, q, *errorMessage);
+ return false;
+ }
+ m_arguments[number - 1].setModifiedType(typeOpt.value());
+ return true;
+}
+
+void AbstractMetaFunction::applyTypeModifications()
+{
+ QString errorMessage;
+ for (const auto &modification : modifications(declaringClass())) {
+ for (const ArgumentModification &am : modification.argument_mods()) {
+ const int n = am.index();
+ if (am.isTypeModified()
+ && !d->applyTypeModification(this, am.modifiedType(),
+ n, &errorMessage)) {
+ throw Exception(errorMessage);
+ } else if (am.isRemoved() && n != 0) {
+ if (n < 1 || n > d->m_arguments.size()) {
+ errorMessage =
+ msgArgumentRemovalFailed(this, n,
+ msgArgumentOutOfRange(n, 1, d->m_arguments.size()));
+ throw Exception(errorMessage);
+ }
+ d->m_arguments[n - 1].setModifiedRemoved(true);
+ }
+ }
+ }
+}
+
QString AbstractMetaFunction::pyiTypeReplaced(int argumentIndex) const
{
for (const auto &modification : modifications(declaringClass())) {
@@ -796,28 +997,26 @@ 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(',');
-
- QString typeName;
- if (comment)
- typeName = q->typeReplaced(i + 1);
- if (typeName.isEmpty())
- typeName = m_arguments.at(i).type().minimalSignature();
- result += typeName;
+ result += u',';
+
+ 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()) {
- QString typeName = q->typeReplaced(0);
- if (typeName.isEmpty())
- typeName = q->type().minimalSignature();
- result += QStringLiteral("->") + typeName;
+ result += u"->"_s;
+ result += q->isTypeModified()
+ ? q->modifiedTypeName() : q->type().minimalSignature();
}
return result;
}
@@ -829,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);
@@ -837,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;
@@ -867,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;
@@ -889,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);
}
@@ -901,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();
}
@@ -918,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
@@ -1011,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
@@ -1024,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;
}
@@ -1082,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();
}
@@ -1113,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
@@ -1178,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
@@ -1203,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)
@@ -1241,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;
@@ -1299,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;
}
@@ -1323,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);
@@ -1333,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);
}
@@ -1363,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
{
@@ -1388,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)
@@ -1402,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 20e2e6d90..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,40 +275,61 @@ 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;
CompareResult compareTo(const AbstractMetaFunction *other) const;
+ bool isConstOverloadOf(const AbstractMetaFunction *other) const;
bool operator <(const AbstractMetaFunction &a) const;
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(); }
+ bool generateOpaqueContainerReturn() const;
- QString typeReplaced(int argument_index) const;
bool isModifiedToArray(int argumentIndex) const;
+ void applyTypeModifications();
+
/// Return the (modified) type for the signature; modified-pyi-type, modified-type
QString pyiTypeReplaced(int argumentIndex) const;
@@ -340,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;
@@ -408,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,
@@ -418,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
@@ -438,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);
@@ -458,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 080257346..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,24 +50,30 @@ 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),
m_hasCachedWrapper(false)
{
}
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;
@@ -97,33 +87,33 @@ 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;
mutable uint m_hasCachedWrapper : 1;
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;
@@ -160,24 +150,6 @@ void AbstractMetaClass::operator-=(AbstractMetaClass::Attribute attribute)
d->m_attributes.setFlag(attribute, false);
}
-/*******************************************************************************
- * Returns true if this class is a subclass of the given class
- */
-bool AbstractMetaClass::inheritsFrom(const AbstractMetaClass *cls) const
-{
- Q_ASSERT(cls);
-
- const AbstractMetaClass *clazz = this;
- while (clazz) {
- if (clazz == cls)
- return true;
-
- clazz = clazz->baseClass();
- }
-
- return false;
-}
-
bool AbstractMetaClass::isPolymorphic() const
{
return d->m_isPolymorphic;
@@ -206,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);
@@ -238,7 +197,7 @@ AbstractMetaFunctionCList AbstractMetaClass::functionsInTargetLang() const
AbstractMetaFunctionCList AbstractMetaClass::implicitConversions() const
{
- if (!hasCloneOperator() && !hasExternalConversionOperators())
+ if (!isCopyConstructible() && !hasExternalConversionOperators())
return {};
AbstractMetaFunctionCList returned;
@@ -250,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()) {
@@ -348,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;
}
@@ -366,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
@@ -420,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;
@@ -432,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
@@ -475,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);
}
@@ -508,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);
@@ -534,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;
}
@@ -577,19 +542,19 @@ bool AbstractMetaClass::isInvisibleNamespace() const
&& !NamespaceTypeEntry::isVisibleScope(d->m_typeEntry);
}
-static bool qObjectPredicate(const AbstractMetaClass *c)
-{
- return c->qualifiedCppName() == QLatin1String("QObject");
-}
-
-bool AbstractMetaClass::isQObject() const
+bool AbstractMetaClass::isInlineNamespace() const
{
- return qObjectPredicate(this) || recurseClassHierarchy(this, qObjectPredicate) != nullptr;
+ 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
@@ -599,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(),
@@ -640,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) {
@@ -658,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;
}
@@ -683,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};
@@ -720,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};
}
@@ -727,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 {};
}
@@ -812,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
@@ -837,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());
+
+ 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;
+}
- d->addConstructor(AbstractMetaFunction::CopyConstructorFunction,
- Access::Public, {arg}, this);
+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
@@ -974,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
@@ -984,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();
});
}
@@ -992,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();
}
@@ -1018,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();
});
}
@@ -1033,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
@@ -1097,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
{
@@ -1108,13 +1136,21 @@ 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
{
return d->isUsingMember(c, memberName, minimumAccess);
}
+bool AbstractMetaClass::hasUsingMemberFor(const QString &memberName) const
+{
+ return std::any_of(d->m_usingMembers.cbegin(), d->m_usingMembers.cend(),
+ [&memberName](const UsingMember &um) {
+ return um.memberName == memberName;
+ });
+}
+
/* Goes through the list of functions and returns a list of all
functions matching all of the criteria in \a query.
*/
@@ -1131,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;
@@ -1206,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;
@@ -1216,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 {};
@@ -1243,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);
}
@@ -1284,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;
@@ -1306,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);
});
}
@@ -1315,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());
});
}
@@ -1323,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()) {
@@ -1344,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);
@@ -1352,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)
@@ -1375,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.
@@ -1384,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);
}
@@ -1400,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
@@ -1454,35 +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) {
- // 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
- }
+ // Set "override" in case it was not spelled out (since it
+ // is then not detected by clang parsing).
+ 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
@@ -1494,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) {
@@ -1558,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));
@@ -1567,16 +1573,19 @@ void AbstractMetaClass::fixFunctions()
bool hasPrivateConstructors = false;
bool hasPublicConstructors = false;
- for (const auto &func : qAsConst(funcs)) {
- for (const auto &mod : func->modifications(this)) {
+ // Apply modifications after the declaring class has been set
+ 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())
- qSharedPointerConstCast<AbstractMetaFunction>(func)->setName(mod.renamedToName());
+ ncFunc->setName(mod.renamedToName());
}
+ ncFunc->applyTypeModifications();
// 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()) {
@@ -1589,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
@@ -1606,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;
@@ -1628,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)
@@ -1657,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;
@@ -1675,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;
@@ -1693,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) {
@@ -1704,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)
@@ -1738,13 +1728,42 @@ const AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassCLi
return nullptr;
}
-const AbstractMetaClass *AbstractMetaClass::findBaseClass(const QString &qualifiedName) const
+/// Returns true if this class is a subclass of the given class
+bool inheritsFrom(const AbstractMetaClassCPtr &c, const AbstractMetaClassCPtr &cls)
{
- if (d->m_templateBaseClass != nullptr
- && d->m_templateBaseClass->qualifiedCppName() == qualifiedName) {
- return d->m_templateBaseClass;
+ Q_ASSERT(cls != nullptr);
+
+ if (c == cls || c->templateBaseClass() == cls)
+ return true;
+
+ return bool(recurseClassHierarchy(c, [cls](const AbstractMetaClassCPtr &c) {
+ return cls.get() == c.get();
+ }));
+}
+
+bool inheritsFrom(const AbstractMetaClassCPtr &c, QAnyStringView name)
+{
+ if (c->qualifiedCppName() == name)
+ return true;
+
+ if (c->templateBaseClass() != nullptr
+ && c->templateBaseClass()->qualifiedCppName() == name) {
+ return true;
}
- return recurseClassHierarchy(this, [&qualifiedName](const AbstractMetaClass *c) {
+
+ return bool(recurseClassHierarchy(c, [&name](const AbstractMetaClassCPtr &c) {
+ return c->qualifiedCppName() == name;
+ }));
+}
+
+AbstractMetaClassCPtr findBaseClass(const AbstractMetaClassCPtr &c,
+ const QString &qualifiedName)
+{
+ auto tp = c->templateBaseClass();
+ if (tp && tp->qualifiedCppName() == qualifiedName)
+ return tp;
+
+ return recurseClassHierarchy(c, [&qualifiedName](const AbstractMetaClassCPtr &c) {
return c->qualifiedCppName() == qualifiedName;
});
}
@@ -1761,21 +1780,35 @@ 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
{
- if (!typeEntry()->isValue())
+ return d->m_valueTypeWithCopyConstructorOnly;
+}
+
+void AbstractMetaClass::setValueTypeWithCopyConstructorOnly(bool v)
+{
+ d->m_valueTypeWithCopyConstructorOnly = v;
+}
+
+bool AbstractMetaClass::determineValueTypeWithCopyConstructorOnly(const AbstractMetaClassCPtr &c,
+ bool avoidProtectedHack)
+{
+
+ if (!c->typeEntry()->isValue())
return false;
- if (attributes().testFlag(AbstractMetaClass::HasRejectedDefaultConstructor))
+ if (c->attributes().testFlag(AbstractMetaClass::HasRejectedDefaultConstructor))
return false;
- const auto ctors = 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;
@@ -1796,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 << '>';
}
@@ -1808,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() << '"';
}
@@ -1825,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);
@@ -1845,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);
@@ -1875,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);
@@ -1885,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 6f1971df9..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,14 +115,17 @@ 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;
AbstractMetaFunctionCList queryFunctionsByName(const QString &name) const;
static bool queryFunction(const AbstractMetaFunction *f, FunctionQueryOptions query);
@@ -181,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();
@@ -208,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 isQObject() const;
+ bool isInlineNamespace() const;
bool isQtNamespace() const;
QString qualifiedCppName() const;
bool hasSignals() const;
- bool inheritsFrom(const AbstractMetaClass *other) const;
/**
* Says if the class that declares or inherits a virtual function.
@@ -252,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;
};
@@ -323,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;
@@ -347,27 +311,28 @@ public:
bool isObjectType() const;
bool isCopyable() const;
bool isValueTypeWithCopyConstructorOnly() const;
-
- 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;
+ void setValueTypeWithCopyConstructorOnly(bool v);
+ 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;
@@ -379,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);
@@ -398,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);
@@ -406,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..802f549cf 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,12 +17,14 @@ class AbstractMetaFunction;
class AbstractMetaType;
struct UsingMember;
-using AbstractMetaFunctionPtr = QSharedPointer<AbstractMetaFunction>;
-using AbstractMetaFunctionCPtr = QSharedPointer<const AbstractMetaFunction>;
+using AbstractMetaFunctionPtr = std::shared_ptr<AbstractMetaFunction>;
+using AbstractMetaFunctionCPtr = std::shared_ptr<const AbstractMetaFunction>;
+using AbstractMetaClassPtr = std::shared_ptr<AbstractMetaClass>;
+using AbstractMetaClassCPtr = std::shared_ptr<const AbstractMetaClass>;
using AbstractMetaArgumentList = QList<AbstractMetaArgument>;
-using AbstractMetaClassList = QList<AbstractMetaClass *>;
-using AbstractMetaClassCList = QList<const AbstractMetaClass *>;
+using AbstractMetaClassList = QList<AbstractMetaClassPtr>;
+using AbstractMetaClassCList = QList<AbstractMetaClassCPtr>;
using AbstractMetaEnumList = QList<AbstractMetaEnum>;
using AbstractMetaEnumValueList = QList<AbstractMetaEnumValue>;
using AbstractMetaFieldList = QList<AbstractMetaField>;
diff --git a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
index 075315d58..dcfc74bbb 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
+++ b/sources/shiboken6/ApiExtractor/abstractmetatype.cpp
@@ -1,50 +1,114 @@
-/****************************************************************************
-**
-** 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>
#endif
+#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"_s, u"float"_s};
+ return result;
+}
+
+const QSet<QString> &AbstractMetaType::cppSignedCharTypes()
+{
+ 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"_s};
+ return result;
+}
+
+const QSet<QString> &AbstractMetaType::cppCharTypes()
+{
+ static const QSet<QString> result = cppSignedCharTypes() | cppUnsignedCharTypes();
+ return result;
+}
+
+const QSet<QString> &AbstractMetaType::cppSignedIntTypes()
+{
+ static QSet<QString> result;
+ if (result.isEmpty()) {
+ 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;
+}
+
+const QSet<QString> &AbstractMetaType::cppUnsignedIntTypes()
+{
+ static QSet<QString> result;
+ if (result.isEmpty()) {
+ 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;
+}
+
+const QSet<QString> &AbstractMetaType::cppIntegralTypes()
+{
+ static QSet<QString> result;
+ if (result.isEmpty()) {
+ result |= cppSignedIntTypes();
+ result |= cppUnsignedIntTypes();
+ result.insert(u"bool"_s);
+ }
+ return result;
+}
+
+const QSet<QString> &AbstractMetaType::cppPrimitiveTypes()
+{
+ static QSet<QString> result;
+ if (result.isEmpty()) {
+ result |= cppIntegralTypes();
+ result |= cppFloatTypes();
+ result.insert(u"wchar_t"_s);
+ }
+ return result;
+}
class AbstractMetaTypeData : public QSharedData
{
public:
- AbstractMetaTypeData(const TypeEntry *t);
+ AbstractMetaTypeData(const TypeEntryCPtr &t);
int actualIndirections() const;
bool passByConstRef() const;
@@ -53,9 +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;
- const TypeEntry *m_typeEntry;
+ template <class Predicate>
+ bool generateOpaqueContainer(Predicate p) const;
+
+ TypeEntryCPtr m_typeEntry;
AbstractMetaTypeList m_instantiations;
mutable QString m_cachedCppSignature;
mutable QString m_cachedPythonSignature;
@@ -77,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),
@@ -86,21 +155,32 @@ 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() : d(new AbstractMetaTypeData(nullptr))
+AbstractMetaType::AbstractMetaType(const TypeEntryCPtr &t) :
+ d(new AbstractMetaTypeData(t))
{
+ Q_ASSERT(t);
+}
+
+AbstractMetaType::AbstractMetaType()
+{
+ *this = AbstractMetaType::createVoid();
}
AbstractMetaType &AbstractMetaType::operator=(const AbstractMetaType &) = default;
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;
@@ -151,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;
@@ -184,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;
@@ -208,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
@@ -243,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;
@@ -271,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;
@@ -349,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();
@@ -467,10 +569,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;
}
@@ -478,13 +603,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
@@ -493,29 +618,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;
@@ -541,7 +667,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())
@@ -549,12 +675,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
@@ -563,22 +689,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;
}
@@ -589,7 +717,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
@@ -620,12 +748,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
@@ -633,11 +761,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;
@@ -649,19 +772,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 lhs.d->equals(*rhs.d);
+}
+
+bool AbstractMetaType::isEquivalent(const AbstractMetaType &rhs) const
{
- return d->equals(*rhs.d);
+ 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));
}
@@ -669,7 +803,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();
@@ -677,12 +811,55 @@ AbstractMetaType AbstractMetaType::createVoid()
return *metaType.data();
}
+void AbstractMetaType::dereference(QString *type)
+{
+ 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')');
+}
+
+bool AbstractMetaType::stripDereference(QString *type)
+{
+ if (type->startsWith(u"(*") && type->endsWith(u')')) {
+ type->chop(1);
+ type->remove(0, 2);
+ *type = type->trimmed();
+ return true;
+ }
+ if (type->startsWith(u'*')) {
+ type->remove(0, 1);
+ *type = type->trimmed();
+ return true;
+ }
+ return false;
+}
+
// Query functions for generators
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()
@@ -699,19 +876,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
@@ -730,15 +907,15 @@ bool AbstractMetaType::isPointerToWrapperType() const
return (isObjectType() && d->m_indirections.size() == 1) || isValuePointer();
}
-bool AbstractMetaType::shouldDereferencePointer() const
+bool AbstractMetaType::isWrapperPassedByReference() const
{
return d->m_referenceType == LValueReference && isWrapperType()
- && !isPointer();
+ && !isPointer();
}
bool AbstractMetaType::isCppIntegralPrimitive() const
{
- return d->m_typeEntry->isCppIntegralPrimitive();
+ return ::isCppIntegralPrimitive(d->m_typeEntry);
}
bool AbstractMetaType::isExtendedCppPrimitive() const
@@ -747,7 +924,129 @@ 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 = std::static_pointer_cast<const ComplexTypeEntry>(d->m_typeEntry);
+ result = cte->isValueTypeWithCopyConstructorOnly();
+ }
+ return result;
+}
+
+bool AbstractMetaType::valueTypeWithCopyConstructorOnlyPassed() const
+{
+ return (passByValue() || passByConstRef())
+ && isValueTypeWithCopyConstructorOnly();
+}
+
+using AbstractMetaTypeCache = QHash<QString, AbstractMetaType>;
+
+Q_GLOBAL_STATIC(AbstractMetaTypeCache, metaTypeFromStringCache)
+
+std::optional<AbstractMetaType>
+AbstractMetaType::fromString(const QString &typeSignatureIn, QString *errorMessage)
+{
+ 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);
+
+ it = cache.find(typeSignature);
+ if (it == cache.end()) {
+ auto metaType =
+ AbstractMetaBuilder::translateType(typeSignature, nullptr, {}, errorMessage);
+ if (Q_UNLIKELY(!metaType.has_value())) {
+ if (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 TypeEntryCPtr &typeEntry)
+{
+ QString typeName = typeEntry->qualifiedCppName();
+ 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 = AbstractMetaType(typeEntry).plainType();
+ cache.insert(typeName, metaType);
+ return metaType;
+}
+
+AbstractMetaType AbstractMetaType::fromAbstractMetaClass(const AbstractMetaClassCPtr &metaClass)
+{
+ return fromTypeEntry(metaClass->typeEntry());
+}
+
+template <class Predicate> // Predicate(containerTypeEntry, signature)
+bool AbstractMetaTypeData::generateOpaqueContainer(Predicate pred) const
+{
+ // Allow for passing containers by pointer as well.
+ if (!m_typeEntry->isContainer())
+ return false;
+ if (m_indirections.size() > 1)
+ return false;
+ auto containerTypeEntry = std::static_pointer_cast<const ContainerTypeEntry>(m_typeEntry);
+ auto kind = containerTypeEntry->containerKind();
+ if (kind != ContainerTypeEntry::ListContainer && kind != ContainerTypeEntry::SpanContainer)
+ return false;
+
+ 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:
+ break;
+ default:
+ return false;
+ }
+
+ return pred(containerTypeEntry, instantiationCppSignatures());
+}
+
+// Simple predicate for checking whether an opaque container should be generated
+static bool opaqueContainerPredicate(const ContainerTypeEntryCPtr &t,
+ const QStringList &instantiations)
+{
+ return t->generateOpaqueContainer(instantiations);
+}
+
+bool AbstractMetaType::generateOpaqueContainer() const
+{
+ return d->generateOpaqueContainer(opaqueContainerPredicate);
+}
+
+// Helper for determining whether a function should return an opaque container,
+// that is, the function return type is modified accordingly
+// (cf AbstractMetaFunction::generateOpaqueContainerReturn())
+bool AbstractMetaType::generateOpaqueContainerForGetter(const QString &modifiedType) const
+{
+ auto predicate = [&modifiedType](const ContainerTypeEntryCPtr &t,
+ const QStringList &instantiations) {
+ return t->opaqueContainerName(instantiations) == modifiedType;
+ };
+ return d->generateOpaqueContainer(predicate);
}
#ifndef QT_NO_DEBUG_STREAM
@@ -769,7 +1068,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]";
@@ -780,9 +1079,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 599321262..8a1ecdf20 100644
--- a/sources/shiboken6/ApiExtractor/abstractmetatype.h
+++ b/sources/shiboken6/ApiExtractor/abstractmetatype.h
@@ -1,40 +1,22 @@
-/****************************************************************************
-**
-** 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>
+
+#include <optional>
QT_FORWARD_DECLARE_CLASS(QDebug)
@@ -67,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;
@@ -87,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); }
@@ -123,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; }
@@ -137,6 +121,7 @@ public:
bool passByConstRef() const;
bool passByValue() const;
+ bool useStdMove() const;
ReferenceType referenceType() const;
void setReferenceType(ReferenceType ref);
@@ -160,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;
@@ -184,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);
@@ -194,6 +183,23 @@ public:
static AbstractMetaType createVoid();
+ /// Builds an AbstractMetaType object from a QString.
+ /// Returns nullopt if no type could be built from the string.
+ /// \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(const QString &typeSignatureIn, QString *errorMessage = nullptr);
+ /// Creates an AbstractMetaType object from a TypeEntry.
+ static AbstractMetaType fromTypeEntry(const TypeEntryCPtr &typeEntry);
+ /// Creates an AbstractMetaType object from an AbstractMetaClass.
+ static AbstractMetaType fromAbstractMetaClass(const 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
/// Check if type is a pointer.
bool isPointer() const;
@@ -214,20 +220,46 @@ public:
/// Checks if the type is an Object/QObject or pointer to Value Type.
/// In other words, tells if the type is "T*" and T has a Python wrapper.
bool isPointerToWrapperType() const;
- /// Checks if a meta type should be dereferenced by the Python method wrapper passing it to C++.
- bool shouldDereferencePointer() const;
+ /// Wrapper type passed by reference
+ bool isWrapperPassedByReference() 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;
+ /// Returns whether the underlying type is a value type with copy constructor only
+ bool isValueTypeWithCopyConstructorOnly() const;
+ /// Returns whether the type (function argument) is a value type with
+ /// copy constructor only is passed as value or const-ref and thus
+ /// no default value can be constructed.
+ bool valueTypeWithCopyConstructorOnlyPassed() const;
+ /// Returns whether to generate an opaque container for the type
+ bool generateOpaqueContainer() const;
+ /// Returns whether to generate an opaque container for a getter
+ bool generateOpaqueContainerForGetter(const QString &modifiedType) const;
+
+ /// Types for which libshiboken has built-in primitive converters
+ static const QSet<QString> &cppFloatTypes();
+ static const QSet<QString> &cppSignedCharTypes();
+ static const QSet<QString> &cppUnsignedCharTypes();
+ static const QSet<QString> &cppCharTypes();
+ static const QSet<QString> &cppSignedIntTypes();
+ static const QSet<QString> &cppUnsignedIntTypes();
+ static const QSet<QString> &cppIntegralTypes();
+ static const QSet<QString> &cppPrimitiveTypes();
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &debug) const;
#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;
@@ -236,11 +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); }
-
#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..83ee4437e 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
{
- TypeDatabase::instance()->addTypesystemPath(path);
+public:
+ explicit ApiExtractorOptionsParser(ApiExtractorOptions *o) : m_options(o) {}
+
+ bool handleBoolOption(const QString &key, OptionSource source) override;
+ bool handleOption(const QString &key, const QString &value,
+ OptionSource source) override;
+
+private:
+ void parseIncludePathOption(const QString &value, HeaderType headerType);
+ void parseIncludePathOption(const QStringList &values, HeaderType headerType);
+ void setLanguageLevel(const QString &value);
+
+ ApiExtractorOptions *m_options;
+};
+
+void ApiExtractorOptionsParser::parseIncludePathOption(const QString &value,
+ HeaderType headerType)
+{
+ if (value.isEmpty())
+ throw Exception(u"Empty value passed to include path option"_s);
+ const auto path = QFile::encodeName(QDir::cleanPath(value));
+ m_options->m_includePaths.append(HeaderPath{path, headerType});
}
-void 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;
+}
+
+bool ApiExtractorOptionsParser::handleBoolOption(const QString &key, OptionSource source)
+{
+ static const auto isystemOption = "isystem"_L1;
+
+ switch (source) {
+ case OptionSource::CommandLine:
+ case OptionSource::ProjectFile:
+ if (key == u"use-global-header") {
+ AbstractMetaBuilder::setUseGlobalHeader(true);
+ return true;
+ }
+ if (key == u"skip-deprecated") {
+ m_options->m_skipDeprecated = true;
+ return true;
+ }
+ break;
+
+ case OptionSource::CommandLineSingleDash:
+ if (key.startsWith(u'I')) { // Shorthand path arguments -I/usr/include...
+ parseIncludePathOption(key.sliced(1), HeaderType::Standard);
+ return true;
+ }
+ if (key.startsWith(u'F')) {
+ parseIncludePathOption(key.sliced(1), HeaderType::Framework);
+ return true;
+ }
+ if (key.startsWith(isystemOption)) {
+ parseIncludePathOption(key.sliced(isystemOption.size()), HeaderType::System);
+ return true;
+ }
+ break;
+ }
+ return false;
}
-void ApiExtractor::addIncludePath(const HeaderPath& path)
+bool ApiExtractorOptionsParser::handleOption(const QString &key, const QString &value,
+ OptionSource source)
{
- m_includePaths << path;
+ 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::addIncludePath(const HeaderPaths& paths)
+std::shared_ptr<OptionsParser> ApiExtractor::createOptionsParser()
{
- m_includePaths << paths;
+ return std::make_shared<ApiExtractorOptionsParser>(d);
}
-void ApiExtractor::setLogDirectory(const QString& logDir)
+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_logDirectory = logDir;
}
-void ApiExtractor::setCppFileNames(const QFileInfoList &cppFileName)
+ApiExtractor::~ApiExtractor()
{
- m_cppFileNames = cppFileName;
+ delete d->m_builder;
+ delete d;
}
-void ApiExtractor::setTypeSystem(const QString& typeSystemFileName)
+HeaderPaths ApiExtractor::includePaths() const
{
- m_typeSystemFileName = typeSystemFileName;
+ return d->m_includePaths;
}
-void ApiExtractor::setSkipDeprecated(bool value)
+void ApiExtractor::setLogDirectory(const QString& logDir)
{
- m_skipDeprecated = value;
- if (m_builder)
- m_builder->setSkipDeprecated(m_skipDeprecated);
+ d->m_logDirectory = logDir;
}
-void ApiExtractor::setSuppressWarnings ( bool value )
+void ApiExtractor::setCppFileNames(const QFileInfoList &cppFileName)
{
- TypeDatabase::instance()->setSuppressWarnings(value);
+ d->m_cppFileNames = cppFileName;
}
-void ApiExtractor::setSilent ( bool value )
+QFileInfoList ApiExtractor::cppFileNames() const
{
- ReportHandler::setSilent(value);
+ return d->m_cppFileNames;
}
-bool ApiExtractor::setApiVersion(const QString& package, const QString &version)
+void ApiExtractor::setTypeSystem(const QString& typeSystemFileName)
{
- return TypeDatabase::setApiVersion(package, version);
+ d->m_typeSystemFileName = typeSystemFileName;
}
-void ApiExtractor::setDropTypeEntries(const QStringList &dropEntries)
+QString ApiExtractor::typeSystem() const
{
- TypeDatabase::instance()->setDropTypeEntries(dropEntries);
+ 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,408 @@ 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 m_clangOptions;
+ return AbstractMetaBuilder::inheritTemplateMember(function, templateTypes,
+ templateClass, subclass);
}
-void ApiExtractor::setClangOptions(const QStringList &co)
+AbstractMetaClassPtr ApiExtractor::inheritTemplateClass(const ComplexTypeEntryPtr &te,
+ const AbstractMetaClassCPtr &templateClass,
+ const AbstractMetaTypeList &templateTypes,
+ InheritTemplateFlags flags)
{
- m_clangOptions = co;
+ return AbstractMetaBuilder::inheritTemplateClass(te, templateClass,
+ templateTypes, flags);
}
-void ApiExtractor::setUseGlobalHeader(bool h)
+QString ApiExtractorPrivate::getSimplifiedContainerTypeName(const AbstractMetaType &type)
{
- AbstractMetaBuilder::setUseGlobalHeader(h);
+ 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;
+}
+
+// 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 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();
+ InheritTemplateFlags flags;
+
+ 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();
+ } else {
+ flags.setFlag(InheritTemplateFlag::SetEnclosingClass);
+ }
+
+ TypedefEntryPtr typedefEntry(new TypedefEntry(name, ste->name(), ste->version(),
+ parentTypeEntry));
+ typedefEntry->setTargetLangPackage(ste->targetLangPackage());
+ auto instantiationEntry = TypeDatabase::initializeTypeDefEntry(typedefEntry, ste);
+
+ smp.specialized = ApiExtractor::inheritTemplateClass(instantiationEntry, smp.smartPointer,
+ {instantiatedType}, flags);
+ Q_ASSERT(smp.specialized);
+ if (withinNameSpace) { // 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 +836,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..feae9454c 100644
--- a/sources/shiboken6/ApiExtractor/apiextractor.h
+++ b/sources/shiboken6/ApiExtractor/apiextractor.h
@@ -1,109 +1,83 @@
-/****************************************************************************
-**
-** 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,
+ InheritTemplateFlags flags = {});
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..4fe6ecc1a
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/apiextractorflags.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 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)
+
+enum class InheritTemplateFlag
+{
+ SetEnclosingClass = 0x1
+};
+
+Q_DECLARE_FLAGS(InheritTemplateFlags, InheritTemplateFlag)
+Q_DECLARE_OPERATORS_FOR_FLAGS(InheritTemplateFlags)
+
+#endif // APIEXTRACTORFLAGS_H
diff --git a/sources/shiboken6/ApiExtractor/apiextractorresult.cpp b/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
index 04566ada2..2a48a30d1 100644
--- a/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
+++ b/sources/shiboken6/ApiExtractor/apiextractorresult.cpp
@@ -1,48 +1,82 @@
-/****************************************************************************
-**
-** 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"
-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;
+}
+
+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..88a2093f1 100644
--- a/sources/shiboken6/ApiExtractor/apiextractorresult.h
+++ b/sources/shiboken6/ApiExtractor/apiextractorresult.h
@@ -1,75 +1,78 @@
-/****************************************************************************
-**
-** 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;
+
+ 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 de0f2eb4f..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,14 +113,27 @@ 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)
{
m_scopeStack.push(NamespaceModelItem(new _FileModelItem(m_model)));
}
+ ~BuilderPrivate()
+ {
+ delete m_model;
+ }
// Determine scope from top item. Note that the scope list does not necessarily
// match the scope stack in case of forward-declared inner classes whose definition
@@ -196,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;
-
- bool visitHeader(const char *cFileName) 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);
@@ -215,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;
@@ -226,21 +214,22 @@ public:
ArgumentModelItem m_currentArgument;
VariableModelItem m_currentField;
TemplateTypeAliasModelItem m_currentTemplateTypeAlias;
- QByteArrayList m_systemIncludes; // files, like "memory"
- QByteArrayList 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:
@@ -283,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.
@@ -343,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);
@@ -356,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);
@@ -395,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;
}
@@ -417,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
@@ -436,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);
}
@@ -449,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));
@@ -520,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)
@@ -574,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)) {
}
@@ -584,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));
@@ -622,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 {};
@@ -644,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);
}
@@ -669,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
{
@@ -681,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:
@@ -735,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
@@ -749,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)
@@ -805,103 +765,115 @@ Builder::~Builder()
delete d;
}
-static const char *cBaseName(const char *fileName)
+static QString baseName(QString path)
{
- const char *lastSlash = std::strrchr(fileName, '/');
+ qsizetype lastSlash = path.lastIndexOf(u'/');
#ifdef Q_OS_WIN
- if (lastSlash == nullptr)
- lastSlash = std::strrchr(fileName, '\\');
+ if (lastSlash < 0)
+ lastSlash = path.lastIndexOf(u'\\');
#endif
- return lastSlash != nullptr ? (lastSlash + 1) : fileName;
+ if (lastSlash > 0)
+ path.remove(0, lastSlash + 1);
+ return path;
}
-static inline bool cCompareFileName(const char *f1, const char *f2)
+const char * BuilderPrivate::specialSystemHeaderReason(BuilderPrivate::SpecialSystemHeader sh)
{
-#ifdef Q_OS_WIN
- return _stricmp(f1, f2) == 0;
-#else
- return std::strcmp(f1, f2) == 0;
-#endif
-}
-
-#ifdef Q_OS_UNIX
-template<size_t N>
-static bool cStringStartsWith(const char *str, const char (&prefix)[N])
-{
- return std::strncmp(prefix, str, N - 1) == 0;
+ 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, "");
}
-#endif
-static bool cStringStartsWith(const char *str, const QByteArray &prefix)
+bool BuilderPrivate::visitHeader(const QString &fileName) const
{
- return std::strncmp(prefix.constData(), str, int(prefix.size())) == 0;
+ 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;
}
-bool BuilderPrivate::visitHeader(const char *cFileName) const
+BuilderPrivate::SpecialSystemHeader
+ BuilderPrivate::specialSystemHeader(const QString &fileName) const
{
// Resolve OpenGL typedefs although the header is considered a system header.
- const char *baseName = cBaseName(cFileName);
- if (cCompareFileName(baseName, "gl.h"))
- return true;
-#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
- if (cStringStartsWith(cFileName, "/usr/include/stdint.h"))
- return true;
-#endif
-#ifdef Q_OS_LINUX
- if (cStringStartsWith(cFileName, "/usr/include/stdlib.h")
- || cStringStartsWith(cFileName, "/usr/include/sys/types.h")) {
- return true;
+ 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 SpecialSystemHeader::OpenGL;
}
-#endif // Q_OS_LINUX
-#ifdef Q_OS_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.
- if (cCompareFileName(baseName, "gltypes.h")
- || cStringStartsWith(cFileName, "/usr/include/_types")
- || cStringStartsWith(cFileName, "/usr/include/_types")
- || cStringStartsWith(cFileName, "/usr/include/sys/_types")) {
- return true;
- }
-#endif // Q_OS_MACOS
- if (baseName) {
- for (const auto &systemInclude : m_systemIncludes) {
- if (systemInclude == baseName)
- return true;
+
+ switch (clang::platform()) {
+ case Platform::Unix:
+ if (fileName == u"/usr/include/stdlib.h"
+ || baseName == u"types.h"
+ || baseName == u"stdint-intn.h" // int32_t
+ || baseName == u"stdint-uintn.h") { // uint32_t
+ 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.contains(u"/usr/include/_types")
+ || fileName.contains(u"/usr/include/sys/_types")) {
+ return SpecialSystemHeader::Types;
+ }
+ break;
+ default:
+ break;
}
- for (const auto &systemIncludePath : m_systemIncludePaths) {
- if (cStringStartsWith(cFileName, systemIncludePath))
- return true;
+
+ // When building against system Qt (as it happens with yocto / Boot2Qt), the Qt headers are
+ // considered system headers by clang_Location_isInSystemHeader, and shiboken will not
+ // process them. We need to explicitly process them by checking against the list of
+ // include paths that were passed to shiboken's --force-process-system-include-paths option
+ // or specified via the <system-include> xml tag.
+ if (m_forceProcessSystemIncludes.contains(baseName))
+ return SpecialSystemHeader::WhiteListed;
+
+ if (std::any_of(m_forceProcessSystemIncludePaths.cbegin(),
+ m_forceProcessSystemIncludePaths.cend(),
+ [fileName](const QString &p) { return fileName.startsWith(p); })) {
+ return SpecialSystemHeader::WhiteListedPath;
}
- return false;
+
+ return SpecialSystemHeader::None;
}
-bool Builder::visitLocation(const CXSourceLocation &location) const
+bool Builder::visitLocation(const QString &fileName, LocationType locationType) const
{
- if (clang_Location_isInSystemHeader(location) == 0)
- return true;
- CXFile file; // void *
- unsigned line;
- unsigned column;
- unsigned offset;
- clang_getExpansionLocation(location, &file, &line, &column, &offset);
- const CXString cxFileName = clang_getFileName(file);
- // Has been observed to be 0 for invalid locations
- bool result = false;
- if (const char *cFileName = clang_getCString(cxFileName)) {
- result = d->visitHeader(cFileName);
- clang_disposeString(cxFileName);
- }
- return result;
+ return locationType != LocationType::System || d->visitHeader(fileName);
}
-void Builder::setSystemIncludes(const QByteArrayList &systemIncludes)
+void Builder::setForceProcessSystemIncludes(const QStringList &systemIncludes)
{
for (const auto &i : systemIncludes) {
- if (i.endsWith('/'))
- 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);
}
}
@@ -910,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)
@@ -944,12 +916,16 @@ 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.
name = getTypeName(clang_getCursorType(cursor));
- if (name.contains(QLatin1String("(anonymous")))
+ if (name.contains(u"(unnamed") // Clang 12.0.1
+ || name.contains(u"(anonymous")) { // earlier
name.clear();
+ }
}
return name;
}
@@ -962,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);
@@ -993,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
@@ -1010,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);
@@ -1031,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;
@@ -1077,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:
@@ -1084,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;
@@ -1099,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);
@@ -1112,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);
@@ -1122,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()) {
@@ -1141,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);
@@ -1164,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);
@@ -1192,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() == ')'
@@ -1228,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:
@@ -1256,53 +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:
- // Add enum only if values were encountered, otherwise assume it
- // is a forward declaration of an enum class.
- if (!d->m_currentEnum.isNull() && d->m_currentEnum->hasValues())
+ 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 dc37dff0f..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,14 +14,14 @@ class BuilderPrivate;
class Builder : public BaseVisitor {
public:
- Q_DISABLE_COPY(Builder)
+ Q_DISABLE_COPY_MOVE(Builder)
Builder();
~Builder();
- void setSystemIncludes(const QByteArrayList &systemIncludes);
+ void setForceProcessSystemIncludes(const QStringList &systemIncludes);
- bool visitLocation(const CXSourceLocation &location) const override;
+ bool visitLocation(const QString &fileName, LocationType locationType) const override;
StartTokenResult startToken(const CXCursor &cursor) override;
bool endToken(const CXCursor &cursor) 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 8cf35641b..da6930476 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);
@@ -108,9 +85,9 @@ std::string_view SourceFileCache::getCodeSnippet(const CXCursor &cursor,
BaseVisitor::BaseVisitor() = default;
BaseVisitor::~BaseVisitor() = default;
-bool BaseVisitor::visitLocation(const CXSourceLocation &location) const
+bool BaseVisitor::visitLocation(const QString &, LocationType locationType) const
{
- return clang_Location_isFromMainFile(location) != 0;
+ return locationType != LocationType::System;
}
BaseVisitor::StartTokenResult BaseVisitor::cbHandleStartToken(const CXCursor &cursor)
@@ -148,6 +125,34 @@ std::string_view BaseVisitor::getCodeSnippet(const CXCursor &cursor)
return result;
}
+bool BaseVisitor::_handleVisitLocation(const CXSourceLocation &location)
+{
+ CXFile cxFile; // void *
+ unsigned line;
+ unsigned column;
+ unsigned offset;
+ clang_getExpansionLocation(location, &cxFile, &line, &column, &offset);
+
+ if (cxFile == m_currentCxFile) // Same file?
+ return m_visitCurrent;
+
+ const QString fileName = getFileName(cxFile);
+
+ LocationType locationType = LocationType::Unknown;
+ if (!fileName.isEmpty()) {
+ if (clang_Location_isFromMainFile(location) != 0)
+ locationType = LocationType::Main;
+ else if (clang_Location_isInSystemHeader(location) != 0)
+ locationType = LocationType::System;
+ else
+ locationType = LocationType::Other;
+ }
+
+ m_currentCxFile = cxFile;
+ m_visitCurrent = visitLocation(fileName, locationType);
+ return m_visitCurrent;
+}
+
QString BaseVisitor::getCodeSnippetString(const CXCursor &cursor)
{
const std::string_view result = getCodeSnippet(cursor);
@@ -162,7 +167,7 @@ static CXChildVisitResult
auto *bv = reinterpret_cast<BaseVisitor *>(clientData);
const CXSourceLocation location = clang_getCursorLocation(cursor);
- if (!bv->visitLocation(location))
+ if (!bv->_handleVisitLocation(location))
return CXChildVisit_Continue;
const BaseVisitor::StartTokenResult startResult = bv->cbHandleStartToken(cursor);
@@ -210,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 += ' ';
@@ -243,7 +248,9 @@ 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;
@@ -251,6 +258,7 @@ static CXTranslationUnit createTranslationUnit(CXIndex index,
clangArgs += emulatedCompilerOptions();
clangArgs += defaultArgs;
}
+ clangArgs += detectVulkan();
clangArgs += args;
QScopedArrayPointer<const char *> argv(byteArrayListToFlatArgV(clangArgs));
qDebug().noquote().nospace() << msgCreateTranslationUnit(clangArgs, flags);
@@ -302,7 +310,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 d95ada602..4a46248e4 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,11 @@
#include <QtCore/QByteArrayList>
#include <QtCore/QHash>
-#include <QtCore/QPair>
#include <QtCore/QString>
#include <QtCore/QList>
#include <string_view>
+#include <utility>
namespace clang {
@@ -56,8 +31,16 @@ private:
FileNameCache m_fileNameCache;
};
+enum class LocationType
+{
+ Main, // Main header parsed for bindings
+ Other, // A header parsed for bindings
+ System, // A system header
+ Unknown // Clang internal
+};
+
class BaseVisitor {
- Q_DISABLE_COPY(BaseVisitor)
+ Q_DISABLE_COPY_MOVE(BaseVisitor)
public:
using Diagnostics = QList<Diagnostic>;
@@ -68,7 +51,7 @@ public:
// Whether location should be visited.
// defaults to clang_Location_isFromMainFile()
- virtual bool visitLocation(const CXSourceLocation &location) const;
+ virtual bool visitLocation(const QString &fileName, LocationType locationType) const;
virtual StartTokenResult startToken(const CXCursor &cursor) = 0;
virtual bool endToken(const CXCursor &cursor) = 0;
@@ -84,9 +67,14 @@ public:
void setDiagnostics(const Diagnostics &d);
void appendDiagnostic(const Diagnostic &d);
+ // For usage by the parser
+ bool _handleVisitLocation( const CXSourceLocation &location);
+
private:
SourceFileCache m_fileCache;
Diagnostics m_diagnostics;
+ CXFile m_currentCxFile{};
+ bool m_visitCurrent = true;
};
bool parse(const QByteArrayList &clangArgs,
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 7631916fb..4c13b141f 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()
@@ -53,6 +32,74 @@ QVersionNumber libClangVersion()
return QVersionNumber(CINDEX_VERSION_MAJOR, CINDEX_VERSION_MINOR);
}
+static Compiler _compiler =
+#if defined (Q_CC_CLANG)
+ Compiler::Clang;
+#elif defined (Q_CC_MSVC)
+ Compiler::Msvc;
+#else
+ Compiler::Gpp;
+#endif
+
+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;
+#elif defined (Q_OS_WIN)
+ Platform::Windows;
+#else
+ Platform::Unix;
+#endif
+
+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)
{
@@ -91,11 +138,8 @@ static bool runProcess(const QString &program, const QStringList &arguments,
return true;
}
-#if defined(Q_CC_GNU)
-
static QByteArray frameworkPath() { return QByteArrayLiteral(" (framework directory)"); }
-# if defined(Q_OS_MACOS)
static void filterHomebrewHeaderPaths(HeaderPaths &headerPaths)
{
QByteArray homebrewPrefix = qgetenv("HOMEBREW_OPT");
@@ -123,7 +167,6 @@ static void filterHomebrewHeaderPaths(HeaderPaths &headerPaths)
}
}
}
-# endif
// Determine g++'s internal include paths from the output of
// g++ -E -x c++ - -v </dev/null
@@ -135,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"))) {
@@ -161,60 +209,27 @@ static HeaderPaths gppInternalIncludePaths(const QString &compiler)
}
}
-# if defined(Q_OS_MACOS)
- filterHomebrewHeaderPaths(result);
-# endif
+ if (platform() == Platform::macOS)
+ filterHomebrewHeaderPaths(result);
+
return result;
}
-#endif // Q_CC_MSVC
// 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 {};
}
-#if defined(Q_CC_GNU)
-enum class LinuxDistribution { RedHat, CentOs, Other };
-
-static LinuxDistribution linuxDistribution()
-{
- const QString &productType = QSysInfo::productType();
- if (productType == QLatin1String("rhel"))
- return LinuxDistribution::RedHat;
- if (productType.compare(QLatin1String("centos"), Qt::CaseInsensitive) == 0)
- return LinuxDistribution::CentOs;
- return LinuxDistribution::Other;
-}
-
-static bool checkProductVersion(const QVersionNumber &minimum,
- const QVersionNumber &excludedMaximum)
-{
- const QVersionNumber osVersion = QVersionNumber::fromString(QSysInfo::productVersion());
- return osVersion.isNull() || (osVersion >= minimum && osVersion < excludedMaximum);
-}
-
-static inline bool needsGppInternalHeaders()
-{
- const LinuxDistribution distro = linuxDistribution();
- switch (distro) {
- case LinuxDistribution::RedHat:
- case LinuxDistribution::CentOs:
- return checkProductVersion(QVersionNumber(6, 10), QVersionNumber(8));
- case LinuxDistribution::Other:
- break;
- }
- return false;
-}
-#endif // Q_CC_GNU
-
// For MSVC, we set the MS compatibility version and let Clang figure out its own
// options and include paths.
// For the others, we pass "-nostdinc" since libclang tries to add it's own system
@@ -222,9 +237,7 @@ static inline bool needsGppInternalHeaders()
// which causes std types not being found and construct -I/-F options from the
// include paths of the host compiler.
-#ifdef Q_CC_CLANG
static QByteArray noStandardIncludeOption() { return QByteArrayLiteral("-nostdinc"); }
-#endif
// The clang builtin includes directory is used to find the definitions for
// intrinsic functions and builtin types. It is necessary to use the clang
@@ -234,35 +247,40 @@ static QByteArray noStandardIncludeOption() { return QByteArrayLiteral("-nostdin
// Besides g++/Linux, as of MSVC 19.28.29334, MSVC needs clang includes
// due to PYSIDE-1433, LLVM-47099
-#if !defined(Q_OS_DARWIN)
-# define NEED_CLANG_BUILTIN_INCLUDES 1
-#else
-# define NEED_CLANG_BUILTIN_INCLUDES 0
-#endif
-#if NEED_CLANG_BUILTIN_INCLUDES
+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)) {
+ qWarning(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);
}
}
- 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()
@@ -272,7 +290,7 @@ static QString findClangBuiltInIncludesDir()
if (!clangPathLibDir.isEmpty()) {
QString candidate;
QVersionNumber lastVersionNumber(1, 0, 0);
- const QString clangDirName = clangPathLibDir + QLatin1String("/clang");
+ const QString clangDirName = clangPathLibDir + u"/clang"_s;
QDir clangDir(clangDirName);
const QFileInfoList versionDirs =
clangDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
@@ -289,26 +307,46 @@ static QString findClangBuiltInIncludesDir()
}
}
if (!candidate.isEmpty())
- return candidate + QStringLiteral("/include");
+ return candidate + "/include"_L1;
}
- return QString();
+ return queryLlvmConfigDir(u"--includedir"_s);
}
-#endif // NEED_CLANG_BUILTIN_INCLUDES
-#if defined(Q_CC_CLANG) || defined(Q_CC_GNU)
-static QString compilerFromCMake(const QString &defaultCompiler)
+QString compilerFromCMake()
{
-// Added !defined(Q_OS_DARWIN) due to PYSIDE-1032
-# if defined(CMAKE_CXX_COMPILER) && !defined(Q_OS_DARWIN)
- Q_UNUSED(defaultCompiler);
+#ifdef CMAKE_CXX_COMPILER
return QString::fromLocal8Bit(CMAKE_CXX_COMPILER);
-# else
- return defaultCompiler;
-# endif
+#else
+ return {};
+#endif
+}
+
+// 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;
}
-#endif // Q_CC_CLANG, Q_CC_GNU
-#if NEED_CLANG_BUILTIN_INCLUDES
static void appendClangBuiltinIncludes(HeaderPaths *p)
{
const QString clangBuiltinIncludesDir =
@@ -318,61 +356,48 @@ 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});
}
}
-#endif // NEED_CLANG_BUILTIN_INCLUDES
// Returns clang options needed for emulating the host compiler
QByteArrayList emulatedCompilerOptions()
{
-#if defined(Q_CC_GNU)
- // Needed to silence a warning, but needsGppInternalHeaders is used below.
- // This seems to be a compiler bug on macOS.
- Q_UNUSED(needsGppInternalHeaders);
-#endif
QByteArrayList result;
-#if defined(Q_CC_MSVC)
- HeaderPaths headerPaths;
- result.append(QByteArrayLiteral("-fms-compatibility-version=19.26.28806"));
- result.append(QByteArrayLiteral("-fdelayed-template-parsing"));
- result.append(QByteArrayLiteral("-Wno-microsoft-enum-value"));
- // 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 NEED_CLANG_BUILTIN_INCLUDES
- appendClangBuiltinIncludes(&headerPaths);
-# endif // NEED_CLANG_BUILTIN_INCLUDES
-
-#elif defined(Q_CC_CLANG)
- HeaderPaths headerPaths = gppInternalIncludePaths(compilerFromCMake(QStringLiteral("clang++")));
- result.append(noStandardIncludeOption());
-#elif defined(Q_CC_GNU)
HeaderPaths headerPaths;
+ switch (compiler()) {
+ case Compiler::Msvc:
+ result.append("-fms-compatibility-version="_ba + msvcCompatVersion());
+ result.append(QByteArrayLiteral("-fdelayed-template-parsing"));
+ 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++"_s)));
+ result.append(noStandardIncludeOption());
+ break;
+ case Compiler::Gpp:
+ if (needsClangBuiltinIncludes())
+ appendClangBuiltinIncludes(&headerPaths);
-# if NEED_CLANG_BUILTIN_INCLUDES
- appendClangBuiltinIncludes(&headerPaths);
-# endif // NEED_CLANG_BUILTIN_INCLUDES
-
- // Append the c++ include paths since Clang is unable to find <list> etc
- // on RHEL 7 with g++ 6.3 or CentOS 7.2.
- // A fix for this has been added to Clang 5.0, so, the code can be removed
- // once Clang 5.0 is the minimum version.
- if (needsGppInternalHeaders()) {
- const HeaderPaths gppPaths = gppInternalIncludePaths(compilerFromCMake(QStringLiteral("g++")));
+ // 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")) { // centOS
+ if (h.path.contains("c++") || h.path.contains("sysroot"))
headerPaths.append(h);
- }
}
+ break;
}
-#else
- HeaderPaths headerPaths;
-#endif
- 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 d9e213e73..462e8f205 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,
@@ -42,6 +18,18 @@ enum class LanguageLevel {
Cpp1Z
};
+enum class Compiler {
+ Msvc,
+ Gpp,
+ Clang
+};
+
+enum class Platform {
+ Unix,
+ Windows,
+ macOS
+};
+
namespace clang {
QVersionNumber libClangVersion();
@@ -50,6 +38,19 @@ 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 2380ee892..b6eda651c 100644
--- a/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp
+++ b/sources/shiboken6/ApiExtractor/conditionalstreamreader.cpp
@@ -1,38 +1,101 @@
-/****************************************************************************
-**
-** 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
+// (which is also used for the proxied resolver).
+class ProxyEntityResolver : public QXmlStreamEntityResolver
+{
+public:
+ QString resolveEntity(const QString& publicId,
+ const QString& systemId) override;
+ QString resolveUndeclaredEntity(const QString &name) override;
+
+ QXmlStreamEntityResolver *source() const { return m_source; }
+ void setSource(QXmlStreamEntityResolver *s) { m_source = s; }
+
+ void defineEntity(const QString &name, const QString &value)
+ {
+ m_undeclaredEntityCache.insert(name, value);
+ }
+
+private:
+ QHash<QString, QString> m_undeclaredEntityCache;
+ QXmlStreamEntityResolver *m_source = nullptr;
+};
+
+QString ProxyEntityResolver::resolveEntity(const QString &publicId, const QString &systemId)
+{
+ QString result;
+ if (m_source != nullptr)
+ result = m_source->resolveEntity(publicId, systemId);
+ if (result.isEmpty())
+ result = QXmlStreamEntityResolver::resolveEntity(publicId, systemId);
+ return result;
+}
+
+QString ProxyEntityResolver::resolveUndeclaredEntity(const QString &name)
+{
+ const auto it = m_undeclaredEntityCache.constFind(name);
+ if (it != m_undeclaredEntityCache.constEnd())
+ return it.value();
+ if (m_source == nullptr)
+ return {};
+ const QString result = m_source->resolveUndeclaredEntity(name);
+ if (!result.isEmpty())
+ defineEntity(name, result);
+ return result;
+}
+
+ConditionalStreamReader::ConditionalStreamReader(QIODevice *iod) :
+ m_reader(iod)
+{
+ init();
+}
+
+ConditionalStreamReader::ConditionalStreamReader(const QString &s) :
+ m_reader(s)
+{
+ init();
+}
+
+void ConditionalStreamReader::init()
+{
+ m_proxyEntityResolver = new ProxyEntityResolver;
+ m_reader.setEntityResolver(m_proxyEntityResolver);
+}
+
+ConditionalStreamReader::~ConditionalStreamReader()
+{
+ m_reader.setEntityResolver(nullptr);
+ delete m_proxyEntityResolver;
+}
+
+void ConditionalStreamReader::setEntityResolver(QXmlStreamEntityResolver *resolver)
+{
+ m_proxyEntityResolver->setSource(resolver);
+}
+
+QXmlStreamEntityResolver *ConditionalStreamReader::entityResolver() const
+{
+ return m_proxyEntityResolver->source();
+}
QXmlStreamReader::TokenType ConditionalStreamReader::readNext()
{
auto exToken = readNextInternal();
+
+ if (exToken.second == PiTokens::EntityDefinition)
+ return readEntityDefinitonPi() ? exToken.first : QXmlStreamReader::Invalid;
+
if (exToken.second != PiTokens::If || conditionMatches())
return exToken.first;
@@ -54,20 +117,43 @@ QXmlStreamReader::TokenType ConditionalStreamReader::readNext()
return exToken.first;
}
+void ConditionalStreamReader::defineEntity(const QString &name, const QString &value)
+{
+ m_proxyEntityResolver->defineEntity(name, value);
+}
+
+// Read an entity definition: "<?entity name value?>:
+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: "_s + data.toString());
+ return false;
+ }
+ defineEntity(data.left(separator).toString(),
+ data.right(data.size() - separator - 1).toString());
+ return true;
+}
+
bool ConditionalStreamReader::conditionMatches() const
{
const auto keywords = m_reader.processingInstructionData().split(u' ', Qt::SkipEmptyParts);
+ if (keywords.isEmpty())
+ return false;
bool matches = false;
+ bool exclusionOnly = true;
for (const auto &keyword : keywords) {
if (keyword.startsWith(u'!')) { // exclusion '!windows' takes preference
if (m_conditions.contains(keyword.mid(1)))
return false;
} else {
+ exclusionOnly = false;
matches |= m_conditions.contains(keyword);
}
}
- return matches;
+ return exclusionOnly || matches;
}
void ConditionalStreamReader::setConditions(const QStringList &newConditions)
@@ -79,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;
}
@@ -102,6 +188,8 @@ ConditionalStreamReader::ExtendedToken ConditionalStreamReader::readNextInternal
piToken = PiTokens::If;
else if (target == u"endif")
piToken = PiTokens::Endif;
+ else if (target == u"entity")
+ piToken = PiTokens::EntityDefinition;
}
return {token, piToken};
}
@@ -120,3 +208,4 @@ QDebug operator<<(QDebug dbg, const QXmlStreamAttributes &attrs)
dbg << ')';
return dbg;
}
+
diff --git a/sources/shiboken6/ApiExtractor/conditionalstreamreader.h b/sources/shiboken6/ApiExtractor/conditionalstreamreader.h
index 691c5e21d..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
@@ -35,6 +10,8 @@
QT_FORWARD_DECLARE_CLASS(QDebug)
+class ProxyEntityResolver;
+
/// ConditionalStreamReader encapsulates QXmlStreamReader, offering the same
/// API (except readNextStartElement() and similar conveniences) and internally
/// uses Processing Instructions like:
@@ -43,17 +20,25 @@ QT_FORWARD_DECLARE_CLASS(QDebug)
/// containing for example the OS.
/// It should be possible to use it as a drop-in replacement for
/// QXmlStreamReader for any parsing code based on readNext().
+/// It also allows for specifying entities using a Processing Instruction:
+/// <?entity name value?>
+/// which can be used in conjunction with conditional processing.
class ConditionalStreamReader
{
public:
+ Q_DISABLE_COPY_MOVE(ConditionalStreamReader)
+
using TokenType = QXmlStreamReader::TokenType;
- explicit ConditionalStreamReader(QIODevice *iod) : m_reader(iod) { }
- explicit ConditionalStreamReader(const QString &s) : m_reader(s) { }
+ explicit ConditionalStreamReader(QIODevice *iod);
+ explicit ConditionalStreamReader(const QString &s);
+ ~ConditionalStreamReader();
QIODevice *device() const { return m_reader.device(); }
- void setEntityResolver(QXmlStreamEntityResolver *resolver) { m_reader.setEntityResolver(resolver); }
- QXmlStreamEntityResolver *entityResolver() const { return m_reader.entityResolver(); }
+ // Note: Caching of entity values is done internally by
+ // ConditionalStreamReader.
+ void setEntityResolver(QXmlStreamEntityResolver *resolver);
+ QXmlStreamEntityResolver *entityResolver() const;
bool atEnd() const { return m_reader.atEnd(); }
TokenType readNext();
@@ -78,20 +63,25 @@ public:
bool hasError() const { return m_reader.hasError(); }
+ // Additional functions (not delegating to QXmlStreamReader)
+ void defineEntity(const QString &name, const QString &value);
+
const QStringList &conditions() const { return m_conditions; }
void setConditions(const QStringList &newConditions);
static QStringList platformConditions();
private:
- enum class PiTokens { None, If, Endif };
+ enum class PiTokens { None, If, Endif, EntityDefinition };
using ExtendedToken = std::pair<TokenType, PiTokens>;
ExtendedToken readNextInternal();
-
+ void init();
bool conditionMatches() const;
+ bool readEntityDefinitonPi();
QXmlStreamReader m_reader;
+ ProxyEntityResolver *m_proxyEntityResolver = nullptr;
QStringList m_conditions = ConditionalStreamReader::platformConditions();
};
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
new file mode 100644
index 000000000..0bd192257
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/dotview.cpp
@@ -0,0 +1,58 @@
+// 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"
+
+#include <QtCore/QDebug>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QProcess>
+#include <QtCore/QTemporaryFile>
+
+using namespace Qt::StringLiterals;
+
+bool showDotGraph(const QString &name, const QString &graph)
+{
+ constexpr auto imageType = "jpg"_L1;
+
+ // Write out the graph to a temporary file
+ QTemporaryFile dotFile(QDir::tempPath() + u'/' + name + u"_XXXXXX.dot"_s);
+ if (!dotFile.open()) {
+ qWarning("Cannot open temporary file: %s", qPrintable(dotFile.errorString()));
+ return false;
+ }
+ const QString tempDotFile = dotFile.fileName();
+ dotFile.write(graph.toUtf8());
+ dotFile.close();
+
+ // Convert to image using "dot"
+ const QString imageFile = tempDotFile.left(tempDotFile.size() - 3) + imageType;
+ QProcess process;
+ 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;
+ }
+ if (process.exitStatus() != QProcess::NormalExit || process.exitCode() != 0) {
+ qWarning("Image conversion failed (%d): %s",
+ process.exitCode(),
+ process.readAllStandardError().constData());
+ return false;
+ }
+
+ // Launch image. Should use QDesktopServices::openUrl(),
+ // but we don't link against QtGui
+#ifdef Q_OS_UNIX
+ constexpr auto imageViewer = "gwenview"_L1;
+#else
+ constexpr auto imageViewer = "mspaint"_L1;
+#endif
+ if (!QProcess::startDetached(imageViewer, {imageFile})) {
+ qWarning("Failed to launch viewer: %s", qPrintable(imageViewer));
+ return false;
+ }
+ qInfo().noquote().nospace() << "Viewing: "
+ << QDir::toNativeSeparators(tempDotFile)
+ << ' ' << QDir::toNativeSeparators(imageFile);
+ return true;
+}
diff --git a/sources/shiboken6/ApiExtractor/dotview.h b/sources/shiboken6/ApiExtractor/dotview.h
new file mode 100644
index 000000000..87fb7db65
--- /dev/null
+++ b/sources/shiboken6/ApiExtractor/dotview.h
@@ -0,0 +1,14 @@
+// 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
+
+#include <QtCore/QString>
+
+/// Show a dot digraph in an image viewer
+/// \param name base name for files
+/// \param graph graph
+bool showDotGraph(const QString &name, const QString &graph);
+
+#endif // DOTVIEW_H
diff --git a/sources/shiboken6/ApiExtractor/doxygenparser.cpp b/sources/shiboken6/ApiExtractor/doxygenparser.cpp
index 90072c227..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 += QLatin1String("/../%1)[1]").arg(tag.second);
+ 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 0961f85af..447a26da0 100644
--- a/sources/shiboken6/ApiExtractor/graph.h
+++ b/sources/shiboken6/ApiExtractor/graph.h
@@ -1,34 +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 GRAPH_H
#define GRAPH_H
+#include "dotview.h"
+
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QHash>
@@ -98,6 +75,10 @@ public:
/// \param f function returning the name of a node
template <class NameFunction>
bool dumpDot(const QString& fileName, NameFunction f) const;
+ template <class NameFunction>
+ void formatDot(QTextStream &str, NameFunction f) const;
+ template <class NameFunction>
+ bool showGraph(const QString &name, NameFunction f) const;
void format(QDebug &debug) const;
@@ -251,6 +232,15 @@ bool Graph<Node>::dumpDot(const QString& fileName,
if (!output.open(QIODevice::WriteOnly))
return false;
QTextStream s(&output);
+ formatDot(s, nameFunction);
+ return true;
+}
+
+template <class Node>
+template <class NameFunction>
+void Graph<Node>::formatDot(QTextStream &s,
+ NameFunction nameFunction) const
+{
s << "digraph D {\n";
for (const auto &nodeEntry : m_nodeEntries) {
if (!nodeEntry.targets.isEmpty()) {
@@ -260,7 +250,16 @@ bool Graph<Node>::dumpDot(const QString& fileName,
}
}
s << "}\n";
- return true;
+}
+
+template <class Node>
+template <class NameFunction>
+bool Graph<Node>::showGraph(const QString &name, NameFunction f) const
+{
+ QString graph;
+ QTextStream s(&graph);
+ formatDot(s, f);
+ return showDotGraph(name, graph);
}
template <class Node>
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 1f79000e2..f9f46f520 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,67 @@ 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)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Unable to modify the ";
+ if (n == 0)
+ str << "return type";
+ else
+ str << "type of argument " << n;
+
+ str << " of ";
+ 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;
+ QTextStream(&result) << "Argument number " << number
+ << " out of range " << minValue << ".." << maxValue << '.';
+ return result;
+}
+
+QString msgArgumentRemovalFailed(const AbstractMetaFunction *func, int n,
+ const QString &why)
+{
+ QString result;
+ QTextStream str(&result);
+ str << "Unable to remove argument " << n << " of ";
+ if (auto c = func->ownerClass())
+ str << c->name() << "::";
+ str << func->signature() << ": " << why;
+ return result;
+}
+
template <class Stream>
static void msgFormatEnumType(Stream &str,
const EnumModelItem &enumItem,
@@ -84,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();
@@ -107,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())
@@ -115,7 +170,7 @@ static void msgFormatEnumType(Stream &str,
}
static void formatAddedFuncError(const QString &addedFuncName,
- const AbstractMetaClass *context,
+ const AbstractMetaClassCPtr &context,
QTextStream &str)
{
if (context) {
@@ -131,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;
@@ -144,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)
{
@@ -168,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);
@@ -185,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
@@ -209,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)
{
- QString result = QLatin1String("Ambiguous types of varying types found for \"") + qualifiedName
- + QLatin1String("\": ");
+ return u"namespace '"_s + name + u"' not found."_s;
+}
+
+QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntryCList &te)
+{
+ 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;
}
@@ -245,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,
@@ -255,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.";
}
@@ -272,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;
@@ -293,47 +356,59 @@ 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,
- const QString &signature)
+QString msgGlobalFunctionNotDefined(const FunctionTypeEntryCPtr &fte,
+ const QString &signature,
+ const QStringList &candidates)
{
QString result;
QTextStream str(&result);
str << fte->sourceLocation() << "Global function '" << signature
- << "' is specified in typesystem, but not defined. " << msgCompilationError;
+ << "' is specified in typesystem, but not defined.";
+ if (!candidates.isEmpty())
+ 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);
@@ -342,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;
@@ -352,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;
@@ -375,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,
@@ -399,24 +472,24 @@ 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 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,
@@ -442,9 +515,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,
@@ -459,12 +532,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;
@@ -474,7 +546,7 @@ QString msgFunctionVisibilityModified(const AbstractMetaClass *c,
return result;
}
-QString msgUsingMemberClassNotFound(const AbstractMetaClass *c,
+QString msgUsingMemberClassNotFound(const AbstractMetaClassCPtr &c,
const QString &baseClassName,
const QString &memberName)
{
@@ -492,40 +564,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,
@@ -553,13 +658,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());
}
@@ -576,80 +681,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() << ')';
}
}
@@ -658,19 +747,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 msgEnclosingClassNotFound(const TypeEntryCPtr &t)
+{
+ 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 msgUnknownOperator(const AbstractMetaFunction *func)
{
- QString result = QLatin1String("Unknown operator: \"") + func->originalName()
- + QLatin1Char('"');
- if (const AbstractMetaClass *c = func->implementingClass())
- result += QLatin1String(" in class: ") + c->name();
+ QString result = u"Unknown operator: \""_s + func->originalName()
+ + u'"';
+ if (const auto c = func->implementingClass())
+ result += u" in class: "_s + c->name();
return result;
}
@@ -680,7 +778,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;
@@ -698,8 +796,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)
@@ -723,17 +820,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;
}
@@ -745,36 +842,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)
@@ -786,6 +883,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)
@@ -811,3 +923,60 @@ QString msgUnknownTypeInArgumentTypeReplacement(const QString &typeReplaced,
<< "', the generated code may be broken.";
return result;
}
+
+QString msgDuplicateBuiltInTypeEntry(const QString &name)
+{
+ 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: '"_s + name + u"'."_s;
+}
+
+QString msgInvalidTargetLanguageApiName(const QString &name)
+{
+ 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;
+}
diff --git a/sources/shiboken6/ApiExtractor/messages.h b/sources/shiboken6/ApiExtractor/messages.h
index 434d33ff5..2899cbdfa 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,23 +25,37 @@ 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,
const AbstractMetaFunctionCList &allFunctions);
-QString msgClassOfEnumNotFound(const EnumTypeEntry *entry);
+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 EnumTypeEntryCPtr &entry);
QString msgNoEnumTypeEntry(const EnumModelItem &enumItem,
const QString &className);
@@ -74,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);
@@ -91,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,
@@ -100,21 +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,
- const QString &signature);
+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,
@@ -148,29 +141,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);
@@ -185,12 +185,13 @@ QString msgWriteFailed(const QFile &f, qsizetype size);
QString msgCannotUseEnumAsInt(const QString &name);
-QString msgConversionTypesDiffer(const QString &varType, const QString &conversionType);
+QString msgCannotFindSmartPointerGetter(const SmartPointerTypeEntryCPtr &);
+
+QString msgCannotFindSmartPointerMethod(const SmartPointerTypeEntryCPtr &te, const QString &m);
-QString msgCannotFindSmartPointer(const QString &instantiationType,
- const AbstractMetaClassCList &pointers);
+QString msgMethodNotFound(const AbstractMetaClassCPtr &klass, const QString &name);
-QString msgLeftOverArguments(const QVariantMap &remainingArgs);
+QString msgLeftOverArguments(const QString &remainingArgs, const QStringList &argV);
QString msgInvalidVersion(const QString &package, const QString &version);
@@ -208,13 +209,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 TypeEntry *t);
+QString msgClassNotFound(const TypeEntryCPtr &t);
-QString msgUnknownOperator(const AbstractMetaFunction* func);
+QString msgEnclosingClassNotFound(const TypeEntryCPtr &t);
+
+QString msgUnknownOperator(const AbstractMetaFunction *func);
QString msgWrongIndex(const char *varName, const QString &capture,
const AbstractMetaFunction *func);
@@ -234,4 +240,21 @@ QString msgPureVirtualFunctionRemoved(const AbstractMetaFunction *f);
QString msgUnknownTypeInArgumentTypeReplacement(const QString &typeReplaced,
const AbstractMetaFunction *f);
+QString msgDuplicateBuiltInTypeEntry(const QString &name);
+QString msgDuplicateTypeEntry(const QString &name);
+QString msgInvalidTargetLanguageApiName(const QString &name);
+
+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);
+
#endif // MESSAGES_H
diff --git a/sources/shiboken6/ApiExtractor/modifications.cpp b/sources/shiboken6/ApiExtractor/modifications.cpp
index f5afef124..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
@@ -108,6 +24,7 @@ public:
bool m_readable = true;
bool m_writable = true;
bool m_removed = false;
+ bool m_opaqueContainer = false;
TypeSystem::SnakeCase snakeCase = TypeSystem::SnakeCase::Unspecified;
};
@@ -117,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
@@ -181,190 +98,26 @@ void FieldModification::setRemoved(bool r)
d->m_removed = r;
}
-TypeSystem::SnakeCase FieldModification::snakeCase() const
-{
- return d->snakeCase;
-}
-
-void FieldModification::setSnakeCase(TypeSystem::SnakeCase s)
-{
- if (d->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
+bool FieldModification::isOpaqueContainer() const
{
- return type == rhs.type && name == rhs.name && defaultValue == rhs.defaultValue;
+ return d->m_opaqueContainer;
}
-#ifndef QT_NO_DEBUG_STREAM
-QDebug operator<<(QDebug d, const Argument &a)
+void FieldModification::setOpaqueContainer(bool r)
{
- 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;
+ if (d->m_opaqueContainer != r)
+ d->m_opaqueContainer = r;
}
-#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)
+TypeSystem::SnakeCase FieldModification::snakeCase() const
{
+ return d->snakeCase;
}
-AddedFunction::AddedFunctionPtr
- AddedFunction::createAddedFunction(const QString &signatureIn, const QString &returnTypeIn,
- QString *errorMessage)
-
+void FieldModification::setSnakeCase(TypeSystem::SnakeCase s)
{
- 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())
- return {};
- arguments.append({type, p.name, p.defaultValue});
- }
-
- AddedFunctionPtr result(new AddedFunction(name, arguments, returnType));
- result->setConstant(isConst);
- return result;
+ if (d->snakeCase != s)
+ d->snakeCase = s;
}
// Remove the parameter names enclosed in '@' from an added function signature
@@ -413,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;
}
@@ -462,11 +227,11 @@ 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;
-QString ArgumentModification::modifiedType() const
+const QString &ArgumentModification::modifiedType() const
{
return d->modified_type;
}
@@ -477,6 +242,11 @@ void ArgumentModification::setModifiedType(const QString &value)
d->modified_type = value;
}
+bool ArgumentModification::isTypeModified() const
+{
+ return !d->modified_type.isEmpty();
+}
+
QString ArgumentModification::pyiType() const
{
return d->pyiType;
@@ -639,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;
@@ -652,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
@@ -669,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())
@@ -773,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;
@@ -795,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;
}
@@ -891,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;
}
@@ -905,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 3335c8098..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,71 +57,6 @@ struct ArgumentOwner
int index = InvalidIndex;
};
-class CodeSnipFragment
-{
-public:
- CodeSnipFragment() = default;
- explicit CodeSnipFragment(const QString &code) : m_code(code) {}
- explicit CodeSnipFragment(TemplateInstance *instance) : m_instance(instance) {}
-
- QString code() const;
-
-private:
- QString m_code;
- TemplateInstance *m_instance = nullptr;
-};
-
-class CodeSnipAbstract : public CodeSnipHelpers
-{
-public:
- QString code() const;
-
- void addCode(const QString &code);
- void addCode(QStringView code) { addCode(code.toString()); }
-
- void addTemplateInstance(TemplateInstance *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:
@@ -179,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
@@ -188,8 +73,9 @@ public:
void addReferenceCount(const ReferenceCount &value);
// The text given for the new type of the argument
- QString modifiedType() const;
+ const QString &modifiedType() const;
void setModifiedType(const QString &value);
+ bool isTypeModified() const;
QString pyiType() const;
void setPyiType(const QString &value);
@@ -206,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;
@@ -248,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,
@@ -269,7 +154,8 @@ public:
CodeInjection = 0x1000,
Rename = 0x2000,
Deprecated = 0x4000,
- ReplaceExpression = 0x8000
+ Undeprecated = 0x8000,
+ ReplaceExpression = 0x10000
};
Q_DECLARE_FLAGS(Modifiers, ModifierFlag);
@@ -304,10 +190,6 @@ public:
{
return accessModifier() == Public;
}
- bool isFriendly() const
- {
- return accessModifier() == Friendly;
- }
bool isFinal() const
{
return modifiers().testFlag(Final);
@@ -316,7 +198,6 @@ public:
{
return modifiers().testFlag(NonFinal);
}
- QString accessModifierString() const;
bool isDeprecated() const
{
@@ -336,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;
@@ -356,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();
@@ -380,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);
@@ -391,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;
@@ -411,6 +291,9 @@ public:
bool isRemoved() const;
void setRemoved(bool r);
+ bool isOpaqueContainer() const;
+ void setOpaqueContainer(bool r);
+
TypeSystem::SnakeCase snakeCase() const;
void setSnakeCase(TypeSystem::SnakeCase s);
@@ -418,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 82f5e1a2c..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)
+{
+}
+
+_ScopeModelItem::_ScopeModelItem(CodeModel *model, const QString &name, int kind)
+ : _CodeModelItem(model, name, kind)
{
- for (It i = i1; i != i2; ++i) {
- if (i != i1)
- d << separator;
- d << i->data();
- }
}
+#ifndef QT_NO_DEBUG_STREAM
void _CodeModelItem::formatKind(QDebug &d, int k)
{
switch (k) {
@@ -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,30 +462,54 @@ 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
+{
+ for (qsizetype i = 0, size = m_enums.size(); i < size; ++i) {
+ if (m_enums.at(i)->name() == name)
+ return i;
+ }
+ return -1;
}
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.
+ const int index = indexOfEnum(item->name());
+ if (index >= 0) {
+ if (item->hasValues() && !m_enums.at(index)->hasValues())
+ m_enums[index] = item;
+ return;
+ }
m_enums.append(item);
}
@@ -555,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) {
@@ -624,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) {
@@ -685,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);
}
@@ -726,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;
@@ -750,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 << '"';
}
@@ -773,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);
@@ -789,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;
@@ -819,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
@@ -875,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
+bool _FunctionModelItem::isHiddenFriend() const
{
- return m_isAbstract;
+ return m_isHiddenFriend;
}
-void _FunctionModelItem::setAbstract(bool isAbstract)
+void _FunctionModelItem::setHiddenFriend(bool f)
{
- m_isAbstract = isAbstract;
-}
-
-// Qt
-bool _FunctionModelItem::isInvokable() const
-{
- return m_isInvokable;
-}
-
-void _FunctionModelItem::setInvokable(bool isInvokable)
-{
- m_isInvokable = isInvokable;
+ m_isHiddenFriend = f;
}
QString _FunctionModelItem::typeSystemSignature() const // For dumping out type system files
@@ -936,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);
@@ -980,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},
@@ -1054,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 << ",...";
@@ -1075,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;
@@ -1126,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();
@@ -1136,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;
@@ -1158,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;
@@ -1168,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
{
@@ -1182,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);
@@ -1191,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;
@@ -1201,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;
@@ -1275,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 75ad60aaf..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);
@@ -245,6 +236,15 @@ protected:
#endif
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;
@@ -259,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;
};
@@ -274,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);
@@ -313,7 +314,7 @@ private:
QList<BaseClass> m_baseClasses;
QList<UsingMember> m_usingMembers;
TemplateParameterList m_templateParameters;
- CodeModel::ClassType m_classType;
+ CodeModel::ClassType m_classType = CodeModel::Class;
QStringList m_propertyDeclarations;
bool m_final = false;
@@ -322,12 +323,12 @@ private:
class _NamespaceModelItem: public _ScopeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_NamespaceModelItem)
DECLARE_MODEL_NODE(Namespace)
- explicit _NamespaceModelItem(CodeModel *model, int kind = __node_kind)
- : _ScopeModelItem(model, kind) {}
- explicit _NamespaceModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _ScopeModelItem(model, name, kind) {}
+ explicit _NamespaceModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _NamespaceModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
~_NamespaceModelItem();
const NamespaceList &namespaces() const { return m_namespaces; }
@@ -337,7 +338,7 @@ public:
void addNamespace(NamespaceModelItem item);
- NamespaceModelItem findNamespace(const QString &name) const;
+ NamespaceModelItem findNamespace(QAnyStringView name) const;
void appendNamespace(const _NamespaceModelItem &other);
@@ -353,24 +354,23 @@ private:
class _FileModelItem: public _NamespaceModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_FileModelItem)
DECLARE_MODEL_NODE(File)
- explicit _FileModelItem(CodeModel *model, int kind = __node_kind)
- : _NamespaceModelItem(model, kind) {}
- explicit _FileModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _NamespaceModelItem(model, name, kind) {}
+ using _NamespaceModelItem::_NamespaceModelItem;
+
~_FileModelItem();
};
class _ArgumentModelItem: public _CodeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_ArgumentModelItem)
DECLARE_MODEL_NODE(Argument)
- explicit _ArgumentModelItem(CodeModel *model, int kind = __node_kind)
- : _CodeModelItem(model, kind), m_defaultValue(false) {}
- explicit _ArgumentModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _CodeModelItem(model, name, kind), m_defaultValue(false) {}
+ explicit _ArgumentModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _ArgumentModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
~_ArgumentModelItem();
TypeInfo type() const;
@@ -382,6 +382,10 @@ public:
QString defaultValueExpression() const { return m_defaultValueExpression; }
void setDefaultValueExpression(const QString &expr) { m_defaultValueExpression = expr; }
+ // Argument type has scope resolution "::ArgumentType"
+ bool scopeResolution() const;
+ void setScopeResolution(bool v);
+
#ifndef QT_NO_DEBUG_STREAM
void formatDebug(QDebug &d) const override;
#endif
@@ -389,18 +393,19 @@ public:
private:
TypeInfo m_type;
QString m_defaultValueExpression;
- bool m_defaultValue;
+ bool m_defaultValue = false;
+ bool m_scopeResolution = false;
};
class _MemberModelItem: public _CodeModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_MemberModelItem)
DECLARE_MODEL_NODE(Member)
- explicit _MemberModelItem(CodeModel *model, int kind = __node_kind)
- : _CodeModelItem(model, kind), m_accessPolicy(Access::Public), m_flags(0) {}
- explicit _MemberModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _CodeModelItem(model, name, kind), m_accessPolicy(Access::Public), m_flags(0) {}
+ explicit _MemberModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _MemberModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
~_MemberModelItem();
bool isConstant() const;
@@ -443,7 +448,7 @@ public:
private:
TemplateParameterList m_templateParameters;
TypeInfo m_type;
- Access m_accessPolicy;
+ Access m_accessPolicy = Access::Public;
union {
struct {
uint m_isConstant: 1;
@@ -463,12 +468,12 @@ private:
class _FunctionModelItem: public _MemberModelItem
{
public:
+ Q_DISABLE_COPY_MOVE(_FunctionModelItem)
DECLARE_MODEL_NODE(Function)
- explicit _FunctionModelItem(CodeModel *model, int kind = __node_kind)
- : _MemberModelItem(model, kind), m_functionType(CodeModel::Normal), m_flags(0) {}
- explicit _FunctionModelItem(CodeModel *model, const QString &name, int kind = __node_kind)
- : _MemberModelItem(model, name, kind), m_functionType(CodeModel::Normal), m_flags(0) {}
+ explicit _FunctionModelItem(CodeModel *model, int kind = __node_kind);
+ explicit _FunctionModelItem(CodeModel *model, const QString &name,
+ int kind = __node_kind);
~_FunctionModelItem();
ArgumentList arguments() const;
@@ -480,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);
@@ -532,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;
};
@@ -556,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
@@ -567,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);
@@ -610,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;
@@ -628,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;
@@ -659,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
@@ -666,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;
@@ -691,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 1b03f9353..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?>
@@ -162,31 +142,35 @@ void TestDropTypeEntries::testConditionalParsing_data()
<?endif?>
<?endif?>
<tag5>text</tag5>
-</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 keyword1 = QStringLiteral("keyword1");
- const QString keyword2 = QStringLiteral("keyword2");
+ <?if !keyword99?> <!-- Exclusion only -->
+ <tag6>text</tag6>
+ <?endif?>
+</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");
QTest::addColumn<QStringList>("expectedTags");
QTest::newRow("no-keywords")
- << xml << QStringList{} << QStringList{root, tag1, tag5};
+ << xml << QStringList{} << QStringList{root, tag1, tag5, tag6};
QTest::newRow("skip-nested-condition")
<< xml << QStringList{keyword1}
- << QStringList{root, tag1, tag2, tag4, tag5};
+ << QStringList{root, tag1, tag2, tag4, tag5, tag6};
QTest::newRow("both/check-not")
<< xml << QStringList{keyword1, keyword2}
- << QStringList{root, tag1, tag2, tag3, tag5};
+ << QStringList{root, tag1, tag2, tag3, tag5, tag6};
}
// Parse XML and return a list of tags encountered
@@ -218,4 +202,27 @@ void TestDropTypeEntries::testConditionalParsing()
QCOMPARE(actualTags, expectedTags);
}
+void TestDropTypeEntries::testEntityParsing()
+{
+ const QString xml = R"(<?xml version="1.0" encoding="UTF-8"?>
+<root>
+ <?entity testentity word1 word2?>
+ <text>bla &testentity;</text>
+</root>)"_L1;
+
+ QString actual;
+ ConditionalStreamReader reader(xml);
+ while (!reader.atEnd()) {
+ auto t = reader.readNext();
+ switch (t) {
+ case QXmlStreamReader::Characters:
+ actual.append(reader.text());
+ default:
+ break;
+ }
+ }
+ QVERIFY2(!reader.hasError(), qPrintable(reader.errorString()));
+ QCOMPARE(actual.trimmed(), u"bla word1 word2");
+}
+
QTEST_APPLESS_MAIN(TestDropTypeEntries)
diff --git a/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h b/sources/shiboken6/ApiExtractor/tests/testdroptypeentries.h
index 7746234ba..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
{
@@ -41,6 +16,7 @@ class TestDropTypeEntries : public QObject
void testDontDropEntryWithChildTags();
void testConditionalParsing_data();
void testConditionalParsing();
+ void testEntityParsing();
};
#endif
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 df744e994..c7c2b8b3b 100644
--- a/sources/shiboken6/ApiExtractor/tests/testenum.cpp
+++ b/sources/shiboken6/ApiExtractor/tests/testenum.cpp
@@ -1,43 +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 <typesystem.h>
+#include <abstractmetabuilder_p.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\
@@ -45,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\
@@ -55,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\
@@ -109,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\
@@ -136,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\
@@ -239,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\
@@ -292,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\
@@ -301,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\
@@ -379,62 +362,216 @@ 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());
}
+// Helper classes and functions for testing enum default value fixing.
+// Put the AbstractMetaBuilder into test fixture struct to avoid having
+// to re-parse for each data row.
+
+struct EnumDefaultValuesFixture
+{
+ std::shared_ptr<AbstractMetaBuilder> builder;
+
+ AbstractMetaType globalEnum;
+ AbstractMetaType testEnum;
+ AbstractMetaType testOptions;
+};
+
+Q_DECLARE_METATYPE(EnumDefaultValuesFixture)
+Q_DECLARE_METATYPE(AbstractMetaType)
+
+static int populateDefaultValuesFixture(EnumDefaultValuesFixture *fixture)
+{
+ static const char cppCode[] =R"(
+enum GlobalEnum { GE1, GE2 };
+namespace Test1
+{
+namespace Test2
+{
+ enum Enum1 { E1, E2 };
+ enum Option { O1, O2 };
+} // namespace Test2
+} // namespace Test1
+)";
+ static const char xmlCode[] = R"(
+<typesystem package="Foo">
+ <enum-type name='GlobalEnum'/>
+ <namespace-type name='Test1'>
+ <namespace-type name='Test2'>
+ <enum-type name='Enum1'/>
+ <enum-type name='Option' flags='Options'/>
+ </namespace-type>
+ </namespace-type>
+</typesystem>
+)";
+
+ fixture->builder.reset(TestUtil::parse(cppCode, xmlCode, false));
+ if (!fixture->builder)
+ return -1;
+
+ const auto globalEnums = fixture->builder->globalEnums();
+ if (globalEnums.size() != 1)
+ return -2;
+
+ fixture->globalEnum = AbstractMetaType(globalEnums.constFirst().typeEntry());
+ fixture->globalEnum.decideUsagePattern();
+
+ AbstractMetaClassCPtr testNamespace;
+ for (const auto &c : fixture->builder->classes()) {
+ if (c->name() == u"Test2") {
+ testNamespace = c;
+ break;
+ }
+ }
+ if (!testNamespace)
+ return -3;
+
+ const auto namespaceEnums = testNamespace->enums();
+ if (namespaceEnums.size() != 2)
+ return -4;
+ 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));
+ fixture->testEnum.decideUsagePattern();
+ fixture->testOptions = AbstractMetaType(enumTypeEntries.at(1)->flags());
+ fixture->testOptions.decideUsagePattern();
+ return 0;
+}
+
+void TestEnum::testEnumDefaultValues_data()
+{
+ EnumDefaultValuesFixture fixture;
+ const int setupOk = populateDefaultValuesFixture(&fixture);
+
+ QTest::addColumn<EnumDefaultValuesFixture>("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");
+
+ // Global should just remain unmodified
+ QTest::newRow("global") << fixture << setupOk
+ << fixture.globalEnum << "GE1" << "GE1";
+ QTest::newRow("global-int") << fixture << setupOk
+ << fixture.globalEnum << "42" << "42";
+ QTest::newRow("global-hex-int") << fixture << setupOk
+ << fixture.globalEnum << "0x10" << "0x10";
+ QTest::newRow("global-int-cast") << fixture << setupOk
+ << fixture.globalEnum << "GlobalEnum(-1)" << "GlobalEnum(-1)";
+
+ // Namespaced enum as number should remain unmodified
+ QTest::newRow("namespace-enum-int") << fixture << setupOk
+ << fixture.testEnum << "42" << "42";
+ QTest::newRow("namespace-enum-hex-int") << fixture << setupOk
+ << fixture.testEnum << "0x10" << "0x10";
+ // Partial qualification of namespaced enum
+ QTest::newRow("namespace-enum-qualified") << fixture << setupOk
+ << fixture.testEnum << "Enum1::E1" << "Test1::Test2::Enum1::E1";
+ // Unqualified namespaced enums
+ QTest::newRow("namespace-enum-unqualified") << fixture << setupOk
+ << fixture.testEnum << "E1" << "Test1::Test2::Enum1::E1";
+ // Namespaced enums cast from int should be qualified by scope
+ QTest::newRow("namespace-enum-int-cast") << fixture << setupOk
+ << fixture.testEnum << "Enum1(-1)" << "Test1::Test2::Enum1(-1)";
+
+ // Namespaced option as number should remain unmodified
+ QTest::newRow("namespace-option-int") << fixture << setupOk
+ << fixture.testOptions << "0x10" << "0x10";
+ QTest::newRow("namespace-option-expression") << fixture << setupOk
+ << fixture.testOptions << "0x10 | 0x20" << "0x10 | 0x20";
+ QTest::newRow("namespace-option-expression1") << fixture << setupOk
+ << fixture.testOptions << "0x10 | Test1::Test2::Option::O1"
+ << "0x10 | Test1::Test2::Option::O1";
+ QTest::newRow("namespace-option-expression2") << fixture << setupOk
+ << fixture.testOptions << "0x10 | O1" << "0x10 | Test1::Test2::Option::O1";
+ // Complicated expressions - should remain unmodified
+ QTest::newRow("namespace-option-expression-paren") << fixture << setupOk
+ << fixture.testOptions << "0x10 | (0x20 | 0x40 | O1)"
+ << "0x10 | (0x20 | 0x40 | O1)";
+
+ // Option: Cast Enum from int should be qualified
+ QTest::newRow("namespace-option-int-cast") << fixture << setupOk
+ << fixture.testOptions << "Option(0x10)" << "Test1::Test2::Option(0x10)";
+ // Option: Cast Flags from int should be qualified
+ QTest::newRow("namespace-options-int-cast") << fixture << setupOk
+ << fixture.testOptions << "Options(0x10 | 0x20)" << "Test1::Test2::Options(0x10 | 0x20)";
+ QTest::newRow("namespace-option-cast-expression1") << fixture << setupOk
+ << fixture.testOptions << "Test1::Test2::Options(0x10 | Test1::Test2::Option::O1)"
+ << "Test1::Test2::Options(0x10 | Test1::Test2::Option::O1)";
+ QTest::newRow("namespace-option-cast-expression2") << fixture << setupOk
+ << fixture.testOptions << "Options(0x10 | O1)"
+ << "Test1::Test2::Options(0x10 | Test1::Test2::Option::O1)";
+}
+
+void TestEnum::testEnumDefaultValues()
+{
+ QFETCH(EnumDefaultValuesFixture, fixture);
+ QFETCH(int, setupOk);
+ QFETCH(AbstractMetaType, metaType);
+ QFETCH(QString, input);
+ QFETCH(QString, expected);
+ QCOMPARE(setupOk, 0);
+ const QString actual = fixture.builder->fixEnumDefault(metaType, input);
+ QCOMPARE(actual, expected);
+}
+
QTEST_APPLESS_MAIN(TestEnum)
diff --git a/sources/shiboken6/ApiExtractor/tests/testenum.h b/sources/shiboken6/ApiExtractor/tests/testenum.h
index 312551763..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
{
@@ -42,6 +18,8 @@ private slots:
void testEnumValueFromExpression();
void testPrivateEnum();
void testTypedefEnum();
+ void testEnumDefaultValues_data();
+ void testEnumDefaultValues();
};
#endif
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 8a4e6d2f1..749c4baa3 100644
--- a/sources/shiboken6/ApiExtractor/typedatabase.cpp
+++ b/sources/shiboken6/ApiExtractor/typedatabase.cpp
@@ -1,71 +1,317 @@
-/****************************************************************************
-**
-** 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 "typesystem.h"
-#include "typesystemparser.h"
+#include "abstractmetatype.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)
-TypeDatabase::TypeDatabase()
+struct PythonType
+{
+ QString name;
+ QString checkFunction;
+ TypeSystem::CPythonType type;
+};
+
+using PythonTypes = QList<PythonType>;
+
+static const PythonTypes &builtinPythonTypes()
+{
+ static const PythonTypes result{
+ // "Traditional" custom types
+ // numpy
+ {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"_s, u"true"_s, TypeSystem::CPythonType::Other},
+ // shiboken-specific
+ {u"PyPathLike"_s, u"Shiboken::String::checkPath"_s, TypeSystem::CPythonType::Other},
+ {u"PySequence"_s, u"Shiboken::String::checkIterable"_s, TypeSystem::CPythonType::Other},
+ {u"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"_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"_s, u"SbkChar_Check"_s, TypeSystem::CPythonType::String}
+ };
+ return result;
+}
+
+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)
+{
+ // 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())
+ d->addBuiltInType(TypeEntryPtr(new PythonTypeEntry(pt.name, pt.checkFunction, pt.type)));
+
+ for (const auto &p : predefinedTemplates())
+ addTemplate(p.name, p.content);
+}
+
+TypeDatabase::~TypeDatabase()
{
- addType(new VoidTypeEntry());
- addType(new VarargsTypeEntry());
+ delete d;
}
-TypeDatabase::~TypeDatabase() = default;
+std::shared_ptr<OptionsParser> TypeDatabase::createOptionsParser()
+{
+ return std::make_shared<TypeDatabaseOptionsParser>(d);
+}
-TypeDatabase* TypeDatabase::instance(bool newInstance)
+TypeDatabase *TypeDatabase::instance(bool newInstance)
{
static TypeDatabase *db = nullptr;
if (!db || newInstance) {
@@ -91,12 +337,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);
}
@@ -105,11 +350,64 @@ static const IntTypeNormalizationEntries &intTypeNormalizationEntries()
return result;
}
+// Normalization helpers
+enum CharCategory { Space, Identifier, Other };
+
+static CharCategory charCategory(QChar c)
+{
+ if (c.isSpace())
+ return Space;
+ if (c.isLetterOrNumber() || c == u'_')
+ return Identifier;
+ return Other;
+}
+
+// Normalize a C++ function signature:
+// Drop space except between identifiers ("unsigned int", "const int")
+static QString normalizeCppFunctionSignature(const QString &signatureIn)
+{
+ const QString signature = signatureIn.simplified();
+ QString result;
+ result.reserve(signature.size());
+
+ CharCategory lastNonSpaceCategory = Other;
+ bool pendingSpace = false;
+ for (QChar c : signature) {
+ if (c.isSpace()) {
+ pendingSpace = true;
+ } else {
+ const auto category = charCategory(c);
+ if (pendingSpace) {
+ if (lastNonSpaceCategory == Identifier && category == Identifier)
+ result.append(u' ');
+ pendingSpace = false;
+ }
+ lastNonSpaceCategory = category;
+ result.append(c);
+ }
+ }
+ return result;
+}
+
+// Normalize a signature for <add-function> by removing spaces
+QString TypeDatabase::normalizedAddedFunctionSignature(const QString &signature)
+{
+ return normalizeCppFunctionSignature(signature);
+}
+
+// Normalize a signature for matching by <modify-function>/<function>
+// by removing spaces and changing const-ref to value.
+// FIXME: PYSIDE7: Check whether the above simple normalization can be used
+// here as well. Note though that const-ref would then have to be spelled out
+// in typeystem XML.
QString TypeDatabase::normalizedSignature(const QString &signature)
{
- QString normalized = QLatin1String(QMetaObject::normalizedSignature(signature.toUtf8().constData()));
+ // QMetaObject::normalizedSignature() changes const-ref to value and
+ // changes "unsigned int" to "uint" which is undone by the below code
+ 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);
@@ -120,141 +418,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();
}
-void TypeDatabase::addSystemInclude(const QString &name)
+const QStringList &TypeDatabase::forceProcessSystemIncludes() const
{
- m_systemIncludes.append(name.toUtf8());
+ return d->m_forceProcessSystemIncludes;
+}
+
+void TypeDatabase::addForceProcessSystemInclude(const QString &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();
}
-TypeEntry* TypeDatabase::findType(const QString& name) const
+TypeEntryPtr TypeDatabase::findType(const QString& name) const
+{
+ return d->findType(name);
+}
+
+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()) {
@@ -278,37 +620,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
@@ -325,36 +678,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;
@@ -373,6 +705,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;
@@ -383,24 +716,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:
@@ -409,23 +742,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;
}
@@ -434,11 +778,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;
@@ -447,35 +791,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;
@@ -483,28 +828,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;
}
-void TypeDatabase::addFlagsType(FlagsTypeEntry *fte)
+TemplateEntryPtr TypeDatabase::findTemplate(const QString &name) const
{
- m_flagsEntries[fte->originalName()] = fte;
+ return d->m_templates[name];
}
-void TypeDatabase::addTemplate(TemplateEntry *t)
+void TypeDatabase::addTemplate(const TemplateEntryPtr &t)
{
- m_templates[t->name()] = t;
+ d->m_templates[t->name()] = t;
+}
+
+void TypeDatabase::addTemplate(const QString &name, const QString &code)
+{
+ auto te = std::make_shared<TemplateEntry>(name);
+ te->addCode(code);
+ addTemplate(te);
+}
+
+AddedFunctionList TypeDatabase::globalUserFunctions() const
+{
+ 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);
}
@@ -513,151 +875,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)
+ 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;
}
@@ -666,22 +1261,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;
}
@@ -689,26 +1284,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;
}
@@ -717,19 +1312,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;
@@ -739,7 +1334,7 @@ static bool typeEntryLessThan(const TypeEntry* t1, const TypeEntry* t2)
static void _computeTypeIndexes()
{
- TypeDatabase* tdb = TypeDatabase::instance();
+ auto *tdb = TypeDatabase::instance();
TypeEntryList list;
@@ -747,7 +1342,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()
@@ -766,7 +1361,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;
}
@@ -803,7 +1398,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;
@@ -812,7 +1407,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;
}
@@ -822,7 +1417,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;
@@ -830,23 +1425,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() << "]=";
@@ -883,10 +1473,182 @@ 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 << ')';
}
+// 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);
+}
+
+PrimitiveTypeEntryPtr
+ TypeDatabasePrivate::addBuiltInPrimitiveType(const QString &name,
+ const TypeSystemTypeEntryCPtr &root,
+ const QString &rootPackage,
+ const CustomTypeEntryPtr &targetLang)
+{
+ auto result = std::make_shared<PrimitiveTypeEntry>(name, QVersionNumber{}, root);
+ result->setTargetLangApiType(targetLang);
+ result->setTargetLangPackage(rootPackage);
+ addBuiltInType(result);
+ return result;
+}
+
+void TypeDatabasePrivate::addBuiltInCppStringPrimitiveType(const QString &name,
+ const QString &viewName,
+ const TypeSystemTypeEntryCPtr &root,
+ const QString &rootPackage,
+ const CustomTypeEntryPtr &targetLang)
+
+{
+ auto stringType = addBuiltInPrimitiveType(name, root, rootPackage,
+ targetLang);
+ auto viewType = addBuiltInPrimitiveType(viewName, root, rootPackage,
+ nullptr);
+ viewType->setViewOn(stringType);
+}
+
+void TypeDatabasePrivate::addBuiltInPrimitiveTypes()
+{
+ auto root = defaultTypeSystemType();
+ const QString &rootPackage = root->name();
+
+ // C++ primitive types
+ auto pyLongEntry = findType(u"PyLong"_s);
+ Q_ASSERT(pyLongEntry && pyLongEntry->isCustom());
+ auto pyLongCustomEntry = std::static_pointer_cast<CustomTypeEntry>(pyLongEntry);
+ auto pyBoolEntry = findType(u"PyBool"_s);
+ Q_ASSERT(pyBoolEntry && pyBoolEntry->isCustom());
+ auto sbkCharEntry = findType(u"SbkChar"_s);
+ Q_ASSERT(sbkCharEntry && sbkCharEntry->isCustom());
+ auto sbkCharCustomEntry = std::static_pointer_cast<CustomTypeEntry>(sbkCharEntry);
+
+ auto pyBoolCustomEntry = std::static_pointer_cast<CustomTypeEntry>(pyBoolEntry);
+ for (const auto &t : AbstractMetaType::cppIntegralTypes()) {
+ if (!m_entries.contains(t)) {
+ CustomTypeEntryPtr targetLangApi = pyLongCustomEntry;
+ if (t == u"bool")
+ targetLangApi = pyBoolCustomEntry;
+ else if (AbstractMetaType::cppCharTypes().contains(t))
+ targetLangApi = sbkCharCustomEntry;
+ addBuiltInPrimitiveType(t, root, rootPackage, targetLangApi);
+ }
+ }
+
+ auto pyFloatEntry = findType(u"PyFloat"_s);
+ Q_ASSERT(pyFloatEntry && pyFloatEntry->isCustom());
+ auto pyFloatCustomEntry = std::static_pointer_cast<CustomTypeEntry>(pyFloatEntry);
+ for (const auto &t : AbstractMetaType::cppFloatTypes()) {
+ if (!m_entries.contains(t))
+ addBuiltInPrimitiveType(t, root, rootPackage, pyFloatCustomEntry);
+ }
+
+ auto pyUnicodeEntry = findType(u"PyUnicode"_s);
+ Q_ASSERT(pyUnicodeEntry && pyUnicodeEntry->isCustom());
+ auto pyUnicodeCustomEntry = std::static_pointer_cast<CustomTypeEntry>(pyUnicodeEntry);
+
+ constexpr auto stdString = "std::string"_L1;
+ if (!m_entries.contains(stdString)) {
+ addBuiltInCppStringPrimitiveType(stdString, u"std::string_view"_s,
+ root, rootPackage,
+ pyUnicodeCustomEntry);
+ }
+ constexpr auto stdWString = "std::wstring"_L1;
+ if (!m_entries.contains(stdWString)) {
+ addBuiltInCppStringPrimitiveType(stdWString, u"std::wstring_view"_s,
+ root, rootPackage,
+ pyUnicodeCustomEntry);
+ }
+}
+
QDebug operator<<(QDebug d, const TypeDatabase &db)
{
QDebugStateSaver saver(d);
diff --git a/sources/shiboken6/ApiExtractor/typedatabase.h b/sources/shiboken6/ApiExtractor/typedatabase.h
index 082d833b5..d5adca324 100644
--- a/sources/shiboken6/ApiExtractor/typedatabase.h
+++ b/sources/shiboken6/ApiExtractor/typedatabase.h
@@ -1,64 +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 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
@@ -85,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
@@ -95,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
@@ -107,44 +79,45 @@ public:
static TypeDatabase *instance(bool newInstance = false);
static QString normalizedSignature(const QString &signature);
+ static QString normalizedAddedFunctionSignature(const QString &signature);
QStringList requiredTargetImports() const;
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 QByteArrayList &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;
@@ -159,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);
@@ -179,69 +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:
- 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;
- QByteArrayList 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 38c556d41..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,9 +281,12 @@ TypeInfo TypeParser::parse(const QString &str, QString *errorMessage)
break;
}
- tok = scanner.nextToken();
+ tok = scanner.nextToken(errorMessage);
}
- Q_ASSERT(!stack.isEmpty());
+ if (stack.isEmpty() || stack.constFirst().qualifiedName().isEmpty()) {
+ *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 d445febfa..99d42b668 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.cpp
+++ b/sources/shiboken6/ApiExtractor/typesystem.cpp
@@ -1,103 +1,92 @@
-/****************************************************************************
-**
-** 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()
#define S_D(Class) auto d = static_cast<Class##Private *>(d_func())
-static const QSet<QString> &primitiveCppTypes()
-{
- static QSet<QString> result;
- if (result.isEmpty()) {
- static const char *cppTypes[] = {
- "bool", "char", "double", "float", "int",
- "long", "long long", "short",
- "wchar_t"
- };
- for (const char *cppType : cppTypes)
- result.insert(QLatin1String(cppType));
- }
- return result;
-}
-
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
- QString m_targetLangApiName;
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;
+ TypeEntryPtr m_viewOn;
+ CustomTypeEntryPtr m_targetLangApiType;
int m_revision = 0;
int m_sbkIndex = 0;
TypeEntry::Type m_type;
bool m_stream = false;
bool m_private = false;
+ bool m_builtin = false;
};
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),
@@ -106,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))
{
}
@@ -123,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;
@@ -174,47 +133,31 @@ 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();
- const QString &typeName = referencedType ? referencedType->name() : m_d->m_name;
- return typeName.contains(QLatin1Char(' ')) || primitiveCppTypes().contains(typeName);
+ PrimitiveTypeEntryCPtr referencedType = basicReferencedTypeEntry(e);
+ const QString &typeName = referencedType->name();
+ return AbstractMetaType::cppPrimitiveTypes().contains(typeName);
}
TypeEntry::Type TypeEntry::type() const
@@ -222,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)
@@ -241,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();
@@ -295,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;
@@ -317,7 +268,7 @@ bool TypeEntry::isVarargs() const
bool TypeEntry::isCustom() const
{
- return m_d->m_type == CustomType;
+ return m_d->m_type == CustomType || m_d->m_type == PythonType;
}
bool TypeEntry::isTypeSystem() const
@@ -345,6 +296,16 @@ void TypeEntry::setStream(bool b)
m_d->m_stream = b;
}
+bool TypeEntry::isBuiltIn() const
+{
+ return m_d->m_builtin;
+}
+
+void TypeEntry::setBuiltIn(bool b)
+{
+ m_d->m_builtin = b;
+}
+
bool TypeEntry::isPrivate() const
{
return m_d->m_private;
@@ -365,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);
@@ -377,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 {
@@ -414,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;
@@ -429,15 +395,25 @@ QString TypeEntry::qualifiedCppName() const
return m_d->m_name;
}
-QString TypeEntry::targetLangApiName() const
+CustomTypeEntryCPtr TypeEntry::targetLangApiType() const
{
- return m_d->m_targetLangApiName.isEmpty()
- ? m_d->m_name : m_d->m_targetLangApiName;
+ return m_d->m_targetLangApiType;
}
-void TypeEntry::setTargetLangApiName(const QString &t)
+bool TypeEntry::hasTargetLangApiType() const
{
- m_d->m_targetLangApiName = t;
+ return m_d->m_targetLangApiType != nullptr;
+}
+
+void TypeEntry::setTargetLangApiType(const CustomTypeEntryPtr &cte)
+{
+ m_d->m_targetLangApiType = cte;
+}
+
+QString TypeEntry::targetLangApiName() const
+{
+ return m_d->m_targetLangApiType != nullptr
+ ? m_d->m_targetLangApiType->name() : m_d->m_name;
}
QString TypeEntry::targetLangName() const
@@ -458,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);
}
}
@@ -489,15 +465,13 @@ void TypeEntry::setSourceLocation(const SourceLocation &sourceLocation)
m_d->m_sourceLocation = sourceLocation;
}
-bool TypeEntry::isUserPrimitive() const
+bool isUserPrimitive(const TypeEntryCPtr &e)
{
- if (!isPrimitive())
+ if (!e->isPrimitive())
return false;
- const auto *trueType = static_cast<const PrimitiveTypeEntry *>(this);
- if (trueType->basicReferencedTypeEntry())
- trueType = trueType->basicReferencedTypeEntry();
- return trueType->isPrimitive() && !trueType->isCppPrimitive()
- && trueType->qualifiedCppName() != u"std::string";
+ const auto type = basicReferencedTypeEntry(e);
+ return !isCppPrimitive(type)
+ && type->qualifiedCppName() != u"std::string";
}
bool TypeEntry::isWrapperType() const
@@ -505,29 +479,23 @@ 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 *trueType = static_cast<const PrimitiveTypeEntry *>(this);
- if (trueType->basicReferencedTypeEntry())
- trueType = trueType->basicReferencedTypeEntry();
- QString typeName = trueType->qualifiedCppName();
- return !typeName.contains(u"double")
- && !typeName.contains(u"float")
- && !typeName.contains(u"wchar");
+ 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 *trueType = static_cast<const PrimitiveTypeEntry *>(this);
- if (trueType->basicReferencedTypeEntry())
- trueType = trueType->basicReferencedTypeEntry();
- return trueType->qualifiedCppName() == u"std::string";
+ const auto type = basicReferencedTypeEntry(e);
+ const QString &name = type->qualifiedCppName();
+ return name == u"std::string" || name == u"std::wstring";
}
const TypeEntryPrivate *TypeEntry::d_func() const
@@ -544,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);
}
@@ -563,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
@@ -596,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;
}
@@ -627,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;
}
@@ -648,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))
{
}
@@ -664,6 +599,12 @@ TypeEntry *CustomTypeEntry::clone() const
return new CustomTypeEntry(new CustomTypeEntryPrivate(*d));
}
+bool CustomTypeEntry::hasCheckFunction() const
+{
+ S_D(const CustomTypeEntry);
+ return !d->m_checkFunction.isEmpty();
+}
+
QString CustomTypeEntry::checkFunction() const
{
S_D(const CustomTypeEntry);
@@ -676,17 +617,62 @@ void CustomTypeEntry::setCheckFunction(const QString &f)
d->m_checkFunction = f;
}
+// ----------------- PythonTypeEntry
+class PythonTypeEntryPrivate : public CustomTypeEntryPrivate
+{
+public:
+ using CustomTypeEntryPrivate::CustomTypeEntryPrivate;
+ explicit PythonTypeEntryPrivate(const QString &entryName,
+ const QString &checkFunction,
+ TypeSystem::CPythonType type) :
+ CustomTypeEntryPrivate(entryName, TypeEntry::PythonType, {}, {}),
+ m_cPythonType(type)
+ {
+ m_checkFunction = checkFunction;
+ }
+
+ TypeSystem::CPythonType m_cPythonType;
+};
+
+PythonTypeEntry::PythonTypeEntry(const QString &entryName,
+ const QString &checkFunction,
+ TypeSystem::CPythonType type) :
+ CustomTypeEntry(new PythonTypeEntryPrivate(entryName, checkFunction, type))
+{
+}
+
+TypeEntry *PythonTypeEntry::clone() const
+{
+ S_D(const PythonTypeEntry);
+ return new PythonTypeEntry(new PythonTypeEntryPrivate(*d));
+}
+
+TypeSystem::CPythonType PythonTypeEntry::cPythonType() const
+{
+ S_D(const PythonTypeEntry);
+ return d->m_cPythonType;
+}
+
+PythonTypeEntry::PythonTypeEntry(TypeEntryPrivate *d) :
+ CustomTypeEntry(d)
+{
+}
+
// ----------------- TypeSystemTypeEntry
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))
{
}
@@ -702,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);
@@ -716,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)
{
}
@@ -731,7 +771,7 @@ TypeEntry *VoidTypeEntry::clone() const
}
VarargsTypeEntry::VarargsTypeEntry() :
- TypeEntry(QLatin1String("..."), VarargsType, QVersionNumber(0, 0), nullptr)
+ TypeEntry(u"..."_s, VarargsType, QVersionNumber(0, 0), nullptr)
{
}
@@ -756,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))
{
}
@@ -788,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;
@@ -820,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
@@ -839,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))
{
}
@@ -874,26 +915,46 @@ 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;
}
-PrimitiveTypeEntry *PrimitiveTypeEntry::basicReferencedTypeEntry() const
+PrimitiveTypeEntryCPtr basicReferencedTypeEntry(const PrimitiveTypeEntryCPtr &e)
{
- S_D(const PrimitiveTypeEntry);
- if (!d->m_referencedTypeEntry)
- return nullptr;
+ auto result = e;
+ while (auto referenced = result->referencedTypeEntry())
+ result = referenced;
+ return result;
+}
- PrimitiveTypeEntry *baseReferencedTypeEntry = d->m_referencedTypeEntry->basicReferencedTypeEntry();
- return baseReferencedTypeEntry ? baseReferencedTypeEntry : d->m_referencedTypeEntry;
+PrimitiveTypeEntryCPtr basicReferencedTypeEntry(const TypeEntryCPtr &e)
+{
+ 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;
+ }
+ return result;
+}
+
+bool PrimitiveTypeEntry::referencesType() const
+{
+ S_D(const PrimitiveTypeEntry);
+ return d->m_referencedTypeEntry != nullptr;
}
bool PrimitiveTypeEntry::preferredTargetLangType() const
@@ -908,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);
@@ -919,22 +998,85 @@ 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
@@ -954,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);
@@ -996,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);
@@ -1003,7 +1169,7 @@ TypeEntry *EnumTypeEntry::clone() const
}
EnumTypeEntry::EnumTypeEntry(EnumTypeEntryPrivate *d) :
- TypeEntry(d)
+ ConfigurableTypeEntry(d)
{
}
@@ -1012,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,
@@ -1023,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))
@@ -1040,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;
@@ -1065,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))
{
}
@@ -1078,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;
}
@@ -1111,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;
@@ -1131,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)
{
}
@@ -1142,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),
@@ -1158,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;
@@ -1169,24 +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))
{
}
@@ -1249,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);
@@ -1279,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);
@@ -1345,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);
@@ -1393,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);
@@ -1405,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;
@@ -1471,6 +1755,31 @@ void ComplexTypeEntry::setSnakeCase(TypeSystem::SnakeCase sc)
d->m_snakeCase = sc;
}
+bool ComplexTypeEntry::isValueTypeWithCopyConstructorOnly() const
+{
+ S_D(const ComplexTypeEntry);
+ return d->m_isValueTypeWithCopyConstructorOnly;
+}
+
+void ComplexTypeEntry::setValueTypeWithCopyConstructorOnly(bool v)
+{
+ S_D(ComplexTypeEntry);
+ 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);
@@ -1478,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)
{
}
@@ -1506,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)
@@ -1514,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))
{
}
@@ -1542,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;
@@ -1578,18 +1888,41 @@ public:
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 QStringList &instantiations) const
+ {
+ return std::find_if(m_opaqueContainers.cbegin(), m_opaqueContainers.cend(),
+ [&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);
@@ -1601,6 +1934,67 @@ ContainerTypeEntry::ContainerKind ContainerTypeEntry::containerKind() const
return d->m_containerKind;
}
+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::appendOpaqueContainers(const OpaqueContainers &l)
+{
+ S_D(ContainerTypeEntry);
+ d->m_opaqueContainers.append(l);
+}
+
+bool ContainerTypeEntry::generateOpaqueContainer(const QStringList &instantiations) const
+{
+ S_D(const ContainerTypeEntry);
+ return d->findOpaqueContainer(instantiations) != d->m_opaqueContainers.cend();
+}
+
+QString ContainerTypeEntry::opaqueContainerName(const QStringList &instantiations) const
+{
+ S_D(const ContainerTypeEntry);
+ 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);
@@ -1618,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);
@@ -1656,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;
@@ -1679,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
@@ -1692,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;
@@ -1700,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))
{
}
@@ -1711,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;
@@ -1780,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
@@ -1799,167 +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
{
- return m_d->sourceTypeCheck;
+ 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
@@ -1968,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))
{
}
@@ -2003,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
@@ -2028,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)
{
}
@@ -2058,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();
@@ -2079,11 +2460,13 @@ void TypeEntry::formatDebug(QDebug &debug) const
if (m_d->m_name != cppName)
debug << "\", cppName=\"" << cppName << '"';
debug << ", type=" << m_d->m_type << ", codeGeneration="
- << m_d->m_codeGeneration << ", target=\"" << targetLangName() << '"';
+ << m_d->m_codeGeneration;
+ const QString &targetName = targetLangName();
+ if (m_d->m_name != targetName)
+ debug << ", target=\"" << targetLangName() << '"';
FORMAT_NONEMPTY_STRING("package", m_d->m_targetLangPackage)
FORMAT_BOOL("stream", m_d->m_stream)
- FORMAT_LIST_SIZE("codeSnips", m_d->m_codeSnips)
- FORMAT_NONEMPTY_STRING("targetConversionRule", m_d->m_targetConversionRule)
+ FORMAT_BOOL("built-in", m_d->m_builtin)
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))
@@ -2099,6 +2482,16 @@ void TypeEntry::formatDebug(QDebug &debug) const
formatList(debug, "extraIncludes", m_d->m_extraIncludes, ", ");
}
+void PrimitiveTypeEntry::formatDebug(QDebug &debug) const
+{
+ TypeEntry::formatDebug(debug);
+ if (auto e = referencedTypeEntry()) {
+ debug << ", references";
+ for (; e ; e = e->referencedTypeEntry())
+ debug << ":\"" << e->qualifiedCppName() <<'"';
+ }
+}
+
void ComplexTypeEntry::formatDebug(QDebug &debug) const
{
S_D(const ComplexTypeEntry);
@@ -2118,16 +2511,31 @@ 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)
}
+void CustomTypeEntry::formatDebug(QDebug &debug) const
+{
+ S_D(const CustomTypeEntry);
+ TypeEntry::formatDebug(debug);
+ debug << ", checkFunction=" << d->m_checkFunction;
+}
+
+void PythonTypeEntry::formatDebug(QDebug &debug) const
+{
+ S_D(const PythonTypeEntry);
+
+ CustomTypeEntry::formatDebug(debug);
+ debug << ", type=" << int(d->m_cPythonType);
+}
+
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
@@ -2144,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 << ')';
}
@@ -2160,12 +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=[" << d->m_opaqueContainers << ']';
}
void SmartPointerTypeEntry::formatDebug(QDebug &debug) const
@@ -2174,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 << ')';
}
}
@@ -2195,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);
@@ -2209,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 fada1fea3..a2e4debc8 100644
--- a/sources/shiboken6/ApiExtractor/typesystem.h
+++ b/sources/shiboken6/ApiExtractor/typesystem.h
@@ -1,84 +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 AbstractMetaType;
+class CustomTypeEntry;
+class PrimitiveTypeEntry;
class SourceLocation;
class TypeSystemTypeEntry;
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
@@ -101,6 +46,7 @@ public:
ArrayType,
TypeSystemType,
CustomType,
+ PythonType,
FunctionType,
SmartPointerType,
TypedefType
@@ -116,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;
@@ -135,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;
@@ -147,6 +91,9 @@ public:
bool stream() const;
void setStream(bool b);
+ bool isBuiltIn() const;
+ void setBuiltIn(bool b);
+
bool isPrivate() const;
void setPrivate(bool b);
@@ -167,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
@@ -180,8 +130,10 @@ public:
/// be a JNI name, for Python it should represent the CPython type name.
/// \return string representing the target language API name
/// Currently used only for PrimitiveTypeEntry (attribute "target").
+ CustomTypeEntryCPtr targetLangApiType() const;
+ bool hasTargetLangApiType() const;
+ void setTargetLangApiType(const CustomTypeEntryPtr &cte);
QString targetLangApiName() const;
- void setTargetLangApiName(const QString &t);
// The type's name in TargetLang
QString targetLangName() const; // "Foo.Bar"
@@ -194,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);
@@ -217,49 +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);
// 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;
@@ -279,539 +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;
-
- QString checkFunction() const;
- void setCheckFunction(const QString &f);
-
-protected:
- explicit CustomTypeEntry(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;
-
-protected:
- explicit VarargsTypeEntry(TypeEntryPrivate *d);
-};
-
-class TemplateArgumentEntry : public TypeEntry
-{
-public:
- explicit TemplateArgumentEntry(const QString &entryName, const QVersionNumber &vr,
- const TypeEntry *parent);
-
- int ordinal() const;
- void setOrdinal(int o);
-
- TypeEntry *clone() const override;
-
-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;
-};
-
-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
- */
- PrimitiveTypeEntry* basicReferencedTypeEntry() const;
-
- bool preferredTargetLangType() const;
- void setPreferredTargetLangType(bool b);
-
- TypeEntry *clone() const override;
-
-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;
+TypeSystemTypeEntryCPtr typeSystemTypeEntry(TypeEntryCPtr e);
- TypeFlags typeFlags() const;
- void setTypeFlags(TypeFlags flags);
+// cf AbstractMetaClass::targetLangEnclosingClass()
+TypeEntryCPtr targetLangEnclosingEntry(const TypeEntryCPtr &e);
- // 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);
+bool isCppPrimitive(const TypeEntryCPtr &e);
- FunctionModificationList functionModifications() const;
- void setFunctionModifications(const FunctionModificationList &functionModifications);
- void addFunctionModification(const FunctionModification &functionModification);
- FunctionModificationList functionModifications(const QString &signature) const;
+/// Returns true if the type is a primitive but not a C++ primitive.
+bool isUserPrimitive(const TypeEntryCPtr &e);
- AddedFunctionList addedFunctions() const;
- void setAddedFunctions(const AddedFunctionList &addedFunctions);
- void addNewFunction(const AddedFunctionPtr &addedFunction);
+/// 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);
- 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);
-
-#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:
- 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;
-
- 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 1a972ec1f..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
};
@@ -98,6 +74,38 @@ enum class BoolCast { // Generate nb_bool (overriding command line)
Enabled
};
+enum class CPythonType
+{
+ Bool,
+ Float,
+ Integer,
+ String,
+ 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 e7a72aa46..5a4e12ff2 100644
--- a/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
+++ b/sources/shiboken6/ApiExtractor/typesystem_typedefs.h
@@ -1,53 +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 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 *>;
+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>;
#endif // TYPESYSTEM_TYPEDEFS_H
diff --git a/sources/shiboken6/ApiExtractor/typesystemparser.cpp b/sources/shiboken6/ApiExtractor/typesystemparser.cpp
index ea07b752e..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,74 +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 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 "^..$"
@@ -126,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());
@@ -140,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,
@@ -223,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,
@@ -234,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)
@@ -244,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)
@@ -253,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)
@@ -261,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)
@@ -269,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)
@@ -285,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)
@@ -293,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)
@@ -311,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)
@@ -320,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)
@@ -336,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)
@@ -350,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)
@@ -362,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},
@@ -394,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},
@@ -415,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)
@@ -427,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)
@@ -438,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;
}
@@ -452,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)
@@ -474,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);
@@ -496,31 +586,30 @@ private:
QString readFile(const QString &entityName, QString *errorMessage) const;
const QString m_currentPath;
- QHash<QString, QString> m_cache;
};
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();
@@ -531,20 +620,33 @@ QString TypeSystemEntityResolver::readFile(const QString &entityName, QString *e
QString TypeSystemEntityResolver::resolveUndeclaredEntity(const QString &name)
{
- auto it = m_cache.find(name);
- if (it == m_cache.end()) {
- QString errorMessage;
- it = m_cache.insert(name, readFile(name, &errorMessage));
- if (it.value().isEmpty()) { // The parser will fail and display the line number.
- qCWarning(lcShiboken, "%s",
- qPrintable(msgCannotResolveEntity(name, errorMessage)));
- }
+ QString errorMessage;
+ const QString result = readFile(name, &errorMessage);
+ if (result.isEmpty()) { // The parser will fail and display the line number.
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgCannotResolveEntity(name, errorMessage)));
}
- return it.value();
+ 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)
{
}
@@ -585,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
@@ -610,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
@@ -627,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);
@@ -668,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;
@@ -683,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)
@@ -706,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())) {
@@ -737,315 +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();
- snip.addTemplateInstance(m_current->value.templateInstance);
- 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:
- m_contextStack.top()->codeSnips.last().addTemplateInstance(m_current->value.templateInstance);
- break;
- case StackElement::Template:
- m_current->parent->value.templateEntry->addTemplateInstance(m_current->value.templateInstance);
- break;
- case StackElement::CustomMetaConstructor:
- case StackElement::CustomMetaDestructor:
- m_current->parent->value.customFunction->addTemplateInstance(m_current->value.templateInstance);
+ }
break;
- case StackElement::ConversionRule:
- m_contextStack.top()->functionMods.last().argument_mods().last().conversionRules().last().addTemplateInstance(m_current->value.templateInstance);
+
+ 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:
- m_contextStack.top()->functionMods.last().snips().last().addTemplateInstance(m_current->value.templateInstance);
+ 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;
@@ -1058,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);
@@ -1129,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.")
@@ -1141,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) {
@@ -1171,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;
}
@@ -1194,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");
@@ -1258,159 +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")) {
- type->setTargetLangApiName(attributes->takeAt(i).value().toString());
- } else if (name == preferredConversionAttribute()) {
+ } else if (name == u"target-lang-api-name") {
+ targetLangApiName = attributes->takeAt(i).value().toString();
+ } 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 (type->targetLangApiName().isEmpty())
- type->setTargetLangApiName(type->name());
+ if (!targetLangApiName.isEmpty()) {
+ auto e = m_context->db->findType(targetLangApiName);
+ if (!e || !e->isCustom()) {
+ m_error = msgInvalidTargetLanguageApiName(targetLangApiName);
+ return nullptr;
+ }
+ type->setTargetLangApiType(std::static_pointer_cast<CustomTypeEntry>(e));
+ }
type->setTargetLangPackage(m_defaultPackage);
return type;
}
-ContainerTypeEntry *
+// "int:QList_int;QString:QList_QString"
+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) {
+ 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;
+}
+
+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->takeAt(typeIndex).value();
+ 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;
}
- auto *type = new ContainerTypeEntry(name, containerTypeOpt.value(),
- since, currentParentTypeEntry());
+ attributes->removeAt(typeIndex);
+ auto type = std::make_shared<ContainerTypeEntry>(name, containerTypeOpt.value(),
+ since, currentParentTypeEntry());
if (!applyCommonAttributes(reader, type, attributes))
return nullptr;
+ applyComplexTypeAttributes(reader, type, attributes);
+
+ for (auto i = attributes->size() - 1; i >= 0; --i) {
+ const auto name = attributes->at(i).qualifiedName();
+ if (name == opaqueContainerAttribute) {
+ const auto attribute = attributes->takeAt(i);
+ 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);
}
@@ -1418,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()) {
@@ -1438,11 +1636,11 @@ NamespaceTypeEntry *
return nullptr;
}
result->setFilePattern(re);
- } else if (attributeName == QLatin1String("extends")) {
- const auto extendsPackageName = attributes->takeAt(i).value();
+ } 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()) {
@@ -1450,7 +1648,8 @@ NamespaceTypeEntry *
return nullptr;
}
result->setExtends(*extendsIt);
- } else if (attributeName == visibleAttribute()) {
+ attributes->removeAt(i);
+ } else if (attributeName == visibleAttribute) {
const auto attribute = attributes->takeAt(i);
const auto visibilityOpt = visibilityFromAttribute(attribute.value());
if (!visibilityOpt.has_value()) {
@@ -1458,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)
@@ -1495,7 +1697,7 @@ ValueTypeEntry *
return typeEntry;
}
-FunctionTypeEntry *
+FunctionTypeEntryPtr
TypeSystemParser::parseFunctionTypeEntry(const ConditionalStreamReader &reader,
const QString &name, const QVersionNumber &since,
QXmlStreamAttributes *attributes)
@@ -1503,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;
@@ -1580,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()) {
@@ -1616,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()) {
@@ -1625,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()) {
@@ -1653,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()) {
@@ -1662,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()) {
@@ -1671,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);
}
}
@@ -1689,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;
@@ -1735,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()) {
@@ -1759,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()) {
@@ -1770,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()) {
@@ -1825,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()) {
@@ -1834,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()) {
@@ -1843,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;
}
@@ -1870,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 = QStringLiteral("Failed to parse: '%1'").arg(typeSystemName);
+ m_error = u"Failed to parse: '"_s + typeSystemName + u'\'';
return result;
}
@@ -1893,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());
@@ -1906,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(
@@ -1924,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()) {
@@ -1949,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.");
@@ -1988,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;
+ }
+ auto customConversion = CustomConversion::getCustomConversion(top->entry);
+ if (!customConversion) {
+ m_error = msgMissingCustomConversion(top->entry);
return false;
}
- m_current->entry->customConversion()->addTargetToNativeConversion(sourceTypeName, typeCheck);
- m_contextStack.top()->codeSnips.append(snip);
+ customConversion->addTargetToNativeConversion(sourceTypeName, typeCheck);
return true;
}
@@ -2047,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;
}
@@ -2065,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;
}
@@ -2079,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;
}
@@ -2111,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;
}
@@ -2132,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) {
@@ -2152,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()) {
@@ -2163,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();
@@ -2182,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();
@@ -2204,19 +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 == 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()) {
+ } 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) {
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()) {
@@ -2228,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;
@@ -2248,70 +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::normalizedSignature(originalSignature);
+ 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);
- if (!signature.contains(QLatin1Char('(')))
- signature += QLatin1String("()");
+ func->setPythonOverride(pythonOverride);
+ func->setTargetLangPackage(m_defaultPackage);
+
+ // Create signature for matching modifications
+ signature = TypeDatabase::normalizedSignature(originalSignature);
+ if (!signature.contains(u'('))
+ signature += u"()"_s;
m_currentSignature = signature;
if (!access.isEmpty()) {
const auto acessOpt = addedFunctionAccessFromAttribute(access);
if (!acessOpt.has_value()) {
- m_error = QString::fromLatin1("Bad access type '%1'").arg(access);
+ m_error = u"Bad access type '"_s + access + u'\'';
return false;
}
func->setAccess(acessOpt.value());
@@ -2322,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);
@@ -2331,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 = QString::fromLatin1("Bad access type '%1'").arg(access);
+ 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()) {
@@ -2488,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;
}
@@ -2515,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()) {
@@ -2566,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();
}
}
@@ -2576,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()) {
@@ -2604,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);
@@ -2651,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()) {
@@ -2677,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()) {
@@ -2691,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()) {
@@ -2728,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;
@@ -2743,57 +3144,79 @@ 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;
+}
+
+// Check for a duplicated type entry and return whether to add the new one.
+// 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)
+bool TypeSystemParser::checkDuplicatedTypeEntry(const ConditionalStreamReader &reader,
+ StackElement t,
+ const QString &name) const
+{
+ if (t == StackElement::PrimitiveTypeEntry || t == StackElement::FunctionTypeEntry)
+ return true;
+ const auto duplicated = m_context->db->findType(name);
+ if (!duplicated || duplicated->isNamespace())
+ return true;
+ if (duplicated->isBuiltIn()) {
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgReaderMessage(reader, "Warning",
+ msgDuplicateBuiltInTypeEntry(name))));
+ return false;
+ }
+ qCWarning(lcShiboken, "%s",
+ qPrintable(msgReaderMessage(reader, "Warning",
+ msgDuplicateTypeEntry(name))));
return true;
}
@@ -2808,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;
@@ -2819,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;
@@ -2835,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 = QStringLiteral("Unknown tag name: '%1'").arg(tagName);
- 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;
}
@@ -2925,144 +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()
- << QStringLiteral("Duplicate type entry: '%1'").arg(name);
+ << "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 (!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()
- << QStringLiteral("Type: %1 was rejected by typesystem").arg(name);
+ << 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 = QStringLiteral("Tag requires parent: '%1'").arg(tagName);
+ } 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))
@@ -3085,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:
@@ -3113,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;
@@ -3129,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:
@@ -3143,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:
@@ -3159,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))
@@ -3175,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:
@@ -3227,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 f1e11d661..000000000
--- a/sources/shiboken6/ApiExtractor/typesystemparser.h
+++ /dev/null
@@ -1,285 +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 *);
-
- 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);