diff options
Diffstat (limited to 'sources/shiboken2/ApiExtractor')
147 files changed, 0 insertions, 33954 deletions
diff --git a/sources/shiboken2/ApiExtractor/AUTHORS b/sources/shiboken2/ApiExtractor/AUTHORS deleted file mode 100644 index 6e802fb53..000000000 --- a/sources/shiboken2/ApiExtractor/AUTHORS +++ /dev/null @@ -1,8 +0,0 @@ -Anderson Lizardo <anderson.lizardo@openbossa.org> -Bruno Araujo <bruno.araujo@openbossa.org> -Hugo Parente Lima <hugo.lima@openbossa.org> -Lauro Moura <lauro.neto@openbossa.org> -Luciano Wolf <luciano.wolf@openbossa.org> -Marcelo Lira <marcelo.lira@openbossa.org> -Renato Araujo Oliveira Filho <renato.filho@openbossa.org> - diff --git a/sources/shiboken2/ApiExtractor/CMakeLists.txt b/sources/shiboken2/ApiExtractor/CMakeLists.txt deleted file mode 100644 index 28644fe49..000000000 --- a/sources/shiboken2/ApiExtractor/CMakeLists.txt +++ /dev/null @@ -1,95 +0,0 @@ -project(apiextractor) - -cmake_minimum_required(VERSION 3.1) -cmake_policy(VERSION 3.1) - -set(CMAKE_AUTOMOC ON) - -set(apiextractor_SRC -apiextractor.cpp -abstractmetabuilder.cpp -abstractmetalang.cpp -fileout.cpp -graph.cpp -messages.cpp -reporthandler.cpp -sourcelocation.cpp -typeparser.cpp -typesystem.cpp -typesystemparser.cpp -include.cpp -typedatabase.cpp -# Clang -clangparser/compilersupport.cpp -clangparser/clangparser.cpp -clangparser/clangbuilder.cpp -clangparser/clangdebugutils.cpp -clangparser/clangutils.cpp -# Old parser -parser/codemodel.cpp -parser/enumvalue.cpp -xmlutils.cpp -) - -find_package(Qt${QT_MAJOR_VERSION}XmlPatterns 5.12) -find_package(Qt${QT_MAJOR_VERSION}Xml 5.12) -find_package(LibXml2 2.6.32) -find_package(LibXslt 1.1.19) - -set(HAS_LIBXSLT 0) -if (LIBXSLT_FOUND AND LIBXML2_FOUND) - set(HAS_LIBXSLT 1) -endif() - -if(NOT Qt${QT_MAJOR_VERSION}XmlPatterns_FOUND AND NOT HAS_LIBXSLT) - set(DISABLE_DOCSTRINGS TRUE) - message(WARNING - "Documentation will not be built due to missing dependency (no Qt5XmlPatterns found).") -endif() - -# Export to parent scope so that generator/CMakeLists.txt gets it -set(DISABLE_DOCSTRINGS ${DISABLE_DOCSTRINGS} PARENT_SCOPE) - -add_library(apiextractor STATIC ${apiextractor_SRC}) -target_include_directories(apiextractor PRIVATE ${CLANG_EXTRA_INCLUDES} - ${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 PRIVATE ${CLANG_EXTRA_LIBRARIES}) - -if (HAS_LIBXSLT) - target_compile_definitions(apiextractor PUBLIC HAVE_LIBXSLT) - target_sources(apiextractor PRIVATE xmlutils_libxslt.cpp) - target_include_directories(apiextractor - PRIVATE ${LIBXSLT_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR}) - target_link_libraries(apiextractor - PRIVATE ${LIBXSLT_LIBRARIES} ${LIBXML2_LIBRARIES}) -endif() - -if (Qt${QT_MAJOR_VERSION}XmlPatterns_FOUND) - target_compile_definitions(apiextractor PUBLIC HAVE_QTXMLPATTERNS) - target_sources(apiextractor PRIVATE xmlutils_qt.cpp) - target_link_libraries(apiextractor PUBLIC Qt${QT_MAJOR_VERSION}::Xml Qt${QT_MAJOR_VERSION}::XmlPatterns) -endif() - -if (NOT DISABLE_DOCSTRINGS) - target_sources(apiextractor PRIVATE docparser.cpp - doxygenparser.cpp - qtdocparser.cpp) - if (NOT HAS_LIBXSLT) - message(WARNING - "libxslt and/or libxml not found, falling back to QtXmlPatterns (QTBUG-66925)") - endif() -endif() - -target_compile_definitions(apiextractor PRIVATE CMAKE_CXX_COMPILER="${CMAKE_CXX_COMPILER}") - -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 5.12 REQUIRED) - set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/tests) - enable_testing() - add_subdirectory(tests) -endif() diff --git a/sources/shiboken2/ApiExtractor/COPYING b/sources/shiboken2/ApiExtractor/COPYING deleted file mode 100644 index 4ccd71466..000000000 --- a/sources/shiboken2/ApiExtractor/COPYING +++ /dev/null @@ -1,342 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - -------------------------------------------------------------------------- diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp b/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp deleted file mode 100644 index 2364cec7a..000000000 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp +++ /dev/null @@ -1,3213 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "abstractmetabuilder_p.h" -#include "messages.h" -#include "reporthandler.h" -#include "typedatabase.h" - -#include <clangparser/clangbuilder.h> -#include <clangparser/clangutils.h> -#include <clangparser/compilersupport.h> - -#include "parser/codemodel.h" - -#include <QDebug> -#include <QDir> -#include <QFile> -#include <QFileInfo> -#include <QRegularExpression> -#include <QTextStream> -#include <QVariant> -#include <QTime> -#include <QQueue> -#include <QDir> - -#include <cstdio> -#include <algorithm> -#include "graph.h" -#include <QTemporaryFile> - -static inline QString colonColon() { return QStringLiteral("::"); } - -static QString stripTemplateArgs(const QString &name) -{ - int pos = name.indexOf(QLatin1Char('<')); - return pos < 0 ? name : name.left(pos); -} - -static QStringList parseTemplateType(const QString &name) { - int n = name.indexOf(QLatin1Char('<')); - if (n <= 0) { - // If name starts with '<' or contains an unmatched (i.e. any) '>', we - // reject it - if (n == 0 || name.count(QLatin1Char('>'))) - return QStringList(); - // Doesn't look like a template instantiation; just return the name - return QStringList() << name; - } - - // Split the type name into the template name and template arguments; the - // part before the opening '<' is the template name - // - // Example: - // "foo<A, bar<B, C>, D>" -> ( "foo", "A", "bar<B, C>", "D" ) - QStringList result; - result << name.left(n).trimmed(); - - // Extract template arguments - int i, depth = 1; - const int l = name.length(); - for (i = n + 1; i < l; ++i) { - // Consume balanced '<'/'>' within a single argument so that we won't - // split on ',' as part of a single argument which is itself a - // multi-argument template type - if (name[i] == QLatin1Char('<')) { - ++depth; - } else if (name[i] == QLatin1Char('>')) { - if (--depth == 0) - break; - } else if (name[i] == QLatin1Char(',') && depth == 1) { - // Encountered ',' in template argument list that is not within - // another template name; add current argument to result and start - // working on the next argument - result << name.mid(n + 1, i - n - 1).trimmed(); - n = i; - } - } - if (i >= l) // arg list not closed - return QStringList(); - if (i + 1 < l) // arg list closed before end of name - return QStringList(); - - // Add final argument and return result - result << name.mid(n + 1, i - n - 1).trimmed(); - return result; -} - -AbstractMetaBuilderPrivate::AbstractMetaBuilderPrivate() : - m_logDirectory(QLatin1String(".") + QDir::separator()) -{ -} - -AbstractMetaBuilderPrivate::~AbstractMetaBuilderPrivate() -{ - qDeleteAll(m_globalEnums); - qDeleteAll(m_globalFunctions); - qDeleteAll(m_templates); - qDeleteAll(m_smartPointers); - qDeleteAll(m_metaClasses); -} - -AbstractMetaBuilder::AbstractMetaBuilder() : d(new AbstractMetaBuilderPrivate) -{ - d->q = this; -} - -AbstractMetaBuilder::~AbstractMetaBuilder() -{ - delete d; -} - -AbstractMetaClassList AbstractMetaBuilder::classes() const -{ - return d->m_metaClasses; -} - -AbstractMetaClassList AbstractMetaBuilder::templates() const -{ - return d->m_templates; -} - -AbstractMetaClassList AbstractMetaBuilder::smartPointers() const -{ - return d->m_smartPointers; -} - -AbstractMetaFunctionList AbstractMetaBuilder::globalFunctions() const -{ - return d->m_globalFunctions; -} - -AbstractMetaEnumList AbstractMetaBuilder::globalEnums() const -{ - return d->m_globalEnums; -} - -AbstractMetaEnum *AbstractMetaBuilder::findEnum(const TypeEntry *typeEntry) const -{ - if (typeEntry && typeEntry->isFlags()) - typeEntry = static_cast<const FlagsTypeEntry *>(typeEntry)->originator(); - return d->m_enums.value(typeEntry); -} - -void AbstractMetaBuilderPrivate::checkFunctionModifications() -{ - const auto &entries = TypeDatabase::instance()->entries(); - - for (auto it = entries.cbegin(), end = entries.cend(); it != end; ++it) { - const TypeEntry *entry = it.value(); - if (!entry) - continue; - if (!entry->isComplex() || entry->codeGeneration() == TypeEntry::GenerateNothing) - continue; - - auto centry = static_cast<const ComplexTypeEntry *>(entry); - - if (!(centry->codeGeneration() & TypeEntry::GenerateTargetLang)) - continue; - - FunctionModificationList modifications = centry->functionModifications(); - - for (const FunctionModification &modification : qAsConst(modifications)) { - QString signature = modification.signature(); - - QString name = signature.trimmed(); - name.truncate(name.indexOf(QLatin1Char('('))); - - AbstractMetaClass *clazz = AbstractMetaClass::findClass(m_metaClasses, centry); - if (!clazz) - continue; - - const AbstractMetaFunctionList functions = clazz->functions(); - bool found = false; - QStringList possibleSignatures; - for (AbstractMetaFunction *function : functions) { - if (function->implementingClass() == clazz - && modification.matches(function->minimalSignature())) { - found = true; - break; - } - - if (function->originalName() == name) { - possibleSignatures.append(function->minimalSignature() + QLatin1String(" in ") - + function->implementingClass()->name()); - } - } - - if (!found) { - qCWarning(lcShiboken).noquote().nospace() - << msgNoFunctionForModification(clazz, signature, - modification.originalSignature(), - possibleSignatures, functions); - } - } - } -} - -AbstractMetaClass *AbstractMetaBuilderPrivate::argumentToClass(const ArgumentModelItem &argument, - AbstractMetaClass *currentClass) -{ - AbstractMetaClass *returned = nullptr; - AbstractMetaType *type = translateType(argument->type(), currentClass); - if (type && type->typeEntry() && type->typeEntry()->isComplex()) { - const TypeEntry *entry = type->typeEntry(); - returned = AbstractMetaClass::findClass(m_metaClasses, entry); - } - delete type; - return returned; -} - -/** - * 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) -{ - ArgumentList arguments = function_item->arguments(); - if (arguments.size() == 1) { - if (AbstractMetaClass *cls = argumentToClass(arguments.at(0), currentClass)) - cls->setHasHashFunction(true); - } -} - -void AbstractMetaBuilderPrivate::registerToStringCapabilityIn(const NamespaceModelItem &nsItem) -{ - const FunctionList &streamOps = nsItem->findFunctions(QLatin1String("operator<<")); - for (const FunctionModelItem &item : streamOps) - registerToStringCapability(item, nullptr); - for (const NamespaceModelItem &ni : nsItem->namespaces()) - registerToStringCapabilityIn(ni); -} - -/** - * Check if a class has a debug stream operator that can be used as toString - */ - -void AbstractMetaBuilderPrivate::registerToStringCapability(const FunctionModelItem &function_item, - AbstractMetaClass *currentClass) -{ - ArgumentList arguments = function_item->arguments(); - if (arguments.size() == 2) { - if (arguments.at(0)->type().toString() == QLatin1String("QDebug")) { - const ArgumentModelItem &arg = arguments.at(1); - if (AbstractMetaClass *cls = argumentToClass(arg, currentClass)) { - if (arg->type().indirections() < 2) - cls->setToStringCapability(true, int(arg->type().indirections())); - } - } - } -} - -void AbstractMetaBuilderPrivate::traverseOperatorFunction(const FunctionModelItem &item, - AbstractMetaClass *currentClass) -{ - if (item->accessPolicy() != CodeModel::Public) - return; - - ArgumentList arguments = item->arguments(); - bool firstArgumentIsSelf = true; - bool unaryOperator = false; - - auto baseoperandClass = argumentToClass(arguments.at(0), currentClass); - - if (arguments.size() == 1) { - unaryOperator = true; - } else if (!baseoperandClass - || !(baseoperandClass->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang)) { - baseoperandClass = argumentToClass(arguments.at(1), currentClass); - firstArgumentIsSelf = false; - } else { - AbstractMetaType *type = translateType(item->type(), currentClass); - const TypeEntry *retType = type ? type->typeEntry() : nullptr; - AbstractMetaClass *otherArgClass = argumentToClass(arguments.at(1), currentClass); - if (otherArgClass && retType - && (retType->isValue() || retType->isObject()) - && retType != baseoperandClass->typeEntry() - && retType == otherArgClass->typeEntry()) { - baseoperandClass = AbstractMetaClass::findClass(m_metaClasses, retType); - firstArgumentIsSelf = false; - } - delete type; - } - - 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); - delete first; - 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); - delete last; - - metaFunction->setArguments(arguments); - metaFunction->setReverseOperator(true); - } - metaFunction->setFunctionType(AbstractMetaFunction::NormalFunction); - metaFunction->setVisibility(AbstractMetaFunction::Public); - metaFunction->setOriginalAttributes(metaFunction->attributes()); - setupFunctionDefaults(metaFunction, baseoperandClass); - baseoperandClass->addFunction(metaFunction); - Q_ASSERT(!metaFunction->wasPrivate()); - } else { - delete metaFunction; - } - } -} - -void AbstractMetaBuilderPrivate::traverseStreamOperator(const FunctionModelItem &item, - AbstractMetaClass *currentClass) -{ - ArgumentList arguments = item->arguments(); - if (arguments.size() == 2 && item->accessPolicy() == CodeModel::Public) { - AbstractMetaClass *streamClass = argumentToClass(arguments.at(0), currentClass); - AbstractMetaClass *streamedClass = argumentToClass(arguments.at(1), currentClass); - - if (streamClass && streamedClass && (streamClass->isStream())) { - AbstractMetaFunction *streamFunction = traverseFunction(item, streamedClass); - - if (streamFunction) { - streamFunction->setFunctionType(AbstractMetaFunction::GlobalScopeFunction); - // Strip first argument, since that is the containing object - AbstractMetaArgumentList arguments = streamFunction->arguments(); - if (!streamClass->typeEntry()->generateCode()) - delete arguments.takeLast(); - else - delete arguments.takeFirst(); - - streamFunction->setArguments(arguments); - - *streamFunction += AbstractMetaAttributes::FinalInTargetLang; - *streamFunction += AbstractMetaAttributes::Public; - streamFunction->setOriginalAttributes(streamFunction->attributes()); - -// streamFunction->setType(0); - - AbstractMetaClass *funcClass; - - if (!streamClass->typeEntry()->generateCode()) { - AbstractMetaArgumentList reverseArgs = reverseList(streamFunction->arguments()); - streamFunction->setArguments(reverseArgs); - streamFunction->setReverseOperator(true); - funcClass = streamedClass; - } else { - funcClass = streamClass; - } - - setupFunctionDefaults(streamFunction, funcClass); - funcClass->addFunction(streamFunction); - if (funcClass == streamClass) - funcClass->typeEntry()->addExtraInclude(streamedClass->typeEntry()->include()); - else - funcClass->typeEntry()->addExtraInclude(streamClass->typeEntry()->include()); - - } else { - delete streamFunction; - } - - } - } -} - -void AbstractMetaBuilderPrivate::sortLists() -{ - for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) - cls->sortFunctions(); -} - -FileModelItem AbstractMetaBuilderPrivate::buildDom(QByteArrayList arguments, - LanguageLevel level, - unsigned clangFlags) -{ - clang::Builder builder; - builder.setSystemIncludes(TypeDatabase::instance()->systemIncludes()); - if (level == LanguageLevel::Default) - level = clang::emulatedCompilerLanguageLevel(); - arguments.prepend(QByteArrayLiteral("-std=") - + clang::languageLevelOption(level)); - FileModelItem result = clang::parse(arguments, clangFlags, builder) - ? builder.dom() : FileModelItem(); - const clang::BaseVisitor::Diagnostics &diagnostics = builder.diagnostics(); - if (const int diagnosticsCount = diagnostics.size()) { - QDebug d = qWarning(); - d.nospace(); - d.noquote(); - d << "Clang: " << diagnosticsCount << " diagnostic messages:\n"; - for (int i = 0; i < diagnosticsCount; ++i) - d << " " << diagnostics.at(i) << '\n'; - } - return result; -} - -void AbstractMetaBuilderPrivate::traverseDom(const FileModelItem &dom) -{ - const TypeDatabase *types = TypeDatabase::instance(); - - pushScope(dom); - - // Start the generation... - const ClassList &typeValues = dom->classes(); - - ReportHandler::startProgress("Generating class model (" - + QByteArray::number(typeValues.size()) + ")..."); - for (const ClassModelItem &item : typeValues) { - if (AbstractMetaClass *cls = traverseClass(dom, item, nullptr)) - addAbstractMetaClass(cls, item.data()); - } - - // We need to know all global enums - const EnumList &enums = dom->enums(); - - ReportHandler::startProgress("Generating enum model (" - + QByteArray::number(enums.size()) + ")..."); - for (const EnumModelItem &item : enums) { - AbstractMetaEnum *metaEnum = traverseEnum(item, nullptr, QSet<QString>()); - if (metaEnum) { - if (metaEnum->typeEntry()->generateCode()) - m_globalEnums << metaEnum; - } - } - - const auto &namespaceTypeValues = dom->namespaces(); - ReportHandler::startProgress("Generating 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()) + ")..."); - for (const TypeDefModelItem &typeDef : typeDefs) { - if (AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, nullptr)) - addAbstractMetaClass(cls, typeDef.data()); - } - - traverseTypesystemTypedefs(); - - for (const ClassModelItem &item : typeValues) - traverseClassMembers(item); - - for (const NamespaceModelItem &item : namespaceTypeValues) - traverseNamespaceMembers(item); - - // Global functions - const FunctionList &functions = dom->functions(); - for (const FunctionModelItem &func : functions) { - if (func->accessPolicy() != CodeModel::Public || func->name().startsWith(QLatin1String("operator"))) - continue; - - FunctionTypeEntry *funcEntry = types->findFunctionType(func->name()); - if (!funcEntry || !funcEntry->generateCode()) - continue; - - AbstractMetaFunction *metaFunc = traverseFunction(func, nullptr); - if (!metaFunc) - continue; - - if (!funcEntry->hasSignature(metaFunc->minimalSignature())) { - delete metaFunc; - continue; - } - - applyFunctionModifications(metaFunc); - - setInclude(funcEntry, func->fileName()); - if (metaFunc->typeEntry()) - delete metaFunc->typeEntry(); - - metaFunc->setTypeEntry(funcEntry); - m_globalFunctions << metaFunc; - } - - ReportHandler::startProgress("Fixing class inheritance..."); - for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) { - if (!cls->isNamespace()) { - setupInheritance(cls); - if (!cls->hasVirtualDestructor() && cls->baseClass() - && cls->baseClass()->hasVirtualDestructor()) - cls->setHasVirtualDestructor(true); - } - } - - ReportHandler::startProgress("Detecting inconsistencies in class model..."); - for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) { - cls->fixFunctions(); - - if (!cls->typeEntry()) { - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("class '%1' does not have an entry in the type system") - .arg(cls->name()); - } else { - const bool couldAddDefaultCtors = cls->isConstructible() - && !cls->isNamespace() - && (cls->attributes() & AbstractMetaAttributes::HasRejectedConstructor) == 0; - if (couldAddDefaultCtors) { - if (!cls->hasConstructors()) - cls->addDefaultConstructor(); - if (cls->typeEntry()->isValue() && !cls->isAbstract() && !cls->hasCopyConstructor()) - cls->addDefaultCopyConstructor(ancestorHasPrivateCopyConstructor(cls)); - } - } - } - const auto &allEntries = types->entries(); - - ReportHandler::startProgress("Detecting inconsistencies in typesystem (" - + QByteArray::number(allEntries.size()) + ")..."); - for (auto it = allEntries.cbegin(), end = allEntries.cend(); it != end; ++it) { - TypeEntry *entry = it.value(); - if (!entry->isPrimitive()) { - if ((entry->isValue() || entry->isObject()) - && !types->shouldDropTypeEntry(entry->qualifiedCppName()) - && !entry->isContainer() - && !entry->isCustom() - && (entry->generateCode() & TypeEntry::GenerateTargetLang) - && !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); - const QStringList &signatures = fte->signatures(); - for (const QString &signature : signatures) { - bool ok = false; - for (AbstractMetaFunction *func : qAsConst(m_globalFunctions)) { - if (signature == func->minimalSignature()) { - ok = true; - break; - } - } - if (!ok) { - qCWarning(lcShiboken, "%s", - qPrintable(msgGlobalFunctionNotDefined(fte, signature))); - } - } - } else if (entry->isEnum() && (entry->generateCode() & TypeEntry::GenerateTargetLang)) { - auto enumEntry = static_cast<const EnumTypeEntry *>(entry); - const QString name = enumEntry->targetLangQualifier(); - AbstractMetaClass *cls = AbstractMetaClass::findClass(m_metaClasses, name); - - const bool enumFound = cls - ? cls->findEnum(entry->targetLangEntryName()) != nullptr - : m_enums.contains(entry); - - if (!enumFound) { - entry->setCodeGeneration(TypeEntry::GenerateNothing); - qCWarning(lcShiboken, "%s", - qPrintable(msgEnumNotDefined(enumEntry))); - } - - } - } - } - - { - const FunctionList &hashFunctions = dom->findFunctions(QLatin1String("qHash")); - for (const FunctionModelItem &item : hashFunctions) - registerHashFunction(item, nullptr); - } - - registerToStringCapabilityIn(dom); - - { - FunctionList binaryOperators = dom->findFunctions(QStringLiteral("operator==")); - binaryOperators.append(dom->findFunctions(QStringLiteral("operator!="))); - binaryOperators.append(dom->findFunctions(QStringLiteral("operator<="))); - binaryOperators.append(dom->findFunctions(QStringLiteral("operator>="))); - binaryOperators.append(dom->findFunctions(QStringLiteral("operator<"))); - binaryOperators.append(dom->findFunctions(QStringLiteral("operator+"))); - binaryOperators.append(dom->findFunctions(QStringLiteral("operator/"))); - // Filter binary operators, skipping for example - // class Iterator { ... Value *operator*() ... }; - const FunctionList potentiallyBinaryOperators = - dom->findFunctions(QStringLiteral("operator*")) - + dom->findFunctions(QStringLiteral("operator&")); - for (const FunctionModelItem &item : potentiallyBinaryOperators) { - if (!item->arguments().isEmpty()) - binaryOperators.append(item); - } - binaryOperators.append(dom->findFunctions(QStringLiteral("operator-"))); - binaryOperators.append(dom->findFunctions(QStringLiteral("operator&"))); - binaryOperators.append(dom->findFunctions(QStringLiteral("operator|"))); - binaryOperators.append(dom->findFunctions(QStringLiteral("operator^"))); - binaryOperators.append(dom->findFunctions(QStringLiteral("operator~"))); - binaryOperators.append(dom->findFunctions(QStringLiteral("operator>"))); - - for (const FunctionModelItem &item : qAsConst(binaryOperators)) - traverseOperatorFunction(item, nullptr); - } - - { - const FunctionList streamOperators = dom->findFunctions(QLatin1String("operator<<")) - + dom->findFunctions(QLatin1String("operator>>")); - for (const FunctionModelItem &item : streamOperators) - traverseStreamOperator(item, nullptr); - } - - ReportHandler::startProgress("Checking inconsistencies in function modifications..."); - - checkFunctionModifications(); - - ReportHandler::startProgress("Writing log files..."); - - // sort all classes topologically - m_metaClasses = classesTopologicalSorted(m_metaClasses); - - for (AbstractMetaClass *cls : qAsConst(m_metaClasses)) { -// setupEquals(cls); -// setupComparable(cls); - setupClonable(cls); - setupExternalConversion(cls); - - // sort all inner classes topologically - if (!cls->typeEntry()->codeGeneration() || cls->innerClasses().size() < 2) - continue; - - cls->setInnerClasses(classesTopologicalSorted(cls->innerClasses())); - } - - dumpLog(); - - sortLists(); - - // Functions added to the module on the type system. - const AddedFunctionList &globalUserFunctions = types->globalUserFunctions(); - for (const AddedFunctionPtr &addedFunc : globalUserFunctions) { - AbstractMetaFunction *metaFunc = traverseFunction(addedFunc); - if (Q_UNLIKELY(!metaFunc)) { - qFatal("Unable to traverse added global function \"%s\".", - qPrintable(addedFunc->name())); - } - metaFunc->setFunctionType(AbstractMetaFunction::NormalFunction); - m_globalFunctions << metaFunc; - } - - m_itemToClass.clear(); - - ReportHandler::endProgress(); -} - -static bool metaEnumLessThan(const AbstractMetaEnum *e1, const AbstractMetaEnum *e2) -{ return e1->fullName() < e2->fullName(); } - -static bool metaClassLessThan(const AbstractMetaClass *c1, const AbstractMetaClass *c2) -{ return c1->fullName() < c2->fullName(); } - -static bool metaFunctionLessThan(const AbstractMetaFunction *f1, const AbstractMetaFunction *f2) -{ return f1->name() < f2->name(); } - -bool AbstractMetaBuilder::build(const QByteArrayList &arguments, - LanguageLevel level, - unsigned clangFlags) -{ - const FileModelItem dom = d->buildDom(arguments, level, clangFlags); - if (dom.isNull()) - return false; - if (ReportHandler::isDebug(ReportHandler::MediumDebug)) - qCDebug(lcShiboken) << dom.data(); - d->traverseDom(dom); - - // Ensure that indexes are in alphabetical order, roughly - std::sort(d->m_globalEnums.begin(), d->m_globalEnums.end(), metaEnumLessThan); - std::sort(d->m_metaClasses.begin(), d->m_metaClasses.end(), metaClassLessThan); - std::sort(d->m_templates.begin(), d->m_templates.end(), metaClassLessThan); - std::sort(d->m_smartPointers.begin(), d->m_smartPointers.end(), metaClassLessThan); - std::sort(d->m_globalFunctions.begin(), d->m_globalFunctions.end(), metaFunctionLessThan); - - return true; -} - -void AbstractMetaBuilder::setLogDirectory(const QString &logDir) -{ - d->m_logDirectory = logDir; - if (!d->m_logDirectory.endsWith(QDir::separator())) - d->m_logDirectory.append(QDir::separator()); -} - -void AbstractMetaBuilderPrivate::addAbstractMetaClass(AbstractMetaClass *cls, - const _CodeModelItem *item) -{ - cls->setOriginalAttributes(cls->attributes()); - m_itemToClass.insert(item, cls); - if (cls->typeEntry()->isContainer()) { - m_templates << cls; - } else if (cls->typeEntry()->isSmartPointer()) { - m_smartPointers << cls; - } else { - m_metaClasses << cls; - } -} - -AbstractMetaClass *AbstractMetaBuilderPrivate::traverseNamespace(const FileModelItem &dom, - const NamespaceModelItem &namespaceItem) -{ - QString namespaceName = currentScope()->qualifiedName().join(colonColon()); - if (!namespaceName.isEmpty()) - namespaceName.append(colonColon()); - namespaceName.append(namespaceItem->name()); - - if (TypeDatabase::instance()->isClassRejected(namespaceName)) { - m_rejectedClasses.insert(namespaceName, AbstractMetaBuilder::GenerationDisabled); - return nullptr; - } - - auto type = TypeDatabase::instance()->findNamespaceType(namespaceName, namespaceItem->fileName()); - if (!type) { - qCWarning(lcShiboken, "%s", - qPrintable(msgNamespaceNoTypeEntry(namespaceItem, namespaceName))); - return nullptr; - } - - if (namespaceItem->type() == NamespaceType::Inline) { - type->setInlineNamespace(true); - TypeDatabase::instance()->addInlineNamespaceLookups(type); - } - - // Continue populating namespace? - AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, type); - if (!metaClass) { - metaClass = new AbstractMetaClass; - metaClass->setTypeEntry(type); - *metaClass += AbstractMetaAttributes::Public; - addAbstractMetaClass(metaClass, namespaceItem.data()); - if (auto extendsType = type->extends()) { - AbstractMetaClass *extended = AbstractMetaClass::findClass(m_metaClasses, extendsType); - if (!extended) { - qCWarning(lcShiboken, "%s", - qPrintable(msgNamespaceToBeExtendedNotFound(extendsType->name(), extendsType->targetLangPackage()))); - return nullptr; - } - metaClass->setExtendedNamespace(extended); - } - } else { - m_itemToClass.insert(namespaceItem.data(), metaClass); - } - - traverseEnums(namespaceItem, metaClass, namespaceItem->enumsDeclarations()); - - pushScope(namespaceItem); - - const ClassList &classes = namespaceItem->classes(); - for (const ClassModelItem &cls : classes) { - AbstractMetaClass *mjc = traverseClass(dom, cls, metaClass); - if (mjc) { - metaClass->addInnerClass(mjc); - mjc->setEnclosingClass(metaClass); - addAbstractMetaClass(mjc, cls.data()); - } - } - - // Go through all typedefs to see if we have defined any - // specific typedefs to be used as classes. - const TypeDefList typeDefs = namespaceItem->typeDefs(); - for (const TypeDefModelItem &typeDef : typeDefs) { - AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, metaClass); - if (cls) { - metaClass->addInnerClass(cls); - cls->setEnclosingClass(metaClass); - addAbstractMetaClass(cls, typeDef.data()); - } - } - - // Traverse namespaces recursively - for (const NamespaceModelItem &ni : namespaceItem->namespaces()) { - AbstractMetaClass *mjc = traverseNamespace(dom, ni); - if (mjc) { - metaClass->addInnerClass(mjc); - mjc->setEnclosingClass(metaClass); - } - } - - popScope(); - - if (!type->include().isValid()) - setInclude(type, namespaceItem->fileName()); - - return metaClass; -} - -AbstractMetaEnum *AbstractMetaBuilderPrivate::traverseEnum(const EnumModelItem &enumItem, - AbstractMetaClass *enclosing, - const QSet<QString> &enumsDeclarations) -{ - QString qualifiedName = enumItem->qualifiedName().join(colonColon()); - - TypeEntry *typeEntry = nullptr; - const TypeEntry *enclosingTypeEntry = enclosing ? enclosing->typeEntry() : nullptr; - if (enumItem->accessPolicy() == CodeModel::Private) { - typeEntry = new EnumTypeEntry(enumItem->qualifiedName().constLast(), - QVersionNumber(0, 0), enclosingTypeEntry); - TypeDatabase::instance()->addType(typeEntry); - } else if (enumItem->enumKind() != AnonymousEnum) { - typeEntry = TypeDatabase::instance()->findType(qualifiedName); - } else { - QStringList tmpQualifiedName = enumItem->qualifiedName(); - const EnumeratorList &enums = enumItem->enumerators(); - for (const EnumeratorModelItem &enumValue : enums) { - tmpQualifiedName.removeLast(); - tmpQualifiedName << enumValue->name(); - qualifiedName = tmpQualifiedName.join(colonColon()); - typeEntry = TypeDatabase::instance()->findType(qualifiedName); - if (typeEntry) - break; - } - } - - QString enumName = enumItem->name(); - - QString className; - if (enclosingTypeEntry) - className = enclosingTypeEntry->qualifiedCppName(); - - QString rejectReason; - if (TypeDatabase::instance()->isEnumRejected(className, enumName, &rejectReason)) { - if (typeEntry) - typeEntry->setCodeGeneration(TypeEntry::GenerateNothing); - m_rejectedEnums.insert(qualifiedName + rejectReason, AbstractMetaBuilder::GenerationDisabled); - return nullptr; - } - - const bool rejectionWarning = !enclosing - || (enclosing->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang); - - if (!typeEntry) { - if (rejectionWarning) - qCWarning(lcShiboken, "%s", qPrintable(msgNoEnumTypeEntry(enumItem, className))); - m_rejectedEnums.insert(qualifiedName, AbstractMetaBuilder::NotInTypeSystem); - return nullptr; - } - - if (!typeEntry->isEnum()) { - if (rejectionWarning) { - qCWarning(lcShiboken, "%s", - qPrintable(msgNoEnumTypeConflict(enumItem, className, typeEntry))); - } - m_rejectedEnums.insert(qualifiedName, AbstractMetaBuilder::NotInTypeSystem); - return nullptr; - } - - auto *metaEnum = new AbstractMetaEnum; - metaEnum->setEnumKind(enumItem->enumKind()); - metaEnum->setSigned(enumItem->isSigned()); - if (enumsDeclarations.contains(qualifiedName) - || enumsDeclarations.contains(enumName)) { - metaEnum->setHasQEnumsDeclaration(true); - } - - auto *enumTypeEntry = static_cast<EnumTypeEntry *>(typeEntry); - metaEnum->setTypeEntry(enumTypeEntry); - switch (enumItem->accessPolicy()) { - case CodeModel::Public: - *metaEnum += AbstractMetaAttributes::Public; - break; - case CodeModel::Protected: - *metaEnum += AbstractMetaAttributes::Protected; - break; - case CodeModel::Private: - *metaEnum += AbstractMetaAttributes::Private; - typeEntry->setCodeGeneration(TypeEntry::GenerateNothing); - break; - default: - break; - } - - const EnumeratorList &enums = enumItem->enumerators(); - for (const EnumeratorModelItem &value : enums) { - - auto *metaEnumValue = new AbstractMetaEnumValue; - metaEnumValue->setName(value->name()); - // Deciding the enum value... - - metaEnumValue->setStringValue(value->stringValue()); - metaEnumValue->setValue(value->value()); - metaEnum->addEnumValue(metaEnumValue); - } - - m_enums.insert(typeEntry, metaEnum); - - if (!metaEnum->typeEntry()->include().isValid()) - setInclude(metaEnum->typeEntry(), enumItem->fileName()); - - metaEnum->setOriginalAttributes(metaEnum->attributes()); - - // 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()); - TypeDatabase::instance()->addType(enumValue); - if (e->value().isNullValue()) - enumTypeEntry->setNullValue(enumValue); - } - - return metaEnum; -} - -AbstractMetaClass *AbstractMetaBuilderPrivate::traverseTypeDef(const FileModelItem &, - const TypeDefModelItem &typeDef, - AbstractMetaClass *currentClass) -{ - TypeDatabase *types = TypeDatabase::instance(); - QString className = stripTemplateArgs(typeDef->name()); - - QString fullClassName = className; - // we have an inner class - if (currentClass) { - fullClassName = stripTemplateArgs(currentClass->typeEntry()->qualifiedCppName()) - + colonColon() + fullClassName; - } - - // If this is the alias for a primitive type - // we store the aliased type on the alias - // TypeEntry - PrimitiveTypeEntry *ptype = types->findPrimitiveType(className); - if (ptype) { - QString typeDefName = typeDef->type().qualifiedName()[0]; - ptype->setReferencedTypeEntry(types->findPrimitiveType(typeDefName)); - return nullptr; - } - - - // If we haven't specified anything for the typedef, then we don't care - ComplexTypeEntry *type = types->findComplexType(fullClassName); - if (!type) - return nullptr; - - auto *metaClass = new AbstractMetaClass; - metaClass->setTypeDef(true); - metaClass->setTypeEntry(type); - metaClass->setBaseClassNames(QStringList(typeDef->type().toString())); - *metaClass += AbstractMetaAttributes::Public; - - // Set the default include file name - if (!type->include().isValid()) - setInclude(type, typeDef->fileName()); - - fillAddedFunctions(metaClass); - - return metaClass; -} - -// Add the typedef'ed classes -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; - metaClass->setTypeDef(true); - metaClass->setTypeEntry(te->target()); - metaClass->setBaseClassNames(QStringList(te->sourceType())); - *metaClass += AbstractMetaAttributes::Public; - fillAddedFunctions(metaClass); - addAbstractMetaClass(metaClass, nullptr); - } -} - -AbstractMetaClass *AbstractMetaBuilderPrivate::traverseClass(const FileModelItem &dom, - const ClassModelItem &classItem, - AbstractMetaClass *currentClass) -{ - QString className = stripTemplateArgs(classItem->name()); - QString fullClassName = className; - - // we have inner an class - if (currentClass) { - fullClassName = stripTemplateArgs(currentClass->typeEntry()->qualifiedCppName()) - + colonColon() + fullClassName; - } - - ComplexTypeEntry *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()) - reason = AbstractMetaBuilder::RedefinedToNotClass; - else - reason = AbstractMetaBuilder::NotInTypeSystem; - } else if (type->codeGeneration() == TypeEntry::GenerateNothing) { - reason = AbstractMetaBuilder::GenerationDisabled; - } - if (reason != AbstractMetaBuilder::NoReason) { - if (fullClassName.isEmpty()) { - QTextStream(&fullClassName) << "anonymous struct at " << classItem->fileName() - << ':' << classItem->startLine(); - } - m_rejectedClasses.insert(fullClassName, reason); - return nullptr; - } - - auto *metaClass = new AbstractMetaClass; - metaClass->setSourceLocation(classItem->sourceLocation()); - metaClass->setTypeEntry(type); - - if (classItem->isFinal()) - *metaClass += AbstractMetaAttributes::FinalCppClass; - - QStringList baseClassNames; - const QVector<_ClassModelItem::BaseClass> &baseClasses = classItem->baseClasses(); - for (const _ClassModelItem::BaseClass &baseClass : baseClasses) { - if (baseClass.accessPolicy == CodeModel::Public) - baseClassNames.append(baseClass.name); - } - - metaClass->setBaseClassNames(baseClassNames); - *metaClass += AbstractMetaAttributes::Public; - if (type->stream()) - metaClass->setStream(true); - - if (ReportHandler::isDebug(ReportHandler::MediumDebug)) { - const QString message = type->isContainer() - ? QStringLiteral("container: '%1'").arg(fullClassName) - : QStringLiteral("class: '%1'").arg(metaClass->fullName()); - qCInfo(lcShiboken, "%s", qPrintable(message)); - } - - TemplateParameterList template_parameters = classItem->templateParameters(); - QVector<TypeEntry *> template_args; - template_args.clear(); - auto argumentParent = metaClass->typeEntry()->typeSystemTypeEntry(); - for (int i = 0; i < template_parameters.size(); ++i) { - const TemplateParameterModelItem ¶m = template_parameters.at(i); - auto param_type = new TemplateArgumentEntry(param->name(), type->version(), - argumentParent); - param_type->setOrdinal(i); - template_args.append(param_type); - } - metaClass->setTemplateArguments(template_args); - - parseQ_Property(metaClass, classItem->propertyDeclarations()); - - traverseEnums(classItem, metaClass, classItem->enumsDeclarations()); - - // Inner classes - { - const ClassList &innerClasses = classItem->classes(); - for (const ClassModelItem &ci : innerClasses) { - AbstractMetaClass *cl = traverseClass(dom, ci, metaClass); - if (cl) { - cl->setEnclosingClass(metaClass); - metaClass->addInnerClass(cl); - addAbstractMetaClass(cl, ci.data()); - } - } - - } - - // Go through all typedefs to see if we have defined any - // specific typedefs to be used as classes. - const TypeDefList typeDefs = classItem->typeDefs(); - for (const TypeDefModelItem &typeDef : typeDefs) { - AbstractMetaClass *cls = traverseTypeDef(dom, typeDef, metaClass); - if (cls) { - cls->setEnclosingClass(metaClass); - addAbstractMetaClass(cls, typeDef.data()); - } - } - - // Set the default include file name - if (!type->include().isValid()) - setInclude(type, classItem->fileName()); - - return metaClass; -} - -void AbstractMetaBuilderPrivate::traverseScopeMembers(const ScopeModelItem &item, - AbstractMetaClass *metaClass) -{ - // Classes/Namespace members - traverseFields(item, metaClass); - traverseFunctions(item, metaClass); - - // Inner classes - const ClassList &innerClasses = item->classes(); - for (const ClassModelItem &ci : innerClasses) - traverseClassMembers(ci); -} - -void AbstractMetaBuilderPrivate::traverseClassMembers(const ClassModelItem &item) -{ - AbstractMetaClass *metaClass = m_itemToClass.value(item.data()); - if (!metaClass) - return; - - // Class members - traverseScopeMembers(item, metaClass); -} - -void AbstractMetaBuilderPrivate::traverseNamespaceMembers(const NamespaceModelItem &item) -{ - AbstractMetaClass *metaClass = m_itemToClass.value(item.data()); - if (!metaClass) - return; - - // Namespace members - traverseScopeMembers(item, metaClass); - - // Inner namespaces - for (const NamespaceModelItem &ni : item->namespaces()) - traverseNamespaceMembers(ni); - -} - -static inline QString fieldSignatureWithType(const VariableModelItem &field) -{ - return field->name() + QStringLiteral(" -> ") + field->type().toString(); -} - -static inline QString qualifiedFieldSignatureWithType(const QString &className, - const VariableModelItem &field) -{ - return className + colonColon() + fieldSignatureWithType(field); -} - -AbstractMetaField *AbstractMetaBuilderPrivate::traverseField(const VariableModelItem &field, - AbstractMetaClass *cls) -{ - QString fieldName = field->name(); - QString className = cls->typeEntry()->qualifiedCppName(); - - // Ignore friend decl. - if (field->isFriend()) - return nullptr; - - if (field->accessPolicy() == CodeModel::Private) - return nullptr; - - QString rejectReason; - if (TypeDatabase::instance()->isFieldRejected(className, fieldName, &rejectReason)) { - m_rejectedFields.insert(qualifiedFieldSignatureWithType(className, field) + rejectReason, - AbstractMetaBuilder::GenerationDisabled); - return nullptr; - } - - - auto *metaField = new AbstractMetaField; - metaField->setName(fieldName); - metaField->setEnclosingClass(cls); - - TypeInfo fieldType = field->type(); - AbstractMetaType *metaType = translateType(fieldType, cls); - - if (!metaType) { - const QString type = TypeInfo::resolveType(fieldType, currentScope()).qualifiedName().join(colonColon()); - if (cls->typeEntry()->codeGeneration() & TypeEntry::GenerateTargetLang) { - qCWarning(lcShiboken, "%s", - qPrintable(msgSkippingField(field, cls->name(), type))); - } - delete metaField; - return nullptr; - } - - metaField->setType(metaType); - - AbstractMetaAttributes::Attributes attr; - if (field->isStatic()) - attr |= AbstractMetaAttributes::Static; - - CodeModel::AccessPolicy policy = field->accessPolicy(); - if (policy == CodeModel::Public) - attr |= AbstractMetaAttributes::Public; - else if (policy == CodeModel::Protected) - attr |= AbstractMetaAttributes::Protected; - else - attr |= AbstractMetaAttributes::Private; - metaField->setAttributes(attr); - - return metaField; -} - -void AbstractMetaBuilderPrivate::traverseFields(const ScopeModelItem &scope_item, - AbstractMetaClass *metaClass) -{ - const VariableList &variables = scope_item->variables(); - for (const VariableModelItem &field : variables) { - AbstractMetaField *metaField = traverseField(field, metaClass); - - if (metaField && !metaField->isModifiedRemoved()) { - metaField->setOriginalAttributes(metaField->attributes()); - metaClass->addField(metaField); - } - } -} - -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 ")); - Q_ASSERT(operatorRegExp.isValid()); - QString castTo = metaFunction->name().remove(operatorRegExp).trimmed(); - - if (castTo.endsWith(QLatin1Char('&'))) - castTo.chop(1); - if (castTo.startsWith(QLatin1String("const "))) - castTo.remove(0, 6); - - TypeEntry *retType = types->findType(castTo); - if (!retType) - return; - - auto *metaType = new AbstractMetaType; - metaType->setTypeEntry(retType); - metaFunction->replaceType(metaType); -} - -AbstractMetaFunctionList AbstractMetaBuilderPrivate::classFunctionList(const ScopeModelItem &scopeItem, - AbstractMetaClass::Attributes *constructorAttributes, - AbstractMetaClass *currentClass) -{ - *constructorAttributes = {}; - AbstractMetaFunctionList result; - const FunctionList &scopeFunctionList = scopeItem->functions(); - result.reserve(scopeFunctionList.size()); - for (const FunctionModelItem &function : scopeFunctionList) { - if (AbstractMetaFunction *metaFunction = traverseFunction(function, currentClass)) { - result.append(metaFunction); - } else if (function->functionType() == CodeModel::Constructor) { - auto arguments = function->arguments(); - *constructorAttributes |= AbstractMetaAttributes::HasRejectedConstructor; - if (arguments.isEmpty() || arguments.constFirst()->defaultValue()) - *constructorAttributes |= AbstractMetaAttributes::HasRejectedDefaultConstructor; - } - } - return result; -} - -void AbstractMetaBuilderPrivate::traverseFunctions(ScopeModelItem scopeItem, - AbstractMetaClass *metaClass) -{ - AbstractMetaAttributes::Attributes constructorAttributes; - const AbstractMetaFunctionList functions = - classFunctionList(scopeItem, &constructorAttributes, metaClass); - metaClass->setAttributes(metaClass->attributes() | constructorAttributes); - - for (AbstractMetaFunction *metaFunction : functions){ - metaFunction->setOriginalAttributes(metaFunction->attributes()); - if (metaClass->isNamespace()) - *metaFunction += AbstractMetaAttributes::Static; - - QPropertySpec *read = nullptr; - if (!metaFunction->isSignal() && (read = metaClass->propertySpecForRead(metaFunction->name()))) { - // Property reader must be in the form "<type> name()" - if (metaFunction->type() && (read->type() == metaFunction->type()->typeEntry()) - && metaFunction->arguments().isEmpty()) { - *metaFunction += AbstractMetaAttributes::PropertyReader; - metaFunction->setPropertySpec(read); - } - } else if (QPropertySpec *write = metaClass->propertySpecForWrite(metaFunction->name())) { - // Property setter must be in the form "void name(<type>)" - // make sure the function was created with all aguments, some argument can be missing during the pareser because of errors on typesystem - if ((!metaFunction->type()) && (metaFunction->arguments().size() == 1) && (write->type() == metaFunction->arguments().at(0)->type()->typeEntry())) { - *metaFunction += AbstractMetaAttributes::PropertyWriter; - metaFunction->setPropertySpec(write); - } - } else if (QPropertySpec *reset = metaClass->propertySpecForReset(metaFunction->name())) { - // Property resetter must be in the form "void name()" - if ((!metaFunction->type()) && metaFunction->arguments().isEmpty()) { - *metaFunction += AbstractMetaAttributes::PropertyResetter; - metaFunction->setPropertySpec(reset); - } - } - - const bool isInvalidDestructor = metaFunction->isDestructor() && metaFunction->isPrivate(); - const bool isInvalidConstructor = metaFunction->functionType() == AbstractMetaFunction::ConstructorFunction - && metaFunction->isPrivate(); - if (isInvalidConstructor) - metaClass->setHasPrivateConstructor(true); - if ((isInvalidDestructor || isInvalidConstructor) - && !metaClass->hasNonPrivateConstructor()) { - *metaClass += AbstractMetaAttributes::FinalInTargetLang; - } else if (metaFunction->isConstructor() && !metaFunction->isPrivate()) { - *metaClass -= AbstractMetaAttributes::FinalInTargetLang; - metaClass->setHasNonPrivateConstructor(true); - } - - if (!metaFunction->isDestructor() - && !(metaFunction->isPrivate() && metaFunction->functionType() == AbstractMetaFunction::ConstructorFunction)) { - - setupFunctionDefaults(metaFunction, metaClass); - - if (metaFunction->isSignal() && metaClass->hasSignal(metaFunction)) { - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("signal '%1' in class '%2' is overloaded.") - .arg(metaFunction->name(), metaClass->name()); - } - - if (metaFunction->isConversionOperator()) - fixReturnTypeOfConversionOperator(metaFunction); - - metaClass->addFunction(metaFunction); - applyFunctionModifications(metaFunction); - } else if (metaFunction->isDestructor()) { - metaClass->setHasPrivateDestructor(metaFunction->isPrivate()); - metaClass->setHasProtectedDestructor(metaFunction->isProtected()); - metaClass->setHasVirtualDestructor(metaFunction->isVirtual()); - } - if (!metaFunction->ownerClass()) { - delete metaFunction; - metaFunction = nullptr; - } - } - - fillAddedFunctions(metaClass); -} - -void AbstractMetaBuilderPrivate::fillAddedFunctions(AbstractMetaClass *metaClass) -{ - // Add the functions added by the typesystem - const AddedFunctionList &addedFunctions = metaClass->typeEntry()->addedFunctions(); - for (const AddedFunctionPtr &addedFunc : addedFunctions) { - if (!traverseFunction(addedFunc, metaClass)) { - qFatal("Unable to traverse function \"%s\" added to \"%s\".", - qPrintable(addedFunc->name()), qPrintable(metaClass->name())); - } - } -} - -void AbstractMetaBuilderPrivate::applyFunctionModifications(AbstractMetaFunction *func) -{ - const FunctionModificationList &mods = func->modifications(func->implementingClass()); - AbstractMetaFunction& funcRef = *func; - for (const FunctionModification &mod : mods) { - if (mod.isRenameModifier()) { - func->setOriginalName(func->name()); - func->setName(mod.renamedTo()); - } else if (mod.isAccessModifier()) { - funcRef -= AbstractMetaAttributes::Public; - funcRef -= AbstractMetaAttributes::Protected; - funcRef -= AbstractMetaAttributes::Private; - funcRef -= AbstractMetaAttributes::Friendly; - - if (mod.isPublic()) - funcRef += AbstractMetaAttributes::Public; - else if (mod.isProtected()) - funcRef += AbstractMetaAttributes::Protected; - else if (mod.isPrivate()) - funcRef += AbstractMetaAttributes::Private; - else if (mod.isFriendly()) - funcRef += AbstractMetaAttributes::Friendly; - } - - if (mod.isFinal()) - funcRef += AbstractMetaAttributes::FinalInTargetLang; - else if (mod.isNonFinal()) - funcRef -= AbstractMetaAttributes::FinalInTargetLang; - } -} - -bool AbstractMetaBuilderPrivate::setupInheritance(AbstractMetaClass *metaClass) -{ - if (m_setupInheritanceDone.contains(metaClass)) - return true; - - m_setupInheritanceDone.insert(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('<'))) { - TypeInfo info; - ComplexTypeEntry* baseContainerType; - AbstractMetaClass* templ = findTemplateClass(baseClasses.constFirst(), metaClass, &info, &baseContainerType); - if (templ) { - setupInheritance(templ); - inheritTemplate(metaClass, templ, info); - metaClass->typeEntry()->setBaseContainerType(templ->typeEntry()); - return true; - } - - if (baseContainerType) { - // Container types are not necessarily wrapped as 'real' classes, - // but there may still be classes derived from them. In such case, - // we still need to set the base container type in order to - // generate correct code for type conversion checking. - // - // Additionally, we consider this case as successfully setting up - // inheritance. - metaClass->typeEntry()->setBaseContainerType(baseContainerType); - return true; - } - - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("template baseclass '%1' of '%2' is not known") - .arg(baseClasses.constFirst(), metaClass->name()); - return false; - } - - TypeDatabase* types = TypeDatabase::instance(); - - for (const auto &baseClassName : baseClasses) { - if (!types->isClassRejected(baseClassName)) { - if (!types->findType(baseClassName)) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnknownBase(metaClass, baseClassName))); - return false; - } - auto baseClass = AbstractMetaClass::findClass(m_metaClasses, baseClassName); - if (!baseClass) { - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("class not found for setup inheritance '%1'").arg(baseClassName); - return false; - } - metaClass->addBaseClass(baseClass); - - setupInheritance(baseClass); - } - } - - return true; -} - -void AbstractMetaBuilderPrivate::traverseEnums(const ScopeModelItem &scopeItem, - AbstractMetaClass *metaClass, - const QStringList &enumsDeclarations) -{ - const EnumList &enums = scopeItem->enums(); -#if QT_VERSION >= 0x050E00 - const QSet<QString> enumsDeclarationSet(enumsDeclarations.cbegin(), enumsDeclarations.cend()); -#else - const QSet<QString> enumsDeclarationSet = QSet<QString>::fromList(enumsDeclarations); -#endif - for (const EnumModelItem &enumItem : enums) { - AbstractMetaEnum* metaEnum = traverseEnum(enumItem, metaClass, enumsDeclarationSet); - if (metaEnum) { - metaClass->addEnum(metaEnum); - metaEnum->setEnclosingClass(metaClass); - } - } -} - -static void applyDefaultExpressionModifications(const FunctionModificationList &functionMods, - int i, AbstractMetaArgument *metaArg) -{ - // use replace/remove-default-expression for set default value - for (const auto &modification : functionMods) { - for (const auto &argumentModification : modification.argument_mods) { - if (argumentModification.index == i + 1) { - if (argumentModification.removedDefaultExpression) { - metaArg->setDefaultValueExpression(QString()); - break; - } - if (!argumentModification.replacedDefaultExpression.isEmpty()) { - metaArg->setDefaultValueExpression(argumentModification.replacedDefaultExpression); - break; - } - } - } - } -} - -AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc) -{ - return traverseFunction(addedFunc, nullptr); -} - -AbstractMetaFunction* AbstractMetaBuilderPrivate::traverseFunction(const AddedFunctionPtr &addedFunc, - AbstractMetaClass *metaClass) -{ - QString errorMessage; - - AbstractMetaType *returnType = nullptr; - if (addedFunc->returnType().name != QLatin1String("void")) { - returnType = translateType(addedFunc->returnType(), &errorMessage); - if (!returnType) { - qCWarning(lcShiboken, "%s", - qPrintable(msgAddedFunctionInvalidReturnType(addedFunc->name(), - addedFunc->returnType().name, - errorMessage))); - return nullptr; - } - } - - auto metaFunction = new AbstractMetaFunction(addedFunc); - metaFunction->setType(returnType); - - const auto &args = addedFunc->arguments(); - AbstractMetaArgumentList metaArguments; - - for (int i = 0; i < args.count(); ++i) { - const AddedFunction::TypeInfo& typeInfo = args.at(i).typeInfo; - auto *metaArg = new AbstractMetaArgument; - AbstractMetaType *type = translateType(typeInfo, &errorMessage); - if (Q_UNLIKELY(!type)) { - qCWarning(lcShiboken, "%s", - qPrintable(msgAddedFunctionInvalidArgType(addedFunc->name(), - typeInfo.name, i + 1, - errorMessage))); - delete metaFunction; - return nullptr; - } - type->decideUsagePattern(); - if (!args.at(i).name.isEmpty()) - metaArg->setName(args.at(i).name); - metaArg->setType(type); - metaArg->setArgumentIndex(i); - metaArg->setDefaultValueExpression(typeInfo.defaultValue); - metaArg->setOriginalDefaultValueExpression(typeInfo.defaultValue); - metaArguments.append(metaArg); - } - - metaFunction->setArguments(metaArguments); - if (metaFunction->isOperatorOverload() && !metaFunction->isCallOperator()) { - if (metaArguments.size() > 2) { - qCWarning(lcShiboken) << "An operator overload need to have 0, 1 or 2 arguments if it's reverse."; - } else if (metaArguments.size() == 2) { - // Check if it's a reverse operator - if (metaArguments[1]->type()->typeEntry() == metaClass->typeEntry()) { - metaFunction->setReverseOperator(true); - // we need to call these two function to cache the old signature (with two args) - // we do this buggy behaviour to comply with the original apiextractor buggy behaviour. - metaFunction->signature(); - metaFunction->minimalSignature(); - metaArguments.removeLast(); - metaFunction->setArguments(metaArguments); - } else { - qCWarning(lcShiboken) << "Operator overload can have two arguments only if it's a reverse operator!"; - } - } - } - - - // Find the correct default values - const FunctionModificationList functionMods = metaFunction->modifications(metaClass); - for (int i = 0; i < metaArguments.size(); ++i) { - AbstractMetaArgument* metaArg = metaArguments.at(i); - - // use replace-default-expression for set default value - applyDefaultExpressionModifications(functionMods, i, metaArg); - metaArg->setOriginalDefaultValueExpression(metaArg->defaultValueExpression()); // appear unmodified - } - - metaFunction->setOriginalAttributes(metaFunction->attributes()); - if (!metaArguments.isEmpty()) - fixArgumentNames(metaFunction, metaFunction->modifications(metaClass)); - - if (metaClass) { - const AbstractMetaArgumentList fargs = metaFunction->arguments(); - if (metaClass->isNamespace()) - *metaFunction += AbstractMetaFunction::Static; - if (metaFunction->name() == metaClass->name()) { - metaFunction->setFunctionType(AbstractMetaFunction::ConstructorFunction); - if (fargs.size() == 1) { - const TypeEntry *te = fargs.constFirst()->type()->typeEntry(); - if (te->isCustom()) - metaFunction->setExplicit(true); - if (te->name() == metaFunction->name()) - metaFunction->setFunctionType(AbstractMetaFunction::CopyConstructorFunction); - } - } else { - auto type = AbstractMetaFunction::NormalFunction; - if (metaFunction->name() == QLatin1String("__getattro__")) - type = AbstractMetaFunction::GetAttroFunction; - else if (metaFunction->name() == QLatin1String("__setattro__")) - type = AbstractMetaFunction::SetAttroFunction; - metaFunction->setFunctionType(type); - } - - metaFunction->setDeclaringClass(metaClass); - metaFunction->setImplementingClass(metaClass); - metaClass->addFunction(metaFunction); - metaClass->setHasNonPrivateConstructor(true); - } - - return metaFunction; -} - -void AbstractMetaBuilderPrivate::fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods) -{ - for (const FunctionModification &mod : mods) { - for (const ArgumentModification &argMod : mod.argument_mods) { - if (!argMod.renamed_to.isEmpty()) { - AbstractMetaArgument* arg = func->arguments().at(argMod.index - 1); - arg->setOriginalName(arg->name()); - arg->setName(argMod.renamed_to, false); - } - } - } - - AbstractMetaArgumentList arguments = func->arguments(); - for (int i = 0, size = arguments.size(); i < size; ++i) { - if (arguments.at(i)->name().isEmpty()) - arguments[i]->setName(QLatin1String("arg__") + QString::number(i + 1), false); - } -} - -static QString functionSignature(const FunctionModelItem &functionItem) -{ - QStringList args; - const ArgumentList &arguments = functionItem->arguments(); - for (const ArgumentModelItem &arg : arguments) - args << arg->type().toString(); - return functionItem->name() + QLatin1Char('(') + args.join(QLatin1Char(',')) + QLatin1Char(')'); -} - -static inline QString qualifiedFunctionSignatureWithType(const FunctionModelItem &functionItem, - const QString &className = QString()) -{ - QString result = functionItem->type().toString() + QLatin1Char(' '); - if (!className.isEmpty()) - result += className + colonColon(); - result += functionSignature(functionItem); - return result; -} -static inline AbstractMetaFunction::FunctionType functionTypeFromCodeModel(CodeModel::FunctionType ft) -{ - AbstractMetaFunction::FunctionType result = AbstractMetaFunction::NormalFunction; - switch (ft) { - case CodeModel::Constructor: - result = AbstractMetaFunction::ConstructorFunction; - break; - case CodeModel::CopyConstructor: - result = AbstractMetaFunction::CopyConstructorFunction; - break; - case CodeModel::MoveConstructor: - result = AbstractMetaFunction::MoveConstructorFunction; - break; - case CodeModel::Destructor: - result = AbstractMetaFunction::DestructorFunction; - break; - case CodeModel::Normal: - break; - case CodeModel::Signal: - result = AbstractMetaFunction::SignalFunction; - break; - case CodeModel::Slot: - result = AbstractMetaFunction::SlotFunction; - break; - } - return result; -} - -// Apply the <array> modifications of the arguments -static bool applyArrayArgumentModifications(const FunctionModificationList &functionMods, - AbstractMetaFunction *func, - QString *errorMessage) -{ - for (const FunctionModification &mod : functionMods) { - for (const ArgumentModification &argMod : mod.argument_mods) { - if (argMod.array) { - const int i = argMod.index - 1; - if (i < 0 || i >= func->arguments().size()) { - *errorMessage = msgCannotSetArrayUsage(func->minimalSignature(), i, - QLatin1String("Index out of range.")); - return false; - } - if (!func->arguments().at(i)->type()->applyArrayModification(errorMessage)) { - *errorMessage = msgCannotSetArrayUsage(func->minimalSignature(), i, *errorMessage); - return false; - } - } - } - } - return true; -} - -AbstractMetaFunction *AbstractMetaBuilderPrivate::traverseFunction(const FunctionModelItem &functionItem, - AbstractMetaClass *currentClass) -{ - if (functionItem->isDeleted() || !functionItem->templateParameters().isEmpty()) - return nullptr; - QString functionName = functionItem->name(); - QString className; - if (currentClass) { - // 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; - } - 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); - - QString rejectReason; - if (TypeDatabase::instance()->isFunctionRejected(className, functionName, &rejectReason)) { - m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); - return nullptr; - } - const QString &signature = functionSignature(functionItem); - const bool rejected = - TypeDatabase::instance()->isFunctionRejected(className, signature, &rejectReason); - - if (rejected) { - if (ReportHandler::isDebug(ReportHandler::MediumDebug)) { - qCInfo(lcShiboken, "%s::%s was rejected by the type database (%s).", - qPrintable(className), qPrintable(signature), qPrintable(rejectReason)); - } - return nullptr; - } - - if (functionItem->isFriend()) - return nullptr; - - const bool deprecated = functionItem->isDeprecated(); - if (deprecated && m_skipDeprecated) { - m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + QLatin1String(" is deprecated."), - AbstractMetaBuilder::GenerationDisabled); - return nullptr; - } - - auto *metaFunction = new AbstractMetaFunction; - metaFunction->setSourceLocation(functionItem->sourceLocation()); - if (deprecated) - *metaFunction += AbstractMetaAttributes::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 += AbstractMetaAttributes::Abstract; - - if (functionItem->isVirtual()) { - *metaFunction += AbstractMetaAttributes::VirtualCppMethod; - if (functionItem->isOverride()) - *metaFunction += AbstractMetaAttributes::OverriddenCppMethod; - if (functionItem->isFinal()) - *metaFunction += AbstractMetaAttributes::FinalCppMethod; - } else { - *metaFunction += AbstractMetaAttributes::FinalInTargetLang; - } - - if (functionItem->isInvokable()) - *metaFunction += AbstractMetaAttributes::Invokable; - - if (functionItem->isStatic()) { - *metaFunction += AbstractMetaAttributes::Static; - *metaFunction += AbstractMetaAttributes::FinalInTargetLang; - } - - // Access rights - if (functionItem->accessPolicy() == CodeModel::Public) - *metaFunction += AbstractMetaAttributes::Public; - else if (functionItem->accessPolicy() == CodeModel::Private) - *metaFunction += AbstractMetaAttributes::Private; - else - *metaFunction += AbstractMetaAttributes::Protected; - - QString errorMessage; - switch (metaFunction->functionType()) { - case AbstractMetaFunction::DestructorFunction: - break; - case AbstractMetaFunction::ConstructorFunction: - metaFunction->setExplicit(functionItem->isExplicit()); - metaFunction->setName(currentClass->name()); - break; - default: { - TypeInfo returnType = functionItem->type(); - - if (TypeDatabase::instance()->isReturnTypeRejected(className, returnType.toString(), &rejectReason)) { - m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); - delete metaFunction; - return nullptr; - } - - AbstractMetaType *type = nullptr; - if (!returnType.isVoid()) { - type = translateType(returnType, currentClass, {}, &errorMessage); - if (!type) { - const QString reason = msgUnmatchedReturnType(functionItem, errorMessage); - qCWarning(lcShiboken, "%s", - qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason))); - m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn, AbstractMetaBuilder::UnmatchedReturnType); - delete metaFunction; - return nullptr; - } - } - - metaFunction->setType(type); - } - break; - } - - ArgumentList arguments = functionItem->arguments(); - - if (arguments.size() == 1) { - ArgumentModelItem arg = arguments.at(0); - TypeInfo type = arg->type(); - if (type.qualifiedName().constFirst() == QLatin1String("void") && type.indirections() == 0) - arguments.pop_front(); - } - - AbstractMetaArgumentList metaArguments; - - for (int i = 0; i < arguments.size(); ++i) { - const ArgumentModelItem &arg = arguments.at(i); - - if (TypeDatabase::instance()->isArgumentTypeRejected(className, arg->type().toString(), &rejectReason)) { - m_rejectedFunctions.insert(originalQualifiedSignatureWithReturn + rejectReason, AbstractMetaBuilder::GenerationDisabled); - delete metaFunction; - return nullptr; - } - - AbstractMetaType *metaType = translateType(arg->type(), currentClass, {}, &errorMessage); - if (!metaType) { - // 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 (!currentClass - || (currentClass->typeEntry()->codeGeneration() - & TypeEntry::GenerateTargetLang)) { - qCWarning(lcShiboken, "%s", - qPrintable(msgStrippingArgument(functionItem, i, originalQualifiedSignatureWithReturn, arg))); - } - break; - } - Q_ASSERT(metaType == nullptr); - const QString reason = msgUnmatchedParameterType(arg, i, errorMessage); - qCWarning(lcShiboken, "%s", - qPrintable(msgSkippingFunction(functionItem, originalQualifiedSignatureWithReturn, reason))); - const QString rejectedFunctionSignature = originalQualifiedSignatureWithReturn - + QLatin1String(": ") + reason; - m_rejectedFunctions.insert(rejectedFunctionSignature, AbstractMetaBuilder::UnmatchedArgumentType); - delete metaFunction; - return nullptr; - } - - auto *metaArgument = new AbstractMetaArgument; - - metaArgument->setType(metaType); - metaArgument->setName(arg->name()); - metaArgument->setArgumentIndex(i); - metaArguments << metaArgument; - } - - metaFunction->setArguments(metaArguments); - - const FunctionModificationList functionMods = metaFunction->modifications(currentClass); - - 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()); - } - - // Find the correct default values - for (int i = 0, size = metaArguments.size(); i < size; ++i) { - const ArgumentModelItem &arg = arguments.at(i); - AbstractMetaArgument* metaArg = metaArguments.at(i); - - const QString originalDefaultExpression = - fixDefaultValue(arg, metaArg->type(), metaFunction, currentClass, i); - - metaArg->setOriginalDefaultValueExpression(originalDefaultExpression); - metaArg->setDefaultValueExpression(originalDefaultExpression); - - applyDefaultExpressionModifications(functionMods, i, metaArg); - - //Check for missing argument name - if (!metaArg->defaultValueExpression().isEmpty() - && !metaArg->hasName() - && !metaFunction->isOperatorOverload() - && !metaFunction->isSignal() - && metaFunction->argumentName(i + 1, false, currentClass).isEmpty()) { - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("Argument %1 on function '%2::%3' has default expression but does not have name.") - .arg(i+1).arg(className, metaFunction->minimalSignature()); - } - - } - - if (!metaArguments.isEmpty()) { - fixArgumentNames(metaFunction, functionMods); - QString errorMessage; - if (!applyArrayArgumentModifications(functionMods, metaFunction, &errorMessage)) { - qCWarning(lcShiboken, "%s", - qPrintable(msgArrayModificationFailed(functionItem, className, errorMessage))); - } - } - - // Determine class special functions - 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=")) { - switch (argType->referenceType()) { - case NoReference: - metaFunction->setFunctionType(AbstractMetaFunction::AssignmentOperatorFunction); - break; - case LValueReference: - if (argType->isConstant()) - metaFunction->setFunctionType(AbstractMetaFunction::AssignmentOperatorFunction); - break; - case RValueReference: - metaFunction->setFunctionType(AbstractMetaFunction::MoveAssignmentOperatorFunction); - break; - } - } - } - } - return metaFunction; -} - -AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const AddedFunction::TypeInfo &typeInfo, - QString *errorMessage) -{ - Q_ASSERT(!typeInfo.name.isEmpty()); - TypeDatabase* typeDb = TypeDatabase::instance(); - TypeEntry* type; - - QString typeName = typeInfo.name; - - if (typeName == QLatin1String("void")) - return nullptr; - - type = typeDb->findType(typeName); - if (!type) - type = typeDb->findFlagsType(typeName); - - // test if the type is a template, like a container - bool isTemplate = false; - QStringList templateArgs; - if (!type && typeInfo.name.contains(QLatin1Char('<'))) { - const QStringList& parsedType = parseTemplateType(typeInfo.name); - if (parsedType.isEmpty()) { - *errorMessage = QStringLiteral("Template type parsing failed for '%1'").arg(typeInfo.name); - return nullptr; - } - templateArgs = parsedType.mid(1); - isTemplate = (type = typeDb->findContainerType(parsedType[0])); - } - - if (!type) { - QStringList candidates; - const auto &entries = typeDb->entries(); - for (auto it = entries.cbegin(), end = entries.cend(); it != end; ++it) { - // Let's try to find the type in different scopes. - if (it.key().endsWith(colonColon() + typeName)) - candidates.append(it.key()); - } - QTextStream str(errorMessage); - str << "Type '" << typeName << "' wasn't found in the type database.\n"; - - if (candidates.isEmpty()) { - str << "Declare it in the type system using the proper <*-type> tag."; - } else { - str << "Remember to inform the full qualified name for the type you want to use.\nCandidates are:\n"; - candidates.sort(); - for (const QString& candidate : qAsConst(candidates)) - str << " " << candidate << '\n'; - } - return nullptr; - } - - // These are only implicit and should not appear in code... - auto *metaType = new AbstractMetaType; - metaType->setTypeEntry(type); - metaType->setIndirections(typeInfo.indirections); - if (typeInfo.isReference) - metaType->setReferenceType(LValueReference); - metaType->setConstant(typeInfo.isConstant); - if (isTemplate) { - for (const QString& templateArg : qAsConst(templateArgs)) { - AbstractMetaType *metaArgType = nullptr; - if (templateArg != QLatin1String("void")) { - metaArgType = translateType(AddedFunction::TypeInfo::fromSignature(templateArg), errorMessage); - if (!metaArgType) - return nullptr; - } - metaType->addInstantiation(metaArgType); - } - metaType->setTypeUsagePattern(AbstractMetaType::ContainerPattern); - } - - return metaType; -} - -static const TypeEntry* findTypeEntryUsingContext(const AbstractMetaClass* metaClass, const QString& qualifiedName) -{ - const TypeEntry* type = nullptr; - QStringList context = metaClass->qualifiedCppName().split(colonColon()); - while (!type && !context.isEmpty()) { - type = TypeDatabase::instance()->findType(context.join(colonColon()) + colonColon() + qualifiedName); - context.removeLast(); - } - return type; -} - -// Helper for translateTypeStatic() -TypeEntries AbstractMetaBuilderPrivate::findTypeEntries(const QString &qualifiedName, - const QString &name, - AbstractMetaClass *currentClass, - AbstractMetaBuilderPrivate *d) -{ - // 5.1 - Try first using the current scope - if (currentClass) { - 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) { - if (auto type = findTypeEntryUsingContext(cls, qualifiedName)) - return {type}; - } - } - } - - // 5.2 - Try without scope - auto types = TypeDatabase::instance()->findCppTypes(qualifiedName); - if (!types.isEmpty()) - return types; - - // 6. No? Try looking it up as a flags type - if (auto type = TypeDatabase::instance()->findFlagsType(qualifiedName)) - return {type}; - - // 7. No? Try looking it up as a container type - if (auto type = TypeDatabase::instance()->findContainerType(name)) - return {type}; - - // 8. No? Check if the current class is a template and this type is one - // of the parameters. - if (currentClass) { - const QVector<TypeEntry *> &template_args = currentClass->templateArguments(); - for (TypeEntry *te : template_args) { - if (te->name() == qualifiedName) - return {te}; - } - } - return {}; -} - -AbstractMetaType *AbstractMetaBuilderPrivate::translateType(const TypeInfo &_typei, - AbstractMetaClass *currentClass, - TranslateTypeFlags flags, - QString *errorMessage) -{ - return translateTypeStatic(_typei, currentClass, this, flags, errorMessage); -} - -static bool isNumber(const QString &s) -{ - return std::all_of(s.cbegin(), s.cend(), - [](QChar c) { return c.isDigit(); }); -} - -AbstractMetaType *AbstractMetaBuilderPrivate::translateTypeStatic(const TypeInfo &_typei, - AbstractMetaClass *currentClass, - AbstractMetaBuilderPrivate *d, - TranslateTypeFlags flags, - QString *errorMessageIn) -{ - // 1. Test the type info without resolving typedefs in case this is present in the - // type system - const bool resolveType = !flags.testFlag(AbstractMetaBuilder::DontResolveType); - if (resolveType) { - AbstractMetaType *resolved = - translateTypeStatic(_typei, currentClass, d, - flags | AbstractMetaBuilder::DontResolveType, - errorMessageIn); - if (resolved) - return resolved; - } - - TypeInfo typeInfo = _typei; - if (resolveType) { - // Go through all parts of the current scope (including global namespace) - // to resolve typedefs. The parser does not properly resolve typedefs in - // 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; - while (i >= 0) { - typeInfo = TypeInfo::resolveType(_typei, d->m_scopes.at(i--)); - if (typeInfo.qualifiedName().join(colonColon()) != _typei.qualifiedName().join(colonColon())) - break; - } - - } - - if (typeInfo.isFunctionPointer()) { - if (errorMessageIn) - *errorMessageIn = msgUnableToTranslateType(_typei, QLatin1String("Unsupported function pointer.")); - return nullptr; - } - - QString errorMessage; - - // 2. Handle arrays. - // 2.1 Handle char arrays with unspecified size (aka "const char[]") as "const char*" with - // NativePointerPattern usage. - bool oneDimensionalArrayOfUnspecifiedSize = - typeInfo.arrayElements().size() == 1 - && typeInfo.arrayElements().at(0).isEmpty(); - - bool isConstCharStarCase = - oneDimensionalArrayOfUnspecifiedSize - && typeInfo.qualifiedName().size() == 1 - && typeInfo.qualifiedName().at(0) == QStringLiteral("char") - && typeInfo.indirections() == 0 - && typeInfo.isConstant() - && typeInfo.referenceType() == NoReference - && typeInfo.arguments().isEmpty(); - - if (isConstCharStarCase) - typeInfo.setIndirections(typeInfo.indirections() + typeInfo.arrayElements().size()); - - // 2.2 Handle regular arrays. - if (!typeInfo.arrayElements().isEmpty() && !isConstCharStarCase) { - TypeInfo newInfo; - //newInfo.setArguments(typeInfo.arguments()); - newInfo.setIndirectionsV(typeInfo.indirectionsV()); - newInfo.setConstant(typeInfo.isConstant()); - newInfo.setVolatile(typeInfo.isVolatile()); - newInfo.setFunctionPointer(typeInfo.isFunctionPointer()); - newInfo.setQualifiedName(typeInfo.qualifiedName()); - newInfo.setReferenceType(typeInfo.referenceType()); - newInfo.setVolatile(typeInfo.isVolatile()); - - AbstractMetaType *elementType = translateTypeStatic(newInfo, currentClass, d, flags, &errorMessage); - if (!elementType) { - if (errorMessageIn) { - errorMessage.prepend(QLatin1String("Unable to translate array element: ")); - *errorMessageIn = msgUnableToTranslateType(_typei, errorMessage); - } - return nullptr; - } - - for (int i = typeInfo.arrayElements().size() - 1; i >= 0; --i) { - auto *arrayType = new AbstractMetaType; - arrayType->setArrayElementType(elementType); - const QString &arrayElement = typeInfo.arrayElements().at(i); - if (!arrayElement.isEmpty()) { - bool _ok; - const qint64 elems = d - ? d->findOutValueFromString(arrayElement, _ok) - : arrayElement.toLongLong(&_ok, 0); - if (_ok) - arrayType->setArrayElementCount(int(elems)); - } - auto elementTypeEntry = elementType->typeEntry(); - arrayType->setTypeEntry(new ArrayTypeEntry(elementTypeEntry, elementTypeEntry->version(), - elementTypeEntry->parent())); - arrayType->decideUsagePattern(); - - elementType = arrayType; - } - - return elementType; - } - - QStringList qualifierList = typeInfo.qualifiedName(); - if (qualifierList.isEmpty()) { - errorMessage = msgUnableToTranslateType(_typei, QLatin1String("horribly broken type")); - if (errorMessageIn) - *errorMessageIn = errorMessage; - else - qCWarning(lcShiboken,"%s", qPrintable(errorMessage)); - return nullptr; - } - - QString qualifiedName = qualifierList.join(colonColon()); - QString name = qualifierList.takeLast(); - - // 4. Special case QFlags (include instantiation in name) - if (qualifiedName == QLatin1String("QFlags")) { - qualifiedName = typeInfo.toString(); - typeInfo.clearInstantiations(); - } - - const TypeEntries types = findTypeEntries(qualifiedName, name, currentClass, d); - if (types.isEmpty()) { - if (errorMessageIn) { - *errorMessageIn = - msgUnableToTranslateType(_typei, msgCannotFindTypeEntry(qualifiedName)); - } - return nullptr; - } - - const TypeEntry *type = types.constFirst(); - const TypeEntry::Type typeEntryType = type->type(); - - QScopedPointer<AbstractMetaType> metaType(new AbstractMetaType); - metaType->setIndirectionsV(typeInfo.indirectionsV()); - metaType->setReferenceType(typeInfo.referenceType()); - metaType->setConstant(typeInfo.isConstant()); - metaType->setVolatile(typeInfo.isVolatile()); - metaType->setOriginalTypeDescription(_typei.toString()); - - const auto &templateArguments = typeInfo.instantiations(); - for (int t = 0, size = templateArguments.size(); t < size; ++t) { - const TypeInfo &ti = templateArguments.at(t); - AbstractMetaType *targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage); - // For non-type template parameters, create a dummy type entry on the fly - // as is done for classes. - if (!targType) { - const QString value = ti.qualifiedName().join(colonColon()); - if (isNumber(value)) { - TypeDatabase::instance()->addConstantValueTypeEntry(value, type->typeSystemTypeEntry()); - targType = translateTypeStatic(ti, currentClass, d, flags, &errorMessage); - } - } - if (!targType) { - if (errorMessageIn) - *errorMessageIn = msgCannotTranslateTemplateArgument(t, ti, errorMessage); - return nullptr; - } - - metaType->addInstantiation(targType, true); - } - - if (types.size() > 1) { - const bool sameType = std::all_of(types.cbegin() + 1, types.cend(), - [typeEntryType](const TypeEntry *e) { - return e->type() == typeEntryType; }); - if (!sameType) { - if (errorMessageIn) - *errorMessageIn = msgAmbiguousVaryingTypesFound(qualifiedName, types); - return nullptr; - } - // Ambiguous primitive/smart pointer types are possible (when - // including type systems). - if (typeEntryType != TypeEntry::PrimitiveType - && typeEntryType != TypeEntry::SmartPointerType) { - if (errorMessageIn) - *errorMessageIn = msgAmbiguousTypesFound(qualifiedName, types); - return nullptr; - } - } - - if (typeEntryType == TypeEntry::SmartPointerType) { - // Find a matching instantiation - if (metaType->instantiations().size() != 1) { - if (errorMessageIn) - *errorMessageIn = msgInvalidSmartPointerType(_typei); - return nullptr; - } - auto instantiationType = metaType->instantiations().constFirst()->typeEntry(); - if (instantiationType->type() == TypeEntry::TemplateArgumentType) { - // Member functions of the template itself, SharedPtr(const SharedPtr &) - type = instantiationType; - } else { - auto it = std::find_if(types.cbegin(), types.cend(), - [instantiationType](const TypeEntry *e) { - auto smartPtr = static_cast<const SmartPointerTypeEntry *>(e); - return smartPtr->matchesInstantiation(instantiationType); - }); - if (it == types.cend()) { - if (errorMessageIn) - *errorMessageIn = msgCannotFindSmartPointerInstantion(_typei); - return nullptr; - } - type =*it; - } - } - - metaType->setTypeEntry(type); - - // The usage pattern *must* be decided *after* the possible template - // instantiations have been determined, or else the absence of - // such instantiations will break the caching scheme of - // AbstractMetaType::cppSignature(). - metaType->decideUsagePattern(); - - return metaType.take(); -} - -AbstractMetaType *AbstractMetaBuilder::translateType(const TypeInfo &_typei, - AbstractMetaClass *currentClass, - TranslateTypeFlags flags, - QString *errorMessage) -{ - return AbstractMetaBuilderPrivate::translateTypeStatic(_typei, currentClass, - nullptr, flags, - errorMessage); -} - -AbstractMetaType *AbstractMetaBuilder::translateType(const QString &t, - AbstractMetaClass *currentClass, - TranslateTypeFlags flags, - QString *errorMessageIn) -{ - QString errorMessage; - TypeInfo typeInfo = TypeParser::parse(t, &errorMessage); - if (typeInfo.qualifiedName().isEmpty()) { - errorMessage = msgUnableToTranslateType(t, errorMessage); - if (errorMessageIn) - *errorMessageIn = errorMessage; - else - qCWarning(lcShiboken, "%s", qPrintable(errorMessage)); - return nullptr; - } - return translateType(typeInfo, currentClass, flags, errorMessageIn); -} - -qint64 AbstractMetaBuilderPrivate::findOutValueFromString(const QString &stringValue, bool &ok) -{ - qint64 value = stringValue.toLongLong(&ok); - if (ok) - return value; - - if (stringValue == QLatin1String("true") || stringValue == QLatin1String("false")) { - ok = true; - return (stringValue == QLatin1String("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_]*$")); - Q_ASSERT(variableNameRegExp.isValid()); - if (!variableNameRegExp.match(stringValue).hasMatch()) { - ok = true; - return 0; - } - - AbstractMetaEnumValue *enumValue = AbstractMetaClass::findEnumValue(m_metaClasses, stringValue); - if (enumValue) { - ok = true; - return enumValue->value().value(); - } - - for (AbstractMetaEnum *metaEnum : qAsConst(m_globalEnums)) { - if (const AbstractMetaEnumValue *ev = metaEnum->findEnumValue(stringValue)) { - ok = true; - return ev->value().value(); - } - } - - ok = false; - return 0; -} - -QString AbstractMetaBuilderPrivate::fixDefaultValue(const ArgumentModelItem &item, - AbstractMetaType *type, - AbstractMetaFunction *fnc, - AbstractMetaClass *implementingClass, - int /* argumentIndex */) -{ - QString expr = item->defaultValueExpression(); - if (expr.isEmpty()) - return expr; - - if (type) { - 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 untill all namespaces are completly - // 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); - } 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("^(?: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; - } - } - } - } - } else { - const QString className = implementingClass ? implementingClass->qualifiedCppName() : QString(); - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("undefined type for default value '%3' of argument in function '%1', class '%2'") - .arg(fnc->name(), className, item->defaultValueExpression()); - - expr.clear(); - } - - return expr; -} - -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 -{ - TypeDatabase* types = TypeDatabase::instance(); - - QStringList scope = context->typeEntry()->qualifiedCppName().split(colonColon()); - 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(); - QString completeName = prefix + name; - const TypeInfo parsed = TypeParser::parse(completeName, &errorMessage); - QString qualifiedName = parsed.qualifiedName().join(colonColon()); - if (qualifiedName.isEmpty()) { - qWarning().noquote().nospace() << "Unable to parse type \"" << completeName - << "\" while looking for template \"" << name << "\": " << errorMessage; - continue; - } - if (info) - *info = parsed; - - AbstractMetaClass *templ = nullptr; - for (AbstractMetaClass *c : qAsConst(m_templates)) { - if (c->typeEntry()->name() == qualifiedName) { - templ = c; - break; - } - } - - if (!templ) - templ = AbstractMetaClass::findClass(m_metaClasses, qualifiedName); - - if (templ) - return templ; - - if (baseContainerType) - *baseContainerType = types->findContainerType(qualifiedName); - } - - return nullptr; -} - -AbstractMetaClassList AbstractMetaBuilderPrivate::getBaseClasses(const AbstractMetaClass *metaClass) const -{ - AbstractMetaClassList 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); - - if (cls) - baseClasses << cls; - } - return baseClasses; -} - -bool AbstractMetaBuilderPrivate::ancestorHasPrivateCopyConstructor(const AbstractMetaClass *metaClass) const -{ - if (metaClass->hasPrivateCopyConstructor()) - return true; - const AbstractMetaClassList &baseClasses = getBaseClasses(metaClass); - for (const AbstractMetaClass *cls : baseClasses) { - if (ancestorHasPrivateCopyConstructor(cls)) - return true; - } - return false; -} - -AbstractMetaType * - AbstractMetaBuilderPrivate::inheritTemplateType(const AbstractMetaTypeList &templateTypes, - const AbstractMetaType *metaType) -{ - Q_ASSERT(metaType); - - QScopedPointer<AbstractMetaType> returned(metaType->copy()); - - if (!metaType->typeEntry()->isTemplateArgument() && !metaType->hasInstantiations()) - return returned.take(); - - returned->setOriginalTemplateType(metaType); - - if (returned->typeEntry()->isTemplateArgument()) { - const auto *tae = static_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. - const AbstractMetaType *templateType = templateTypes.value(tae->ordinal()); - if (!templateType || templateType->typeEntry()->isVoid()) - return nullptr; - - AbstractMetaType* t = returned->copy(); - t->setTypeEntry(templateType->typeEntry()); - t->setIndirections(templateType->indirections() + t->indirections() ? 1 : 0); - t->decideUsagePattern(); - - return inheritTemplateType(templateTypes, t); - } - - if (returned->hasInstantiations()) { - AbstractMetaTypeList instantiations = returned->instantiations(); - for (int i = 0; i < instantiations.count(); ++i) { - instantiations[i] = - inheritTemplateType(templateTypes, instantiations.at(i)); - if (!instantiations.at(i)) - return nullptr; - } - returned->setInstantiations(instantiations, true); - } - - return returned.take(); -} - -bool AbstractMetaBuilderPrivate::inheritTemplate(AbstractMetaClass *subclass, - const AbstractMetaClass *templateClass, - const TypeInfo &info) -{ - QVector<TypeInfo> targs = info.instantiations(); - QVector<AbstractMetaType *> templateTypes; - QString errorMessage; - - if (subclass->isTypeDef()) { - subclass->setHasCloneOperator(templateClass->hasCloneOperator()); - subclass->setHasEqualsOperator(templateClass->hasEqualsOperator()); - subclass->setHasHashFunction(templateClass->hasHashFunction()); - subclass->setHasNonPrivateConstructor(templateClass->hasNonPrivateConstructor()); - subclass->setHasPrivateDestructor(templateClass->hasPrivateDestructor()); - subclass->setHasProtectedDestructor(templateClass->hasProtectedDestructor()); - subclass->setHasVirtualDestructor(templateClass->hasVirtualDestructor()); - } - - for (const TypeInfo &i : qAsConst(targs)) { - QString typeName = i.qualifiedName().join(colonColon()); - TypeDatabase *typeDb = TypeDatabase::instance(); - TypeEntry *t = nullptr; - // Check for a non-type template integer parameter, that is, for a base - // "template <int R, int C> Matrix<R, C>" and subclass - // "typedef Matrix<2,3> Matrix2x3;". If so, create dummy entries of - // EnumValueTypeEntry for the integer values encountered on the fly. - if (isNumber(typeName)) { - t = typeDb->findType(typeName); - if (!t) { - auto parent = subclass->typeEntry()->typeSystemTypeEntry(); - t = TypeDatabase::instance()->addConstantValueTypeEntry(typeName, parent); - } - } else { - QStringList possibleNames; - possibleNames << subclass->qualifiedCppName() + colonColon() + typeName; - possibleNames << templateClass->qualifiedCppName() + colonColon() + typeName; - if (subclass->enclosingClass()) - possibleNames << subclass->enclosingClass()->qualifiedCppName() + colonColon() + typeName; - possibleNames << typeName; - - for (const QString &possibleName : qAsConst(possibleNames)) { - t = typeDb->findType(possibleName); - if (t) - break; - } - } - - if (t) { - auto *temporaryType = new AbstractMetaType; - temporaryType->setTypeEntry(t); - temporaryType->setConstant(i.isConstant()); - temporaryType->setReferenceType(i.referenceType()); - temporaryType->setIndirectionsV(i.indirectionsV()); - temporaryType->decideUsagePattern(); - templateTypes << temporaryType; - } else { - qCWarning(lcShiboken).noquote().nospace() - << "Ignoring template parameter " << typeName << " from " - << info.toString() << ". The corresponding type was not found in the typesystem."; - } - } - - const AbstractMetaFunctionList &subclassFuncs = subclass->functions(); - const AbstractMetaFunctionList &templateClassFunctions = templateClass->functions(); - for (const AbstractMetaFunction *function : templateClassFunctions) { - // If the function is modified or the instantiation has an equally named - // function we have shadowing, so we need to skip it. - if (function->isModifiedRemoved(TypeSystem::All) - || AbstractMetaFunction::find(subclassFuncs, function->name()) != nullptr) { - continue; - } - - QScopedPointer<AbstractMetaFunction> f(function->copy()); - f->setArguments(AbstractMetaArgumentList()); - - if (function->type()) { // Non-void - AbstractMetaType *returnType = inheritTemplateType(templateTypes, function->type()); - if (!returnType) - continue; - f->replaceType(returnType); - } - - const AbstractMetaArgumentList &arguments = function->arguments(); - for (AbstractMetaArgument *argument : arguments) { - AbstractMetaType *argType = inheritTemplateType(templateTypes, argument->type()); - if (!argType) - break; - AbstractMetaArgument *arg = argument->copy(); - arg->replaceType(argType); - 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 (!applyArrayArgumentModifications(f->modifications(subclass), f.data(), - &errorMessage)) { - qCWarning(lcShiboken, "While specializing %s (%s): %s", - qPrintable(subclass->name()), qPrintable(templateClass->name()), - qPrintable(errorMessage)); - } - subclass->addFunction(f.take()); - } - - const AbstractMetaFieldList &subClassFields = subclass->fields(); - const AbstractMetaFieldList &templateClassFields = templateClass->fields(); - 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->attributes().testFlag(AbstractMetaAttributes::Static) - || AbstractMetaField::find(subClassFields, field->name()) != nullptr) { - continue; - } - - QScopedPointer<AbstractMetaField> f(field->copy()); - f->setEnclosingClass(subclass); - AbstractMetaType *fieldType = inheritTemplateType(templateTypes, field->type()); - if (!fieldType) - continue; - f->replaceType(fieldType); - subclass->addField(f.take()); - } - - subclass->setTemplateBaseClass(templateClass); - subclass->setTemplateBaseClassInstantiations(templateTypes); - subclass->setBaseClass(templateClass->baseClass()); - - return true; -} - -void AbstractMetaBuilderPrivate::parseQ_Property(AbstractMetaClass *metaClass, - const QStringList &declarations) -{ - const QStringList scopes = currentScope()->qualifiedName(); - - for (int i = 0; i < declarations.size(); ++i) { - const auto propertyTokens = declarations.at(i).splitRef(QLatin1Char(' ')); - - AbstractMetaType *type = nullptr; - for (int j = scopes.size(); j >= 0; --j) { - QStringList qualifiedName = scopes.mid(0, j); - qualifiedName.append(propertyTokens.at(0).toString()); - TypeInfo info; - info.setQualifiedName(qualifiedName); - - type = translateType(info, metaClass); - if (type) - break; - } - - if (!type) { - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("Unable to decide type of property: '%1' in class '%2'") - .arg(propertyTokens.at(0).toString(), metaClass->name()); - continue; - } - - auto *spec = new QPropertySpec(type->typeEntry()); - spec->setName(propertyTokens.at(1).toString()); - spec->setIndex(i); - - for (int pos = 2; pos + 1 < propertyTokens.size(); pos += 2) { - if (propertyTokens.at(pos) == QLatin1String("READ")) - spec->setRead(propertyTokens.at(pos + 1).toString()); - else if (propertyTokens.at(pos) == QLatin1String("WRITE")) - spec->setWrite(propertyTokens.at(pos + 1).toString()); - else if (propertyTokens.at(pos) == QLatin1String("DESIGNABLE")) - spec->setDesignable(propertyTokens.at(pos + 1).toString()); - else if (propertyTokens.at(pos) == QLatin1String("RESET")) - spec->setReset(propertyTokens.at(pos + 1).toString()); - } - - metaClass->addPropertySpec(spec); - delete type; - } -} - -static AbstractMetaFunction* findCopyCtor(AbstractMetaClass* cls) -{ - - const auto &functions = cls->functions(); - - for (AbstractMetaFunction *f : qAsConst(functions)) { - const AbstractMetaFunction::FunctionType t = f->functionType(); - if (t == AbstractMetaFunction::CopyConstructorFunction || t == AbstractMetaFunction::AssignmentOperatorFunction) - return f; - } - return nullptr; -} - -void AbstractMetaBuilderPrivate::setupClonable(AbstractMetaClass *cls) -{ - bool result = true; - - // find copy ctor for the current class - AbstractMetaFunction* copyCtor = findCopyCtor(cls); - if (copyCtor) { // 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) -{ - const AbstractMetaFunctionList &convOps = cls->operatorOverloads(AbstractMetaClass::ConversionOp); - for (AbstractMetaFunction *func : convOps) { - if (func->isModifiedRemoved()) - continue; - AbstractMetaClass *metaClass = AbstractMetaClass::findClass(m_metaClasses, func->type()->typeEntry()); - if (!metaClass) - continue; - metaClass->addExternalConversionOperator(func); - } - const AbstractMetaClassList &innerClasses = cls->innerClasses(); - for (AbstractMetaClass *innerClass : innerClasses) - setupExternalConversion(innerClass); -} - -static void writeRejectLogFile(const QString &name, - const QMap<QString, AbstractMetaBuilder::RejectReason> &rejects) -{ - QFile f(name); - if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) { - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("failed to write log file: '%1'") - .arg(QDir::toNativeSeparators(f.fileName())); - return; - } - - 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; - } - - 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; - } - -} - -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); -} - -using ClassIndexHash = QHash<AbstractMetaClass *, int>; - -static ClassIndexHash::ConstIterator findByTypeEntry(const ClassIndexHash &map, - const TypeEntry *typeEntry) -{ - auto it = map.cbegin(); - for (auto end = map.cend(); it != end; ++it) { - if (it.key()->typeEntry() == typeEntry) - break; - } - return it; -} - -AbstractMetaClassList AbstractMetaBuilderPrivate::classesTopologicalSorted(const AbstractMetaClassList &classList, - const Dependencies &additionalDependencies) const -{ - ClassIndexHash map; - QHash<int, AbstractMetaClass *> reverseMap; - - int i = 0; - for (AbstractMetaClass *clazz : classList) { - if (map.contains(clazz)) - continue; - map.insert(clazz, i); - reverseMap.insert(i, clazz); - i++; - } - - Graph graph(map.count()); - - for (const auto &dep : additionalDependencies) { - const int parentIndex = map.value(dep.parent, -1); - const int childIndex = map.value(dep.child, -1); - if (parentIndex >= 0 && childIndex >= 0) { - graph.addEdge(parentIndex, childIndex); - } else { - qCWarning(lcShiboken).noquote().nospace() - << "AbstractMetaBuilder::classesTopologicalSorted(): Invalid additional dependency: " - << dep.child->name() << " -> " << dep.parent->name() << '.'; - } - } - - for (AbstractMetaClass *clazz : classList) { - const int classIndex = map.value(clazz); - if (auto enclosing = clazz->enclosingClass()) { - const auto enclosingIt = map.constFind(const_cast< AbstractMetaClass *>(enclosing)); - if (enclosingIt!= map.cend()) - graph.addEdge(enclosingIt.value(), classIndex); - } - - const AbstractMetaClassList &bases = getBaseClasses(clazz); - for (AbstractMetaClass *baseClass : bases) { - const auto baseIt = map.constFind(baseClass); - if (baseIt!= map.cend()) - graph.addEdge(baseIt.value(), classIndex); - } - - const AbstractMetaFunctionList &functions = clazz->functions(); - for (AbstractMetaFunction *func : functions) { - const AbstractMetaArgumentList &arguments = func->arguments(); - for (AbstractMetaArgument *arg : arguments) { - // Check methods with default args: If a class is instantiated by value, - // ("QString s = QString()"), add a dependency. - if (!arg->originalDefaultValueExpression().isEmpty() - && arg->type()->isValue()) { - auto typeEntry = arg->type()->typeEntry(); - if (typeEntry->isComplex() && typeEntry != clazz->typeEntry()) { - auto ait = findByTypeEntry(map, typeEntry); - if (ait != map.cend() && ait.key()->enclosingClass() != clazz) - graph.addEdge(ait.value(), classIndex); - } - } - } - } - } - - AbstractMetaClassList result; - const auto unmappedResult = graph.topologicalSort(); - if (unmappedResult.isEmpty() && graph.nodeCount()) { - QTemporaryFile tempFile(QDir::tempPath() + QLatin1String("/cyclic_depXXXXXX.dot")); - tempFile.setAutoRemove(false); - tempFile.open(); - QHash<int, QString> hash; - for (auto it = map.cbegin(), end = map.cend(); it != end; ++it) - hash.insert(it.value(), it.key()->qualifiedCppName()); - graph.dumpDot(hash, tempFile.fileName()); - qCWarning(lcShiboken).noquote().nospace() - << "Cyclic dependency found! Graph can be found at " - << QDir::toNativeSeparators(tempFile.fileName()); - } else { - for (int i : qAsConst(unmappedResult)) { - Q_ASSERT(reverseMap.contains(i)); - result << reverseMap[i]; - } - } - - return result; -} - -void AbstractMetaBuilderPrivate::pushScope(const NamespaceModelItem &item) -{ - // For purposes of type lookup, join all namespaces of the same name - // within the parent item. - QVector<NamespaceModelItem> candidates; - const QString name = item->name(); - if (!m_scopes.isEmpty()) { - for (const auto &n : m_scopes.constLast()->namespaces()) { - if (n->name() == name) - candidates.append(n); - } - } - if (candidates.size() > 1) { - NamespaceModelItem joined(new _NamespaceModelItem(m_scopes.constLast()->model(), - name, _CodeModelItem::Kind_Namespace)); - joined->setScope(item->scope()); - for (const auto &n : candidates) - joined->appendNamespace(*n); - m_scopes << joined; - } else { - m_scopes << item; - } -} - -AbstractMetaClassList AbstractMetaBuilder::classesTopologicalSorted(const AbstractMetaClassList &classList, - const Dependencies &additionalDependencies) const -{ - return d->classesTopologicalSorted(classList, additionalDependencies); -} - -AbstractMetaArgumentList AbstractMetaBuilderPrivate::reverseList(const AbstractMetaArgumentList &list) -{ - AbstractMetaArgumentList ret; - - int index = list.size(); - for (AbstractMetaArgument *arg : list) { - arg->setArgumentIndex(index); - ret.prepend(arg); - index--; - } - - return ret; -} - -void AbstractMetaBuilder::setGlobalHeaders(const QFileInfoList &globalHeaders) -{ - d->m_globalHeaders = globalHeaders; -} - -void AbstractMetaBuilder::setHeaderPaths(const HeaderPaths &hp) -{ - for (const auto & h: hp) { - if (h.type != HeaderType::Framework && h.type != HeaderType::FrameworkSystem) - d->m_headerPaths.append(QFile::decodeName(h.path)); - } -} - -void AbstractMetaBuilder::setSkipDeprecated(bool value) -{ - d->m_skipDeprecated = value; -} - -// 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('\\'); -} - -static bool matchHeader(const QString &headerPath, const QString &fileName) -{ -#if defined(Q_OS_WIN) || defined(Q_OS_DARWIN) - static const Qt::CaseSensitivity caseSensitivity = Qt::CaseInsensitive; -#else - static const Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive; -#endif - const int pathSize = headerPath.size(); - return fileName.size() > pathSize - && isFileSystemSlash(fileName.at(pathSize)) - && fileName.startsWith(headerPath, caseSensitivity); -} - -void AbstractMetaBuilderPrivate::setInclude(TypeEntry *te, const QString &path) const -{ - auto it = m_resolveIncludeHash.find(path); - if (it == m_resolveIncludeHash.end()) { - QFileInfo info(path); - const QString fileName = info.fileName(); - if (std::any_of(m_globalHeaders.cbegin(), m_globalHeaders.cend(), - [fileName] (const QFileInfo &fi) { - return fi.fileName() == fileName; })) { - return; - } - - int bestMatchLength = 0; - for (const auto &headerPath : m_headerPaths) { - if (headerPath.size() > bestMatchLength && matchHeader(headerPath, path)) - bestMatchLength = headerPath.size(); - } - const QString include = bestMatchLength > 0 - ? path.right(path.size() - bestMatchLength - 1) : fileName; - it = m_resolveIncludeHash.insert(path, {Include::IncludePath, include}); - } - te->setInclude(it.value()); -} - -#ifndef QT_NO_DEBUG_STREAM -template <class Container> -static void debugFormatSequence(QDebug &d, const char *key, const Container& c, - const char *separator = ", ") -{ - if (c.isEmpty()) - return; - const auto begin = c.begin(); - const auto end = c.end(); - d << "\n " << key << '[' << c.size() << "]=("; - for (auto it = begin; it != end; ++it) { - if (it != begin) - d << separator; - d << *it; - } - d << ')'; -} - -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()) { - debug << "\n scopes[" << scopeCount << "]=("; - for (int i = 0; i < scopeCount; ++i) { - if (i) - debug << ", "; - _CodeModelItem::formatKind(debug, d->m_scopes.at(i)->kind()); - debug << " \"" << d->m_scopes.at(i)->name() << '"'; - } - debug << ')'; - } - debugFormatSequence(debug, "classes", d->m_metaClasses, "\n"); - debugFormatSequence(debug, "templates", d->m_templates, "\n"); -} - -QDebug operator<<(QDebug d, const AbstractMetaBuilder &ab) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaBuilder("; - ab.formatDebug(d); - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder.h deleted file mode 100644 index 37022a544..000000000 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder.h +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ABSTRACTMETABUILDER_H -#define ABSTRACTMETABUILDER_H - -#include "abstractmetalang_typedefs.h" -#include "header_paths.h" -#include "dependency.h" - -#include "clangparser/compilersupport.h" - -#include <QFileInfoList> - -QT_FORWARD_DECLARE_CLASS(QIODevice) - -class AbstractMetaBuilderPrivate; -class AbstractMetaClass; -class AbstractMetaType; -class AbstractMetaEnumValue; -class TypeInfo; -class TypeEntry; - -class AbstractMetaBuilder -{ -public: - enum RejectReason { - NotInTypeSystem, - GenerationDisabled, - RedefinedToNotClass, - UnmatchedArgumentType, - UnmatchedReturnType, - ApiIncompatible, - Deprecated, - NoReason - }; - - AbstractMetaBuilder(); - virtual ~AbstractMetaBuilder(); - - AbstractMetaClassList classes() const; - AbstractMetaClassList templates() const; - AbstractMetaClassList smartPointers() const; - AbstractMetaFunctionList globalFunctions() const; - AbstractMetaEnumList globalEnums() const; - AbstractMetaEnum *findEnum(const TypeEntry *typeEntry) const; - - /** - * Sorts a list of classes topologically. - * \return a list of classes sorted topologically - */ - AbstractMetaClassList classesTopologicalSorted(const AbstractMetaClassList &classList, - const Dependencies &additionalDependencies = Dependencies()) const; - - bool build(const QByteArrayList &arguments, - LanguageLevel level = LanguageLevel::Default, - unsigned clangFlags = 0); - void setLogDirectory(const QString& logDir); - - /** - * AbstractMetaBuilder should know what's the global header being used, - * so any class declared under this header wont have the include file - * filled. - */ - void setGlobalHeaders(const QFileInfoList& globalHeaders); - void setHeaderPaths(const HeaderPaths &h); - - void setSkipDeprecated(bool value); - - enum TranslateTypeFlag { - DontResolveType = 0x1 - }; - Q_DECLARE_FLAGS(TranslateTypeFlags, TranslateTypeFlag); - - static AbstractMetaType *translateType(const TypeInfo &_typei, - AbstractMetaClass *currentClass = nullptr, - TranslateTypeFlags flags = {}, - QString *errorMessage = nullptr); - static AbstractMetaType *translateType(const QString &t, - AbstractMetaClass *currentClass = nullptr, - TranslateTypeFlags flags = {}, - QString *errorMessage = nullptr); - - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const; -#endif - -private: - friend class AbstractMetaBuilderPrivate; - AbstractMetaBuilderPrivate *d; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaBuilder::TranslateTypeFlags); - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaBuilder &ab); -#endif - -#endif // ABSTRACTMETBUILDER_H diff --git a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h b/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h deleted file mode 100644 index 2686ebacb..000000000 --- a/sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h +++ /dev/null @@ -1,206 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef ABSTRACTMETABUILDER_P_H -#define ABSTRACTMETABUILDER_P_H - -#include "abstractmetabuilder.h" -#include "parser/codemodel_fwd.h" -#include "abstractmetalang.h" -#include "typesystem.h" -#include "typeparser.h" - -#include <QSet> -#include <QFileInfo> -#include <QVector> - -class TypeDatabase; - -class AbstractMetaBuilderPrivate -{ -public: - using TranslateTypeFlags = AbstractMetaBuilder::TranslateTypeFlags; - - Q_DISABLE_COPY(AbstractMetaBuilderPrivate) - - AbstractMetaBuilderPrivate(); - ~AbstractMetaBuilderPrivate(); - - static FileModelItem buildDom(QByteArrayList arguments, - LanguageLevel level, - unsigned clangFlags); - void traverseDom(const FileModelItem &dom); - - void dumpLog() const; - AbstractMetaClassList classesTopologicalSorted(const AbstractMetaClassList &classList, - const Dependencies &additionalDependencies = Dependencies()) const; - NamespaceModelItem popScope() { return m_scopes.takeLast(); } - - void pushScope(const NamespaceModelItem &item); - - NamespaceModelItem currentScope() const { return m_scopes.constLast(); } - - AbstractMetaClass *argumentToClass(const ArgumentModelItem &, - AbstractMetaClass *currentClass); - - void addAbstractMetaClass(AbstractMetaClass *cls, const _CodeModelItem *item); - AbstractMetaClass *traverseTypeDef(const FileModelItem &dom, - const TypeDefModelItem &typeDef, - AbstractMetaClass *currentClass); - void traverseTypesystemTypedefs(); - AbstractMetaClass *traverseClass(const FileModelItem &dom, - const ClassModelItem &item, - AbstractMetaClass *currentClass); - void traverseScopeMembers(const ScopeModelItem &item, AbstractMetaClass *metaClass); - void traverseClassMembers(const ClassModelItem &scopeItem); - void traverseNamespaceMembers(const NamespaceModelItem &scopeItem); - bool setupInheritance(AbstractMetaClass *metaClass); - AbstractMetaClass *traverseNamespace(const FileModelItem &dom, - const NamespaceModelItem &item); - AbstractMetaEnum *traverseEnum(const EnumModelItem &item, AbstractMetaClass *enclosing, - const QSet<QString> &enumsDeclarations); - void traverseEnums(const ScopeModelItem &item, AbstractMetaClass *parent, - const QStringList &enumsDeclarations); - AbstractMetaFunctionList classFunctionList(const ScopeModelItem &scopeItem, - AbstractMetaClass::Attributes *constructorAttributes, - AbstractMetaClass *currentClass); - AbstractMetaFunctionList templateClassFunctionList(const ScopeModelItem &scopeItem, - AbstractMetaClass *metaClass, - bool *constructorRejected); - void traverseFunctions(ScopeModelItem item, AbstractMetaClass *parent); - void applyFunctionModifications(AbstractMetaFunction* func); - void traverseFields(const ScopeModelItem &item, AbstractMetaClass *parent); - void traverseStreamOperator(const FunctionModelItem &functionItem, - AbstractMetaClass *currentClass); - void traverseOperatorFunction(const FunctionModelItem &item, - AbstractMetaClass *currentClass); - AbstractMetaFunction* traverseFunction(const AddedFunctionPtr &addedFunc); - AbstractMetaFunction* traverseFunction(const AddedFunctionPtr &addedFunc, - AbstractMetaClass *metaClass); - AbstractMetaFunction *traverseFunction(const FunctionModelItem &function, - AbstractMetaClass *currentClass); - AbstractMetaField *traverseField(const VariableModelItem &field, - AbstractMetaClass *cls); - void checkFunctionModifications(); - void registerHashFunction(const FunctionModelItem &functionItem, - AbstractMetaClass *currentClass); - void registerToStringCapabilityIn(const NamespaceModelItem &namespaceItem); - void registerToStringCapability(const FunctionModelItem &functionItem, - AbstractMetaClass *currentClass); - - /** - * A conversion operator function should not have its owner class as - * its return type, but unfortunately it does. This function fixes the - * return type of operator functions of this kind making the return type - * be the same as it is supposed to generate when used in C++. - * If the returned type is a wrapped C++ class, this method also adds the - * conversion operator to the collection of external conversions of the - * said class. - * \param metaFunction conversion operator function to be fixed. - */ - void fixReturnTypeOfConversionOperator(AbstractMetaFunction *metaFunction); - - void parseQ_Property(AbstractMetaClass *metaClass, const QStringList &declarations); - void setupEquals(AbstractMetaClass *metaClass); - void setupComparable(AbstractMetaClass *metaClass); - void setupClonable(AbstractMetaClass *cls); - void setupExternalConversion(AbstractMetaClass *cls); - void setupFunctionDefaults(AbstractMetaFunction *metaFunction, - AbstractMetaClass *metaClass); - - QString fixDefaultValue(const ArgumentModelItem &item, AbstractMetaType *type, - AbstractMetaFunction *fnc, AbstractMetaClass *, - int argumentIndex); - AbstractMetaType *translateType(const AddedFunction::TypeInfo &typeInfo, - QString *errorMessage); - AbstractMetaType *translateType(const TypeInfo &type, - AbstractMetaClass *currentClass, - TranslateTypeFlags flags = {}, - QString *errorMessage = nullptr); - static AbstractMetaType *translateTypeStatic(const TypeInfo &type, - AbstractMetaClass *current, - AbstractMetaBuilderPrivate *d = nullptr, - TranslateTypeFlags flags = {}, - QString *errorMessageIn = nullptr); - static TypeEntries findTypeEntries(const QString &qualifiedName, const QString &name, - AbstractMetaClass *currentClass = nullptr, - AbstractMetaBuilderPrivate *d = 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; - bool ancestorHasPrivateCopyConstructor(const AbstractMetaClass *metaClass) const; - - bool inheritTemplate(AbstractMetaClass *subclass, - const AbstractMetaClass *templateClass, - const TypeInfo &info); - AbstractMetaType *inheritTemplateType(const AbstractMetaTypeList &templateTypes, - const AbstractMetaType *metaType); - - bool isQObject(const FileModelItem &dom, const QString &qualifiedName); - bool isEnum(const FileModelItem &dom, const QStringList &qualifiedName); - - void sortLists(); - AbstractMetaArgumentList reverseList(const AbstractMetaArgumentList &list); - void setInclude(TypeEntry *te, const QString &path) const; - void fixArgumentNames(AbstractMetaFunction *func, const FunctionModificationList &mods); - - void fillAddedFunctions(AbstractMetaClass *metaClass); - - AbstractMetaBuilder *q; - AbstractMetaClassList m_metaClasses; - AbstractMetaClassList m_templates; - AbstractMetaClassList m_smartPointers; - QHash<const _CodeModelItem *, AbstractMetaClass *> m_itemToClass; - AbstractMetaFunctionList m_globalFunctions; - AbstractMetaEnumList m_globalEnums; - - using RejectMap = QMap<QString, AbstractMetaBuilder::RejectReason>; - - RejectMap m_rejectedClasses; - RejectMap m_rejectedEnums; - RejectMap m_rejectedFunctions; - RejectMap m_rejectedFields; - - QHash<const TypeEntry *, AbstractMetaEnum *> m_enums; - - QVector<NamespaceModelItem> m_scopes; - - QSet<AbstractMetaClass *> m_setupInheritanceDone; - - QString m_logDirectory; - QFileInfoList m_globalHeaders; - QStringList m_headerPaths; - mutable QHash<QString, Include> m_resolveIncludeHash; - bool m_skipDeprecated = false; -}; - -#endif // ABSTRACTMETBUILDER_P_H diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp b/sources/shiboken2/ApiExtractor/abstractmetalang.cpp deleted file mode 100644 index e9a2c2b57..000000000 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.cpp +++ /dev/null @@ -1,2727 +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$ -** -****************************************************************************/ - -#include "abstractmetalang.h" -#include "messages.h" -#include "reporthandler.h" -#include "typedatabase.h" -#include "typesystem.h" - -#include <parser/codemodel.h> - -#ifndef QT_NO_DEBUG_STREAM -# include <QtCore/QMetaEnum> -# include <QtCore/QMetaObject> -#endif - -#include <QtCore/QRegularExpression> -#include <QtCore/QStack> - -#include <algorithm> - -#include <algorithm> - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaAttributes("; - if (aa) - d << aa->attributes(); - else - d << '0'; - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -template <class MetaClass> -MetaClass *findByName(QVector<MetaClass *> haystack, QStringView needle) -{ - for (MetaClass *c : haystack) { - if (c->name() == needle) - return c; - } - return nullptr; -} - -// 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) -{ - if (pred(klass)) - return klass; - for (auto base : klass->baseClasses()) { - if (auto r = recurseClassHierarchy(base, pred)) - return r; - } - return nullptr; -} - -/******************************************************************************* - * AbstractMetaVariable - */ - -AbstractMetaVariable::AbstractMetaVariable() = default; - -AbstractMetaVariable::~AbstractMetaVariable() -{ - delete m_type; -} - -void AbstractMetaVariable::assignMetaVariable(const AbstractMetaVariable &other) -{ - m_originalName = other.m_originalName; - m_name = other.m_name; - m_type = other.m_type->copy(); - m_hasName = other.m_hasName; - m_doc = other.m_doc; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaVariable *av) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaVariable("; - if (av) { - d << av->type()->name() << ' ' << av->name(); - } else { - d << '0'; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -/******************************************************************************* - * AbstractMetaAttributes - */ - -AbstractMetaAttributes::AbstractMetaAttributes() = default; -AbstractMetaAttributes::~AbstractMetaAttributes() = default; - -void AbstractMetaAttributes::assignMetaAttributes(const AbstractMetaAttributes &other) -{ - m_attributes = other.m_attributes; - m_originalAttributes = other.m_originalAttributes; - m_doc = other.m_doc; -} - -/******************************************************************************* - * AbstractMetaType - */ - -AbstractMetaType::AbstractMetaType() : - m_constant(false), - m_volatile(false), - m_cppInstantiation(true), - m_reserved(0) -{ -} - -AbstractMetaType::~AbstractMetaType() -{ - qDeleteAll(m_children); - m_instantiations.clear(); -} - -QString AbstractMetaType::package() const -{ - return m_typeEntry->targetLangPackage(); -} - -QString AbstractMetaType::name() const -{ - return m_typeEntry->targetLangEntryName(); -} - -QString AbstractMetaType::fullName() const -{ - return m_typeEntry->qualifiedTargetLangName(); -} - -AbstractMetaType *AbstractMetaType::copy() const -{ - auto *cpy = new AbstractMetaType; - - cpy->setTypeUsagePattern(typeUsagePattern()); - cpy->setConstant(isConstant()); - cpy->setVolatile(isVolatile()); - cpy->setReferenceType(referenceType()); - cpy->setIndirectionsV(indirectionsV()); - cpy->setInstantiations(instantiations()); - cpy->setArrayElementCount(arrayElementCount()); - cpy->setOriginalTypeDescription(originalTypeDescription()); - cpy->setOriginalTemplateType(originalTemplateType() ? originalTemplateType()->copy() : nullptr); - - cpy->setArrayElementType(arrayElementType() ? arrayElementType()->copy() : nullptr); - - cpy->setTypeEntry(typeEntry()); - - return cpy; -} - -// For applying the <array> function argument modification: change into a type -// where "int *" becomes "int[]". -bool AbstractMetaType::applyArrayModification(QString *errorMessage) -{ - if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern) { - *errorMessage = QLatin1String("<array> modification already applied."); - return false; - } - if (m_arrayElementType != nullptr) { - QTextStream(errorMessage) << "The type \"" << cppSignature() - << "\" is an array of " << m_arrayElementType->name() << '.'; - return false; - } - if (m_indirections.isEmpty()) { - QTextStream(errorMessage) << "The type \"" << cppSignature() - << "\" does not have indirections."; - return false; - } - // Element type to be used for ArrayHandle<>, strip constness. - auto elementType = copy(); - elementType->m_indirections.pop_front(); - elementType->setConstant(false); - elementType->setVolatile(false); - elementType->decideUsagePattern(); - m_arrayElementType = elementType; - setTypeUsagePattern(AbstractMetaType::NativePointerAsArrayPattern); - return true; -} - -AbstractMetaTypeCList AbstractMetaType::nestedArrayTypes() const -{ - AbstractMetaTypeCList result; - switch (m_pattern) { - case ArrayPattern: - for (const AbstractMetaType *t = this; t->typeUsagePattern() == ArrayPattern; ) { - const AbstractMetaType *elt = t->arrayElementType(); - result.append(elt); - t = elt; - } - break; - case NativePointerAsArrayPattern: - result.append(m_arrayElementType); - break; - default: - break; - } - return result; -} - -bool AbstractMetaType::passByConstRef() const -{ - return isConstant() && m_referenceType == LValueReference && indirections() == 0; -} - -bool AbstractMetaType::passByValue() const -{ - return m_referenceType == NoReference && indirections() == 0; -} - -QString AbstractMetaType::cppSignature() const -{ - if (m_cachedCppSignature.isEmpty()) - m_cachedCppSignature = formatSignature(false); - return m_cachedCppSignature; -} - -QString AbstractMetaType::pythonSignature() const -{ - // PYSIDE-921: Handle container returntypes correctly. - // This is now a clean reimplementation. - if (m_cachedPythonSignature.isEmpty()) - m_cachedPythonSignature = formatPythonSignature(); - return m_cachedPythonSignature; -} - -AbstractMetaType::TypeUsagePattern AbstractMetaType::determineUsagePattern() const -{ - if (m_typeEntry->isTemplateArgument() || m_referenceType == RValueReference) - return InvalidPattern; - - if (m_typeEntry->isPrimitive() && (actualIndirections() == 0 || passByConstRef())) - return PrimitivePattern; - - if (m_typeEntry->isVoid()) - return NativePointerPattern; - - if (m_typeEntry->isVarargs()) - return VarargsPattern; - - if (m_typeEntry->isEnum() && (actualIndirections() == 0 || passByConstRef())) - return EnumPattern; - - if (m_typeEntry->isObject()) { - if (indirections() == 0 && m_referenceType == NoReference) - return ValuePattern; - return ObjectPattern; - } - - if (m_typeEntry->isContainer() && indirections() == 0) - return ContainerPattern; - - if (m_typeEntry->isSmartPointer() && indirections() == 0) - return SmartPointerPattern; - - if (m_typeEntry->isFlags() && (actualIndirections() == 0 || passByConstRef())) - return FlagsPattern; - - if (m_typeEntry->isArray()) - return ArrayPattern; - - if (m_typeEntry->isValue()) - return indirections() == 1 ? ValuePointerPattern : ValuePattern; - - return NativePointerPattern; -} - -void AbstractMetaType::decideUsagePattern() -{ - TypeUsagePattern pattern = determineUsagePattern(); - if (m_typeEntry->isObject() && indirections() == 1 - && m_referenceType == LValueReference && isConstant()) { - // const-references to pointers can be passed as pointers - setReferenceType(NoReference); - setConstant(false); - pattern = ObjectPattern; - } - setTypeUsagePattern(pattern); -} - -bool AbstractMetaType::hasTemplateChildren() const -{ - QStack<AbstractMetaType *> children; - children << m_children; - - // Recursively iterate over the children / descendants of the type, to check if any of them - // corresponds to a template argument type. - while (!children.isEmpty()) { - AbstractMetaType *child = children.pop(); - if (child->typeEntry()->isTemplateArgument()) - return true; - children << child->m_children; - } - - return false; -} - -bool AbstractMetaType::compare(const AbstractMetaType &rhs, ComparisonFlags flags) const -{ - if (m_typeEntry != rhs.m_typeEntry - || m_indirections != rhs.m_indirections - || m_instantiations.size() != rhs.m_instantiations.size() - || m_arrayElementCount != rhs.m_arrayElementCount) { - return false; - } - - if (m_constant != rhs.m_constant || m_referenceType != rhs.m_referenceType) { - if (!flags.testFlag(ConstRefMatchesValue) - || !(passByValue() || passByConstRef()) - || !(rhs.passByValue() || rhs.passByConstRef())) { - return false; - } - } - - if ((m_arrayElementType != nullptr) != (rhs.m_arrayElementType != nullptr) - || (m_arrayElementType != nullptr && !m_arrayElementType->compare(*rhs.m_arrayElementType, flags))) { - return false; - } - for (int i = 0, size = m_instantiations.size(); i < size; ++i) { - if (!m_instantiations.at(i)->compare(*rhs.m_instantiations.at(i), flags)) - return false; - } - return true; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaType *at) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaType("; - if (at) { - d << at->name(); - if (d.verbosity() > 2) { - d << ", typeEntry=" << at->typeEntry() << ", signature=\"" - << at->cppSignature() << "\", pattern=" - << at->typeUsagePattern(); - const auto indirections = at->indirectionsV(); - if (!indirections.isEmpty()) { - d << ", indirections="; - for (auto i : indirections) - d << ' ' << TypeInfo::indirectionKeyword(i); - } - if (at->referenceType()) - d << ", reftype=" << at->referenceType(); - if (at->isConstant()) - d << ", [const]"; - if (at->isVolatile()) - d << ", [volatile]"; - if (at->isArray()) { - d << ", array of \"" << at->arrayElementType()->cppSignature() - << "\", arrayElementCount=" << at->arrayElementCount(); - } - const auto &instantiations = at->instantiations(); - if (const int instantiationsSize = instantiations.size()) { - d << ", instantiations[" << instantiationsSize << "]=<"; - for (int i = 0; i < instantiationsSize; ++i) { - if (i) - d << ", "; - d << instantiations.at(i); - } - } - d << '>'; - } - } else { - d << '0'; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -/******************************************************************************* - * AbstractMetaArgument - */ - -AbstractMetaArgument::AbstractMetaArgument() = default; - -void AbstractMetaArgument::assignMetaArgument(const AbstractMetaArgument &other) -{ - assignMetaVariable(other); - m_expression = other.m_expression; - m_originalExpression = other.m_originalExpression; - m_argumentIndex = other.m_argumentIndex; -} - -AbstractMetaArgument *AbstractMetaArgument::copy() const -{ - auto *copy = new AbstractMetaArgument; - copy->assignMetaArgument(*this); - return copy; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaArgument *aa) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaArgument("; - if (aa) - d << aa->toString(); - else - d << '0'; - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -/******************************************************************************* - * AbstractMetaFunction - */ - -AbstractMetaFunction::AbstractMetaFunction(const AddedFunctionPtr &addedFunc) : - AbstractMetaFunction() -{ - m_addedFunction = addedFunc; - setConstant(addedFunc->isConstant()); - setName(addedFunc->name()); - setOriginalName(addedFunc->name()); - auto atts = attributes() | AbstractMetaAttributes::FinalInTargetLang; - switch (addedFunc->access()) { - case AddedFunction::InvalidAccess: - break; - case AddedFunction::Protected: - atts |= AbstractMetaAttributes::Protected; - break; - case AddedFunction::Public: - atts |= AbstractMetaAttributes::Public; - break; - } - if (addedFunc->isStatic()) - atts |= AbstractMetaFunction::Static; - setAttributes(atts); -} - -AbstractMetaFunction::AbstractMetaFunction() - : m_constant(false), - m_reverse(false), - m_explicit(false), - m_pointerOperator(false), - m_isCallOperator(false) -{ -} - -AbstractMetaFunction::~AbstractMetaFunction() -{ - qDeleteAll(m_arguments); - delete m_type; -} - -/******************************************************************************* - * Indicates that this function has a modification that removes it - */ -bool AbstractMetaFunction::isModifiedRemoved(int types) const -{ - const FunctionModificationList &mods = modifications(implementingClass()); - for (const FunctionModification &mod : mods) { - if (!mod.isRemoveModifier()) - continue; - - if ((mod.removal & types) == types) - return true; - } - - return false; -} - -bool AbstractMetaFunction::operator<(const AbstractMetaFunction &other) const -{ - return compareTo(&other) & NameLessThan; -} - - -/*! - Returns a mask of CompareResult describing how this function is - compares to another function -*/ -AbstractMetaFunction::CompareResult AbstractMetaFunction::compareTo(const AbstractMetaFunction *other) const -{ - CompareResult result; - - // Enclosing class... - if (ownerClass() == other->ownerClass()) - result |= EqualImplementor; - - // Attributes - if (attributes() == other->attributes()) - result |= EqualAttributes; - - // Compare types - AbstractMetaType *t = type(); - AbstractMetaType *ot = other->type(); - if ((!t && !ot) || ((t && ot && t->name() == ot->name()))) - result |= EqualReturnType; - - // Compare names - int cmp = originalName().compare(other->originalName()); - - if (cmp < 0) - result |= NameLessThan; - else if (!cmp) - result |= EqualName; - - // compare name after modification... - cmp = modifiedName().compare(other->modifiedName()); - if (!cmp) - result |= EqualModifiedName; - - // Compare arguments... - AbstractMetaArgumentList minArguments; - AbstractMetaArgumentList maxArguments; - if (arguments().size() < other->arguments().size()) { - minArguments = arguments(); - maxArguments = other->arguments(); - } else { - minArguments = other->arguments(); - maxArguments = arguments(); - } - - int minCount = minArguments.size(); - int maxCount = maxArguments.size(); - bool same = true; - for (int i = 0; i < maxCount; ++i) { - if (i < minCount) { - const AbstractMetaArgument *min_arg = minArguments.at(i); - const AbstractMetaArgument *max_arg = maxArguments.at(i); - if (min_arg->type()->name() != max_arg->type()->name() - && (min_arg->defaultValueExpression().isEmpty() || max_arg->defaultValueExpression().isEmpty())) { - same = false; - break; - } - } else { - if (maxArguments.at(i)->defaultValueExpression().isEmpty()) { - same = false; - break; - } - } - } - - if (same) - result |= minCount == maxCount ? EqualArguments : EqualDefaultValueOverload; - - return result; -} - -AbstractMetaFunction *AbstractMetaFunction::copy() const -{ - auto *cpy = new AbstractMetaFunction; - cpy->assignMetaAttributes(*this); - cpy->setName(name()); - cpy->setOriginalName(originalName()); - cpy->setOwnerClass(ownerClass()); - cpy->setImplementingClass(implementingClass()); - cpy->setFunctionType(functionType()); - cpy->setDeclaringClass(declaringClass()); - if (type()) - cpy->setType(type()->copy()); - cpy->setConstant(isConstant()); - cpy->setExceptionSpecification(m_exceptionSpecification); - cpy->setAllowThreadModification(m_allowThreadModification); - cpy->setExceptionHandlingModification(m_exceptionHandlingModification); - cpy->m_addedFunction = m_addedFunction; - - for (AbstractMetaArgument *arg : m_arguments) - cpy->addArgument(arg->copy()); - - Q_ASSERT((!type() && !cpy->type()) - || (type()->instantiations() == cpy->type()->instantiations())); - - return cpy; -} - -bool AbstractMetaFunction::usesRValueReferences() const -{ - if (m_functionType == MoveConstructorFunction || m_functionType == MoveAssignmentOperatorFunction) - return true; - if (m_type && m_type->referenceType() == RValueReference) - return true; - for (const AbstractMetaArgument *a : m_arguments) { - if (a->type()->referenceType() == RValueReference) - return true; - } - return false; -} - -QStringList AbstractMetaFunction::introspectionCompatibleSignatures(const QStringList &resolvedArguments) 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; - - 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("::"))); - } - - return returned; -} - -QString AbstractMetaFunction::signature() const -{ - if (m_cachedSignature.isEmpty()) { - m_cachedSignature = m_originalName; - - m_cachedSignature += QLatin1Char('('); - - for (int i = 0; i < m_arguments.count(); ++i) { - AbstractMetaArgument *a = m_arguments.at(i); - AbstractMetaType *t = a->type(); - if (t) { - if (i > 0) - m_cachedSignature += QLatin1String(", "); - m_cachedSignature += t->cppSignature(); - // We need to have the argument names in the qdoc files - m_cachedSignature += QLatin1Char(' '); - m_cachedSignature += a->name(); - } else { - qCWarning(lcShiboken).noquote().nospace() - << QString::fromLatin1("No abstract meta type found for argument '%1' while" - "constructing signature for function '%2'.") - .arg(a->name(), name()); - } - } - m_cachedSignature += QLatin1Char(')'); - - if (isConstant()) - m_cachedSignature += QLatin1String(" const"); - } - return m_cachedSignature; -} - -int AbstractMetaFunction::actualMinimumArgumentCount() const -{ - AbstractMetaArgumentList arguments = this->arguments(); - - int count = 0; - for (int i = 0; i < arguments.size(); ++i && ++count) { - if (argumentRemoved(i + 1)) - --count; - else if (!arguments.at(i)->defaultValueExpression().isEmpty()) - break; - } - - return count; -} - -// Returns reference counts for argument at idx, or all arguments if idx == -2 -QVector<ReferenceCount> AbstractMetaFunction::referenceCounts(const AbstractMetaClass *cls, int idx) const -{ - QVector<ReferenceCount> returned; - - const FunctionModificationList &mods = this->modifications(cls); - for (const FunctionModification &mod : mods) { - for (const ArgumentModification &argumentMod : mod.argument_mods) { - if (argumentMod.index != idx && idx != -2) - continue; - returned += argumentMod.referenceCounts; - } - } - - return returned; -} - - -ArgumentOwner AbstractMetaFunction::argumentOwner(const AbstractMetaClass *cls, int idx) const -{ - const FunctionModificationList &mods = this->modifications(cls); - for (const FunctionModification &mod : mods) { - for (const ArgumentModification &argumentMod : mod.argument_mods) { - if (argumentMod.index != idx) - continue; - return argumentMod.owner; - } - } - return ArgumentOwner(); -} - -QString AbstractMetaFunction::conversionRule(TypeSystem::Language language, int key) const -{ - const FunctionModificationList &modifications = this->modifications(declaringClass()); - for (const FunctionModification &modification : modifications) { - for (const ArgumentModification &argumentModification : modification.argument_mods) { - if (argumentModification.index != key) - continue; - - for (const CodeSnip &snip : argumentModification.conversion_rules) { - if (snip.language == language && !snip.code().isEmpty()) - return snip.code(); - } - } - } - - return QString(); -} - -// FIXME If we remove a arg. in the method at the base class, it will not reflect here. -bool AbstractMetaFunction::argumentRemoved(int key) const -{ - const FunctionModificationList &modifications = this->modifications(declaringClass()); - for (const FunctionModification &modification : modifications) { - for (const ArgumentModification &argumentModification : modification.argument_mods) { - if (argumentModification.index == key) { - if (argumentModification.removed) - return true; - } - } - } - - return false; -} - -bool AbstractMetaFunction::isDeprecated() const -{ - const FunctionModificationList &modifications = this->modifications(declaringClass()); - for (const FunctionModification &modification : modifications) { - if (modification.isDeprecated()) - return true; - } - return false; -} - -// 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 -// functions, anything that might call a virtual function (potentially -// reimplemented in Python), and recommended for lengthy I/O or similar. -// It has performance costs, though. -bool AbstractMetaFunction::autoDetectAllowThread() const -{ - // Disallow for simple getter functions. - const bool maybeGetter = m_constant != 0 && m_type != nullptr - && m_arguments.isEmpty(); - return !maybeGetter; -} - -SourceLocation AbstractMetaFunction::sourceLocation() const -{ - return m_sourceLocation; -} - -void AbstractMetaFunction::setSourceLocation(const SourceLocation &sourceLocation) -{ - m_sourceLocation = sourceLocation; -} - -static inline TypeSystem::AllowThread allowThreadMod(const AbstractMetaClass *klass) -{ - return klass->typeEntry()->allowThread(); -} - -static inline bool hasAllowThreadMod(const AbstractMetaClass *klass) -{ - return allowThreadMod(klass) != TypeSystem::AllowThread::Unspecified; -} - -bool AbstractMetaFunction::allowThread() const -{ - auto allowThreadModification = m_allowThreadModification; - // If there is no modification on the function, check for a base class. - if (m_class && allowThreadModification == TypeSystem::AllowThread::Unspecified) { - if (auto base = recurseClassHierarchy(m_class, hasAllowThreadMod)) - allowThreadModification = allowThreadMod(base); - } - - bool result = true; - switch (allowThreadModification) { - case TypeSystem::AllowThread::Disallow: - result = false; - break; - case TypeSystem::AllowThread::Allow: - break; - case TypeSystem::AllowThread::Auto: - result = autoDetectAllowThread(); - break; - case TypeSystem::AllowThread::Unspecified: - result = false; - break; - } - if (!result && ReportHandler::isDebug(ReportHandler::MediumDebug)) - qCInfo(lcShiboken).noquote() << msgDisallowThread(this); - return result; -} - -TypeSystem::Ownership AbstractMetaFunction::ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int key) const -{ - const FunctionModificationList &modifications = this->modifications(cls); - for (const FunctionModification &modification : modifications) { - for (const ArgumentModification &argumentModification : modification.argument_mods) { - if (argumentModification.index == key) - return argumentModification.ownerships.value(language, TypeSystem::InvalidOwnership); - } - } - - return TypeSystem::InvalidOwnership; -} - -bool AbstractMetaFunction::isRemovedFromAllLanguages(const AbstractMetaClass *cls) const -{ - return isRemovedFrom(cls, TypeSystem::All); -} - -bool AbstractMetaFunction::isRemovedFrom(const AbstractMetaClass *cls, TypeSystem::Language language) const -{ - const FunctionModificationList &modifications = this->modifications(cls); - for (const FunctionModification &modification : modifications) { - if ((modification.removal & language) == language) - return true; - } - - return false; - -} - -QString AbstractMetaFunction::typeReplaced(int key) const -{ - const FunctionModificationList &modifications = this->modifications(declaringClass()); - for (const FunctionModification &modification : modifications) { - for (const ArgumentModification &argumentModification : modification.argument_mods) { - if (argumentModification.index == key - && !argumentModification.modified_type.isEmpty()) { - return argumentModification.modified_type; - } - } - } - - return QString(); -} - -bool AbstractMetaFunction::isModifiedToArray(int argumentIndex) const -{ - const FunctionModificationList &modifications = this->modifications(declaringClass()); - for (const FunctionModification &modification : modifications) { - for (const ArgumentModification &argumentModification : modification.argument_mods) { - if (argumentModification.index == argumentIndex && argumentModification.array != 0) - return true; - } - } - return false; -} - -QString AbstractMetaFunction::minimalSignature() const -{ - if (!m_cachedMinimalSignature.isEmpty()) - return m_cachedMinimalSignature; - - QString minimalSignature = originalName() + QLatin1Char('('); - AbstractMetaArgumentList arguments = this->arguments(); - - for (int i = 0; i < arguments.count(); ++i) { - AbstractMetaType *t = arguments.at(i)->type(); - if (t) { - if (i > 0) - minimalSignature += QLatin1Char(','); - minimalSignature += t->minimalSignature(); - } else { - qCWarning(lcShiboken).noquote().nospace() - << QString::fromLatin1("No abstract meta type found for argument '%1' while constructing" - " minimal signature for function '%2'.") - .arg(arguments.at(i)->name(), name()); - } - } - minimalSignature += QLatin1Char(')'); - if (isConstant()) - minimalSignature += QLatin1String("const"); - - minimalSignature = TypeDatabase::normalizedSignature(minimalSignature); - m_cachedMinimalSignature = minimalSignature; - - return minimalSignature; -} - -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 "); - result += minimalSignature(); - if (isOverride) - result += QLatin1String(" override"); - if (isFinal) - result += QLatin1String(" final"); - return result; -} - -FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaClass *implementor) const -{ - if (!m_addedFunction.isNull()) - return m_addedFunction->modifications; - if (!implementor) - implementor = ownerClass(); - - if (!implementor) - return TypeDatabase::instance()->functionModifications(minimalSignature()); - - FunctionModificationList mods; - while (implementor) { - mods += implementor->typeEntry()->functionModifications(minimalSignature()); - if ((implementor == implementor->baseClass()) || - (implementor == implementingClass() && !mods.isEmpty())) { - break; - } - implementor = implementor->baseClass(); - } - return mods; -} - -QString AbstractMetaFunction::argumentName(int index, - bool /* create */, - const AbstractMetaClass * /* implementor */) const -{ - return m_arguments[--index]->name(); -} - -bool AbstractMetaFunction::isCallOperator() const -{ - return m_name == QLatin1String("operator()"); -} - -bool AbstractMetaFunction::hasInjectedCode() const -{ - const FunctionModificationList &mods = modifications(ownerClass()); - for (const FunctionModification &mod : mods) { - if (mod.isCodeInjection()) - return true; - } - return false; -} - -CodeSnipList AbstractMetaFunction::injectedCodeSnips(TypeSystem::CodeSnipPosition position, TypeSystem::Language language) const -{ - CodeSnipList result; - const FunctionModificationList &mods = modifications(ownerClass()); - for (const FunctionModification &mod : mods) { - if (mod.isCodeInjection()) { - for (const CodeSnip &snip : mod.snips) { - if ((snip.language & language) && (snip.position == position || position == TypeSystem::CodeSnipPositionAny)) - result << snip; - } - } - } - return result; -} - -bool AbstractMetaFunction::hasSignatureModifications() const -{ - const FunctionModificationList &mods = modifications(); - for (const FunctionModification &mod : mods) { - if (mod.isRenameModifier()) - return true; - for (const ArgumentModification &argmod : mod.argument_mods) { - // since zero represents the return type and we're - // interested only in checking the function arguments, - // it will be ignored. - if (argmod.index > 0) - return true; - } - } - return false; -} - -bool AbstractMetaFunction::isConversionOperator(const QString &funcName) -{ - static const QRegularExpression opRegEx(QStringLiteral("^operator(?:\\s+(?:const|volatile))?\\s+(\\w+\\s*)&?$")); - Q_ASSERT(opRegEx.isValid()); - return opRegEx.match(funcName).hasMatch(); -} - -ExceptionSpecification AbstractMetaFunction::exceptionSpecification() const -{ - return m_exceptionSpecification; -} - -void AbstractMetaFunction::setExceptionSpecification(ExceptionSpecification e) -{ - m_exceptionSpecification = e; -} - -static inline TypeSystem::ExceptionHandling exceptionMod(const AbstractMetaClass *klass) -{ - return klass->typeEntry()->exceptionHandling(); -} - -static inline bool hasExceptionMod(const AbstractMetaClass *klass) -{ - return exceptionMod(klass) != TypeSystem::ExceptionHandling::Unspecified; -} - -bool AbstractMetaFunction::generateExceptionHandling() const -{ - switch (m_functionType) { - case AbstractMetaFunction::CopyConstructorFunction: - case AbstractMetaFunction::MoveConstructorFunction: - case AbstractMetaFunction::AssignmentOperatorFunction: - case AbstractMetaFunction::MoveAssignmentOperatorFunction: - case AbstractMetaFunction::DestructorFunction: - return false; - default: - break; - } - - auto exceptionHandlingModification = m_exceptionHandlingModification; - // If there is no modification on the function, check for a base class. - if (m_class && exceptionHandlingModification == TypeSystem::ExceptionHandling::Unspecified) { - if (auto base = recurseClassHierarchy(m_class, hasExceptionMod)) - exceptionHandlingModification = exceptionMod(base); - } - - bool result = false; - switch (exceptionHandlingModification) { - case TypeSystem::ExceptionHandling::On: - result = true; - break; - case TypeSystem::ExceptionHandling::AutoDefaultToOn: - result = m_exceptionSpecification != ExceptionSpecification::NoExcept; - break; - case TypeSystem::ExceptionHandling::AutoDefaultToOff: - result = m_exceptionSpecification == ExceptionSpecification::Throws; - break; - case TypeSystem::ExceptionHandling::Unspecified: - case TypeSystem::ExceptionHandling::Off: - break; - } - return result; -} - -bool AbstractMetaFunction::isOperatorOverload(const QString &funcName) -{ - if (isConversionOperator(funcName)) - return true; - - static const QRegularExpression opRegEx(QLatin1String("^operator([+\\-\\*/%=&\\|\\^\\<>!][=]?" - "|\\+\\+|\\-\\-|&&|\\|\\||<<[=]?|>>[=]?|~" - "|\\[\\]|\\s+delete\\[?\\]?" - "|\\(\\)" - "|\\s+new\\[?\\]?)$")); - Q_ASSERT(opRegEx.isValid()); - return opRegEx.match(funcName).hasMatch(); -} - -bool AbstractMetaFunction::isCastOperator() const -{ - return originalName().startsWith(QLatin1String("operator ")); -} - -bool AbstractMetaFunction::isArithmeticOperator() const -{ - if (!isOperatorOverload()) - return false; - - QString name = originalName(); - - // It's a dereference operator! - if (name == QLatin1String("operator*") && m_arguments.isEmpty()) - return false; - - return name == QLatin1String("operator+") || name == QLatin1String("operator+=") - || name == QLatin1String("operator-") || name == QLatin1String("operator-=") - || name == QLatin1String("operator*") || name == QLatin1String("operator*=") - || name == QLatin1String("operator/") || name == QLatin1String("operator/=") - || name == QLatin1String("operator%") || name == QLatin1String("operator%=") - || name == QLatin1String("operator++") || name == QLatin1String("operator--"); -} - -bool AbstractMetaFunction::isBitwiseOperator() const -{ - if (!isOperatorOverload()) - return false; - - QString name = originalName(); - return name == QLatin1String("operator<<") || name == QLatin1String("operator<<=") - || name == QLatin1String("operator>>") || name == QLatin1String("operator>>=") - || name == QLatin1String("operator&") || name == QLatin1String("operator&=") - || name == QLatin1String("operator|") || name == QLatin1String("operator|=") - || name == QLatin1String("operator^") || name == QLatin1String("operator^=") - || name == QLatin1String("operator~"); -} - -bool AbstractMetaFunction::isComparisonOperator() const -{ - if (!isOperatorOverload()) - return false; - - QString name = originalName(); - return name == QLatin1String("operator<") || name == QLatin1String("operator<=") - || name == QLatin1String("operator>") || name == QLatin1String("operator>=") - || name == QLatin1String("operator==") || name == QLatin1String("operator!="); -} - -bool AbstractMetaFunction::isLogicalOperator() const -{ - if (!isOperatorOverload()) - return false; - - QString name = originalName(); - return name == QLatin1String("operator!") - || name == QLatin1String("operator&&") - || name == QLatin1String("operator||"); -} - -bool AbstractMetaFunction::isSubscriptOperator() const -{ - if (!isOperatorOverload()) - return false; - - return originalName() == QLatin1String("operator[]"); -} - -bool AbstractMetaFunction::isAssignmentOperator() const -{ - return m_functionType == AssignmentOperatorFunction - || m_functionType == MoveAssignmentOperatorFunction; -} - -bool AbstractMetaFunction::isOtherOperator() const -{ - if (!isOperatorOverload()) - return false; - - return !isArithmeticOperator() - && !isBitwiseOperator() - && !isComparisonOperator() - && !isLogicalOperator() - && !isConversionOperator() - && !isSubscriptOperator() - && !isAssignmentOperator(); -} - -int AbstractMetaFunction::arityOfOperator() const -{ - if (!isOperatorOverload() || isCallOperator()) - return -1; - - int arity = m_arguments.size(); - - // Operator overloads that are class members - // implicitly includes the instance and have - // one parameter less than their arity, - // so we increment it. - if (ownerClass() && arity < 2) - arity++; - - return arity; -} - -bool AbstractMetaFunction::isInplaceOperator() const -{ - if (!isOperatorOverload()) - return false; - - QString name = originalName(); - return name == QLatin1String("operator+=") || name == QLatin1String("operator&=") - || name == QLatin1String("operator-=") || name == QLatin1String("operator|=") - || name == QLatin1String("operator*=") || name == QLatin1String("operator^=") - || name == QLatin1String("operator/=") || name == QLatin1String("operator<<=") - || name == QLatin1String("operator%=") || name == QLatin1String("operator>>="); -} - -bool AbstractMetaFunction::isVirtual() const -{ - return attributes() & AbstractMetaAttributes::VirtualCppMethod; -} - -QString AbstractMetaFunction::modifiedName() const -{ - if (m_cachedModifiedName.isEmpty()) { - const FunctionModificationList &mods = modifications(implementingClass()); - for (const FunctionModification &mod : mods) { - if (mod.isRenameModifier()) { - m_cachedModifiedName = mod.renamedToName; - break; - } - } - if (m_cachedModifiedName.isEmpty()) - m_cachedModifiedName = name(); - } - return m_cachedModifiedName; -} - -bool function_sorter(AbstractMetaFunction *a, AbstractMetaFunction *b) -{ - return a->signature() < b->signature(); -} - -AbstractMetaFunction * -AbstractMetaFunction::find(const AbstractMetaFunctionList &haystack, - const QString &needle) -{ - return findByName(haystack, needle); -} - -#ifndef QT_NO_DEBUG_STREAM -static inline void formatMetaFunctionBrief(QDebug &d, const AbstractMetaFunction *af) -{ - d << '"' << af->debugSignature() << '"'; -} - -void AbstractMetaFunction::formatDebugVerbose(QDebug &d) const -{ - d << m_functionType << ' ' << m_type << ' ' << m_name; - switch (m_exceptionSpecification) { - case ExceptionSpecification::Unknown: - break; - case ExceptionSpecification::NoExcept: - d << " noexcept"; - break; - case ExceptionSpecification::Throws: - d << " throw(...)"; - break; - } - if (m_exceptionHandlingModification != TypeSystem::ExceptionHandling::Unspecified) - d << " exeption-mod " << int(m_exceptionHandlingModification); - d << '('; - for (int i = 0, count = m_arguments.size(); i < count; ++i) { - if (i) - d << ", "; - d << m_arguments.at(i); - } - d << "), signature=\"" << minimalSignature() << '"'; - if (m_constant) - d << " [const]"; - if (m_reverse) - d << " [reverse]"; - if (isUserAdded()) - d << " [userAdded]"; - if (m_explicit) - d << " [explicit]"; - if (attributes().testFlag(AbstractMetaAttributes::Deprecated)) - d << " [deprecated]"; - if (m_pointerOperator) - d << " [operator->]"; - if (m_isCallOperator) - d << " [operator()]"; - if (m_class) - d << " class: " << m_class->name(); - if (m_implementingClass) - d << " implementing class: " << m_implementingClass->name(); - if (m_declaringClass) - d << " declaring class: " << m_declaringClass->name(); -} - -QDebug operator<<(QDebug d, const AbstractMetaFunction *af) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaFunction("; - if (af) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) - if (d.verbosity() > 2) { - af->formatDebugVerbose(d); - } else { -#endif - d << "signature="; - formatMetaFunctionBrief(d, af); -#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) - } -#endif - } else { - d << '0'; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -/******************************************************************************* - * AbstractMetaClass - */ - -AbstractMetaClass::AbstractMetaClass() - : m_hasVirtuals(false), - m_isPolymorphic(false), - m_hasNonpublic(false), - m_hasNonPrivateConstructor(false), - m_hasPrivateConstructor(false), - m_functionsFixed(false), - m_hasPrivateDestructor(false), - m_hasProtectedDestructor(false), - m_hasVirtualDestructor(false), - m_hasHashFunction(false), - m_hasEqualsOperator(false), - m_hasCloneOperator(false), - m_isTypeDef(false), - m_hasToStringCapability(false) -{ -} - -AbstractMetaClass::~AbstractMetaClass() -{ - qDeleteAll(m_functions); - qDeleteAll(m_fields); - qDeleteAll(m_enums); - if (hasTemplateBaseClassInstantiations()) - qDeleteAll(templateBaseClassInstantiations()); -} - -/******************************************************************************* - * 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; -} - -/******************************************************************************* - * Returns a list of all the functions with a given name - */ -AbstractMetaFunctionList AbstractMetaClass::queryFunctionsByName(const QString &name) const -{ - AbstractMetaFunctionList returned; - for (AbstractMetaFunction *function : m_functions) { - if (function->name() == name) - returned.append(function); - } - - return returned; -} - -/******************************************************************************* - * Returns a list of all the functions retrieved during parsing which should - * be added to the API. - */ -AbstractMetaFunctionList AbstractMetaClass::functionsInTargetLang() const -{ - FunctionQueryOptions default_flags = NormalFunctions | Visible | NotRemovedFromTargetLang; - - // Only public functions in final classes - // default_flags |= isFinal() ? WasPublic : 0; - FunctionQueryOptions public_flags; - if (isFinalInTargetLang()) - public_flags |= WasPublic; - - // Constructors - AbstractMetaFunctionList returned = queryFunctions(Constructors | default_flags | public_flags); - - // Final functions - returned += queryFunctions(FinalInTargetLangFunctions | NonStaticFunctions | default_flags | public_flags); - - // Virtual functions - returned += queryFunctions(VirtualInTargetLangFunctions | NonStaticFunctions | default_flags | public_flags); - - // Static functions - returned += queryFunctions(StaticFunctions | default_flags | public_flags); - - // Empty, private functions, since they aren't caught by the other ones - returned += queryFunctions(Empty | Invisible); - - return returned; -} - -AbstractMetaFunctionList AbstractMetaClass::implicitConversions() const -{ - if (!hasCloneOperator() && !hasExternalConversionOperators()) - return AbstractMetaFunctionList(); - - AbstractMetaFunctionList returned; - const AbstractMetaFunctionList list = queryFunctions(Constructors) + externalConversionOperators(); - - // Exclude anything that uses rvalue references, be it a move - // constructor "QPolygon(QPolygon &&)" or something else like - // "QPolygon(QVector<QPoint> &&)". - for (AbstractMetaFunction *f : list) { - if ((f->actualMinimumArgumentCount() == 1 || f->arguments().size() == 1 || f->isConversionOperator()) - && !f->isExplicit() - && f->functionType() != AbstractMetaFunction::CopyConstructorFunction - && !f->usesRValueReferences() - && !f->isModifiedRemoved() - && (f->originalAttributes() & Public)) { - returned += f; - } - } - return returned; -} - -AbstractMetaFunctionList AbstractMetaClass::operatorOverloads(OperatorQueryOptions query) const -{ - const AbstractMetaFunctionList &list = queryFunctions(OperatorOverloads | Visible); - AbstractMetaFunctionList returned; - for (AbstractMetaFunction *f : list) { - if (((query & ArithmeticOp) && f->isArithmeticOperator()) - || ((query & BitwiseOp) && f->isBitwiseOperator()) - || ((query & ComparisonOp) && f->isComparisonOperator()) - || ((query & LogicalOp) && f->isLogicalOperator()) - || ((query & SubscriptionOp) && f->isSubscriptOperator()) - || ((query & AssignmentOp) && f->isAssignmentOperator()) - || ((query & ConversionOp) && f->isConversionOperator()) - || ((query & OtherOp) && f->isOtherOperator())) - returned += f; - } - - return returned; -} - -bool AbstractMetaClass::hasArithmeticOperatorOverload() const -{ - for (const AbstractMetaFunction *f : m_functions) { - if (f->ownerClass() == f->implementingClass() && f->isArithmeticOperator() && !f->isPrivate()) - return true; - } - return false; -} - -bool AbstractMetaClass::hasBitwiseOperatorOverload() const -{ - for (const AbstractMetaFunction *f : m_functions) { - if (f->ownerClass() == f->implementingClass() && f->isBitwiseOperator() && !f->isPrivate()) - return true; - } - return false; -} - -bool AbstractMetaClass::hasComparisonOperatorOverload() const -{ - for (const AbstractMetaFunction *f : m_functions) { - if (f->ownerClass() == f->implementingClass() && f->isComparisonOperator() && !f->isPrivate()) - return true; - } - return false; -} - -bool AbstractMetaClass::hasLogicalOperatorOverload() const -{ - for (const AbstractMetaFunction *f : m_functions) { - if (f->ownerClass() == f->implementingClass() && f->isLogicalOperator() && !f->isPrivate()) - return true; - } - return false; -} - -void AbstractMetaClass::sortFunctions() -{ - std::sort(m_functions.begin(), m_functions.end(), function_sorter); -} - -void AbstractMetaClass::setFunctions(const AbstractMetaFunctionList &functions) -{ - m_functions = functions; - - // Functions must be sorted by name before next loop - sortFunctions(); - - for (AbstractMetaFunction *f : qAsConst(m_functions)) { - f->setOwnerClass(this); - if (!f->isPublic()) - m_hasNonpublic = true; - } -} - -bool AbstractMetaClass::hasFieldAccessors() const -{ - for (const AbstractMetaField *field : m_fields) { - if (field->getter() || field->setter()) - return true; - } - - return false; -} - -bool AbstractMetaClass::hasDefaultToStringFunction() const -{ - const AbstractMetaFunctionList &funcs = queryFunctionsByName(QLatin1String("toString")); - for (const AbstractMetaFunction *f : funcs) { - if (!f->actualMinimumArgumentCount()) - return true; - } - return false; -} - -void AbstractMetaClass::addFunction(AbstractMetaFunction *function) -{ - Q_ASSERT(!function->signature().startsWith(QLatin1Char('('))); - function->setOwnerClass(this); - - if (!function->isDestructor()) - m_functions << function; - else - Q_ASSERT(false); //memory leak - - m_hasVirtuals |= function->isVirtual(); - m_isPolymorphic |= m_hasVirtuals; - m_hasNonpublic |= !function->isPublic(); -} - -bool AbstractMetaClass::hasSignal(const AbstractMetaFunction *other) const -{ - if (!other->isSignal()) - return false; - - for (const AbstractMetaFunction *f : m_functions) { - if (f->isSignal() && f->compareTo(other) & AbstractMetaFunction::EqualName) - return other->modifiedName() == f->modifiedName(); - } - - return false; -} - - -QString AbstractMetaClass::name() const -{ - return m_typeEntry->targetLangEntryName(); -} - -void AbstractMetaClass::addBaseClass(AbstractMetaClass *baseClass) -{ - Q_ASSERT(baseClass); - m_baseClasses.append(baseClass); - m_isPolymorphic |= baseClass->isPolymorphic(); -} - -void AbstractMetaClass::setBaseClass(AbstractMetaClass *baseClass) -{ - if (baseClass) { - m_baseClasses.prepend(baseClass); - m_isPolymorphic |= baseClass->isPolymorphic(); - } -} - -QString AbstractMetaClass::package() const -{ - return m_typeEntry->targetLangPackage(); -} - -bool AbstractMetaClass::isNamespace() const -{ - return m_typeEntry->isNamespace(); -} - -static bool qObjectPredicate(const AbstractMetaClass *c) -{ - return c->qualifiedCppName() == QLatin1String("QObject"); -} - -bool AbstractMetaClass::isQObject() const -{ - return qObjectPredicate(this) || recurseClassHierarchy(this, qObjectPredicate) != nullptr; -} - -QString AbstractMetaClass::qualifiedCppName() const -{ - return m_typeEntry->qualifiedCppName(); -} - -bool AbstractMetaClass::hasFunction(const QString &str) const -{ - return findFunction(str); -} - -const AbstractMetaFunction *AbstractMetaClass::findFunction(const QString &functionName) const -{ - return AbstractMetaFunction::find(m_functions, functionName); -} - -bool AbstractMetaClass::hasProtectedFunctions() const -{ - for (AbstractMetaFunction *func : m_functions) { - if (func->isProtected()) - return true; - } - return false; -} - -bool AbstractMetaClass::hasProtectedFields() const -{ - for (const AbstractMetaField *field : m_fields) { - if (field->isProtected()) - return true; - } - return false; -} - -bool AbstractMetaClass::hasProtectedMembers() const -{ - return hasProtectedFields() || hasProtectedFunctions(); -} - -QPropertySpec *AbstractMetaClass::propertySpecForRead(const QString &name) const -{ - for (const auto &propertySpec : m_propertySpecs) { - if (name == propertySpec->read()) - return propertySpec; - } - return nullptr; -} - -QPropertySpec *AbstractMetaClass::propertySpecForWrite(const QString &name) const -{ - for (const auto &propertySpec : m_propertySpecs) { - if (name == propertySpec->write()) - return propertySpec; - } - return nullptr; -} - -QPropertySpec *AbstractMetaClass::propertySpecForReset(const QString &name) const -{ - for (const auto &propertySpec : m_propertySpecs) { - if (name == propertySpec->reset()) - return propertySpec; - } - return nullptr; -} - -using AbstractMetaClassBaseTemplateInstantiationsMap = QHash<const AbstractMetaClass *, AbstractMetaTypeList>; -Q_GLOBAL_STATIC(AbstractMetaClassBaseTemplateInstantiationsMap, metaClassBaseTemplateInstantiations); - -bool AbstractMetaClass::hasTemplateBaseClassInstantiations() const -{ - if (!templateBaseClass()) - return false; - return metaClassBaseTemplateInstantiations()->contains(this); -} - -AbstractMetaTypeList AbstractMetaClass::templateBaseClassInstantiations() const -{ - if (!templateBaseClass()) - return AbstractMetaTypeList(); - return metaClassBaseTemplateInstantiations()->value(this); -} - -void AbstractMetaClass::setTemplateBaseClassInstantiations(AbstractMetaTypeList &instantiations) -{ - if (!templateBaseClass()) - return; - metaClassBaseTemplateInstantiations()->insert(this, instantiations); -} - -// Does any of the base classes require deletion in the main thread? -bool AbstractMetaClass::deleteInMainThread() const -{ - return typeEntry()->deleteInMainThread() - || (!m_baseClasses.isEmpty() && m_baseClasses.constFirst()->deleteInMainThread()); -} - -static bool functions_contains(const AbstractMetaFunctionList &l, const AbstractMetaFunction *func) -{ - for (const AbstractMetaFunction *f : l) { - if ((f->compareTo(func) & AbstractMetaFunction::PrettySimilar) == AbstractMetaFunction::PrettySimilar) - return true; - } - return false; -} - -AbstractMetaField::AbstractMetaField() = default; - -AbstractMetaField::~AbstractMetaField() -{ - delete m_setter; - delete m_getter; -} - -AbstractMetaField *AbstractMetaField::copy() const -{ - auto *returned = new AbstractMetaField; - returned->assignMetaVariable(*this); - returned->assignMetaAttributes(*this); - returned->setEnclosingClass(nullptr); - return returned; -} - -AbstractMetaField *AbstractMetaField::find(const AbstractMetaFieldList &haystack, - const QString &needle) -{ - return findByName(haystack, needle); -} -/******************************************************************************* - * Indicates that this field has a modification that removes it - */ -bool AbstractMetaField::isModifiedRemoved(int types) const -{ - const FieldModificationList &mods = modifications(); - for (const FieldModification &mod : mods) { - if (!mod.isRemoveModifier()) - continue; - - if ((mod.removal & types) == types) - return true; - } - - return false; -} - -static QString upCaseFirst(const QString &str) -{ - Q_ASSERT(!str.isEmpty()); - QString s = str; - s[0] = s.at(0).toUpper(); - return s; -} - -static AbstractMetaFunction *createXetter(const AbstractMetaField *g, const QString &name, - AbstractMetaAttributes::Attributes type) -{ - auto *f = new AbstractMetaFunction; - - f->setName(name); - f->setOriginalName(name); - f->setOwnerClass(g->enclosingClass()); - f->setImplementingClass(g->enclosingClass()); - f->setDeclaringClass(g->enclosingClass()); - - AbstractMetaAttributes::Attributes attr = AbstractMetaAttributes::FinalInTargetLang | type; - if (g->isStatic()) - attr |= AbstractMetaAttributes::Static; - if (g->isPublic()) - attr |= AbstractMetaAttributes::Public; - else if (g->isProtected()) - attr |= AbstractMetaAttributes::Protected; - else - attr |= AbstractMetaAttributes::Private; - f->setAttributes(attr); - f->setOriginalAttributes(attr); - - const FieldModificationList &mods = g->modifications(); - for (const FieldModification &mod : mods) { - if (mod.isRenameModifier()) - f->setName(mod.renamedTo()); - if (mod.isAccessModifier()) { - if (mod.isPrivate()) - f->setVisibility(AbstractMetaAttributes::Private); - else if (mod.isProtected()) - f->setVisibility(AbstractMetaAttributes::Protected); - else if (mod.isPublic()) - f->setVisibility(AbstractMetaAttributes::Public); - else if (mod.isFriendly()) - f->setVisibility(AbstractMetaAttributes::Friendly); - } - } - return f; -} - -FieldModificationList AbstractMetaField::modifications() const -{ - const FieldModificationList &mods = enclosingClass()->typeEntry()->fieldModifications(); - FieldModificationList returned; - - for (const FieldModification &mod : mods) { - if (mod.name == name()) - returned += mod; - } - - return returned; -} - -const AbstractMetaFunction *AbstractMetaField::setter() const -{ - if (!m_setter) { - m_setter = createXetter(this, - QLatin1String("set") + upCaseFirst(name()), - AbstractMetaAttributes::SetterFunction); - AbstractMetaArgumentList arguments; - auto *argument = new AbstractMetaArgument; - argument->setType(type()->copy()); - argument->setName(name()); - arguments.append(argument); - m_setter->setArguments(arguments); - } - return m_setter; -} - -const AbstractMetaClass *EnclosingClassMixin::targetLangEnclosingClass() const -{ - auto result = m_enclosingClass; - while (result && !NamespaceTypeEntry::isVisibleScope(result->typeEntry())) - result = result->enclosingClass(); - return result; -} - -const AbstractMetaFunction *AbstractMetaField::getter() const -{ - if (!m_getter) { - m_getter = createXetter(this, - name(), - AbstractMetaAttributes::GetterFunction); - m_getter->setType(type()); - } - - return m_getter; -} - -#ifndef QT_NO_DEBUG_STREAM -static void formatMetaAttributes(QDebug &d, AbstractMetaAttributes::Attributes value) -{ - static const int meIndex = AbstractMetaAttributes::staticMetaObject.indexOfEnumerator("Attribute"); - Q_ASSERT(meIndex >= 0); - const QMetaEnum me = AbstractMetaAttributes::staticMetaObject.enumerator(meIndex); - d << me.valueToKeys(value); -} - -static void formatMetaField(QDebug &d, const AbstractMetaField *af) -{ - formatMetaAttributes(d, af->attributes()); - d << ' ' << af->type()->name() << " \"" << af->name() << '"'; -} - -QDebug operator<<(QDebug d, const AbstractMetaField *af) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaField("; - if (af) - formatMetaField(d, af); - else - d << '0'; - d << ')'; - return d; -} - -static void formatMetaEnumValue(QDebug &d, const AbstractMetaEnumValue *v) -{ - const QString &name = v->stringValue(); - if (!name.isEmpty()) - d << name << '='; - d << v->value(); -} - -QDebug operator<<(QDebug d, const AbstractMetaEnumValue *v) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaEnumValue("; - if (v) - formatMetaEnumValue(d, v); - else - d << '0'; - d << ')'; - return d; -} - -QDebug operator<<(QDebug d, const AbstractMetaEnum *ae) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaEnum("; - if (ae) { - d << ae->fullName(); - if (!ae->isSigned()) - d << " (unsigned) "; - d << '['; - const AbstractMetaEnumValueList &values = ae->values(); - for (int i = 0, count = values.size(); i < count; ++i) { - if (i) - d << ' '; - formatMetaEnumValue(d, values.at(i)); - } - d << ']'; - } else { - d << '0'; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -bool AbstractMetaClass::hasConstructors() const -{ - return AbstractMetaClass::queryFirstFunction(m_functions, Constructors) != nullptr; -} - -const AbstractMetaFunction *AbstractMetaClass::copyConstructor() const -{ - for (const AbstractMetaFunction *f : m_functions) { - if (f->functionType() == AbstractMetaFunction::CopyConstructorFunction) - return f; - } - return nullptr; -} - -bool AbstractMetaClass::hasPrivateCopyConstructor() const -{ - const AbstractMetaFunction *copyCt = copyConstructor(); - return copyCt && copyCt->isPrivate(); -} - -void AbstractMetaClass::addDefaultConstructor() -{ - auto *f = new AbstractMetaFunction; - f->setOriginalName(name()); - f->setName(name()); - f->setOwnerClass(this); - f->setFunctionType(AbstractMetaFunction::ConstructorFunction); - f->setArguments(AbstractMetaArgumentList()); - f->setDeclaringClass(this); - - f->setAttributes(Public | FinalInTargetLang | AddedMethod); - f->setImplementingClass(this); - f->setOriginalAttributes(f->attributes()); - - addFunction(f); - this->setHasNonPrivateConstructor(true); -} - -void AbstractMetaClass::addDefaultCopyConstructor(bool isPrivate) -{ - auto f = new AbstractMetaFunction; - f->setOriginalName(name()); - f->setName(name()); - f->setOwnerClass(this); - f->setFunctionType(AbstractMetaFunction::CopyConstructorFunction); - f->setDeclaringClass(this); - - auto argType = new AbstractMetaType; - argType->setTypeEntry(typeEntry()); - argType->setReferenceType(LValueReference); - argType->setConstant(true); - argType->setTypeUsagePattern(AbstractMetaType::ValuePattern); - - auto arg = new AbstractMetaArgument; - arg->setType(argType); - arg->setName(name()); - f->addArgument(arg); - - AbstractMetaAttributes::Attributes attr = FinalInTargetLang | AddedMethod; - if (isPrivate) - attr |= AbstractMetaAttributes::Private; - else - attr |= AbstractMetaAttributes::Public; - f->setAttributes(attr); - f->setImplementingClass(this); - f->setOriginalAttributes(f->attributes()); - - addFunction(f); -} - -void AbstractMetaClass::setHasVirtualDestructor(bool value) -{ - m_hasVirtualDestructor = value; - if (value) - m_hasVirtuals = m_isPolymorphic = 1; -} - -bool AbstractMetaClass::hasFunction(const AbstractMetaFunction *f) const -{ - return functions_contains(m_functions, f); -} - -bool AbstractMetaClass::generateExceptionHandling() const -{ - return queryFirstFunction(m_functions, AbstractMetaClass::Visible - | AbstractMetaClass::GenerateExceptionHandling) != nullptr; -} -/* Goes through the list of functions and returns a list of all - functions matching all of the criteria in \a query. - */ - -bool AbstractMetaClass::queryFunction(const AbstractMetaFunction *f, FunctionQueryOptions query) -{ - if ((query & NotRemovedFromTargetLang) - && f->isRemovedFrom(f->implementingClass(), TypeSystem::TargetLangCode)) { - return false; - } - - if ((query & NotRemovedFromTargetLang) && f->isVirtual() - && f->isRemovedFrom(f->declaringClass(), TypeSystem::TargetLangCode)) { - return false; - } - - if ((query & Visible) && f->isPrivate()) - return false; - - if ((query & VirtualInTargetLangFunctions) && f->isFinalInTargetLang()) - return false; - - if ((query & Invisible) && !f->isPrivate()) - return false; - - if ((query & Empty) && !f->isEmptyFunction()) - return false; - - if ((query & WasPublic) && !f->wasPublic()) - return false; - - if ((query & ClassImplements) && f->ownerClass() != f->implementingClass()) - return false; - - if ((query & FinalInTargetLangFunctions) && !f->isFinalInTargetLang()) - return false; - - if ((query & VirtualInCppFunctions) && !f->isVirtual()) - return false; - - if ((query & Signals) && (!f->isSignal())) - return false; - - if ((query & Constructors) && (!f->isConstructor() || f->ownerClass() != f->implementingClass())) - return false; - - if (!(query & Constructors) && f->isConstructor()) - return false; - - // Destructors are never included in the functions of a class currently - /* - if ((query & Destructors) && (!f->isDestructor() - || f->ownerClass() != f->implementingClass()) - || f->isDestructor() && (query & Destructors) == 0) { - return false; - }*/ - - if ((query & StaticFunctions) && (!f->isStatic() || f->isSignal())) - return false; - - if ((query & NonStaticFunctions) && (f->isStatic())) - return false; - - if ((query & NormalFunctions) && (f->isSignal())) - return false; - - if ((query & OperatorOverloads) && !f->isOperatorOverload()) - return false; - - if ((query & GenerateExceptionHandling) && !f->generateExceptionHandling()) - return false; - - if (query.testFlag(GetAttroFunction) - && f->functionType() != AbstractMetaFunction::GetAttroFunction) { - return false; - } - - if (query.testFlag(SetAttroFunction) - && f->functionType() != AbstractMetaFunction::SetAttroFunction) { - return false; - } - - return true; -} - -AbstractMetaFunctionList AbstractMetaClass::queryFunctionList(const AbstractMetaFunctionList &list, - FunctionQueryOptions query) -{ - AbstractMetaFunctionList result; - for (AbstractMetaFunction *f : list) { - if (queryFunction(f, query)) - result.append(f); - } - return result; -} - -const AbstractMetaFunction *AbstractMetaClass::queryFirstFunction(const AbstractMetaFunctionList &list, - FunctionQueryOptions query) -{ - AbstractMetaFunctionList result; - for (AbstractMetaFunction *f : list) { - if (queryFunction(f, query)) - return f; - } - return nullptr; -} - -AbstractMetaFunctionList AbstractMetaClass::queryFunctions(FunctionQueryOptions query) const -{ - return AbstractMetaClass::queryFunctionList(m_functions, query); -} - -bool AbstractMetaClass::hasSignals() const -{ - return queryFirstFunction(m_functions, Signals | Visible | NotRemovedFromTargetLang) != nullptr; -} - -AbstractMetaFunctionList AbstractMetaClass::cppSignalFunctions() const -{ - return queryFunctions(Signals | Visible | NotRemovedFromTargetLang); -} - -AbstractMetaField *AbstractMetaClass::findField(const QString &name) const -{ - return AbstractMetaField::find(m_fields, name); -} - -AbstractMetaEnum *AbstractMetaClass::findEnum(const QString &enumName) -{ - if (AbstractMetaEnum *e = findByName(m_enums, enumName)) - return e; - return nullptr; -} - -/*! Recursively searches for the enum value named \a enumValueName in - this class and its superclasses and interfaces. -*/ -AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const QString &enumValueName) -{ - for (AbstractMetaEnum *e : qAsConst(m_enums)) { - if (AbstractMetaEnumValue *v = e->findEnumValue(enumValueName)) - return v; - } - if (baseClass()) - return baseClass()->findEnumValue(enumValueName); - - return nullptr; -} - - -static void addExtraIncludeForType(AbstractMetaClass *metaClass, const AbstractMetaType *type) -{ - if (!type) - return; - - Q_ASSERT(metaClass); - const TypeEntry *entry = (type ? type->typeEntry() : nullptr); - 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()); - } - - if (type->hasInstantiations()) { - const AbstractMetaTypeList &instantiations = type->instantiations(); - for (const AbstractMetaType *instantiation : instantiations) - addExtraIncludeForType(metaClass, instantiation); - } -} - -static void addExtraIncludesForFunction(AbstractMetaClass *metaClass, const AbstractMetaFunction *meta_function) -{ - Q_ASSERT(metaClass); - Q_ASSERT(meta_function); - addExtraIncludeForType(metaClass, meta_function->type()); - - const AbstractMetaArgumentList &arguments = meta_function->arguments(); - for (AbstractMetaArgument *argument : arguments) - addExtraIncludeForType(metaClass, argument->type()); -} - -void AbstractMetaClass::fixFunctions() -{ - if (m_functionsFixed) - return; - - m_functionsFixed = true; - - AbstractMetaFunctionList funcs = functions(); - - for (auto superClass : m_baseClasses) { - superClass->fixFunctions(); - // 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. - AbstractMetaFunctionList 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 -= AbstractMetaAttributes::FinalInTargetLang; - } - superFuncs = superClass->queryFunctions(AbstractMetaClass::ClassImplements); - AbstractMetaFunctionList virtuals = superClass->queryFunctions(AbstractMetaClass::VirtualInCppFunctions); - superFuncs += virtuals; - - QSet<AbstractMetaFunction *> funcsToAdd; - for (auto sf : qAsConst(superFuncs)) { - if (sf->isRemovedFromAllLanguages(sf->implementingClass())) - continue; - - // skip functions added in base classes - if (sf->isUserAdded() && sf->declaringClass() != this) - continue; - - // 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 = (sf->isNormal() || sf->isSignal() || sf->isEmptyFunction()); - for (AbstractMetaFunction *f : funcs) { - if (f->isRemovedFromAllLanguages(f->implementingClass())) - continue; - - - const AbstractMetaFunction::CompareResult cmp = f->compareTo(sf); - - 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 -= AbstractMetaAttributes::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 - } - } - - if (f->visibility() != sf->visibility()) { - QString warn = QStringLiteral("visibility of function '%1' modified in class '%2'") - .arg(f->name(), name()); - qCWarning(lcShiboken).noquote().nospace() << warn; -#if 0 - // If new visibility is private, we can't - // do anything. If it isn't, then we - // prefer the parent class's visibility - // setting for the function. - if (!f->isPrivate() && !sf->isPrivate()) - f->setVisibility(sf->visibility()); -#endif - // 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()) { - f->setFunctionType(AbstractMetaFunction::EmptyFunction); - *f += AbstractMetaAttributes::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).noquote().nospace() - << QStringLiteral("Shadowing: %1::%2 and %3::%4") - .arg(sf->implementingClass()->name(), sf->signature(), - f->implementingClass()->name(), f->signature()); - } - } - } - - } - - if (cmp & AbstractMetaFunction::EqualDefaultValueOverload) { - AbstractMetaArgumentList arguments; - if (f->arguments().size() < sf->arguments().size()) - arguments = sf->arguments(); - else - arguments = f->arguments(); - //TODO: fix this - //for (int i=0; i<arguments.size(); ++i) - // arguments[i]->setDefaultValueExpression("<#>" + QString()); - } - - - // Otherwise we have function shadowing and we can - // skip the thing... - } else if (cmp & AbstractMetaFunction::EqualName && !sf->isSignal()) { - // In the case of function shadowing where the function name has been altered to - // avoid conflict, we don't copy in the original. - add = false; - } - } - - if (add) - funcsToAdd << sf; - } - - for (AbstractMetaFunction *f : qAsConst(funcsToAdd)) { - AbstractMetaFunction *copy = f->copy(); - (*copy) += AddedMethod; - funcs.append(copy); - } - } - - bool hasPrivateConstructors = false; - bool hasPublicConstructors = false; - for (AbstractMetaFunction *func : qAsConst(funcs)) { - const FunctionModificationList &mods = func->modifications(this); - for (const FunctionModification &mod : mods) { - if (mod.isRenameModifier()) { - func->setName(mod.renamedTo()); - } - } - - // Make sure class is abstract if one of the functions is - if (func->isAbstract()) { - (*this) += AbstractMetaAttributes::Abstract; - (*this) -= AbstractMetaAttributes::FinalInTargetLang; - } - - if (func->isConstructor()) { - if (func->isPrivate()) - hasPrivateConstructors = true; - else - hasPublicConstructors = true; - } - - - - // Make sure that we include files for all classes that are in use - - if (!func->isRemovedFrom(this, TypeSystem::ShellCode)) - addExtraIncludesForFunction(this, func); - } - - if (hasPrivateConstructors && !hasPublicConstructors) { - (*this) += AbstractMetaAttributes::Abstract; - (*this) -= AbstractMetaAttributes::FinalInTargetLang; - } - - setFunctions(funcs); -} - -static inline QString formatArraySize(int e) -{ - QString result; - result += QLatin1Char('['); - if (e >= 0) - result += QString::number(e); - result += QLatin1Char(']'); - return result; -} - -QString AbstractMetaType::formatSignature(bool minimal) const -{ - QString result; - if (isConstant()) - result += QLatin1String("const "); - if (isVolatile()) - result += QLatin1String("volatile "); - if (isArray()) { - // Build nested array dimensions a[2][3] in correct order - result += m_arrayElementType->minimalSignature(); - const int arrayPos = result.indexOf(QLatin1Char('[')); - if (arrayPos != -1) - result.insert(arrayPos, formatArraySize(m_arrayElementCount)); - else - result.append(formatArraySize(m_arrayElementCount)); - } else { - result += typeEntry()->qualifiedCppName(); - } - if (!m_instantiations.isEmpty()) { - result += QLatin1Char('<'); - if (minimal) - result += QLatin1Char(' '); - for (int i = 0, size = m_instantiations.size(); i < size; ++i) { - if (i > 0) - result += QLatin1Char(','); - result += m_instantiations.at(i)->minimalSignature(); - } - result += QLatin1String(" >"); - } - - if (!minimal && (!m_indirections.isEmpty() || m_referenceType != NoReference)) - result += QLatin1Char(' '); - for (Indirection i : m_indirections) - result += TypeInfo::indirectionKeyword(i); - switch (referenceType()) { - case NoReference: - break; - case LValueReference: - result += QLatin1Char('&'); - break; - case RValueReference: - result += QLatin1String("&&"); - break; - } - return result; -} - -QString AbstractMetaType::formatPythonSignature() const -{ - /* - * This is a version of the above, more suitable for Python. - * We avoid extra keywords that are not needed in Python. - * We prepend the package name, unless it is a primitive type. - * - * Primitive types like 'int', 'char' etc.: - * When we have a primitive with an indirection, we use that '*' - * character for later postprocessing, since those indirections - * need to be modified into a result tuple. - */ - QString result; - if (m_pattern == AbstractMetaType::NativePointerAsArrayPattern) - result += QLatin1String("array "); - // We no longer use the "const" qualifier for heuristics. Instead, - // NativePointerAsArrayPattern indicates when we have <array> in XML. - // if (m_typeEntry->isPrimitive() && isConstant()) - // result += QLatin1String("const "); - if (!m_typeEntry->isPrimitive() && !package().isEmpty()) - result += package() + QLatin1Char('.'); - if (isArray()) { - // Build nested array dimensions a[2][3] in correct order - result += m_arrayElementType->formatPythonSignature(); - const int arrayPos = result.indexOf(QLatin1Char('[')); - if (arrayPos != -1) - result.insert(arrayPos, formatArraySize(m_arrayElementCount)); - else - result.append(formatArraySize(m_arrayElementCount)); - } else { - result += typeEntry()->targetLangName(); - } - if (!m_instantiations.isEmpty()) { - result += QLatin1Char('['); - for (int i = 0, size = m_instantiations.size(); i < size; ++i) { - if (i > 0) - result += QLatin1String(", "); - result += m_instantiations.at(i)->formatPythonSignature(); - } - result += QLatin1Char(']'); - } - 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: - // "PySide2.QtCore.Qt.ItemFlags" instead of "PySide2.QtCore.QFlags<Qt.ItemFlag>" - if (m_typeEntry->isFlags()) - result = fullName(); - result.replace(QLatin1String("::"), QLatin1String(".")); - return result; -} - -bool AbstractMetaType::isCppPrimitive() const -{ - return m_pattern == PrimitivePattern && m_typeEntry->isCppPrimitive(); -} - -/******************************************************************************* - * Other stuff... - */ - - -AbstractMetaEnum *AbstractMetaClass::findEnum(const AbstractMetaClassList &classes, - const EnumTypeEntry *entry) -{ - Q_ASSERT(entry->isEnum()); - - QString qualifiedName = entry->qualifiedCppName(); - int pos = qualifiedName.lastIndexOf(QLatin1String("::")); - - QString enumName; - QString className; - - if (pos > 0) { - enumName = qualifiedName.mid(pos + 2); - className = qualifiedName.mid(0, pos); - } else { - enumName = qualifiedName; - className = TypeDatabase::globalNamespaceClassName(entry); - } - - AbstractMetaClass *metaClass = AbstractMetaClass::findClass(classes, className); - if (!metaClass) { - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("AbstractMeta::findEnum(), unknown class '%1' in '%2'") - .arg(className, entry->qualifiedCppName()); - return nullptr; - } - - return metaClass->findEnum(enumName); -} - -AbstractMetaEnumValue *AbstractMetaClass::findEnumValue(const AbstractMetaClassList &classes, - const QString &name) -{ - const QVector<QStringRef> lst = name.splitRef(QLatin1String("::")); - - if (lst.size() > 1) { - const QStringRef &prefixName = lst.at(0); - const QStringRef &enumName = lst.at(1); - if (AbstractMetaClass *cl = findClass(classes, prefixName.toString())) - return cl->findEnumValue(enumName.toString()); - } - - for (AbstractMetaClass *metaClass : classes) { - if (AbstractMetaEnumValue *enumValue = metaClass->findEnumValue(name)) - return enumValue; - } - - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("no matching enum '%1'").arg(name); - return nullptr; -} - -/*! - * Searches the list after a class that mathces \a name; either as - * C++, Target language base name or complete Target language package.class name. - */ - -AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &classes, - const QString &name) -{ - if (name.isEmpty()) - return nullptr; - - for (AbstractMetaClass *c : classes) { - if (c->qualifiedCppName() == name) - return c; - } - - for (AbstractMetaClass *c : classes) { - if (c->fullName() == name) - return c; - } - - for (AbstractMetaClass *c : classes) { - if (c->name() == name) - return c; - } - - return nullptr; -} - -AbstractMetaClass *AbstractMetaClass::findClass(const AbstractMetaClassList &classes, - const TypeEntry *typeEntry) -{ - for (AbstractMetaClass *c : classes) { - if (c->typeEntry() == typeEntry) - return c; - } - return nullptr; -} - -#ifndef QT_NO_DEBUG_STREAM - -void AbstractMetaClass::format(QDebug &d) const -{ - if (d.verbosity() > 2) - d << static_cast<const void *>(this) << ", "; - d << '"' << qualifiedCppName(); - if (const int count = m_templateArgs.size()) { - for (int i = 0; i < count; ++i) - d << (i ? ',' : '<') << m_templateArgs.at(i)->qualifiedCppName(); - d << '>'; - } - d << '"'; - if (isNamespace()) - d << " [namespace]"; - if (attributes() & AbstractMetaAttributes::FinalCppClass) - d << " [final]"; - if (attributes().testFlag(AbstractMetaAttributes::Deprecated)) - d << " [deprecated]"; - if (!m_baseClasses.isEmpty()) { - d << ", inherits "; - for (auto b : m_baseClasses) - d << " \"" << b->name() << '"'; - } - if (auto templateBase = templateBaseClass()) { - const auto instantiatedTypes = templateBaseClassInstantiations(); - d << ", instantiates \"" << templateBase->name(); - for (int i = 0, count = instantiatedTypes.size(); i < count; ++i) - d << (i ? ',' : '<') << instantiatedTypes.at(i)->name(); - d << ">\""; - } -} - -void AbstractMetaClass::formatMembers(QDebug &d) const -{ - if (!m_enums.isEmpty()) - d << ", enums[" << m_enums.size() << "]=" << m_enums; - if (!m_functions.isEmpty()) { - const int count = m_functions.size(); - d << ", functions=[" << count << "]("; - for (int i = 0; i < count; ++i) { - if (i) - d << ", "; - formatMetaFunctionBrief(d, m_functions.at(i)); - } - d << ')'; - } - if (const int count = m_fields.size()) { - d << ", fields=[" << count << "]("; - for (int i = 0; i < count; ++i) { - if (i) - d << ", "; - formatMetaField(d, m_fields.at(i)); - } - d << ')'; - } -} - -SourceLocation AbstractMetaClass::sourceLocation() const -{ - return m_sourceLocation; -} - -void AbstractMetaClass::setSourceLocation(const SourceLocation &sourceLocation) -{ - m_sourceLocation = sourceLocation; -} - -QDebug operator<<(QDebug d, const AbstractMetaClass *ac) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "AbstractMetaClass("; - if (ac) { - ac->format(d); - if (d.verbosity() > 2) - ac->formatMembers(d); - } else { - d << '0'; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -/******************************************************************************* -* AbstractMetaEnum -*/ - -AbstractMetaEnum::AbstractMetaEnum() : - m_hasQenumsDeclaration(false), m_signed(true) -{ -} - -AbstractMetaEnum::~AbstractMetaEnum() -{ - qDeleteAll(m_enumValues); -} - -template <class String> -AbstractMetaEnumValue *findMatchingEnumValue(const AbstractMetaEnumValueList &list, const String &value) -{ - for (AbstractMetaEnumValue *enumValue : list) { - if (enumValue->name() == value) - return enumValue; - } - return nullptr; -} - -// Find enum values for "enum Enum { e1 }" either for "e1" or "Enum::e1" -AbstractMetaEnumValue *AbstractMetaEnum::findEnumValue(const QString &value) const -{ - if (isAnonymous()) - return findMatchingEnumValue(m_enumValues, value); - const int sepPos = value.indexOf(QLatin1String("::")); - if (sepPos == -1) - return findMatchingEnumValue(m_enumValues, value); - return name() == value.leftRef(sepPos) - ? findMatchingEnumValue(m_enumValues, value.rightRef(value.size() - sepPos - 2)) - : nullptr; -} - -QString AbstractMetaEnum::name() const -{ - return m_typeEntry->targetLangEntryName(); -} - -QString AbstractMetaEnum::qualifier() const -{ - return m_typeEntry->targetLangQualifier(); -} - -QString AbstractMetaEnum::package() const -{ - return m_typeEntry->targetLangPackage(); -} diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang.h b/sources/shiboken2/ApiExtractor/abstractmetalang.h deleted file mode 100644 index 830631e68..000000000 --- a/sources/shiboken2/ApiExtractor/abstractmetalang.h +++ /dev/null @@ -1,1820 +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 ABSTRACTMETALANG_H -#define ABSTRACTMETALANG_H - -#include "abstractmetalang_typedefs.h" -#include "sourcelocation.h" -#include "typesystem_enums.h" -#include "typesystem_typedefs.h" - -#include "parser/codemodel_enums.h" -#include "parser/enumvalue.h" - -#include <QtCore/qobjectdefs.h> -#include <QtCore/QStringList> - -QT_FORWARD_DECLARE_CLASS(QDebug) - -class AbstractMeta; -class AbstractMetaClass; -class AbstractMetaField; -class AbstractMetaFunction; -class AbstractMetaType; -class AbstractMetaVariable; -class AbstractMetaArgument; -class AbstractMetaEnumValue; -class AbstractMetaEnum; -class QPropertySpec; - -class CodeSnip; -class ComplexTypeEntry; -class EnumTypeEntry; -class FlagsTypeEntry; -class FunctionTypeEntry; -class TypeEntry; - -struct ArgumentOwner; -struct FieldModification; -struct FunctionModification; -struct ReferenceCount; - -class Documentation -{ -public: - enum Format { - Native, - Target - }; - - Documentation() = default; - - Documentation(const QString& value, Format fmt = Documentation::Native) - : m_data(value.trimmed()), m_format(fmt) {} - - bool isEmpty() const { return m_data.isEmpty(); } - - QString value() const - { - return m_data; - } - - void setValue(const QString& value, Format fmt = Documentation::Native) - { - m_data = value.trimmed(); - m_format = fmt; - } - - Documentation::Format format() const - { - return m_format; - } - - void setFormat(Format f) { m_format = f; } - -private: - QString m_data; - Format m_format = Documentation::Native; - -}; - -class AbstractMetaAttributes -{ - Q_GADGET -public: - Q_DISABLE_COPY(AbstractMetaAttributes) - - AbstractMetaAttributes(); - virtual ~AbstractMetaAttributes(); - - enum Attribute { - None = 0x00000000, - - Private = 0x00000001, - Protected = 0x00000002, - Public = 0x00000004, - Friendly = 0x00000008, - Visibility = 0x0000000f, - - Abstract = 0x00000020, - Static = 0x00000040, - - FinalInTargetLang = 0x00000080, - - GetterFunction = 0x00000400, - SetterFunction = 0x00000800, - - PropertyReader = 0x00004000, - PropertyWriter = 0x00008000, - PropertyResetter = 0x00010000, - - Invokable = 0x00040000, - - HasRejectedConstructor = 0x00080000, - HasRejectedDefaultConstructor = 0x00100000, - - FinalCppClass = 0x00200000, - VirtualCppMethod = 0x00400000, - OverriddenCppMethod = 0x00800000, - FinalCppMethod = 0x01000000, - // Add by meta builder (implicit constructors, inherited methods, etc) - AddedMethod = 0x02000000, - Deprecated = 0x04000000 - }; - Q_DECLARE_FLAGS(Attributes, Attribute) - Q_FLAG(Attribute) - - Attributes attributes() const - { - return m_attributes; - } - - void setAttributes(Attributes attributes) - { - m_attributes = attributes; - } - - Attributes originalAttributes() const - { - return m_originalAttributes; - } - - void setOriginalAttributes(Attributes attributes) - { - m_originalAttributes = attributes; - } - - Attributes visibility() const - { - return m_attributes & Visibility; - } - - void setVisibility(Attributes visi) - { - m_attributes = (m_attributes & ~Visibility) | visi; - } - - void operator+=(Attribute attribute) - { - m_attributes |= attribute; - } - - void operator-=(Attribute attribute) - { - m_attributes &= ~attribute; - } - - bool isFinalInTargetLang() const - { - return m_attributes & FinalInTargetLang; - } - - bool isAbstract() const - { - return m_attributes & Abstract; - } - - bool isStatic() const - { - return m_attributes & Static; - } - - bool isInvokable() const - { - return m_attributes & Invokable; - } - - bool isPropertyReader() const - { - return m_attributes & PropertyReader; - } - - bool isPropertyWriter() const - { - return m_attributes & PropertyWriter; - } - - bool isPropertyResetter() const - { - return m_attributes & PropertyResetter; - } - - bool isPrivate() const - { - return m_attributes & Private; - } - - bool isProtected() const - { - return m_attributes & Protected; - } - - bool isPublic() const - { - return m_attributes & Public; - } - - bool isFriendly() const - { - return m_attributes & Friendly; - } - - bool wasPrivate() const - { - return m_originalAttributes & Private; - } - - bool wasPublic() const - { - return m_originalAttributes & Public; - } - - void setDocumentation(const Documentation& doc) - { - m_doc = doc; - } - - Documentation documentation() const - { - return m_doc; - } - -protected: - void assignMetaAttributes(const AbstractMetaAttributes &other); - -private: - Attributes m_attributes; - Attributes m_originalAttributes; - Documentation m_doc; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaAttributes::Attributes) - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaAttributes *aa); -#endif - -class AbstractMetaType -{ - Q_GADGET -public: - using Indirections = QVector<Indirection>; - - enum TypeUsagePattern { - InvalidPattern, - PrimitivePattern, - FlagsPattern, - EnumPattern, - ValuePattern, - ObjectPattern, - ValuePointerPattern, - NativePointerPattern, - NativePointerAsArrayPattern, // "int*" as "int[]" - ContainerPattern, - SmartPointerPattern, - VarargsPattern, - ArrayPattern - }; - Q_ENUM(TypeUsagePattern) - - enum ComparisonFlag { - ConstRefMatchesValue = 0x1 - }; - Q_DECLARE_FLAGS(ComparisonFlags, ComparisonFlag); - - AbstractMetaType(); - ~AbstractMetaType(); - - QString package() const; - QString name() const; - QString fullName() const; - - void setTypeUsagePattern(TypeUsagePattern pattern) - { - m_pattern = pattern; - } - TypeUsagePattern typeUsagePattern() const - { - return m_pattern; - } - - // true when use pattern is container - bool hasInstantiations() const - { - return !m_instantiations.isEmpty(); - } - - void addInstantiation(AbstractMetaType* inst, bool owner = false) - { - if (owner) - m_children << inst; - m_instantiations << inst; - } - - void setInstantiations(const AbstractMetaTypeList &insts, bool owner = false) - { - m_instantiations = insts; - if (owner) { - m_children.clear(); - m_children = insts; - } - } - - AbstractMetaTypeList instantiations() const - { - return m_instantiations; - } - - void setInstantiationInCpp(bool incpp) - { - m_cppInstantiation = incpp; - } - - QString minimalSignature() const { return formatSignature(true); } - - // returns true if the typs is used as a non complex primitive, no & or *'s - bool isPrimitive() const - { - return m_pattern == PrimitivePattern; - } - - bool isCppPrimitive() const; - - // returns true if the type is used as an enum - bool isEnum() const - { - return m_pattern == EnumPattern; - } - - // returns true if the type is used as an object, e.g. Xxx * - bool isObject() const - { - return m_pattern == ObjectPattern; - } - - // returns true if the type is used as an array, e.g. Xxx[42] - bool isArray() const - { - return m_pattern == ArrayPattern; - } - - // returns true if the type is used as a value type (X or const X &) - bool isValue() const - { - return m_pattern == ValuePattern; - } - - bool isValuePointer() const - { - return m_pattern == ValuePointerPattern; - } - - // returns true for more complex types... - bool isNativePointer() const - { - return m_pattern == NativePointerPattern; - } - - // return true if the type was originally a varargs - bool isVarargs() const - { - return m_pattern == VarargsPattern; - } - - // returns true if the type was used as a container - bool isContainer() const - { - return m_pattern == ContainerPattern; - } - - // returns true if the type was used as a smart pointer - bool isSmartPointer() const { return m_pattern == SmartPointerPattern; } - - // returns true if the type was used as a flag - bool isFlags() const - { - return m_pattern == FlagsPattern; - } - - bool isConstant() const - { - return m_constant; - } - void setConstant(bool constant) - { - m_constant = constant; - } - - bool isVolatile() const { return m_volatile; } - void setVolatile(bool v) { m_volatile = v; } - - bool passByConstRef() const; - bool passByValue() const; - - ReferenceType referenceType() const { return m_referenceType; } - void setReferenceType(ReferenceType ref) { m_referenceType = ref; } - - int actualIndirections() const - { - return m_indirections.size() + (m_referenceType == LValueReference ? 1 : 0); - } - - Indirections indirectionsV() const { return m_indirections; } - void setIndirectionsV(const Indirections &i) { m_indirections = i; } - void clearIndirections() { m_indirections.clear(); } - - // "Legacy"? - int indirections() const { return m_indirections.size(); } - void setIndirections(int indirections) - { - m_indirections = Indirections(indirections, Indirection::Pointer); - } - void addIndirection(Indirection i = Indirection::Pointer) - { m_indirections.append(i); } - - void setArrayElementCount(int n) - { - m_arrayElementCount = n; - } - int arrayElementCount() const - { - return m_arrayElementCount; - } - - const AbstractMetaType *arrayElementType() const - { - return m_arrayElementType; - } - void setArrayElementType(const AbstractMetaType *t) - { - m_arrayElementType = t; - } - - AbstractMetaTypeCList nestedArrayTypes() const; - - QString cppSignature() const; - - QString pythonSignature() const; - - AbstractMetaType *copy() const; - bool applyArrayModification(QString *errorMessage); - - const TypeEntry *typeEntry() const - { - return m_typeEntry; - } - void setTypeEntry(const TypeEntry *type) - { - m_typeEntry = type; - } - - void setOriginalTypeDescription(const QString &otd) - { - m_originalTypeDescription = otd; - } - QString originalTypeDescription() const - { - return m_originalTypeDescription; - } - - void setOriginalTemplateType(const AbstractMetaType *type) - { - m_originalTemplateType = type; - } - const AbstractMetaType *originalTemplateType() const - { - return m_originalTemplateType; - } - - AbstractMetaType *getSmartPointerInnerType() const - { - Q_ASSERT(isSmartPointer()); - AbstractMetaTypeList instantiations = this->instantiations(); - Q_ASSERT(!instantiations.isEmpty()); - AbstractMetaType *innerType = instantiations.at(0); - return innerType; - } - - QString getSmartPointerInnerTypeName() const - { - Q_ASSERT(isSmartPointer()); - AbstractMetaType *innerType = getSmartPointerInnerType(); - Q_ASSERT(innerType); - return innerType->name(); - } - - /// Decides and sets the proper usage patter for the current meta type. - void decideUsagePattern(); - - bool hasTemplateChildren() const; - - bool compare(const AbstractMetaType &rhs, ComparisonFlags = {}) const; - -private: - TypeUsagePattern determineUsagePattern() const; - QString formatSignature(bool minimal) const; - QString formatPythonSignature() const; - - const TypeEntry *m_typeEntry = nullptr; - AbstractMetaTypeList m_instantiations; - QString m_package; - mutable QString m_cachedCppSignature; - mutable QString m_cachedPythonSignature; - QString m_originalTypeDescription; - - int m_arrayElementCount = -1; - const AbstractMetaType *m_arrayElementType = nullptr; - const AbstractMetaType *m_originalTemplateType = nullptr; - Indirections m_indirections; - - TypeUsagePattern m_pattern = InvalidPattern; - uint m_constant : 1; - uint m_volatile : 1; - uint m_cppInstantiation : 1; - uint m_reserved : 29; // unused - - ReferenceType m_referenceType = NoReference; - AbstractMetaTypeList m_children; - - Q_DISABLE_COPY(AbstractMetaType) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaType::ComparisonFlags); - -inline bool operator==(const AbstractMetaType &t1, const AbstractMetaType &t2) -{ return t1.compare(t2); } -inline bool operator!=(const AbstractMetaType &t1, const AbstractMetaType &t2) -{ return !t1.compare(t2); } - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaType *at); -#endif - -class AbstractMetaVariable -{ - Q_DISABLE_COPY(AbstractMetaVariable) -public: - AbstractMetaVariable(); - - virtual ~AbstractMetaVariable(); - - AbstractMetaType *type() const - { - return m_type; - } - void setType(AbstractMetaType *type) - { - Q_ASSERT(m_type == nullptr); - m_type = type; - } - void replaceType(AbstractMetaType *type) - { - delete m_type; - m_type = type; - } - - QString name() const - { - return m_name; - } - void setName(const QString &name, bool realName = true) - { - m_name = name; - m_hasName = realName; - } - bool hasName() const - { - return m_hasName; - } - QString originalName() const - { - return m_originalName; - } - void setOriginalName(const QString& name) - { - m_originalName = name; - } - void setDocumentation(const Documentation& doc) - { - m_doc = doc; - } - Documentation documentation() const - { - return m_doc; - } - -protected: - void assignMetaVariable(const AbstractMetaVariable &other); - -private: - QString m_originalName; - QString m_name; - AbstractMetaType *m_type = nullptr; - bool m_hasName = false; - - Documentation m_doc; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaVariable *av); -#endif - -class AbstractMetaArgument : public AbstractMetaVariable -{ -public: - AbstractMetaArgument(); - - QString defaultValueExpression() const - { - return m_expression; - } - void setDefaultValueExpression(const QString &expr) - { - m_expression = expr; - } - - QString originalDefaultValueExpression() const - { - return m_originalExpression; - } - void setOriginalDefaultValueExpression(const QString &expr) - { - m_originalExpression = expr; - } - - bool hasDefaultValueExpression() const - { return !m_expression.isEmpty(); } - bool hasOriginalDefaultValueExpression() const - { return !m_originalExpression.isEmpty(); } - bool hasUnmodifiedDefaultValueExpression() const - { return !m_originalExpression.isEmpty() && m_originalExpression == m_expression; } - bool hasModifiedDefaultValueExpression() const - { return !m_expression.isEmpty() && m_originalExpression != m_expression; } - - QString toString() const - { - return type()->name() + QLatin1Char(' ') + AbstractMetaVariable::name() + - (m_expression.isEmpty() ? QString() : QLatin1String(" = ") + m_expression); - } - - int argumentIndex() const - { - return m_argumentIndex; - } - void setArgumentIndex(int argIndex) - { - m_argumentIndex = argIndex; - } - - AbstractMetaArgument *copy() const; - -protected: - void assignMetaArgument(const AbstractMetaArgument &other); - -private: - QString m_expression; - QString m_originalExpression; - int m_argumentIndex = 0; - - friend class AbstractMetaClass; -}; - -class EnclosingClassMixin { -public: - const AbstractMetaClass *enclosingClass() const { return m_enclosingClass; } - void setEnclosingClass(const AbstractMetaClass *cls) { m_enclosingClass = cls; } - const AbstractMetaClass *targetLangEnclosingClass() const; - -private: - const AbstractMetaClass *m_enclosingClass = nullptr; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaArgument *aa); -#endif - -class AbstractMetaField : public AbstractMetaVariable, public AbstractMetaAttributes, public EnclosingClassMixin -{ -public: - AbstractMetaField(); - ~AbstractMetaField(); - - const AbstractMetaFunction *getter() const; - const AbstractMetaFunction *setter() const; - - FieldModificationList modifications() const; - - bool isModifiedRemoved(int types = TypeSystem::All) const; - - using AbstractMetaVariable::setDocumentation; - using AbstractMetaVariable::documentation; - - AbstractMetaField *copy() const; - - static AbstractMetaField * - find(const AbstractMetaFieldList &haystack, const QString &needle); - -private: - mutable AbstractMetaFunction *m_getter = nullptr; - mutable AbstractMetaFunction *m_setter = nullptr; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaField *af); -#endif - -class AbstractMetaFunction : public AbstractMetaAttributes -{ - Q_GADGET -public: - enum FunctionType { - ConstructorFunction, - CopyConstructorFunction, - MoveConstructorFunction, - AssignmentOperatorFunction, - MoveAssignmentOperatorFunction, - DestructorFunction, - NormalFunction, - SignalFunction, - EmptyFunction, - SlotFunction, - GlobalScopeFunction, - GetAttroFunction, - SetAttroFunction - }; - Q_ENUM(FunctionType) - - enum CompareResultFlag { - EqualName = 0x00000001, - EqualArguments = 0x00000002, - EqualAttributes = 0x00000004, - EqualImplementor = 0x00000008, - EqualReturnType = 0x00000010, - EqualDefaultValueOverload = 0x00000020, - EqualModifiedName = 0x00000040, - - NameLessThan = 0x00001000, - - PrettySimilar = EqualName | EqualArguments, - Equal = 0x0000001f, - NotEqual = 0x00001000 - }; - Q_DECLARE_FLAGS(CompareResult, CompareResultFlag) - Q_FLAG(CompareResultFlag) - - AbstractMetaFunction(); - explicit AbstractMetaFunction(const AddedFunctionPtr &addedFunc); - ~AbstractMetaFunction(); - - QString name() const - { - return m_name; - } - - void setName(const QString &name) - { - m_name = name; - } - - QString originalName() const - { - return m_originalName.isEmpty() ? name() : m_originalName; - } - - void setOriginalName(const QString &name) - { - m_originalName = name; - } - - void setReverseOperator(bool reverse) - { - m_reverse = reverse; - } - - bool isReverseOperator() const - { - return m_reverse; - } - - /** - * Returns true if this is a operator and the "self" operand is a pointer. - * e.g. class Foo {}; operator+(SomeEnum, Foo*); - */ - bool isPointerOperator() const - { - return m_pointerOperator; - } - - void setPointerOperator(bool value) - { - m_pointerOperator = value; - } - - void setExplicit(bool isExplicit) - { - m_explicit = isExplicit; - } - /** - * Says if the function (a constructor) was declared as explicit in C++. - * \return true if the function was declared as explicit in C++ - */ - bool isExplicit() const - { - return m_explicit; - } - - static bool isConversionOperator(const QString& funcName); - - ExceptionSpecification exceptionSpecification() const; - void setExceptionSpecification(ExceptionSpecification e); - - bool generateExceptionHandling() const; - - bool isConversionOperator() const - { - return isConversionOperator(originalName()); - } - - static bool isOperatorOverload(const QString& funcName); - bool isOperatorOverload() const - { - return isOperatorOverload(originalName()); - } - bool isCastOperator() const; - - bool isArithmeticOperator() const; - bool isBitwiseOperator() const; - bool isComparisonOperator() const; - bool isLogicalOperator() const; - bool isSubscriptOperator() const; - bool isAssignmentOperator() const; // Assignment or move assignment - bool isOtherOperator() const; - - /** - * Informs the arity of the operator or -1 if the function is not - * an operator overload. - * /return the arity of the operator or -1 - */ - int arityOfOperator() const; - bool isUnaryOperator() const { return arityOfOperator() == 1; } - bool isBinaryOperator() const { return arityOfOperator() == 2; } - bool isInplaceOperator() const; - - bool isVirtual() const; - bool allowThread() const; - QString modifiedName() const; - - QString minimalSignature() const; - QString debugSignature() const; // including virtual/override/final, etc., for debugging only. - - bool isModifiedRemoved(int types = TypeSystem::All) const; - - AbstractMetaType *type() const - { - return m_type; - } - void setType(AbstractMetaType *type) - { - Q_ASSERT(m_type == nullptr); - m_type = type; - } - - void replaceType(AbstractMetaType *type) - { - delete m_type; - m_type = type; - } - - // The class that has this function as a member. - const AbstractMetaClass *ownerClass() const - { - return m_class; - } - void setOwnerClass(const AbstractMetaClass *cls) - { - m_class = cls; - } - - // The first class in a hierarchy that declares the function - const AbstractMetaClass *declaringClass() const - { - return m_declaringClass; - } - void setDeclaringClass(const AbstractMetaClass *cls) - { - m_declaringClass = cls; - } - - // The class that actually implements this function - const AbstractMetaClass *implementingClass() const - { - return m_implementingClass; - } - void setImplementingClass(const AbstractMetaClass *cls) - { - m_implementingClass = cls; - } - - AbstractMetaArgumentList arguments() const - { - return m_arguments; - } - void setArguments(const AbstractMetaArgumentList &arguments) - { - m_arguments = arguments; - } - void addArgument(AbstractMetaArgument *argument) - { - m_arguments << argument; - } - int actualMinimumArgumentCount() const; - - bool isDeprecated() const; - bool isDestructor() const - { - return functionType() == DestructorFunction; - } - bool isConstructor() const - { - return m_functionType == ConstructorFunction || m_functionType == CopyConstructorFunction - || m_functionType == MoveConstructorFunction; - } - bool isNormal() const - { - return functionType() == NormalFunction || isSlot() || isInGlobalScope(); - } - bool isInGlobalScope() const - { - return functionType() == GlobalScopeFunction; - } - bool isSignal() const - { - return functionType() == SignalFunction; - } - bool isSlot() const - { - return functionType() == SlotFunction; - } - bool isEmptyFunction() const - { - return functionType() == EmptyFunction; - } - FunctionType functionType() const - { - return m_functionType; - } - void setFunctionType(FunctionType type) - { - m_functionType = type; - } - - bool usesRValueReferences() const; - QStringList introspectionCompatibleSignatures(const QStringList &resolvedArguments = QStringList()) const; - QString signature() const; - - bool isConstant() const - { - return m_constant; - } - void setConstant(bool constant) - { - m_constant = constant; - } - - /// Returns true if the AbstractMetaFunction was added by the user via the type system description. - bool isUserAdded() const { return !m_addedFunction.isNull(); } - - QString toString() const - { - return m_name; - } - - CompareResult compareTo(const AbstractMetaFunction *other) const; - - bool operator <(const AbstractMetaFunction &a) const; - - AbstractMetaFunction *copy() const; - - QString conversionRule(TypeSystem::Language language, int idx) const; - QVector<ReferenceCount> referenceCounts(const AbstractMetaClass *cls, int idx = -2) const; - ArgumentOwner argumentOwner(const AbstractMetaClass *cls, int idx) const; - - // Returns the ownership rules for the given argument in the given context - TypeSystem::Ownership ownership(const AbstractMetaClass *cls, TypeSystem::Language language, int idx) const; - - QString typeReplaced(int argument_index) const; - bool isModifiedToArray(int argumentIndex) const; - bool isRemovedFromAllLanguages(const AbstractMetaClass *) const; - bool isRemovedFrom(const AbstractMetaClass *, TypeSystem::Language language) const; - bool argumentRemoved(int) const; - /** - * Verifies if any modification to the function is an inject code. - * \return true if there is inject code modifications to the function. - */ - bool hasInjectedCode() const; - /** - * Returns a list of code snips for this function. - * The code snips can be filtered by position and language. - * \return list of code snips - */ - CodeSnipList injectedCodeSnips(TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny, - TypeSystem::Language language = TypeSystem::All) const; - - /** - * Verifies if any modification to the function alters/removes its - * arguments types or default values. - * \return true if there is some modification to function signature - */ - bool hasSignatureModifications() const; - FunctionModificationList modifications(const AbstractMetaClass* implementor = nullptr) const; - - /** - * 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; - - void setPropertySpec(QPropertySpec *spec) - { - m_propertySpec = spec; - } - - QPropertySpec *propertySpec() const - { - return m_propertySpec; - } - - FunctionTypeEntry* typeEntry() const - { - return m_typeEntry; - } - - void setTypeEntry(FunctionTypeEntry* typeEntry) - { - m_typeEntry = typeEntry; - } - - bool isCallOperator() const; - - static AbstractMetaFunction * - find(const AbstractMetaFunctionList &haystack, const QString &needle); - - // for the meta builder only - void setAllowThreadModification(TypeSystem::AllowThread am) - { m_allowThreadModification = am; } - void setExceptionHandlingModification(TypeSystem::ExceptionHandling em) - { m_exceptionHandlingModification = em; } - -#ifndef QT_NO_DEBUG_STREAM - void formatDebugVerbose(QDebug &d) const; -#endif - - SourceLocation sourceLocation() const; - void setSourceLocation(const SourceLocation &sourceLocation); - -private: - bool autoDetectAllowThread() const; - - QString m_name; - QString m_originalName; - mutable QString m_cachedMinimalSignature; - mutable QString m_cachedSignature; - mutable QString m_cachedModifiedName; - - FunctionTypeEntry* m_typeEntry = nullptr; - FunctionType m_functionType = NormalFunction; - AbstractMetaType *m_type = nullptr; - const AbstractMetaClass *m_class = nullptr; - const AbstractMetaClass *m_implementingClass = nullptr; - const AbstractMetaClass *m_declaringClass = nullptr; - QPropertySpec *m_propertySpec = nullptr; - AbstractMetaArgumentList m_arguments; - AddedFunctionPtr m_addedFunction; - SourceLocation m_sourceLocation; - uint m_constant : 1; - uint m_reverse : 1; - uint m_explicit : 1; - uint m_pointerOperator : 1; - uint m_isCallOperator : 1; - ExceptionSpecification m_exceptionSpecification = ExceptionSpecification::Unknown; - TypeSystem::AllowThread m_allowThreadModification = TypeSystem::AllowThread::Unspecified; - TypeSystem::ExceptionHandling m_exceptionHandlingModification = TypeSystem::ExceptionHandling::Unspecified; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaFunction::CompareResult) - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaFunction *af); -#endif - -class AbstractMetaEnumValue -{ -public: - AbstractMetaEnumValue() = default; - - EnumValue value() const - { - return m_value; - } - - void setValue(EnumValue value) - { - m_value = value; - } - - QString stringValue() const - { - return m_stringValue; - } - - void setStringValue(const QString &v) - { - m_stringValue = v; - } - - QString name() const - { - return m_name; - } - - void setName(const QString &name) - { - m_name = name; - } - - void setDocumentation(const Documentation& doc) - { - m_doc = doc; - } - - Documentation documentation() const - { - return m_doc; - } - -private: - QString m_name; - QString m_stringValue; - - EnumValue m_value; - - Documentation m_doc; -}; - -class AbstractMetaEnum : public AbstractMetaAttributes, public EnclosingClassMixin -{ -public: - AbstractMetaEnum(); - ~AbstractMetaEnum(); - - AbstractMetaEnumValueList values() const - { - return m_enumValues; - } - - void addEnumValue(AbstractMetaEnumValue *enumValue) - { - m_enumValues << enumValue; - } - - AbstractMetaEnumValue *findEnumValue(const QString &value) const; - - QString name() const; - - QString qualifier() const; - - QString package() const; - - QString fullName() const - { - return package() + QLatin1Char('.') + qualifier() + QLatin1Char('.') + name(); - } - - EnumKind enumKind() const { return m_enumKind; } - void setEnumKind(EnumKind kind) { m_enumKind = kind; } - - bool isAnonymous() const { return m_enumKind == AnonymousEnum; } - - // Has the enum been declared inside a Q_ENUMS() macro in its enclosing class? - void setHasQEnumsDeclaration(bool on) - { - m_hasQenumsDeclaration = on; - } - - bool hasQEnumsDeclaration() const - { - return m_hasQenumsDeclaration; - } - - EnumTypeEntry *typeEntry() const - { - return m_typeEntry; - } - - void setTypeEntry(EnumTypeEntry *entry) - { - m_typeEntry = entry; - } - - bool isSigned() const { return m_signed; } - void setSigned(bool s) { m_signed = s; } - -private: - AbstractMetaEnumValueList m_enumValues; - EnumTypeEntry *m_typeEntry = nullptr; - - EnumKind m_enumKind = CEnum; - uint m_hasQenumsDeclaration : 1; - uint m_signed : 1; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AbstractMetaEnum *ae); -#endif - -class AbstractMetaClass : public AbstractMetaAttributes, public EnclosingClassMixin -{ - Q_GADGET -public: - enum FunctionQueryOption { - Constructors = 0x0000001, // Only 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 - NotRemovedFromTargetLang = 0x0400000, // Only functions that have not been removed from TargetLang - OperatorOverloads = 0x2000000, // Only functions that are operator overloads - GenerateExceptionHandling = 0x4000000, - GetAttroFunction = 0x8000000, - SetAttroFunction = 0x10000000 - }; - Q_DECLARE_FLAGS(FunctionQueryOptions, FunctionQueryOption) - Q_FLAG(FunctionQueryOption) - - enum OperatorQueryOption { - ArithmeticOp = 0x01, // Arithmetic: +, -, *, /, %, +=, -=, *=, /=, %=, ++, --, unary+, unary- - BitwiseOp = 0x02, // Bitwise: <<, <<=, >>, >>=, ~, &, &=, |, |=, ^, ^= - ComparisonOp = 0x04, // Comparison: <, <=, >, >=, !=, == - LogicalOp = 0x08, // Logical: !, &&, || - ConversionOp = 0x10, // Conversion: operator [const] TYPE() - SubscriptionOp = 0x20, // Subscription: [] - AssignmentOp = 0x40, // Assignment: = - OtherOp = 0x80, // The remaining operators: call(), etc - AllOperators = ArithmeticOp | BitwiseOp | ComparisonOp - | LogicalOp | ConversionOp | SubscriptionOp - | AssignmentOp | OtherOp - }; - Q_DECLARE_FLAGS(OperatorQueryOptions, OperatorQueryOption) - Q_FLAG(OperatorQueryOption) - - AbstractMetaClass(); - ~AbstractMetaClass(); - - void fixFunctions(); - - AbstractMetaFunctionList functions() const - { - return m_functions; - } - - void setFunctions(const AbstractMetaFunctionList &functions); - void addFunction(AbstractMetaFunction *function); - bool hasFunction(const AbstractMetaFunction *f) const; - bool hasFunction(const QString &str) const; - const AbstractMetaFunction* findFunction(const QString& functionName) const; - bool hasSignal(const AbstractMetaFunction *f) const; - - bool hasConstructors() const; - const AbstractMetaFunction *copyConstructor() const; - bool hasCopyConstructor() const { return copyConstructor() != nullptr; } - bool hasPrivateCopyConstructor() const; - - void addDefaultConstructor(); - void addDefaultCopyConstructor(bool isPrivate = false); - - bool hasNonPrivateConstructor() const - { - return m_hasNonPrivateConstructor; - } - - void setHasNonPrivateConstructor(bool value) - { - m_hasNonPrivateConstructor = value; - } - - bool hasPrivateConstructor() const - { - return m_hasPrivateConstructor; - } - - void setHasPrivateConstructor(bool value) - { - m_hasPrivateConstructor = value; - } - - bool hasPrivateDestructor() const - { - return m_hasPrivateDestructor; - } - - void setHasPrivateDestructor(bool value) - { - m_hasPrivateDestructor = value; - } - - bool hasProtectedDestructor() const - { - return m_hasProtectedDestructor; - } - - void setHasProtectedDestructor(bool value) - { - m_hasProtectedDestructor = value; - } - - bool hasVirtualDestructor() const - { - return m_hasVirtualDestructor; - } - - void setHasVirtualDestructor(bool value); - - bool isConstructible() const - { - return (hasNonPrivateConstructor() || !hasPrivateConstructor()) && !hasPrivateDestructor(); - } - - bool generateExceptionHandling() const; - - AbstractMetaFunctionList queryFunctionsByName(const QString &name) const; - static bool queryFunction(const AbstractMetaFunction *f, FunctionQueryOptions query); - static AbstractMetaFunctionList queryFunctionList(const AbstractMetaFunctionList &list, - FunctionQueryOptions query); - static const AbstractMetaFunction *queryFirstFunction(const AbstractMetaFunctionList &list, - FunctionQueryOptions query); - - AbstractMetaFunctionList queryFunctions(FunctionQueryOptions query) const; - AbstractMetaFunctionList functionsInTargetLang() const; - AbstractMetaFunctionList cppSignalFunctions() const; - AbstractMetaFunctionList implicitConversions() const; - - /** - * Retrieves all class' operator overloads that meet - * query criteria defined with the OperatorQueryOption - * enum. - * /param query composition of OperatorQueryOption enum values - * /return list of operator overload methods that meet the - * query criteria - */ - AbstractMetaFunctionList operatorOverloads(OperatorQueryOptions query = AllOperators) const; - - bool hasArithmeticOperatorOverload() const; - bool hasBitwiseOperatorOverload() const; - bool hasComparisonOperatorOverload() const; - bool hasLogicalOperatorOverload() const; - - AbstractMetaFieldList fields() const - { - return m_fields; - } - - void setFields(const AbstractMetaFieldList &fields) - { - m_fields = fields; - } - - void addField(AbstractMetaField *field) - { - m_fields << field; - } - - AbstractMetaField *findField(const QString &name) const; - - AbstractMetaEnumList enums() const - { - return m_enums; - } - void setEnums(const AbstractMetaEnumList &enums) - { - m_enums = enums; - } - - void addEnum(AbstractMetaEnum *e) - { - m_enums << e; - } - - AbstractMetaEnum *findEnum(const QString &enumName); - AbstractMetaEnumValue *findEnumValue(const QString &enumName); - - QString fullName() const - { - return package() + QLatin1Char('.') + name(); - } - - /** - * Retrieves the class name without any namespace/scope information. - * /return the class name without scope information - */ - QString name() const; - - QString baseClassName() const - { - return m_baseClasses.isEmpty() ? QString() : m_baseClasses.constFirst()->name(); - } - - AbstractMetaClass *baseClass() const - { - return m_baseClasses.value(0, nullptr); - } - const AbstractMetaClassList &baseClasses() const { return m_baseClasses; } - - void addBaseClass(AbstractMetaClass *base_class); - void setBaseClass(AbstractMetaClass *base_class); - - /** - * \return the namespace from another package which this namespace extends. - */ - AbstractMetaClass *extendedNamespace() const { return m_extendedNamespace; } - void setExtendedNamespace(AbstractMetaClass *e) { m_extendedNamespace = e; } - - const AbstractMetaClassList& innerClasses() const - { - return m_innerClasses; - } - - void addInnerClass(AbstractMetaClass* cl) - { - m_innerClasses << cl; - } - - void setInnerClasses(const AbstractMetaClassList &innerClasses) - { - m_innerClasses = innerClasses; - } - - QString package() const; - - bool isNamespace() const; - - bool isQObject() const; - - bool isQtNamespace() const - { - return isNamespace() && name() == QLatin1String("Qt"); - } - - QString qualifiedCppName() const; - - bool hasSignals() const; - bool inheritsFrom(const AbstractMetaClass *other) const; - - /** - * Says if the class that declares or inherits a virtual function. - * \return true if the class implements or inherits any virtual methods - */ - bool isPolymorphic() const - { - return m_isPolymorphic; - } - - /** - * 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; - - - QVector<TypeEntry *> templateArguments() const - { - return m_templateArgs; - } - - void setTemplateArguments(const QVector<TypeEntry *> &args) - { - m_templateArgs = args; - } - - bool hasFieldAccessors() const; - - // only valid during metabuilder's run - QStringList baseClassNames() const - { - return m_baseClassNames; - } - - void setBaseClassNames(const QStringList &names) - { - m_baseClassNames = names; - } - - const ComplexTypeEntry *typeEntry() const - { - return m_typeEntry; - } - - ComplexTypeEntry *typeEntry() - { - return m_typeEntry; - } - - void setTypeEntry(ComplexTypeEntry *type) - { - m_typeEntry = type; - } - - void setHasHashFunction(bool on) - { - m_hasHashFunction = on; - } - - bool hasHashFunction() const - { - return m_hasHashFunction; - } - virtual bool hasDefaultToStringFunction() const; - - void setHasEqualsOperator(bool on) - { - m_hasEqualsOperator = on; - } - - bool hasEqualsOperator() const - { - return m_hasEqualsOperator; - } - - void setHasCloneOperator(bool on) - { - m_hasCloneOperator = on; - } - - bool hasCloneOperator() const - { - return m_hasCloneOperator; - } - - void addPropertySpec(QPropertySpec *spec) - { - m_propertySpecs << spec; - } - - QVector<QPropertySpec *> propertySpecs() const - { - return m_propertySpecs; - } - - QPropertySpec *propertySpecForRead(const QString &name) const; - QPropertySpec *propertySpecForWrite(const QString &name) const; - QPropertySpec *propertySpecForReset(const QString &name) const; - - /// Returns a list of conversion operators for this class. The conversion operators are defined in other classes of the same module. - AbstractMetaFunctionList externalConversionOperators() const - { - return m_externalConversionOperators; - } - /// Adds a converter operator for this class. - void addExternalConversionOperator(AbstractMetaFunction* conversionOp) - { - if (!m_externalConversionOperators.contains(conversionOp)) - m_externalConversionOperators.append(conversionOp); - } - /// Returns true if this class has any converter operators defined elsewhere. - bool hasExternalConversionOperators() const - { - return !m_externalConversionOperators.isEmpty(); - } - - void sortFunctions(); - - const AbstractMetaClass *templateBaseClass() const - { - return m_templateBaseClass; - } - - void setTemplateBaseClass(const AbstractMetaClass *cls) - { - m_templateBaseClass = cls; - } - - bool hasTemplateBaseClassInstantiations() const; - AbstractMetaTypeList templateBaseClassInstantiations() const; - void setTemplateBaseClassInstantiations(AbstractMetaTypeList& instantiations); - - void setTypeDef(bool typeDef) { m_isTypeDef = typeDef; } - bool isTypeDef() const { return m_isTypeDef; } - - void setStream(bool stream) - { - m_stream = stream; - } - - bool isStream() const - { - return m_stream; - } - - void setToStringCapability(bool value, uint indirections = 0) - { - m_hasToStringCapability = value; - m_toStringCapabilityIndirections = indirections; - } - - bool hasToStringCapability() const - { - return m_hasToStringCapability; - } - - uint toStringCapabilityIndirections() const - { - return m_toStringCapabilityIndirections; - } - - bool deleteInMainThread() const; - - static AbstractMetaClass *findClass(const AbstractMetaClassList &classes, - const QString &name); - static AbstractMetaClass *findClass(const AbstractMetaClassList &classes, - const TypeEntry* typeEntry); - static AbstractMetaEnumValue *findEnumValue(const AbstractMetaClassList &classes, - const QString &string); - static AbstractMetaEnum *findEnum(const AbstractMetaClassList &classes, - const EnumTypeEntry *entry); - - SourceLocation sourceLocation() const; - void setSourceLocation(const SourceLocation &sourceLocation); - -private: -#ifndef QT_NO_DEBUG_STREAM - void format(QDebug &d) const; - void formatMembers(QDebug &d) const; - friend QDebug operator<<(QDebug d, const AbstractMetaClass *ac); -#endif - uint m_hasVirtuals : 1; - uint m_isPolymorphic : 1; - uint m_hasNonpublic : 1; - uint m_hasNonPrivateConstructor : 1; - uint m_hasPrivateConstructor : 1; - uint m_functionsFixed : 1; - 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; - - const AbstractMetaClass *m_enclosingClass = nullptr; - AbstractMetaClassList m_baseClasses; // Real base classes after setting up inheritance - AbstractMetaClass *m_extendedNamespace = nullptr; - - const AbstractMetaClass *m_templateBaseClass = nullptr; - AbstractMetaFunctionList m_functions; - AbstractMetaFieldList m_fields; - AbstractMetaEnumList m_enums; - QVector<QPropertySpec *> m_propertySpecs; - AbstractMetaClassList m_innerClasses; - - AbstractMetaFunctionList m_externalConversionOperators; - - QStringList m_baseClassNames; // Base class names from C++, including rejected - QVector<TypeEntry *> m_templateArgs; - ComplexTypeEntry *m_typeEntry = nullptr; - SourceLocation m_sourceLocation; -// FunctionModelItem m_qDebugStreamFunction; - - bool m_stream = false; - uint m_toStringCapabilityIndirections = 0; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaClass::FunctionQueryOptions) -Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractMetaClass::OperatorQueryOptions) - -class QPropertySpec -{ -public: - explicit QPropertySpec(const TypeEntry *type) : m_type(type) {} - - const TypeEntry *type() const - { - return m_type; - } - - QString name() const - { - return m_name; - } - - void setName(const QString &name) - { - m_name = name; - } - - QString read() const - { - return m_read; - } - - void setRead(const QString &read) - { - m_read = read; - } - - QString write() const - { - return m_write; - } - - void setWrite(const QString &write) - { - m_write = write; - } - - QString designable() const - { - return m_designable; - } - - void setDesignable(const QString &designable) - { - m_designable = designable; - } - - QString reset() const - { - return m_reset; - } - - void setReset(const QString &reset) - { - m_reset = reset; - } - - int index() const - { - return m_index; - } - - void setIndex(int index) - { - m_index = index; - } - -private: - QString m_name; - QString m_read; - QString m_write; - QString m_designable; - QString m_reset; - const TypeEntry *m_type; - int m_index = -1; -}; - -#endif // ABSTRACTMETALANG_H diff --git a/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h b/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h deleted file mode 100644 index 617ebcf4f..000000000 --- a/sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h +++ /dev/null @@ -1,51 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef ABSTRACTMETALANG_TYPEDEFS_H -#define ABSTRACTMETALANG_TYPEDEFS_H - -#include <QtCore/QVector> - -class AbstractMetaClass; -class AbstractMetaField; -class AbstractMetaArgument; -class AbstractMetaEnum; -class AbstractMetaEnumValue; -class AbstractMetaFunction; -class AbstractMetaType; - -using AbstractMetaArgumentList = QVector<AbstractMetaArgument *>; -using AbstractMetaClassList = QVector<AbstractMetaClass *>; -using AbstractMetaEnumList = QVector<AbstractMetaEnum *>; -using AbstractMetaEnumValueList = QVector<AbstractMetaEnumValue *>; -using AbstractMetaFieldList = QVector<AbstractMetaField *>; -using AbstractMetaFunctionList = QVector<AbstractMetaFunction *>; -using AbstractMetaTypeList = QVector<AbstractMetaType *>; -using AbstractMetaTypeCList = QVector<const AbstractMetaType *>; - -#endif // ABSTRACTMETALANG_TYPEDEFS_H diff --git a/sources/shiboken2/ApiExtractor/apiextractor.cpp b/sources/shiboken2/ApiExtractor/apiextractor.cpp deleted file mode 100644 index 530ed0252..000000000 --- a/sources/shiboken2/ApiExtractor/apiextractor.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "apiextractor.h" -#include "abstractmetalang.h" - -#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 "typedatabase.h" -#include "typesystem.h" - -ApiExtractor::ApiExtractor() -{ - // Environment TYPESYSTEMPATH - QString envTypesystemPaths = QFile::decodeName(qgetenv("TYPESYSTEMPATH")); - if (!envTypesystemPaths.isEmpty()) - TypeDatabase::instance()->addTypesystemPath(envTypesystemPaths); -} - -ApiExtractor::~ApiExtractor() -{ - delete m_builder; -} - -void ApiExtractor::addTypesystemSearchPath (const QString& path) -{ - TypeDatabase::instance()->addTypesystemPath(path); -} - -void ApiExtractor::addTypesystemSearchPath(const QStringList& paths) -{ - for (const QString &path : paths) - addTypesystemSearchPath(path); -} - -void ApiExtractor::addIncludePath(const HeaderPath& path) -{ - m_includePaths << path; -} - -void ApiExtractor::addIncludePath(const HeaderPaths& paths) -{ - m_includePaths << paths; -} - -void ApiExtractor::setLogDirectory(const QString& logDir) -{ - m_logDirectory = logDir; -} - -void ApiExtractor::setCppFileNames(const QFileInfoList &cppFileName) -{ - m_cppFileNames = cppFileName; -} - -void ApiExtractor::setTypeSystem(const QString& typeSystemFileName) -{ - m_typeSystemFileName = typeSystemFileName; -} - -void ApiExtractor::setSkipDeprecated(bool value) -{ - m_skipDeprecated = value; - if (m_builder) - m_builder->setSkipDeprecated(m_skipDeprecated); -} - -void ApiExtractor::setSuppressWarnings ( bool value ) -{ - TypeDatabase::instance()->setSuppressWarnings(value); -} - -void ApiExtractor::setSilent ( bool value ) -{ - ReportHandler::setSilent(value); -} - -bool ApiExtractor::setApiVersion(const QString& package, const QString &version) -{ - return TypeDatabase::setApiVersion(package, version); -} - -void ApiExtractor::setDropTypeEntries(QString dropEntries) -{ - dropEntries.remove(QLatin1Char(' ')); - QStringList entries = dropEntries.split(QLatin1Char(';')); - TypeDatabase::instance()->setDropTypeEntries(entries); -} - -AbstractMetaEnumList ApiExtractor::globalEnums() const -{ - Q_ASSERT(m_builder); - return m_builder->globalEnums(); -} - -AbstractMetaFunctionList ApiExtractor::globalFunctions() const -{ - Q_ASSERT(m_builder); - return m_builder->globalFunctions(); -} - -AbstractMetaClassList ApiExtractor::classes() const -{ - Q_ASSERT(m_builder); - return m_builder->classes(); -} - -AbstractMetaClassList ApiExtractor::smartPointers() const -{ - Q_ASSERT(m_builder); - return m_builder->smartPointers(); -} - -AbstractMetaClassList ApiExtractor::classesTopologicalSorted(const Dependencies &additionalDependencies) const -{ - Q_ASSERT(m_builder); - return m_builder->classesTopologicalSorted(m_builder->classes(), additionalDependencies); -} - -PrimitiveTypeEntryList ApiExtractor::primitiveTypes() const -{ - return TypeDatabase::instance()->primitiveTypes(); -} - -ContainerTypeEntryList ApiExtractor::containerTypes() const -{ - return TypeDatabase::instance()->containerTypes(); -} - -const AbstractMetaEnum* ApiExtractor::findAbstractMetaEnum(const TypeEntry* typeEntry) const -{ - return m_builder->findEnum(typeEntry); -} - -int ApiExtractor::classCount() const -{ - Q_ASSERT(m_builder); - return m_builder->classes().count(); -} - -bool ApiExtractor::run() -{ - if (m_builder) - return false; - - if (!TypeDatabase::instance()->parseFile(m_typeSystemFileName)) { - std::cerr << "Cannot parse file: " << qPrintable(m_typeSystemFileName); - return false; - } - - const QString pattern = QDir::tempPath() + QLatin1Char('/') - + m_cppFileNames.constFirst().baseName() - + QStringLiteral("_XXXXXX.hpp"); - QTemporaryFile ppFile(pattern); - bool autoRemove = !qEnvironmentVariableIsSet("KEEP_TEMP_FILES"); - // make sure that a tempfile can be written - if (!ppFile.open()) { - std::cerr << "could not create tempfile " << qPrintable(pattern) - << ": " << qPrintable(ppFile.errorString()) << '\n'; - return false; - } - for (const auto &cppFileName : qAsConst(m_cppFileNames)) { - ppFile.write("#include \""); - ppFile.write(cppFileName.absoluteFilePath().toLocal8Bit()); - ppFile.write("\"\n"); - } - const QString preprocessedCppFileName = ppFile.fileName(); - ppFile.close(); - m_builder = new AbstractMetaBuilder; - m_builder->setLogDirectory(m_logDirectory); - m_builder->setGlobalHeaders(m_cppFileNames); - m_builder->setSkipDeprecated(m_skipDeprecated); - m_builder->setHeaderPaths(m_includePaths); - QByteArrayList arguments; - arguments.reserve(m_includePaths.size() + 1); - for (const HeaderPath &headerPath : qAsConst(m_includePaths)) - arguments.append(HeaderPath::includeOption(headerPath)); - arguments.append(QFile::encodeName(preprocessedCppFileName)); - if (ReportHandler::isDebug(ReportHandler::SparseDebug)) { - qCInfo(lcShiboken).noquote().nospace() - << "clang language level: " << int(m_languageLevel) - << "\nclang arguments: " << arguments; - } - const bool result = m_builder->build(arguments, m_languageLevel); - if (!result) - autoRemove = false; - if (!autoRemove) { - ppFile.setAutoRemove(false); - std::cerr << "Keeping temporary file: " << qPrintable(QDir::toNativeSeparators(preprocessedCppFileName)) << '\n'; - } - return result; -} - -LanguageLevel ApiExtractor::languageLevel() const -{ - return m_languageLevel; -} - -void ApiExtractor::setLanguageLevel(LanguageLevel languageLevel) -{ - m_languageLevel = languageLevel; -} - -#ifndef QT_NO_DEBUG_STREAM -template <class Container> -static void debugFormatSequence(QDebug &d, const char *key, const Container& c) -{ - if (c.isEmpty()) - return; - const auto begin = c.begin(); - d << "\n " << key << '[' << c.size() << "]=("; - for (auto it = begin, end = c.end(); it != end; ++it) { - if (it != begin) - d << ", "; - d << *it; - } - d << ')'; -} - -QDebug operator<<(QDebug d, const ApiExtractor &ae) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - if (ReportHandler::debugLevel() >= ReportHandler::FullDebug) - d.setVerbosity(3); // Trigger verbose output of AbstractMetaClass - d << "ApiExtractor(typeSystem=\"" << ae.typeSystem() << "\", cppFileNames=\"" - << ae.cppFileNames() << ", "; - ae.m_builder->formatDebug(d); - d << ')'; - return d; -} -#endif // QT_NO_DEBUG_STREAM diff --git a/sources/shiboken2/ApiExtractor/apiextractor.h b/sources/shiboken2/ApiExtractor/apiextractor.h deleted file mode 100644 index f6dd2ba8e..000000000 --- a/sources/shiboken2/ApiExtractor/apiextractor.h +++ /dev/null @@ -1,112 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef APIEXTRACTOR_H -#define APIEXTRACTOR_H - -#include "dependency.h" -#include "abstractmetalang_typedefs.h" -#include "apiextractormacros.h" -#include "header_paths.h" -#include "typedatabase_typedefs.h" -#include "typesystem_typedefs.h" -#include "clangparser/compilersupport.h" -#include <QFileInfoList> -#include <QStringList> - -class AbstractMetaBuilder; -class AbstractMetaClass; -class AbstractMetaEnum; -class AbstractMetaFunction; -class AbstractMetaType; -class ContainerTypeEntry; -class EnumTypeEntry; -class FlagsTypeEntry; -class PrimitiveTypeEntry; -class TypeEntry; - -QT_BEGIN_NAMESPACE -class QDebug; -class QIODevice; -QT_END_NAMESPACE - -class ApiExtractor -{ -public: - Q_DISABLE_COPY(ApiExtractor) - - ApiExtractor(); - ~ApiExtractor(); - - void setTypeSystem(const QString& typeSystemFileName); - QString typeSystem() const { return m_typeSystemFileName; } - void setCppFileNames(const QFileInfoList &cppFileNames); - QFileInfoList cppFileNames() const { return m_cppFileNames; } - void setSkipDeprecated(bool value); - void setSuppressWarnings(bool value); - void setSilent(bool value); - void addTypesystemSearchPath(const QString& path); - void addTypesystemSearchPath(const QStringList& paths); - void addIncludePath(const HeaderPath& path); - void addIncludePath(const HeaderPaths& paths); - HeaderPaths includePaths() const { return m_includePaths; } - void setLogDirectory(const QString& logDir); - bool setApiVersion(const QString& package, const QString& version); - void setDropTypeEntries(QString dropEntries); - LanguageLevel languageLevel() const; - void setLanguageLevel(LanguageLevel languageLevel); - - AbstractMetaEnumList globalEnums() const; - AbstractMetaFunctionList globalFunctions() const; - AbstractMetaClassList classes() const; - AbstractMetaClassList smartPointers() const; - AbstractMetaClassList classesTopologicalSorted(const Dependencies &additionalDependencies = Dependencies()) const; - PrimitiveTypeEntryList primitiveTypes() const; - ContainerTypeEntryList containerTypes() const; - - const AbstractMetaEnum* findAbstractMetaEnum(const TypeEntry* typeEntry) const; - - int classCount() const; - - bool run(); -private: - QString m_typeSystemFileName; - QFileInfoList m_cppFileNames; - HeaderPaths m_includePaths; - AbstractMetaBuilder* m_builder = nullptr; - QString m_logDirectory; - LanguageLevel m_languageLevel = LanguageLevel::Default; - bool m_skipDeprecated = false; - -#ifndef QT_NO_DEBUG_STREAM - friend QDebug operator<<(QDebug d, const ApiExtractor &ae); -#endif -}; - -#endif // APIEXTRACTOR_H - diff --git a/sources/shiboken2/ApiExtractor/apiextractormacros.h b/sources/shiboken2/ApiExtractor/apiextractormacros.h deleted file mode 100644 index 026cd5a9e..000000000 --- a/sources/shiboken2/ApiExtractor/apiextractormacros.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef APIEXTRACTORMACROS_H -#define APIEXTRACTORMACROS_H - - -// APIEXTRACTOR_API is used for the public API symbols. -#if defined _WIN32 - #define APIEXTRACTOR_DEPRECATED(func) __declspec(deprecated) func -#elif __GNUC__ >= 4 - #define APIEXTRACTOR_DEPRECATED(func) func __attribute__ ((deprecated)) -#else - #define APIEXTRACTOR_DEPRECATED(func) func -#endif -#endif diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp deleted file mode 100644 index 1eaa36540..000000000 --- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp +++ /dev/null @@ -1,1175 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#include "clangbuilder.h" -#include "compilersupport.h" -#include "clangutils.h" - -#include <codemodel.h> - -#include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtCore/QHash> -#include <QtCore/QMap> -#include <QtCore/QString> -#include <QtCore/QStack> -#include <QtCore/QVector> - -#include <cstring> -#include <ctype.h> - -#if QT_VERSION < 0x050800 -# define Q_FALLTHROUGH() (void)0 -#endif - -namespace clang { - -static inline QString colonColon() { return QStringLiteral("::"); } -static inline QString templateBrackets() { return QStringLiteral("<>"); } - -static inline bool isClassCursor(const CXCursor &c) -{ - return c.kind == CXCursor_ClassDecl || c.kind == CXCursor_StructDecl - || c.kind == CXCursor_ClassTemplate - || c.kind == CXCursor_ClassTemplatePartialSpecialization; -} - -static inline bool withinClassDeclaration(const CXCursor &cursor) -{ - return isClassCursor(clang_getCursorLexicalParent(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(' ')) - t.remove(pos, 1); - return t; -} - -// Insert template parameter to class name: "Foo<>" -> "Foo<T1>" -> "Foo<T1,T2>" -// This needs to be done immediately when template parameters are encountered since -// 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('>')))) - return false; - const bool needsComma = name->at(name->size() - 2) != QLatin1Char('<'); - const int insertionPos = name->size() - 1; - name->insert(insertionPos, parmName); - if (needsComma) - name->insert(insertionPos, QLatin1Char(',')); - return true; -} - -static inline bool insertTemplateParameterIntoClassName(const QString &parmName, - const ClassModelItem &item) -{ - QString name = item->name(); - const bool result = insertTemplateParameterIntoClassName(parmName, &name); - item->setName(name); - return result; -} - -static inline CodeModel::AccessPolicy accessPolicy(CX_CXXAccessSpecifier access) -{ - CodeModel::AccessPolicy result = CodeModel::Public; - switch (access) { - case CX_CXXProtected: - result = CodeModel::Protected; - break; - case CX_CXXPrivate: - result = CodeModel::Private; - break; - default: - break; - } - return result; -} - -static void setFileName(const CXCursor &cursor, _CodeModelItem *item) -{ - const SourceRange range = getCursorRange(cursor); - if (!range.first.file.isEmpty()) { // Has been observed to be 0 for invalid locations - item->setFileName(QDir::cleanPath(range.first.file)); - item->setStartPosition(int(range.first.line), int(range.first.column)); - item->setEndPosition(int(range.second.line), int(range.second.column)); - } -} - -static bool isSigned(CXTypeKind kind) -{ - switch (kind) { - case CXType_UChar: - case CXType_Char16: - case CXType_Char32: - case CXType_UShort: - case CXType_UInt: - case CXType_ULong: - case CXType_ULongLong: - case CXType_UInt128: - return false; - default: - break; - } - return true; -} - -class BuilderPrivate { -public: - 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))); - } - - // 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 - // appears in the translation unit while the scope is the outer class. - void updateScope() - { - if (m_scopeStack.size() <= 1) - m_scope.clear(); - else - m_scope = m_scopeStack.back()->scope() << m_scopeStack.back()->name(); - } - - void pushScope(const ScopeModelItem &i) - { - m_scopeStack.push(i); - updateScope(); - } - - void popScope() - { - m_scopeStack.pop(); - updateScope(); - } - - bool addClass(const CXCursor &cursor, CodeModel::ClassType t); - FunctionModelItem createFunction(const CXCursor &cursor, - CodeModel::FunctionType t = CodeModel::Normal) const; - FunctionModelItem createMemberFunction(const CXCursor &cursor) const; - void qualifyConstructor(const CXCursor &cursor); - TypeInfo createTypeInfoHelper(const CXType &type) const; // uncashed - TypeInfo createTypeInfo(const CXType &type) const; - TypeInfo createTypeInfo(const CXCursor &cursor) const - { return createTypeInfo(clang_getCursorType(cursor)); } - void addTemplateInstantiations(const CXType &type, - QString *typeName, - TypeInfo *t) const; - bool addTemplateInstantiationsRecursion(const CXType &type, TypeInfo *t) const; - - void addTypeDef(const CXCursor &cursor, const CXType &cxType); - void startTemplateTypeAlias(const CXCursor &cursor); - void endTemplateTypeAlias(const CXCursor &typeAliasCursor); - - TemplateParameterModelItem createTemplateParameter(const CXCursor &cursor) const; - TemplateParameterModelItem createNonTypeTemplateParameter(const CXCursor &cursor) const; - void addField(const CXCursor &cursor); - - QString cursorValueExpression(BaseVisitor *bv, const CXCursor &cursor) 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; - - BaseVisitor *m_baseVisitor; - CodeModel *m_model; - - QStack<ScopeModelItem> m_scopeStack; - QStringList m_scope; - // Store all classes by cursor so that base classes can be found and inner - // 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; - - ClassModelItem m_currentClass; - EnumModelItem m_currentEnum; - FunctionModelItem m_currentFunction; - ArgumentModelItem m_currentArgument; - VariableModelItem m_currentField; - TemplateTypeAliasModelItem m_currentTemplateTypeAlias; - QByteArrayList m_systemIncludes; // files, like "memory" - QByteArrayList m_systemIncludePaths; // paths, like "/usr/include/Qt/" - - int m_anonymousEnumCount = 0; - CodeModel::FunctionType m_currentFunctionType = CodeModel::Normal; -}; - -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()); - 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: - // class QMetaObject { class Connection; } - // class QMetaObject::Connection {} - const CXCursor semPar = clang_getCursorSemanticParent(cursor); - if (isClassCursor(semPar)) { - const CursorClassHash::const_iterator it = m_cursorClassHash.constFind(semPar); - if (it == m_cursorClassHash.constEnd()) { - const QString message = QStringLiteral("Unable to find parent of inner class ") + className; - const Diagnostic d(message, cursor, CXDiagnostic_Error); - qWarning() << d; - m_baseVisitor->appendDiagnostic(d); - return false; - } - const ClassModelItem &containingClass = it.value(); - containingClass->addClass(m_currentClass); - m_currentClass->setScope(containingClass->scope() << containingClass->name()); - } else { - m_currentClass->setScope(m_scope); - m_scopeStack.back()->addClass(m_currentClass); - } - pushScope(m_currentClass); - m_cursorClassHash.insert(cursor, m_currentClass); - return true; -} - -static inline ExceptionSpecification exceptionSpecificationFromClang(int ce) -{ - switch (ce) { - case CXCursor_ExceptionSpecificationKind_BasicNoexcept: - case CXCursor_ExceptionSpecificationKind_ComputedNoexcept: - case CXCursor_ExceptionSpecificationKind_DynamicNone: // throw() - return ExceptionSpecification::NoExcept; - case CXCursor_ExceptionSpecificationKind_Dynamic: // throw(t1..) - case CXCursor_ExceptionSpecificationKind_MSAny: // throw(...) - return ExceptionSpecification::Throws; - default: - // CXCursor_ExceptionSpecificationKind_None, - // CXCursor_ExceptionSpecificationKind_Unevaluated, - // CXCursor_ExceptionSpecificationKind_Uninstantiated - break; - } - return ExceptionSpecification::Unknown; -} - -FunctionModelItem BuilderPrivate::createFunction(const CXCursor &cursor, - CodeModel::FunctionType t) const -{ - QString name = getCursorSpelling(cursor); - // Apply type fixes to "operator X &" -> "operator X&" - if (name.startsWith(QLatin1String("operator "))) - name = fixTypeName(name); - FunctionModelItem result(new _FunctionModelItem(m_model, name)); - setFileName(cursor, result.data()); - result->setType(createTypeInfoHelper(clang_getCursorResultType(cursor))); - result->setFunctionType(t); - result->setScope(m_scope); - result->setStatic(clang_Cursor_getStorageClass(cursor) == CX_SC_Static); - result->setExceptionSpecification(exceptionSpecificationFromClang(clang_getCursorExceptionSpecificationType(cursor))); - switch (clang_getCursorAvailability(cursor)) { - case CXAvailability_Available: - break; - case CXAvailability_Deprecated: - result->setDeprecated(true); - break; - case CXAvailability_NotAvailable: // "Foo(const Foo&) = delete;" - result->setDeleted(true); - break; - case CXAvailability_NotAccessible: - break; - } - return result; -} - -static inline CodeModel::FunctionType functionTypeFromCursor(const CXCursor &cursor) -{ - CodeModel::FunctionType result = CodeModel::Normal; - switch (cursor.kind) { - case CXCursor_Constructor: - if (clang_CXXConstructor_isCopyConstructor(cursor) != 0) - result = CodeModel::CopyConstructor; - else if (clang_CXXConstructor_isMoveConstructor(cursor) != 0) - result = CodeModel::MoveConstructor; - else - result = CodeModel::Constructor; - break; - case CXCursor_Destructor: - result = CodeModel::Destructor; - break; - default: - break; - } - return result; -} - -FunctionModelItem BuilderPrivate::createMemberFunction(const CXCursor &cursor) const -{ - const CodeModel::FunctionType functionType = - m_currentFunctionType == CodeModel::Signal || m_currentFunctionType == CodeModel::Slot - ? m_currentFunctionType // by annotation - : functionTypeFromCursor(cursor); - FunctionModelItem result = createFunction(cursor, functionType); - 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); - return result; -} - -// For CXCursor_Constructor, on endToken(). -void BuilderPrivate::qualifyConstructor(const CXCursor &cursor) -{ - // Clang does not tell us whether a constructor is explicit, preventing it - // from being used for implicit conversions. Try to guess whether a - // constructor is explicit in the C++99 sense (1 parameter) by checking for - // isConvertingConstructor() == 0. Fixme: The notion of "isConvertingConstructor" - // should be used in the code model instead of "explicit" - if (clang_CXXConstructor_isDefaultConstructor(cursor) == 0 - && m_currentFunction->arguments().size() == 1 - && clang_CXXConstructor_isCopyConstructor(cursor) == 0 - && clang_CXXConstructor_isMoveConstructor(cursor) == 0) { - m_currentFunction->setExplicit(clang_CXXConstructor_isConvertingConstructor(cursor) == 0); - } -} - -TemplateParameterModelItem BuilderPrivate::createTemplateParameter(const CXCursor &cursor) const -{ - return TemplateParameterModelItem(new _TemplateParameterModelItem(m_model, getCursorSpelling(cursor))); -} - -TemplateParameterModelItem BuilderPrivate::createNonTypeTemplateParameter(const CXCursor &cursor) const -{ - TemplateParameterModelItem result = createTemplateParameter(cursor); - result->setType(createTypeInfoHelper(clang_getCursorType(cursor))); - return result; -} - -// CXCursor_VarDecl, CXCursor_FieldDecl cursors -void BuilderPrivate::addField(const CXCursor &cursor) -{ - VariableModelItem field(new _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); - m_currentField = field; - m_scopeStack.back()->addVariable(field); -} - -// Array helpers: Parse "a[2][4]" into a list of dimensions - -struct ArrayDimensionResult -{ - QVector<QStringRef> dimensions; - int position; -}; - -// Create qualified name "std::list<std::string>" -> ("std", "list<std::string>") -static QStringList qualifiedName(const QString &t) -{ - QStringList result; - int end = t.indexOf(QLatin1Char('<')); - if (end == -1) - end = t.indexOf(QLatin1Char('(')); - if (end == -1) - end = t.size(); - int lastPos = 0; - while (true) { - const int nextPos = t.indexOf(colonColon(), lastPos); - if (nextPos < 0 || nextPos >= end) - break; - result.append(t.mid(lastPos, nextPos - lastPos)); - lastPos = nextPos + 2; - } - result.append(t.right(t.size() - lastPos)); - return result; -} - -static bool isArrayType(CXTypeKind k) -{ - return k == CXType_ConstantArray || k == CXType_IncompleteArray - || k == CXType_VariableArray || k == CXType_DependentSizedArray; -} - -static bool isPointerType(CXTypeKind k) -{ - return k == CXType_Pointer || k == CXType_LValueReference || k == CXType_RValueReference; -} - -bool BuilderPrivate::addTemplateInstantiationsRecursion(const CXType &type, TypeInfo *t) const -{ - // Template arguments - switch (type.kind) { - case CXType_Elaborated: - case CXType_Record: - case CXType_Unexposed: - if (const int numTemplateArguments = qMax(0, clang_Type_getNumTemplateArguments(type))) { - for (unsigned tpl = 0; tpl < unsigned(numTemplateArguments); ++tpl) { - const CXType argType = clang_Type_getTemplateArgumentAsType(type, tpl); - // CXType_Invalid is returned when hitting on a specialization - // of a non-type template (template <int v>). - if (argType.kind == CXType_Invalid) - return false; - t->addInstantiation(createTypeInfoHelper(argType)); - } - } - break; - default: - break; - } - return true; -} - -static void dummyTemplateArgumentHandler(int, const QStringRef &) {} - -void BuilderPrivate::addTemplateInstantiations(const CXType &type, - QString *typeName, - TypeInfo *t) const -{ - // In most cases, for templates like "Vector<A>", Clang will give us the - // arguments by recursing down the type. However this will fail for example - // within template classes (for functions like the copy constructor): - // template <class T> - // class Vector { - // Vector(const Vector&); - // }; - // In that case, have TypeInfo parse the list from the spelling. - // Finally, remove the list "<>" from the type name. - const bool parsed = addTemplateInstantiationsRecursion(type, t) - && !t->instantiations().isEmpty(); - if (!parsed) - t->setInstantiations({}); - const QPair<int, int> pos = parsed - ? parseTemplateArgumentList(*typeName, dummyTemplateArgumentHandler) - : t->parseTemplateArgumentList(*typeName); - if (pos.first != -1 && pos.second != -1 && pos.second > pos.first) - typeName->remove(pos.first, pos.second - pos.first); -} - -TypeInfo BuilderPrivate::createTypeInfoHelper(const CXType &type) const -{ - if (type.kind == CXType_Pointer) { // Check for function pointers, first. - const CXType pointeeType = clang_getPointeeType(type); - const int argCount = clang_getNumArgTypes(pointeeType); - if (argCount >= 0) { - TypeInfo result = createTypeInfoHelper(clang_getResultType(pointeeType)); - result.setFunctionPointer(true); - for (int a = 0; a < argCount; ++a) - result.addArgument(createTypeInfoHelper(clang_getArgType(pointeeType, unsigned(a)))); - return result; - } - } - - TypeInfo typeInfo; - - CXType nestedType = type; - for (; isArrayType(nestedType.kind); nestedType = clang_getArrayElementType(nestedType)) { - const long long size = clang_getArraySize(nestedType); - typeInfo.addArrayElement(size >= 0 ? QString::number(size) : QString()); - } - - TypeInfo::Indirections indirections; - for (; isPointerType(nestedType.kind); nestedType = clang_getPointeeType(nestedType)) { - switch (nestedType.kind) { - case CXType_Pointer: - indirections.prepend(clang_isConstQualifiedType(nestedType) != 0 - ? Indirection::ConstPointer : Indirection::Pointer); - break; - case CXType_LValueReference: - typeInfo.setReferenceType(LValueReference); - break; - case CXType_RValueReference: - typeInfo.setReferenceType(RValueReference); - break; - default: - break; - } - } - typeInfo.setIndirectionsV(indirections); - - typeInfo.setConstant(clang_isConstQualifiedType(nestedType) != 0); - typeInfo.setVolatile(clang_isVolatileQualifiedType(nestedType) != 0); - - QString typeName = getTypeName(nestedType); - while (TypeInfo::stripLeadingConst(&typeName) - || TypeInfo::stripLeadingVolatile(&typeName)) { - } - - // Obtain template instantiations if the name has '<' (thus excluding - // typedefs like "std::string". - if (typeName.contains(QLatin1Char('<'))) - addTemplateInstantiations(nestedType, &typeName, &typeInfo); - - typeInfo.setQualifiedName(qualifiedName(typeName)); - // 3320:CINDEX_LINKAGE int clang_getNumArgTypes(CXType T); function ptr types? - typeInfo.simplifyStdType(); - return typeInfo; -} - -TypeInfo BuilderPrivate::createTypeInfo(const CXType &type) const -{ - TypeInfoHash::iterator it = m_typeInfoHash.find(type); - if (it == m_typeInfoHash.end()) - it = m_typeInfoHash.insert(type, createTypeInfoHelper(type)); - return it.value(); -} - -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()); - item->setType(createTypeInfo(cxType)); - item->setScope(m_scope); - m_scopeStack.back()->addTypeDef(item); - m_cursorTypedefHash.insert(cursor, item); -} - -void BuilderPrivate::startTemplateTypeAlias(const CXCursor &cursor) -{ - const QString target = getCursorSpelling(cursor); - m_currentTemplateTypeAlias.reset(new _TemplateTypeAliasModelItem(m_model, target)); - setFileName(cursor, m_currentTemplateTypeAlias.data()); - m_currentTemplateTypeAlias->setScope(m_scope); -} - -void BuilderPrivate::endTemplateTypeAlias(const CXCursor &typeAliasCursor) -{ - CXType type = clang_getTypedefDeclUnderlyingType(typeAliasCursor); - // Usually "<elaborated>std::list<T>" or "<unexposed>Container1<T>", - // as obtained with parser of PYSIDE-323 - if (type.kind == CXType_Unexposed || type.kind == CXType_Elaborated) { - m_currentTemplateTypeAlias->setType(createTypeInfo(type)); - m_scopeStack.back()->addTemplateTypeAlias(m_currentTemplateTypeAlias); - } - m_currentTemplateTypeAlias.reset(); -} - -// extract an expression from the cursor via source -// CXCursor_EnumConstantDecl, ParmDecl (a = Flag1 | Flag2) -QString BuilderPrivate::cursorValueExpression(BaseVisitor *bv, const CXCursor &cursor) const -{ - BaseVisitor::CodeSnippet snippet = bv->getCodeSnippet(cursor); - const char *equalSign = std::find(snippet.first, snippet.second, '='); - if (equalSign == snippet.second) - return QString(); - ++equalSign; - return QString::fromLocal8Bit(equalSign, int(snippet.second - equalSign)).trimmed(); -} - -// A hacky reimplementation of clang_EnumDecl_isScoped() for Clang < 5.0 -// which simply checks for a blank-delimited " class " keyword in the enum snippet. - -#define CLANG_NO_ENUMDECL_ISSCOPED \ - (CINDEX_VERSION_MAJOR == 0 && CINDEX_VERSION_MINOR < 43) - -#if CLANG_NO_ENUMDECL_ISSCOPED -static const char *indexOf(const BaseVisitor::CodeSnippet &snippet, const char *needle) -{ - const size_t snippetLength = snippet.first ? size_t(snippet.second - snippet.first) : 0; - const size_t needleLength = strlen(needle); - if (needleLength > snippetLength) - return nullptr; - for (const char *c = snippet.first, *end = snippet.second - needleLength; c < end; ++c) { - if (memcmp(c, needle, needleLength) == 0) - return c; - } - return nullptr; -} - -long clang_EnumDecl_isScoped4(BaseVisitor *bv, const CXCursor &cursor) -{ - BaseVisitor::CodeSnippet snippet = bv->getCodeSnippet(cursor); - const char *classSpec = indexOf(snippet, "class"); - const bool isClass = classSpec && classSpec > snippet.first - && isspace(*(classSpec - 1)) && isspace(*(classSpec + 5)); - return isClass ? 1 : 0; -} -#endif // CLANG_NO_ENUMDECL_ISSCOPED - -// Resolve declaration and type of a base class - -struct TypeDeclaration -{ - CXType type; - CXCursor declaration; -}; - -static TypeDeclaration resolveBaseSpecifier(const CXCursor &cursor) -{ - Q_ASSERT(clang_getCursorKind(cursor) == CXCursor_CXXBaseSpecifier); - CXType inheritedType = clang_getCursorType(cursor); - CXCursor decl = clang_getTypeDeclaration(inheritedType); - if (inheritedType.kind != CXType_Unexposed) { - while (true) { - auto kind = clang_getCursorKind(decl); - if (kind != CXCursor_TypeAliasDecl && kind != CXCursor_TypedefDecl) - break; - inheritedType = clang_getTypedefDeclUnderlyingType(decl); - decl = clang_getTypeDeclaration(inheritedType); - } - } - return {inheritedType, decl}; -} - -// Add a base class to the current class from CXCursor_CXXBaseSpecifier -void BuilderPrivate::addBaseClass(const CXCursor &cursor) -{ - Q_ASSERT(clang_getCursorKind(cursor) == CXCursor_CXXBaseSpecifier); - // Note: spelling has "struct baseClass", use type - QString baseClassName; - const auto decl = resolveBaseSpecifier(cursor); - 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); - - auto it = m_cursorClassHash.constFind(decl.declaration); - const CodeModel::AccessPolicy access = accessPolicy(clang_getCXXAccessSpecifier(cursor)); - if (it == m_cursorClassHash.constEnd()) { - // 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. - m_currentClass->addBaseClass(baseClassName, access); - return; - } - // Completely qualify the class name by looking it up and taking its scope - // plus the actual baseClass stripped off any scopes. Consider: - // namespace std { - // template <class T> class vector {}; - // namespace n { - // class Foo : public vector<int> {}; - // } - // } - // should have "std::vector<int>" as base class (whereas the type of the base class is - // "std::vector<T>"). - const QStringList &baseScope = it.value()->scope(); - if (!baseScope.isEmpty()) { - const int lastSep = baseClassName.lastIndexOf(colonColon()); - if (lastSep >= 0) - baseClassName.remove(0, lastSep + colonColon().size()); - baseClassName.prepend(colonColon()); - baseClassName.prepend(baseScope.join(colonColon())); - } - 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); - } - } -} - -Builder::Builder() -{ - d = new BuilderPrivate(this); -} - -Builder::~Builder() -{ - delete d; -} - -static const char *cBaseName(const char *fileName) -{ - const char *lastSlash = std::strrchr(fileName, '/'); -#ifdef Q_OS_WIN - if (lastSlash == nullptr) - lastSlash = std::strrchr(fileName, '\\'); -#endif - return lastSlash != nullptr ? (lastSlash + 1) : fileName; -} - -static inline bool cCompareFileName(const char *f1, const char *f2) -{ -#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; -} -#endif - -static bool cStringStartsWith(const char *str, const QByteArray &prefix) -{ - return std::strncmp(prefix.constData(), str, int(prefix.size())) == 0; -} - -bool BuilderPrivate::visitHeader(const char *cFileName) 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; - } -#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; - } - } - for (const auto &systemIncludePath : m_systemIncludePaths) { - if (cStringStartsWith(cFileName, systemIncludePath)) - return true; - } - return false; -} - -bool Builder::visitLocation(const CXSourceLocation &location) 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; -} - -void Builder::setSystemIncludes(const QByteArrayList &systemIncludes) -{ - for (const auto &i : systemIncludes) { - if (i.endsWith('/')) - d->m_systemIncludePaths.append(i); - else - d->m_systemIncludes.append(i); - } -} - -FileModelItem Builder::dom() const -{ - Q_ASSERT(!d->m_scopeStack.isEmpty()); - return qSharedPointerDynamicCast<_FileModelItem>(d->m_scopeStack.constFirst()); -} - -static QString msgOutOfOrder(const CXCursor &cursor, const char *expectedScope) -{ - return getCursorKindName(cursor.kind) + QLatin1Char(' ') - + getCursorSpelling(cursor) + QLatin1String(" encountered outside ") - + QLatin1String(expectedScope) + QLatin1Char('.'); -} - -static CodeModel::ClassType codeModelClassTypeFromCursor(CXCursorKind kind) -{ - CodeModel::ClassType result = CodeModel::Class; - if (kind == CXCursor_UnionDecl) - result = CodeModel::Union; - else if (kind == CXCursor_StructDecl) - result = CodeModel::Struct; - return result; -} - -static NamespaceType namespaceType(const CXCursor &cursor) -{ - if (clang_Cursor_isAnonymous(cursor)) - return NamespaceType::Anonymous; -#if CINDEX_VERSION_MAJOR > 0 || CINDEX_VERSION_MINOR >= 59 - if (clang_Cursor_isInlineNamespace(cursor)) - return NamespaceType::Inline; -#endif - return NamespaceType::Default; -} - -static QString enumType(const CXCursor &cursor) -{ - QString name = getCursorSpelling(cursor); // "enum Foo { v1, v2 };" - 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"))) - name.clear(); - } - return name; -} - -BaseVisitor::StartTokenResult Builder::startToken(const CXCursor &cursor) -{ - switch (cursor.kind) { - case CXCursor_CXXAccessSpecifier: - d->m_currentFunctionType = CodeModel::Normal; - break; - case CXCursor_AnnotateAttr: { - const QString annotation = getCursorSpelling(cursor); - if (annotation == QLatin1String("qt_slot")) - d->m_currentFunctionType = CodeModel::Slot; - else if (annotation == QLatin1String("qt_signal")) - d->m_currentFunctionType = CodeModel::Signal; - else - d->m_currentFunctionType = CodeModel::Normal; - } - break; - case CXCursor_CXXBaseSpecifier: - if (d->m_currentClass.isNull()) { - const Diagnostic d(msgOutOfOrder(cursor, "class"), cursor, CXDiagnostic_Error); - qWarning() << d; - appendDiagnostic(d); - return Error; - } - d->addBaseClass(cursor); - break; - case CXCursor_ClassDecl: - case CXCursor_UnionDecl: - case CXCursor_StructDecl: - if (clang_isCursorDefinition(cursor) == 0) - return Skip; - if (!d->addClass(cursor, codeModelClassTypeFromCursor(cursor.kind))) - return Error; - break; - case CXCursor_ClassTemplate: - case CXCursor_ClassTemplatePartialSpecialization: - if (clang_isCursorDefinition(cursor) == 0) - return Skip; - d->addClass(cursor, CodeModel::Class); - d->m_currentClass->setName(d->m_currentClass->name() + templateBrackets()); - d->m_scope.back() += templateBrackets(); - break; - case CXCursor_EnumDecl: { - QString name = enumType(cursor); - EnumKind kind = CEnum; - if (name.isEmpty()) { - kind = AnonymousEnum; - name = QStringLiteral("enum_") + QString::number(++d->m_anonymousEnumCount); -#if !CLANG_NO_ENUMDECL_ISSCOPED - } else if (clang_EnumDecl_isScoped(cursor) != 0) { -#else - } else if (clang_EnumDecl_isScoped4(this, cursor) != 0) { -#endif - kind = EnumClass; - } - d->m_currentEnum.reset(new _EnumModelItem(d->m_model, name)); - setFileName(cursor, d->m_currentEnum.data()); - 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()) - d->m_currentEnum->setAccessPolicy(accessPolicy(clang_getCXXAccessSpecifier(cursor))); - } - break; - case CXCursor_EnumConstantDecl: { - const QString name = getCursorSpelling(cursor); - if (d->m_currentEnum.isNull()) { - const Diagnostic d(msgOutOfOrder(cursor, "enum"), cursor, CXDiagnostic_Error); - qWarning() << d; - appendDiagnostic(d); - return Error; - } - EnumValue enumValue; - if (d->m_currentEnum->isSigned()) - enumValue.setValue(clang_getEnumConstantDeclValue(cursor)); - else - enumValue.setUnsignedValue(clang_getEnumConstantDeclUnsignedValue(cursor)); - EnumeratorModelItem enumConstant(new _EnumeratorModelItem(d->m_model, name)); - enumConstant->setStringValue(d->cursorValueExpression(this, cursor)); - enumConstant->setValue(enumValue); - d->m_currentEnum->addEnumerator(enumConstant); - } - break; - case CXCursor_VarDecl: - // static class members are seen as CXCursor_VarDecl - if (!d->m_currentClass.isNull() && isClassCursor(clang_getCursorSemanticParent(cursor))) { - d->addField(cursor); - d->m_currentField->setStatic(true); - } - break; - case CXCursor_FieldDecl: - d->addField(cursor); - break; -#if CINDEX_VERSION_MAJOR > 0 || CINDEX_VERSION_MINOR >= 37 // Clang 4.0 - case CXCursor_FriendDecl: - return Skip; -#endif - case CXCursor_Constructor: - case CXCursor_Destructor: // Note: Also use clang_CXXConstructor_is..Constructor? - case CXCursor_CXXMethod: - case CXCursor_ConversionFunction: - // Skip inline member functions outside class, only go by declarations inside class - if (!withinClassDeclaration(cursor)) - return Skip; - d->m_currentFunction = d->createMemberFunction(cursor); - d->m_scopeStack.back()->addFunction(d->m_currentFunction); - break; - // Not fully supported, currently, seen as normal function - // Note: May appear inside class (member template) or outside (free template). - case CXCursor_FunctionTemplate: { - const CXCursor semParent = clang_getCursorSemanticParent(cursor); - if (isClassCursor(semParent)) { - if (semParent == clang_getCursorLexicalParent(cursor)) { - d->m_currentFunction = d->createMemberFunction(cursor); - d->m_scopeStack.back()->addFunction(d->m_currentFunction); - break; - } - return Skip; // inline member functions outside class - } - } - Q_FALLTHROUGH(); // fall through to free template function. - case CXCursor_FunctionDecl: - d->m_currentFunction = d->createFunction(cursor); - d->m_scopeStack.back()->addFunction(d->m_currentFunction); - break; - case CXCursor_Namespace: { - const auto type = namespaceType(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 QString message = msgOutOfOrder(cursor, "namespace") - + QLatin1String(" (current scope: ") + d->m_scopeStack.back()->name() + QLatin1Char(')'); - const Diagnostic d(message, cursor, CXDiagnostic_Error); - qWarning() << d; - appendDiagnostic(d); - return Error; - } - // Treat namespaces separately to allow for extending namespaces - // in subsequent modules. - NamespaceModelItem namespaceItem = parentNamespaceItem->findNamespace(name); - namespaceItem.reset(new _NamespaceModelItem(d->m_model, name)); - setFileName(cursor, namespaceItem.data()); - namespaceItem->setScope(d->m_scope); - namespaceItem->setType(type); - parentNamespaceItem->addNamespace(namespaceItem); - d->pushScope(namespaceItem); - } - break; - 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()) { - const QString name = getCursorSpelling(cursor); - d->m_currentArgument.reset(new _ArgumentModelItem(d->m_model, name)); - d->m_currentArgument->setType(d->createTypeInfo(cursor)); - d->m_currentFunction->addArgument(d->m_currentArgument); - QString defaultValueExpression = d->cursorValueExpression(this, cursor); - if (!defaultValueExpression.isEmpty()) { - d->m_currentArgument->setDefaultValueExpression(defaultValueExpression); - d->m_currentArgument->setDefaultValue(true); - } - } else { - return Skip; - } - break; - case CXCursor_TemplateTypeParameter: - case CXCursor_NonTypeTemplateParameter: { - const TemplateParameterModelItem tItem = cursor.kind == CXCursor_TemplateTemplateParameter - ? d->createTemplateParameter(cursor) : d->createNonTypeTemplateParameter(cursor); - // Apply to function/member template? - if (!d->m_currentFunction.isNull()) { - d->m_currentFunction->setTemplateParameters(d->m_currentFunction->templateParameters() << tItem); - } else if (!d->m_currentTemplateTypeAlias.isNull()) { - d->m_currentTemplateTypeAlias->addTemplateParameter(tItem); - } else if (!d->m_currentClass.isNull()) { // 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 Diagnostic d(message, cursor, CXDiagnostic_Error); - qWarning() << d; - appendDiagnostic(d); - return Error; - } - d->m_currentClass->setTemplateParameters(d->m_currentClass->templateParameters() << tItem); - } - } - break; - case CXCursor_TypeAliasTemplateDecl: - d->startTemplateTypeAlias(cursor); - break; - case CXCursor_TypeAliasDecl: // May contain nested CXCursor_TemplateTypeParameter - if (d->m_currentTemplateTypeAlias.isNull()) { - const CXType type = clang_getCanonicalType(clang_getCursorType(cursor)); - if (type.kind > CXType_Unexposed) - d->addTypeDef(cursor, type); - return Skip; - } else { - d->endTemplateTypeAlias(cursor); - } - break; - case CXCursor_TypedefDecl: { - auto underlyingType = clang_getTypedefDeclUnderlyingType(cursor); - d->addTypeDef(cursor, underlyingType); - // For "typedef enum/struct {} Foo;", skip the enum/struct - // definition nested into the typedef (PYSIDE-1228). - if (underlyingType.kind == CXType_Elaborated) - return Skip; - } - 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); - } - break; - case CXCursor_CXXFinalAttr: - if (!d->m_currentFunction.isNull()) - d->m_currentFunction->setFinal(true); - else if (!d->m_currentClass.isNull()) - d->m_currentClass->setFinal(true); - break; - case CXCursor_CXXOverrideAttr: - if (!d->m_currentFunction.isNull()) - d->m_currentFunction->setOverride(true); - break; - default: - break; - } - return BaseVisitor::Recurse; -} - -bool Builder::endToken(const CXCursor &cursor) -{ - switch (cursor.kind) { - case CXCursor_UnionDecl: - case CXCursor_ClassDecl: - case CXCursor_StructDecl: - case CXCursor_ClassTemplate: - case CXCursor_ClassTemplatePartialSpecialization: - d->popScope(); - // Continue in outer class after leaving inner class? - if (ClassModelItem lastClass = qSharedPointerDynamicCast<_ClassModelItem>(d->m_scopeStack.back())) - d->m_currentClass = lastClass; - else - d->m_currentClass.clear(); - 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()) - d->m_scopeStack.back()->addEnum(d->m_currentEnum); - d->m_currentEnum.clear(); - break; - case CXCursor_VarDecl: - case CXCursor_FieldDecl: - d->m_currentField.clear(); - break; - case CXCursor_Constructor: - d->qualifyConstructor(cursor); - d->m_currentFunction.clear(); - break; - case CXCursor_Destructor: - case CXCursor_CXXMethod: - case CXCursor_FunctionDecl: - case CXCursor_FunctionTemplate: - d->m_currentFunction.clear(); - break; - case CXCursor_Namespace: - d->popScope(); - break; - case CXCursor_ParmDecl: - d->m_currentArgument.clear(); - break; - case CXCursor_TypeAliasTemplateDecl: - d->m_currentTemplateTypeAlias.reset(); - break; - default: - break; - } - return true; -} - -} // namespace clang diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h b/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h deleted file mode 100644 index dc37dff0f..000000000 --- a/sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef CLANGBUILDER_H -#define CLANGBUILDER_H - -#include "clangparser.h" - -#include <codemodel_fwd.h> - -namespace clang { - -class BuilderPrivate; - -class Builder : public BaseVisitor { -public: - Q_DISABLE_COPY(Builder) - - Builder(); - ~Builder(); - - void setSystemIncludes(const QByteArrayList &systemIncludes); - - bool visitLocation(const CXSourceLocation &location) const override; - - StartTokenResult startToken(const CXCursor &cursor) override; - bool endToken(const CXCursor &cursor) override; - - FileModelItem dom() const; - -private: - BuilderPrivate *d; -}; - -} // namespace clang - -#endif // CLANGBUILDER_H diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.cpp deleted file mode 100644 index d6915daab..000000000 --- a/sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#include "clangdebugutils.h" -#include "clangutils.h" - -#include <QtCore/QDebug> -#include <QtCore/QString> - -#include <string.h> - -#ifndef QT_NO_DEBUG_STREAM - -#ifdef Q_OS_WIN -const char pathSep = '\\'; -#else -const char pathSep = '/'; -#endif - -static const char *baseName(const char *fileName) -{ - const char *b = strrchr(fileName, pathSep); - return b ? b + 1 : fileName; -} - -QDebug operator<<(QDebug s, const CXString &cs) -{ - s << clang_getCString(cs); - return s; -} - -QDebug operator<<(QDebug s, CXCursorKind cursorKind) // Enum -{ - const CXString kindName = clang_getCursorKindSpelling(cursorKind); - s << kindName; - clang_disposeString(kindName); - return s; -} - -static const char *accessSpecsStrings[] -{ - // CX_CXXInvalidAccessSpecifier, CX_CXXPublic, CX_CXXProtected, CX_CXXPrivate - "invalid", "public", "protected", "private" -}; - -QDebug operator<<(QDebug s, CX_CXXAccessSpecifier ac) -{ - s << accessSpecsStrings[ac]; - return s; -} - -QDebug operator<<(QDebug s, const CXType &t) -{ - CXString typeSpelling = clang_getTypeSpelling(t); - s << typeSpelling; - clang_disposeString(typeSpelling); - return s; -} - -QDebug operator<<(QDebug s, const CXCursor &cursor) -{ - QDebugStateSaver saver(s); - s.nospace(); - s.noquote(); - const CXCursorKind kind = clang_getCursorKind(cursor); - s << kind; - if (kind >= CXCursor_FirstInvalid && kind <= CXCursor_LastInvalid) - return s; - const CXType type = clang_getCursorType(cursor); - switch (kind) { - case CXCursor_CXXAccessSpecifier: - s << ' ' << clang_getCXXAccessSpecifier(cursor); - break; - case CXCursor_CXXBaseSpecifier: - s << ", inherits=\"" << clang::getCursorSpelling(clang_getTypeDeclaration(type)) << '"'; - break; - case CXCursor_CXXMethod: - case CXCursor_FunctionDecl: - case CXCursor_ConversionFunction: - s << ", result type=\"" << clang_getCursorResultType(cursor) << '"'; - break; - case CXCursor_TypedefDecl: - s << ", underlyingType=\"" << clang_getTypedefDeclUnderlyingType(cursor) << '"'; - break; - default: - break; - } - - if (type.kind != CXType_Invalid) - s << ", type=\"" << type << '"'; - if (clang_Cursor_hasAttrs(cursor)) - s << ", [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; -} - -QDebug operator<<(QDebug s, const CXSourceLocation &location) -{ - QDebugStateSaver saver(s); - s.nospace(); - 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 - if (const char *cFileName = clang_getCString(cxFileName)) - s << baseName(cFileName) << ':'; - s << line << ':' << column; - clang_disposeString(cxFileName); - return s; -} - -#endif // !QT_NO_DEBUG_STREAM diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.h b/sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.h deleted file mode 100644 index 2bbe526f7..000000000 --- a/sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.h +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef CLANGDEBUGUTILS_H -#define CLANGDEBUGUTILS_H - -#include <QtCore/QtGlobal> - -#include <clang-c/Index.h> - -QT_FORWARD_DECLARE_CLASS(QDebug) -QT_FORWARD_DECLARE_CLASS(QString) - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug s, const CXString &cs); -QDebug operator<<(QDebug s, CXCursorKind cursorKind); -QDebug operator<<(QDebug s, CX_CXXAccessSpecifier ac); -QDebug operator<<(QDebug s, const CXType &t); -QDebug operator<<(QDebug s, const CXCursor &cursor); -QDebug operator<<(QDebug s, const CXSourceLocation &location); -#endif // !QT_NO_DEBUG_STREAM - -#endif // CLANGDEBUGUTILS_H diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp deleted file mode 100644 index 6303d09e5..000000000 --- a/sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp +++ /dev/null @@ -1,266 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#include "clangparser.h" -#include "clangutils.h" -#include "clangdebugutils.h" -#include "compilersupport.h" - -#include <QtCore/QByteArrayList> -#include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtCore/QFile> -#include <QtCore/QScopedArrayPointer> -#include <QtCore/QString> - -namespace clang { - -SourceFileCache::Snippet SourceFileCache::getCodeSnippet(const CXCursor &cursor) -{ - Snippet result(nullptr, nullptr); - const SourceRange range = getCursorRange(cursor); - if (range.first.file.isEmpty() || range.second.file != range.first.file) - return result; - FileBufferCache::Iterator it = m_fileBufferCache.find(range.first.file); - if (it == m_fileBufferCache.end()) { - QFile file(range.first.file); - if (!file.open(QIODevice::ReadOnly)) { - qWarning().noquote().nospace() - << "Can't open " << QDir::toNativeSeparators(range.first.file) - << ": " << file.errorString(); - return result; - } - it = m_fileBufferCache.insert(range.first.file, file.readAll()); - } - - const unsigned pos = range.first.offset; - const unsigned end = range.second.offset; - const QByteArray &contents = it.value(); - if (end >= unsigned(contents.size())) { - qWarning().noquote().nospace() << "Range end " << end << " is above size of " - << range.first.file << " (" << contents.size() << ')'; - return result; - } - result.first = contents.constData() + pos; - result.second = contents.constData() + end; - return result; -} - -BaseVisitor::BaseVisitor() = default; -BaseVisitor::~BaseVisitor() = default; - -bool BaseVisitor::visitLocation(const CXSourceLocation &location) const -{ - return clang_Location_isFromMainFile(location) != 0; -} - -BaseVisitor::StartTokenResult BaseVisitor::cbHandleStartToken(const CXCursor &cursor) -{ - switch (cursor.kind) { - default: - break; - } - - return startToken(cursor); -} - -bool BaseVisitor::cbHandleEndToken(const CXCursor &cursor, StartTokenResult startResult) -{ - const bool result = startResult != Recurse || endToken(cursor); - switch (cursor.kind) { - default: - break; - } - - return result; -} - -BaseVisitor::CodeSnippet BaseVisitor::getCodeSnippet(const CXCursor &cursor) -{ - CodeSnippet result = m_fileCache.getCodeSnippet(cursor); - if (result.first == nullptr) - appendDiagnostic(Diagnostic(QStringLiteral("Unable to retrieve code snippet."), cursor, CXDiagnostic_Error)); - return result; -} - -QString BaseVisitor::getCodeSnippetString(const CXCursor &cursor) -{ - CodeSnippet result = m_fileCache.getCodeSnippet(cursor); - return result.first != nullptr - ? QString::fromUtf8(result.first, int(result.second - result.first)) - : QString(); -} - -static CXChildVisitResult - visitorCallback(CXCursor cursor, CXCursor /* parent */, CXClientData clientData) -{ - auto *bv = reinterpret_cast<BaseVisitor *>(clientData); - - const CXSourceLocation location = clang_getCursorLocation(cursor); - if (!bv->visitLocation(location)) - return CXChildVisit_Continue; - - const BaseVisitor::StartTokenResult startResult = bv->cbHandleStartToken(cursor); - switch (startResult) { - case clang::BaseVisitor::Error: - return CXChildVisit_Break; - case clang::BaseVisitor::Skip: - break; - case clang::BaseVisitor::Recurse: - clang_visitChildren(cursor, visitorCallback, clientData); - break; - } - - if (!bv->cbHandleEndToken(cursor, startResult)) - return CXChildVisit_Break; - - return CXChildVisit_Continue; -} - -BaseVisitor::Diagnostics BaseVisitor::diagnostics() const -{ - return m_diagnostics; -} - -void BaseVisitor::setDiagnostics(const Diagnostics &d) -{ - m_diagnostics = d; -} - -void BaseVisitor::appendDiagnostic(const Diagnostic &d) -{ - m_diagnostics.append(d); -} - -static inline const char **byteArrayListToFlatArgV(const QByteArrayList &bl) -{ - const char **result = new const char *[bl.size() + 1]; - result[bl.size()] = nullptr; - std::transform(bl.cbegin(), bl.cend(), result, - [] (const QByteArray &a) { return a.constData(); }); - return result; -} - -static QByteArray msgCreateTranslationUnit(const QByteArrayList &clangArgs, unsigned flags) -{ - QByteArray result = "clang_parseTranslationUnit2(0x"; - result += QByteArray::number(flags, 16); - const int count = clangArgs.size(); - result += ", cmd[" + QByteArray::number(count) + "]="; - for (int i = 0; i < count; ++i) { - const QByteArray &arg = clangArgs.at(i); - if (i) - result += ' '; - const bool quote = arg.contains(' ') || arg.contains('('); - if (quote) - result += '"'; - result += arg; - if (quote) - result += '"'; - } - result += ')'; - return result; -} - -static CXTranslationUnit createTranslationUnit(CXIndex index, - const QByteArrayList &args, - unsigned flags = 0) -{ - // courtesy qdoc - const unsigned defaultFlags = CXTranslationUnit_SkipFunctionBodies - | CXTranslationUnit_Incomplete; - - static const QByteArrayList defaultArgs = { -#ifndef Q_OS_WIN - "-fPIC", -#endif -#ifdef Q_OS_MACOS - "-Wno-expansion-to-defined", // Workaround for warnings in Darwin stdlib, see - // https://github.com/darlinghq/darling/issues/204 -#endif - "-Wno-constant-logical-operand" - }; - - const QByteArrayList clangArgs = emulatedCompilerOptions() + defaultArgs + args; - QScopedArrayPointer<const char *> argv(byteArrayListToFlatArgV(clangArgs)); - qDebug().noquote().nospace() << msgCreateTranslationUnit(clangArgs, flags); - - CXTranslationUnit tu; - CXErrorCode err = clang_parseTranslationUnit2(index, nullptr, argv.data(), - clangArgs.size(), nullptr, 0, - defaultFlags | flags, &tu); - if (err || !tu) { - qWarning().noquote().nospace() << "Could not parse " - << clangArgs.constLast().constData() << ", error code: " << err; - return nullptr; - } - return tu; -} - -/* clangFlags are flags to clang_parseTranslationUnit2() such as - * CXTranslationUnit_KeepGoing (from CINDEX_VERSION_MAJOR/CINDEX_VERSION_MINOR 0.35) - */ - -bool parse(const QByteArrayList &clangArgs, unsigned clangFlags, BaseVisitor &bv) -{ - CXIndex index = clang_createIndex(0 /* excludeDeclarationsFromPCH */, - 1 /* displayDiagnostics */); - if (!index) { - qWarning() << "clang_createIndex() failed!"; - return false; - } - - CXTranslationUnit translationUnit = createTranslationUnit(index, clangArgs, clangFlags); - if (!translationUnit) - return false; - - CXCursor rootCursor = clang_getTranslationUnitCursor(translationUnit); - - clang_visitChildren(rootCursor, visitorCallback, reinterpret_cast<CXClientData>(&bv)); - - QVector<Diagnostic> diagnostics = getDiagnostics(translationUnit); - diagnostics.append(bv.diagnostics()); - bv.setDiagnostics(diagnostics); - - const bool ok = maxSeverity(diagnostics) < CXDiagnostic_Error; - if (!ok) { - QDebug debug = qWarning(); - debug.noquote(); - debug.nospace(); - debug << "Errors in " - << QDir::toNativeSeparators(QFile::decodeName(clangArgs.constLast())) << ":\n"; - for (const Diagnostic &diagnostic : qAsConst(diagnostics)) - debug << diagnostic << '\n'; - } - - clang_disposeTranslationUnit(translationUnit); - clang_disposeIndex(index); - return ok; -} - -} // namespace clang diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangparser.h b/sources/shiboken2/ApiExtractor/clangparser/clangparser.h deleted file mode 100644 index 4248be853..000000000 --- a/sources/shiboken2/ApiExtractor/clangparser/clangparser.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef CLANGPARSER_H -#define CLANGPARSER_H - -#include <clang-c/Index.h> - -#include <QtCore/QByteArrayList> -#include <QtCore/QHash> -#include <QtCore/QPair> -#include <QtCore/QString> -#include <QtCore/QVector> - -namespace clang { - -struct Diagnostic; - -class SourceFileCache { -public: - using Snippet = QPair<const char *, const char *>; - - Snippet getCodeSnippet(const CXCursor &cursor); - -private: - using FileBufferCache = QHash<QString, QByteArray>; - - FileBufferCache m_fileBufferCache; -}; - -class BaseVisitor { - Q_DISABLE_COPY(BaseVisitor) -public: - using Diagnostics = QVector<Diagnostic>; - using CodeSnippet = SourceFileCache::Snippet; - - enum StartTokenResult { Error, Skip, Recurse }; - - BaseVisitor(); - virtual ~BaseVisitor(); - - // Whether location should be visited. - // defaults to clang_Location_isFromMainFile() - virtual bool visitLocation(const CXSourceLocation &location) const; - - virtual StartTokenResult startToken(const CXCursor &cursor) = 0; - virtual bool endToken(const CXCursor &cursor) = 0; - - StartTokenResult cbHandleStartToken(const CXCursor &cursor); - bool cbHandleEndToken(const CXCursor &cursor, StartTokenResult startResult); - - CodeSnippet getCodeSnippet(const CXCursor &cursor); - QString getCodeSnippetString(const CXCursor &cursor); - - Diagnostics diagnostics() const; - void setDiagnostics(const Diagnostics &d); - void appendDiagnostic(const Diagnostic &d); - -private: - SourceFileCache m_fileCache; - Diagnostics m_diagnostics; -}; - -bool parse(const QByteArrayList &clangArgs, unsigned clangFlags, BaseVisitor &ctx); - -} // namespace clang - -#endif // !CLANGPARSER_H diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp b/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp deleted file mode 100644 index df2476100..000000000 --- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#include "clangutils.h" - -#include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtCore/QHashFunctions> -#include <QtCore/QProcess> - -bool operator==(const CXCursor &c1, const CXCursor &c2) -{ - return c1.kind == c2.kind - && c1.xdata == c2.xdata - && std::equal(c1.data, c1.data + sizeof(c1.data) / sizeof(c1.data[0]), c2.data); -} - -QtCompatHashFunctionType qHash(const CXCursor &c, QtCompatHashFunctionType seed) -{ - return qHash(c.kind) ^ qHash(c.xdata) ^ qHash(c.data[0]) - ^ qHash(c.data[1]) ^ qHash(c.data[2]) ^ seed; -} - -bool operator==(const CXType &t1, const CXType &t2) -{ - return t1.kind == t2.kind && t1.data[0] == t2.data[0] - && t1.data[1] == t2.data[1]; -} - -QtCompatHashFunctionType qHash(const CXType &ct, QtCompatHashFunctionType seed) -{ - return QtCompatHashFunctionType(ct.kind) ^ QtCompatHashFunctionType(0xFFFFFFFF & quintptr(ct.data[0])) - ^ QtCompatHashFunctionType(0xFFFFFFFF & quintptr(ct.data[1])) ^ seed; -} - -namespace clang { - -SourceLocation getExpansionLocation(const CXSourceLocation &location) -{ - SourceLocation result; - CXFile file; // void * - clang_getExpansionLocation(location, &file, &result.line, &result.column, &result.offset); - const CXString cxFileName = clang_getFileName(file); - // Has been observed to be 0 for invalid locations - if (const char *cFileName = clang_getCString(cxFileName)) - result.file = QString::fromUtf8(cFileName); - clang_disposeString(cxFileName); - return result; -} - -SourceLocation getCursorLocation(const CXCursor &cursor) -{ - const CXSourceRange extent = clang_getCursorExtent(cursor); - return getExpansionLocation(clang_getRangeStart(extent)); -} - -CXString getFileNameFromLocation(const CXSourceLocation &location) -{ - CXFile file; - unsigned line; - unsigned column; - unsigned offset; - clang_getExpansionLocation(location, &file, &line, &column, &offset); - return clang_getFileName(file); -} - -SourceRange getCursorRange(const CXCursor &cursor) -{ - const CXSourceRange extent = clang_getCursorExtent(cursor); - return qMakePair(getExpansionLocation(clang_getRangeStart(extent)), - getExpansionLocation(clang_getRangeEnd(extent))); -} - -QString getCursorKindName(CXCursorKind cursorKind) -{ - CXString kindName = clang_getCursorKindSpelling(cursorKind); - const QString result = QString::fromUtf8(clang_getCString(kindName)); - clang_disposeString(kindName); - return result; -} - -QString getCursorSpelling(const CXCursor &cursor) -{ - CXString cursorSpelling = clang_getCursorSpelling(cursor); - const QString result = QString::fromUtf8(clang_getCString(cursorSpelling)); - clang_disposeString(cursorSpelling); - return result; -} - -QString getCursorDisplayName(const CXCursor &cursor) -{ - CXString displayName = clang_getCursorDisplayName(cursor); - const QString result = QString::fromUtf8(clang_getCString(displayName)); - clang_disposeString(displayName); - return result; -} - -QString getTypeName(const CXType &type) -{ - CXString typeSpelling = clang_getTypeSpelling(type); - const QString result = QString::fromUtf8(clang_getCString(typeSpelling)); - clang_disposeString(typeSpelling); - return result; -} - -Diagnostic::Diagnostic(const QString &m, const CXCursor &c, CXDiagnosticSeverity s) - : message(m), location(getCursorLocation(c)), source(Other), severity(s) -{ -} - -Diagnostic Diagnostic::fromCXDiagnostic(CXDiagnostic cd) -{ - Diagnostic result; - result.source = Clang; - CXString spelling = clang_getDiagnosticSpelling(cd); - result.message = QString::fromUtf8(clang_getCString(spelling)); - clang_disposeString(spelling); - result.severity = clang_getDiagnosticSeverity(cd); - result.location = getExpansionLocation(clang_getDiagnosticLocation(cd)); - - CXDiagnosticSet childDiagnostics = clang_getChildDiagnostics(cd); - if (const unsigned childCount = clang_getNumDiagnosticsInSet(childDiagnostics)) { - result.childMessages.reserve(int(childCount)); - const unsigned format = clang_defaultDiagnosticDisplayOptions(); - for (unsigned i = 0; i < childCount; ++i) { - CXDiagnostic childDiagnostic = clang_getDiagnosticInSet(childDiagnostics, i); - CXString cdm = clang_formatDiagnostic(childDiagnostic, format); - result.childMessages.append(QString::fromUtf8(clang_getCString(cdm))); - clang_disposeString(cdm); - clang_disposeDiagnostic(childDiagnostic); - } - } - - return result; -} - -QVector<Diagnostic> getDiagnostics(CXTranslationUnit tu) -{ - QVector<Diagnostic> result; - const unsigned count = clang_getNumDiagnostics(tu); - result.reserve(int(count)); - for (unsigned i = 0; i < count; ++i) { - const CXDiagnostic d = clang_getDiagnostic(tu, i); - result.append(Diagnostic::fromCXDiagnostic(d)); - clang_disposeDiagnostic(d); - } - return result; -} - -QPair<int, int> parseTemplateArgumentList(const QString &l, - const TemplateArgumentHandler &handler, - int from) -{ - const int ltPos = l.indexOf(QLatin1Char('<'), from); - if (ltPos == - 1) - return qMakePair(-1, -1); - int startPos = ltPos + 1; - int level = 1; - for (int p = startPos, end = l.size(); p < end; ) { - const char c = l.at(p).toLatin1(); - switch (c) { - case ',': - case '>': - handler(level, l.midRef(startPos, p - startPos).trimmed()); - ++p; - if (c == '>') { - if (--level == 0) - return qMakePair(ltPos, p); - // Skip over next ',': "a<b<c,d>,e>" - for (; p < end && (l.at(p).isSpace() || l.at(p) == QLatin1Char(',')); ++p) {} - } - startPos = p; - break; - case '<': - handler(level, l.midRef(startPos, p - startPos).trimmed()); - ++level; - startPos = ++p; - break; - default: - ++p; - break; - } - } - return qMakePair(-1, -1); -} - -CXDiagnosticSeverity maxSeverity(const QVector<Diagnostic> &ds) -{ - CXDiagnosticSeverity result = CXDiagnostic_Ignored; - for (const Diagnostic& d : ds) { - if (d.severity > result) - result = d.severity; - } - return result; -} - -#ifndef QT_NO_DEBUG_STREAM - -QDebug operator<<(QDebug s, const SourceLocation &l) -{ - QDebugStateSaver saver(s); - s.nospace(); - s.noquote(); - s << QDir::toNativeSeparators(l.file) << ':' << l.line; - if (l.column) - s << ':' << l.column; - return s; -} - -// Roughly follow g++ format: -// file.cpp:214:37: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] -QDebug operator<<(QDebug s, const Diagnostic &d) -{ - QDebugStateSaver saver(s); - s.nospace(); - s.noquote(); - s << d.location << ": "; - switch (d.severity) { - case CXDiagnostic_Ignored: - s << "ignored"; - break; - case CXDiagnostic_Note: - s << "note"; - break; - case CXDiagnostic_Warning: - s << "warning"; - break; - case CXDiagnostic_Error: - s << "error"; - break; - case CXDiagnostic_Fatal: - s << "fatal"; - break; - } - s << ": " << d.message; - - if (d.source != Diagnostic::Clang) - s << " [other]"; - - if (const int childMessagesCount = d.childMessages.size()) { - s << '\n'; - for (int i = 0; i < childMessagesCount; ++i) - s << " " << d.childMessages.at(i) << '\n'; - } - - return s; -} - -#endif // QT_NO_DEBUG_STREAM - -} // namespace clang diff --git a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h b/sources/shiboken2/ApiExtractor/clangparser/clangutils.h deleted file mode 100644 index 5f005bd5d..000000000 --- a/sources/shiboken2/ApiExtractor/clangparser/clangutils.h +++ /dev/null @@ -1,116 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef CLANGUTILS_H -#define CLANGUTILS_H - -#include <clang-c/Index.h> -#include <qtcompat.h> -#include <QtCore/QPair> -#include <QtCore/QString> -#include <QtCore/QStringList> -#include <QtCore/QVector> - -#include <functional> - -QT_FORWARD_DECLARE_CLASS(QDebug) - -bool operator==(const CXCursor &c1, const CXCursor &c2); -QtCompatHashFunctionType qHash(const CXCursor &c, QtCompatHashFunctionType seed = 0); - -bool operator==(const CXType &t1, const CXType &t2); -QtCompatHashFunctionType qHash(const CXType &ct, QtCompatHashFunctionType seed); - -namespace clang { - -QString getCursorKindName(CXCursorKind cursorKind); -QString getCursorSpelling(const CXCursor &cursor); -QString getCursorDisplayName(const CXCursor &cursor); -QString getTypeName(const CXType &type); -inline QString getCursorTypeName(const CXCursor &cursor) - { return getTypeName(clang_getCursorType(cursor)); } -inline QString getCursorResultTypeName(const CXCursor &cursor) - { return getTypeName(clang_getCursorResultType(cursor)); } - -inline bool isCursorValid(const CXCursor &c) -{ - return c.kind < CXCursor_FirstInvalid || c.kind > CXCursor_LastInvalid; -} - -struct SourceLocation -{ - int compare(const SourceLocation &rhs) const; - - QString file; - unsigned line = 0; - unsigned column = 0; - unsigned offset = 0; -}; - -SourceLocation getExpansionLocation(const CXSourceLocation &location); - -using SourceRange =QPair<SourceLocation, SourceLocation>; - -SourceLocation getCursorLocation(const CXCursor &cursor); -CXString getFileNameFromLocation(const CXSourceLocation &location); -SourceRange getCursorRange(const CXCursor &cursor); - -struct Diagnostic { - enum Source { Clang, Other }; - - Diagnostic() = default; - // Clang - static Diagnostic fromCXDiagnostic(CXDiagnostic cd); - // Other - explicit Diagnostic(const QString &m, const CXCursor &c, CXDiagnosticSeverity s = CXDiagnostic_Warning); - - QString message; - QStringList childMessages; - SourceLocation location; - Source source = Clang; - CXDiagnosticSeverity severity = CXDiagnostic_Warning; -}; - -QVector<Diagnostic> getDiagnostics(CXTranslationUnit tu); -CXDiagnosticSeverity maxSeverity(const QVector<Diagnostic> &ds); - -// Parse a template argument list "a<b<c,d>,e>" and invoke a handler -// with each match (level and string). Return begin and end of the list. -using TemplateArgumentHandler = std::function<void (int, const QStringRef &)>; - -QPair<int, int> parseTemplateArgumentList(const QString &l, - const TemplateArgumentHandler &handler, - int from = 0); - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug, const SourceLocation &); -QDebug operator<<(QDebug, const Diagnostic &); -#endif // QT_NO_DEBUG_STREAM -} // namespace clang - -#endif // CLANGUTILS_H diff --git a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp deleted file mode 100644 index dac511003..000000000 --- a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp +++ /dev/null @@ -1,404 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#include "compilersupport.h" -#include "header_paths.h" - -#include <reporthandler.h> - -#include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtCore/QFile> -#include <QtCore/QFileInfo> -#include <QtCore/QProcess> -#include <QtCore/QStandardPaths> -#include <QtCore/QStringList> -#include <QtCore/QVersionNumber> - -#include <clang-c/Index.h> - -#include <string.h> -#include <algorithm> -#include <iterator> - -namespace clang { - -QVersionNumber libClangVersion() -{ - return QVersionNumber(CINDEX_VERSION_MAJOR, CINDEX_VERSION_MINOR); -} - -static bool runProcess(const QString &program, const QStringList &arguments, - QByteArray *stdOutIn = nullptr, QByteArray *stdErrIn = nullptr) -{ - QProcess process; - process.start(program, arguments, QProcess::ReadWrite); - if (!process.waitForStarted()) { - qWarning().noquote().nospace() << "Unable to start " - << process.program() << ": " << process.errorString(); - return false; - } - process.closeWriteChannel(); - const bool finished = process.waitForFinished(); - const QByteArray stdErr = process.readAllStandardError(); - if (stdErrIn) - *stdErrIn = stdErr; - if (stdOutIn) - *stdOutIn = process.readAllStandardOutput(); - - if (!finished) { - qWarning().noquote().nospace() << process.program() << " timed out: " << stdErr; - process.kill(); - return false; - } - - if (process.exitStatus() != QProcess::NormalExit) { - qWarning().noquote().nospace() << process.program() << " crashed: " << stdErr; - return false; - } - - if (process.exitCode() != 0) { - qWarning().noquote().nospace() << process.program() << " exited " - << process.exitCode() << ": " << stdErr; - return false; - } - - 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"); - - // If HOMEBREW_OPT is found we assume that the build is happening - // inside a brew environment, which means we need to filter out - // the -isystem flags added by the brew clang shim. This is needed - // because brew passes the Qt include paths as system include paths - // and because our parser ignores system headers, Qt classes won't - // be found and thus compilation errors will occur. - if (homebrewPrefix.isEmpty()) - return; - - qCInfo(lcShiboken) << "Found HOMEBREW_OPT with value:" << homebrewPrefix - << "Assuming homebrew build environment."; - - HeaderPaths::iterator it = headerPaths.begin(); - while (it != headerPaths.end()) { - if (it->path.startsWith(homebrewPrefix)) { - qCInfo(lcShiboken) << "Filtering out homebrew include path: " - << it->path; - it = headerPaths.erase(it); - } else { - ++it; - } - } -} -#endif - -// Determine g++'s internal include paths from the output of -// g++ -E -x c++ - -v </dev/null -// Output looks like: -// #include <...> search starts here: -// /usr/local/include -// /System/Library/Frameworks (framework directory) -// End of search list. -static HeaderPaths gppInternalIncludePaths(const QString &compiler) -{ - HeaderPaths result; - QStringList arguments; - arguments << QStringLiteral("-E") << QStringLiteral("-x") << QStringLiteral("c++") - << QStringLiteral("-") << QStringLiteral("-v"); - QByteArray stdOut; - QByteArray stdErr; - if (!runProcess(compiler, arguments, &stdOut, &stdErr)) - return result; - const QByteArrayList stdErrLines = stdErr.split('\n'); - bool isIncludeDir = false; - for (const QByteArray &line : stdErrLines) { - if (isIncludeDir) { - if (line.startsWith(QByteArrayLiteral("End of search list"))) { - isIncludeDir = false; - } else { - HeaderPath headerPath{line.trimmed(), HeaderType::System}; - if (headerPath.path.endsWith(frameworkPath())) { - headerPath.type = HeaderType::FrameworkSystem; - headerPath.path.truncate(headerPath.path.size() - frameworkPath().size()); - } - result.append(headerPath); - } - } else if (line.startsWith(QByteArrayLiteral("#include <...> search starts here"))) { - isIncludeDir = true; - } - } - -#if defined(Q_OS_MACOS) - filterHomebrewHeaderPaths(result); -#endif - return result; -} -#endif // Q_CC_MSVC - -// Detect Vulkan as supported from Qt 5.10 by checking the environment variables. -static void detectVulkan(HeaderPaths *headerPaths) -{ - 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; - } - } -} - -#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 -// include paths, which together with the clang compiler paths causes some clash -// 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 -// includes to prevent redefinition errors. The default toolchain includes -// should be picked up automatically by clang without specifying -// them implicitly. - -#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN) -# define NEED_CLANG_BUILTIN_INCLUDES 1 -#else -# define NEED_CLANG_BUILTIN_INCLUDES 0 -#endif - -#if NEED_CLANG_BUILTIN_INCLUDES -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"); - if (QFileInfo::exists(path)) - return path; - } - } - 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; - } - } - return QString(); -} - -static QString findClangBuiltInIncludesDir() -{ - // Find the include directory of the highest version. - const QString clangPathLibDir = findClangLibDir(); - if (!clangPathLibDir.isEmpty()) { - QString candidate; - QVersionNumber lastVersionNumber(1, 0, 0); - QDir clangDir(clangPathLibDir + QLatin1String("/clang")); - const QFileInfoList versionDirs = - clangDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); - for (const QFileInfo &fi : versionDirs) { - const QString fileName = fi.fileName(); - if (fileName.at(0).isDigit()) { - const QVersionNumber versionNumber = QVersionNumber::fromString(fileName); - if (!versionNumber.isNull() && versionNumber > lastVersionNumber) { - candidate = fi.absoluteFilePath(); - lastVersionNumber = versionNumber; - } - } - } - if (!candidate.isEmpty()) - return candidate + QStringLiteral("/include"); - } - return QString(); -} -#endif // NEED_CLANG_BUILTIN_INCLUDES - -#if defined(Q_CC_CLANG) || defined(Q_CC_GNU) -static QString compilerFromCMake(const QString &defaultCompiler) -{ -// Added !defined(Q_OS_DARWIN) due to PYSIDE-1032 -# if defined(CMAKE_CXX_COMPILER) && !defined(Q_OS_DARWIN) - Q_UNUSED(defaultCompiler) - return QString::fromLocal8Bit(CMAKE_CXX_COMPILER); -# else - return defaultCompiler; -# endif -} -#endif // Q_CC_CLANG, Q_CC_GNU - -// Returns clang options needed for emulating the host compiler -QByteArrayList emulatedCompilerOptions() -{ - QByteArrayList result; -#if defined(Q_CC_MSVC) - HeaderPaths headerPaths; - result.append(QByteArrayLiteral("-fms-compatibility-version=19")); - 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")); -#elif defined(Q_CC_CLANG) - HeaderPaths headerPaths = gppInternalIncludePaths(compilerFromCMake(QStringLiteral("clang++"))); - result.append(noStandardIncludeOption()); -#elif defined(Q_CC_GNU) - HeaderPaths headerPaths; - -#if NEED_CLANG_BUILTIN_INCLUDES - const QString clangBuiltinIncludesDir = - QDir::toNativeSeparators(findClangBuiltInIncludesDir()); - if (clangBuiltinIncludesDir.isEmpty()) { - qCWarning(lcShiboken, "Unable to locate Clang's built-in include directory " - "(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", - qPrintable(clangBuiltinIncludesDir)); - headerPaths.append(HeaderPath{QFile::encodeName(clangBuiltinIncludesDir), - HeaderType::System}); - } -#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++"))); - for (const HeaderPath &h : gppPaths) { - if (h.path.contains("c++") - || h.path.contains("sysroot")) { // centOS - headerPaths.append(h); - } - } - } -#else - HeaderPaths headerPaths; -#endif - detectVulkan(&headerPaths); - std::transform(headerPaths.cbegin(), headerPaths.cend(), - std::back_inserter(result), HeaderPath::includeOption); - return result; -} - -LanguageLevel emulatedCompilerLanguageLevel() -{ -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) - return LanguageLevel::Cpp17; -#else -# if defined(Q_CC_MSVC) && _MSC_VER > 1900 - // Fixes constexpr errors in MSVC2017 library headers with Clang 4.1..5.X (0.45 == Clang 6). - if (libClangVersion() < QVersionNumber(0, 45)) - return LanguageLevel::Cpp1Z; -# endif // Q_CC_MSVC && _MSC_VER > 1900 - return LanguageLevel::Cpp14; // otherwise, t.h is parsed as "C" -#endif // Qt 5 -} - -struct LanguageLevelMapping -{ - const char *option; - LanguageLevel level; -}; - -static const LanguageLevelMapping languageLevelMapping[] = -{ - {"c++11", LanguageLevel::Cpp11}, - {"c++14", LanguageLevel::Cpp14}, - {"c++17", LanguageLevel::Cpp17}, - {"c++20", LanguageLevel::Cpp20}, - {"c++1z", LanguageLevel::Cpp1Z} -}; - -const char *languageLevelOption(LanguageLevel l) -{ - for (const LanguageLevelMapping &m : languageLevelMapping) { - if (m.level == l) - return m.option; - } - return nullptr; -} - -LanguageLevel languageLevelFromOption(const char *o) -{ - for (const LanguageLevelMapping &m : languageLevelMapping) { - if (!strcmp(m.option, o)) - return m.level; - } - return LanguageLevel::Default; -} - -} // namespace clang diff --git a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.h b/sources/shiboken2/ApiExtractor/clangparser/compilersupport.h deleted file mode 100644 index d9e213e73..000000000 --- a/sources/shiboken2/ApiExtractor/clangparser/compilersupport.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef COMPILERSUPPORT_H -#define COMPILERSUPPORT_H - -#include <QtCore/QByteArrayList> - -QT_FORWARD_DECLARE_CLASS(QVersionNumber) - -enum class LanguageLevel { - Default, - Cpp11, - Cpp14, - Cpp17, - Cpp20, - Cpp1Z -}; - -namespace clang { -QVersionNumber libClangVersion(); - -QByteArrayList emulatedCompilerOptions(); -LanguageLevel emulatedCompilerLanguageLevel(); - -const char *languageLevelOption(LanguageLevel l); -LanguageLevel languageLevelFromOption(const char *); -} // namespace clang - -#endif // COMPILERSUPPORT_H diff --git a/sources/shiboken2/ApiExtractor/cmake_uninstall.cmake b/sources/shiboken2/ApiExtractor/cmake_uninstall.cmake deleted file mode 100644 index df95fb9d8..000000000 --- a/sources/shiboken2/ApiExtractor/cmake_uninstall.cmake +++ /dev/null @@ -1,21 +0,0 @@ -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") - -FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) -STRING(REGEX REPLACE "\n" ";" files "${files}") -FOREACH(file ${files}) - MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") - IF(EXISTS "$ENV{DESTDIR}${file}") - EXEC_PROGRAM( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" - OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval - ) - IF(NOT "${rm_retval}" STREQUAL 0) - MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") - ENDIF(NOT "${rm_retval}" STREQUAL 0) - ELSE(EXISTS "$ENV{DESTDIR}${file}") - MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") - ENDIF(EXISTS "$ENV{DESTDIR}${file}") -ENDFOREACH(file) diff --git a/sources/shiboken2/ApiExtractor/dependency.h b/sources/shiboken2/ApiExtractor/dependency.h deleted file mode 100644 index 7168ea3bc..000000000 --- a/sources/shiboken2/ApiExtractor/dependency.h +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef DEPENDENCY_H -#define DEPENDENCY_H - -#include <QtCore/QVector> - -#include <utility> - -// Dependencies for topologically sorting classes - -class AbstractMetaClass; - -struct Dependency { - AbstractMetaClass *parent; - AbstractMetaClass *child; -}; - -using Dependencies = QVector<Dependency>; - -#endif // DEPENDENCY_H diff --git a/sources/shiboken2/ApiExtractor/docparser.cpp b/sources/shiboken2/ApiExtractor/docparser.cpp deleted file mode 100644 index cb5d85074..000000000 --- a/sources/shiboken2/ApiExtractor/docparser.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "docparser.h" -#include "abstractmetalang.h" -#include "messages.h" -#include "reporthandler.h" -#include "typesystem.h" -#include "xmlutils.h" -#include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtCore/QTextStream> -#include <QBuffer> - -#include <cstdlib> -#ifdef HAVE_LIBXSLT -# include <libxslt/xsltutils.h> -# include <libxslt/transform.h> -#endif - -#include <algorithm> - -DocParser::DocParser() -{ -#ifdef HAVE_LIBXSLT - xmlSubstituteEntitiesDefault(1); -#endif -} - -DocParser::~DocParser() = default; - -QString DocParser::getDocumentation(const XQueryPtr &xquery, const QString& query, - const DocModificationList& mods) const -{ - QString doc = execXQuery(xquery, query); - return applyDocModifications(mods, doc.trimmed()); -} - -QString DocParser::execXQuery(const XQueryPtr &xquery, const QString& query) const -{ - QString errorMessage; - const QString result = xquery->evaluate(query, &errorMessage); - if (!errorMessage.isEmpty()) - qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage)); - return result; -} - -bool DocParser::skipForQuery(const AbstractMetaFunction *func) -{ - // Skip private functions and copies created by AbstractMetaClass::fixFunctions() - if (!func || func->isPrivate() - || (func->attributes() & AbstractMetaAttributes::AddedMethod) != 0 - || func->isModifiedRemoved() - || func->declaringClass() != func->ownerClass() - || func->isCastOperator()) { - return true; - } - switch (func->functionType()) { - case AbstractMetaFunction::MoveConstructorFunction: - case AbstractMetaFunction::AssignmentOperatorFunction: - case AbstractMetaFunction::MoveAssignmentOperatorFunction: - return true; - default: - break; - } - return false; -} - -AbstractMetaFunctionList DocParser::documentableFunctions(const AbstractMetaClass *metaClass) -{ - AbstractMetaFunctionList 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); - } - return result; -} - -static inline bool isXpathDocModification(const DocModification &mod) -{ - return mod.mode() == TypeSystem::DocModificationXPathReplace; -} - -QString DocParser::applyDocModifications(const DocModificationList& mods, const QString& xml) const -{ - const char xslPrefix[] = -R"(<xsl:template match="/"> - <xsl:apply-templates /> -</xsl:template> -<xsl:template match="*"> -<xsl:copy> - <xsl:copy-of select="@*"/> - <xsl:apply-templates/> -</xsl:copy> -</xsl:template> -)"; - - if (mods.isEmpty() || xml.isEmpty() - || !std::any_of(mods.cbegin(), mods.cend(), isXpathDocModification)) { - return xml; - } - - QString xsl = QLatin1String(xslPrefix); - for (const DocModification &mod : mods) { - if (isXpathDocModification(mod)) { - QString xpath = mod.xpath(); - xpath.replace(QLatin1Char('"'), QLatin1String(""")); - xsl += QLatin1String("<xsl:template match=\"") - + xpath + QLatin1String("\">") - + mod.code() + QLatin1String("</xsl:template>\n"); - } - } - - QString errorMessage; - const QString result = xsl_transform(xml, xsl, &errorMessage); - if (!errorMessage.isEmpty()) - qCWarning(lcShibokenDoc, "%s", - qPrintable(msgXpathDocModificationError(mods, errorMessage))); - if (result == xml) { - const QString message = QLatin1String("Query did not result in any modifications to \"") - + xml + QLatin1Char('"'); - qCWarning(lcShibokenDoc, "%s", - qPrintable(msgXpathDocModificationError(mods, message))); - } - return result; -} diff --git a/sources/shiboken2/ApiExtractor/docparser.h b/sources/shiboken2/ApiExtractor/docparser.h deleted file mode 100644 index 1dccae4d6..000000000 --- a/sources/shiboken2/ApiExtractor/docparser.h +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef DOCPARSER_H -#define DOCPARSER_H - -#include "typesystem_typedefs.h" -#include "abstractmetalang_typedefs.h" - -#include <QtCore/QString> -#include <QtCore/QSharedPointer> - -class AbstractMetaClass; -class DocModification; -class Documentation; - -class XQuery; - -class DocParser -{ -public: - Q_DISABLE_COPY(DocParser) - - using XQueryPtr = QSharedPointer<XQuery>; - - DocParser(); - virtual ~DocParser(); - virtual void fillDocumentation(AbstractMetaClass* metaClass) = 0; - - /** - * Process and retrieves documentation concerning the entire - * module or library. - * \return object containing module/library documentation information - */ - virtual Documentation retrieveModuleDocumentation() = 0; - - void setDocumentationDataDirectory(const QString& dir) - { - m_docDataDir = dir; - } - - /** - * Informs the location of the XML data generated by the tool - * (e.g.: DoxyGen, qdoc) used to extract the library's documentation - * comment. - * \return the path for the directory containing the XML data created - * from the library's documentation beign parsed. - */ - QString documentationDataDirectory() const - { - return m_docDataDir; - } - - void setLibrarySourceDirectory(const QString& dir) - { - m_libSourceDir = dir; - } - /** - * Informs the location of the library being parsed. The library - * source code is parsed for the documentation comments. - * \return the path for the directory containing the source code of - * the library beign parsed. - */ - QString librarySourceDirectory() const - { - return m_libSourceDir; - } - - void setPackageName(const QString& packageName) - { - m_packageName = packageName; - } - /** - * Retrieves the name of the package (or module or library) being parsed. - * \return the name of the package (module/library) being parsed - */ - QString packageName() const - { - return m_packageName; - } - - /** - * Process and retrieves documentation concerning the entire - * module or library. - * \param name module name - * \return object containing module/library documentation information - * \todo Merge with retrieveModuleDocumentation() on next ABI change. - */ - virtual Documentation retrieveModuleDocumentation(const QString& name) = 0; - - static bool skipForQuery(const AbstractMetaFunction *func); - -protected: - QString getDocumentation(const XQueryPtr &xquery, const QString& query, - const DocModificationList& mods) const; - - - static AbstractMetaFunctionList documentableFunctions(const AbstractMetaClass *metaClass); - -private: - QString m_packageName; - QString m_docDataDir; - QString m_libSourceDir; - - QString execXQuery(const XQueryPtr &xquery, const QString& query) const; - QString applyDocModifications(const DocModificationList& mods, const QString& xml) const; -}; - -#endif // DOCPARSER_H - diff --git a/sources/shiboken2/ApiExtractor/doxygenparser.cpp b/sources/shiboken2/ApiExtractor/doxygenparser.cpp deleted file mode 100644 index 7c15db1ca..000000000 --- a/sources/shiboken2/ApiExtractor/doxygenparser.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "doxygenparser.h" -#include "abstractmetalang.h" -#include "messages.h" -#include "reporthandler.h" -#include "typesystem.h" -#include "xmlutils.h" - -#include <QtCore/QFile> -#include <QtCore/QDir> - -static QString getSectionKindAttr(const AbstractMetaFunction *func) -{ - if (func->isSignal()) - return QLatin1String("signal"); - QString kind = func->isPublic() - ? QLatin1String("public") : QLatin1String("protected"); - if (func->isStatic()) - kind += QLatin1String("-static"); - else if (func->isSlot()) - kind += QLatin1String("-slot"); - return kind; -} - -Documentation DoxygenParser::retrieveModuleDocumentation() -{ - return retrieveModuleDocumentation(packageName()); -} - -void DoxygenParser::fillDocumentation(AbstractMetaClass* metaClass) -{ - if (!metaClass) - return; - - QString doxyFileSuffix; - if (metaClass->enclosingClass()) { - doxyFileSuffix += metaClass->enclosingClass()->name(); - doxyFileSuffix += QLatin1String("_1_1"); // FIXME: Check why _1_1!! - } - doxyFileSuffix += metaClass->name(); - doxyFileSuffix += QLatin1String(".xml"); - - const char* prefixes[] = { "class", "struct", "namespace" }; - bool isProperty = false; - - QString doxyFilePath; - for (const char *prefix : prefixes) { - doxyFilePath = documentationDataDirectory() + QLatin1Char('/') - + QLatin1String(prefix) + doxyFileSuffix; - if (QFile::exists(doxyFilePath)) - break; - doxyFilePath.clear(); - } - - if (doxyFilePath.isEmpty()) { - qCWarning(lcShibokenDoc).noquote().nospace() - << "Can't find doxygen file for class " << metaClass->name() << ", tried: " - << QDir::toNativeSeparators(documentationDataDirectory()) - << "/{struct|class|namespace}"<< doxyFileSuffix; - return; - } - - QString errorMessage; - XQueryPtr xquery = XQuery::create(doxyFilePath, &errorMessage); - if (xquery.isNull()) { - qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage)); - return; - } - - // Get class documentation - const QString classQuery = QLatin1String("/doxygen/compounddef/detaileddescription"); - QString classDoc = getDocumentation(xquery, classQuery, - metaClass->typeEntry()->docModifications()); - if (classDoc.isEmpty()) - qCWarning(lcShibokenDoc, "%s", qPrintable(msgCannotFindDocumentation(doxyFilePath, "class", metaClass->name(), classQuery))); - metaClass->setDocumentation(classDoc); - - //Functions Documentation - const AbstractMetaFunctionList &funcs = DocParser::documentableFunctions(metaClass); - for (AbstractMetaFunction *func : funcs) { - QString query = QLatin1String("/doxygen/compounddef/sectiondef"); - // properties - if (func->isPropertyReader() || func->isPropertyWriter() - || func->isPropertyResetter()) { - query += QLatin1String("[@kind=\"property\"]/memberdef/name[text()=\"") - + func->propertySpec()->name() + QLatin1String("\"]"); - isProperty = true; - } else { // normal methods - QString kind = getSectionKindAttr(func); - query += QLatin1String("[@kind=\"") + kind - + QLatin1String("-func\"]/memberdef/name[text()=\"") - + func->originalName() + QLatin1String("\"]"); - - if (func->arguments().isEmpty()) { - QString args = func->isConstant() ? QLatin1String("() const ") : QLatin1String("()"); - query += QLatin1String("/../argsstring[text()=\"") + args + QLatin1String("\"]"); - } else { - int i = 1; - const AbstractMetaArgumentList &arguments = func->arguments(); - for (AbstractMetaArgument *arg : arguments) { - if (!arg->type()->isPrimitive()) { - query += QLatin1String("/../param[") + QString::number(i) - + QLatin1String("]/type/ref[text()=\"") - + arg->type()->name() + QLatin1String("\"]/../.."); - } else { - query += QLatin1String("/../param[") + QString::number(i) - + QLatin1String("]/type[text()=\"") - + arg->type()->name() + QLatin1String("\"]/.."); - } - ++i; - } - } - } - if (!isProperty) { - query += QLatin1String("/../detaileddescription"); - } else { - query = QLatin1Char('(') + query; - query += QLatin1String("/../detaileddescription)[1]"); - } - QString doc = getDocumentation(xquery, query, DocModificationList()); - if (doc.isEmpty()) { - qCWarning(lcShibokenDoc, "%s", - qPrintable(msgCannotFindDocumentation(doxyFilePath, metaClass, func, query))); - } - func->setDocumentation(doc); - isProperty = false; - } - - //Fields - const AbstractMetaFieldList &fields = metaClass->fields(); - for (AbstractMetaField *field : fields) { - if (field->isPrivate()) - return; - - QString query = QLatin1String("/doxygen/compounddef/sectiondef/memberdef/name[text()=\"") - + field->name() + QLatin1String("\"]/../detaileddescription"); - QString doc = getDocumentation(xquery, query, DocModificationList()); - if (doc.isEmpty()) { - qCWarning(lcShibokenDoc, "%s", - qPrintable(msgCannotFindDocumentation(doxyFilePath, metaClass, field, query))); - } - field->setDocumentation(doc); - } - - //Enums - const AbstractMetaEnumList &enums = metaClass->enums(); - for (AbstractMetaEnum *meta_enum : enums) { - QString query = QLatin1String("/doxygen/compounddef/sectiondef/memberdef[@kind=\"enum\"]/name[text()=\"") - + meta_enum->name() + QLatin1String("\"]/.."); - QString doc = getDocumentation(xquery, query, DocModificationList()); - if (doc.isEmpty()) { - qCWarning(lcShibokenDoc, "%s", - qPrintable(msgCannotFindDocumentation(doxyFilePath, metaClass, meta_enum, query))); - } - meta_enum->setDocumentation(doc); - } - -} - -Documentation DoxygenParser::retrieveModuleDocumentation(const QString& name){ - - QString sourceFile = documentationDataDirectory() + QLatin1String("/indexpage.xml"); - - if (!QFile::exists(sourceFile)) { - qCWarning(lcShibokenDoc).noquote().nospace() - << "Can't find doxygen XML file for module " << name << ", tried: " - << QDir::toNativeSeparators(sourceFile); - return Documentation(); - } - - QString errorMessage; - XQueryPtr xquery = XQuery::create(sourceFile, &errorMessage); - if (xquery.isNull()) { - qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage)); - return {}; - } - - // Module documentation - QString query = QLatin1String("/doxygen/compounddef/detaileddescription"); - return Documentation(getDocumentation(xquery, query, DocModificationList())); -} - diff --git a/sources/shiboken2/ApiExtractor/doxygenparser.h b/sources/shiboken2/ApiExtractor/doxygenparser.h deleted file mode 100644 index ada64ac18..000000000 --- a/sources/shiboken2/ApiExtractor/doxygenparser.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DOXYGENPARSER_H -#define DOXYGENPARSER_H - -#include "docparser.h" - -class DoxygenParser : public DocParser -{ -public: - DoxygenParser() = default; - void fillDocumentation(AbstractMetaClass *metaClass) override; - Documentation retrieveModuleDocumentation() override; - Documentation retrieveModuleDocumentation(const QString& name) override; -}; - -#endif // DOXYGENPARSER_H diff --git a/sources/shiboken2/ApiExtractor/fileout.cpp b/sources/shiboken2/ApiExtractor/fileout.cpp deleted file mode 100644 index ba5bf19de..000000000 --- a/sources/shiboken2/ApiExtractor/fileout.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "fileout.h" -#include "messages.h" -#include "reporthandler.h" - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -# include <QtCore/QTextCodec> -#endif -#include <QtCore/QFileInfo> -#include <QtCore/QDir> -#include <QtCore/QDebug> - -#include <cstdio> - -bool FileOut::dummy = false; -bool FileOut::diff = false; - -#ifdef Q_OS_LINUX -static const char colorDelete[] = "\033[31m"; -static const char colorAdd[] = "\033[32m"; -static const char colorInfo[] = "\033[36m"; -static const char colorReset[] = "\033[0m"; -#else -static const char colorDelete[] = ""; -static const char colorAdd[] = ""; -static const char colorInfo[] = ""; -static const char colorReset[] = ""; -#endif - -FileOut::FileOut(QString n) : - name(std::move(n)), - stream(&tmp), - isDone(false) -{ -} - -FileOut::~FileOut() -{ - if (!isDone) - done(); -} - -static QVector<int> lcsLength(const QByteArrayList &a, const QByteArrayList &b) -{ - const int height = a.size() + 1; - const int width = b.size() + 1; - - QVector<int> 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; - else - res[width * row + col] = qMax(res[width * row + col-1], - res[width * (row-1) + col]); - } - } - return res; -} - -enum Type { - Add, - Delete, - Unchanged -}; - -struct Unit -{ - Type type; - int start; - int end; - - void print(const QByteArrayList &a, const QByteArrayList &b) const; -}; - -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++) - 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++) - std::printf(" %s\n", a.at(i).constData()); - } else { - for (int 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++) - 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++) - std::printf("- %s\n", a.at(i).constData()); - std::fputs(colorReset, stdout); - break; - } -} - -static void unitAppend(Type type, int pos, QVector<Unit> *units) -{ - if (!units->isEmpty() && units->last().type == type) - units->last().end = pos; - else - units->append(Unit{type, pos, pos}); -} - -static QVector<Unit> diffHelper(const QVector<int> &lcs, - const QByteArrayList &a, const QByteArrayList &b, - int row, int col) -{ - if (row > 0 && col > 0 && a.at(row - 1) == b.at(col - 1)) { - QVector<Unit> result = diffHelper(lcs, a, b, row - 1, col - 1); - unitAppend(Unchanged, row - 1, &result); - return result; - } - - const int width = b.size() + 1; - if (col > 0 - && (row == 0 || lcs.at(width * row + col -1 ) >= lcs.at(width * (row - 1) + col))) { - QVector<Unit> result = diffHelper(lcs, a, b, row, col - 1); - unitAppend(Add, col - 1, &result); - return result; - } - if (row > 0 - && (col == 0 || lcs.at(width * row + col-1) < lcs.at(width * (row - 1) + col))) { - QVector<Unit> result = diffHelper(lcs, a, b, row - 1, col); - unitAppend(Delete, row - 1, &result); - return result; - } - return QVector<Unit>{}; -} - -static void diff(const QByteArrayList &a, const QByteArrayList &b) -{ - const QVector<Unit> res = diffHelper(lcsLength(a, b), a, b, a.size(), b.size()); - for (const Unit &unit : res) - unit.print(a, b); -} - -FileOut::State FileOut::done() -{ - QString errorMessage; - const State result = done(&errorMessage); - if (result == Failure) - qCWarning(lcShiboken, "%s", qPrintable(errorMessage)); - return result; -} - -FileOut::State FileOut::done(QString *errorMessage) -{ - Q_ASSERT(!isDone); - if (name.isEmpty()) - return Failure; - - isDone = true; - bool fileEqual = false; - QFile fileRead(name); - QFileInfo info(fileRead); - stream.flush(); - QByteArray original; - if (info.exists() && (diff || (info.size() == tmp.size()))) { - if (!fileRead.open(QIODevice::ReadOnly)) { - *errorMessage = msgCannotOpenForReading(fileRead); - return Failure; - } - - original = fileRead.readAll(); - fileRead.close(); - fileEqual = (original == tmp); - } - - if (fileEqual) - return Unchanged; - - if (!FileOut::dummy) { - QDir dir(info.absolutePath()); - if (!dir.mkpath(dir.absolutePath())) { - *errorMessage = QStringLiteral("unable to create directory '%1'") - .arg(QDir::toNativeSeparators(dir.absolutePath())); - return Failure; - } - - QFile fileWrite(name); - if (!fileWrite.open(QIODevice::WriteOnly)) { - *errorMessage = msgCannotOpenForWriting(fileWrite); - return Failure; - } -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - QTextCodec *codec = QTextCodec::codecForName("UTF-8"); - stream.setCodec(codec); -#endif - stream.setDevice(&fileWrite); - stream << tmp; - } - if (diff) { - std::printf("%sFile: %s%s\n", colorInfo, qPrintable(name), colorReset); - ::diff(original.split('\n'), tmp.split('\n')); - std::printf("\n"); - } - - return Success; -} - -void FileOut::touchFile(const QString &filePath) -{ - QFile toucher(filePath); - qint64 size = toucher.size(); - if (!toucher.open(QIODevice::ReadWrite)) { - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("Failed to touch file '%1'") - .arg(QDir::toNativeSeparators(filePath)); - return; - } - toucher.resize(size+1); - toucher.resize(size); - toucher.close(); -} diff --git a/sources/shiboken2/ApiExtractor/fileout.h b/sources/shiboken2/ApiExtractor/fileout.h deleted file mode 100644 index b1011c4d6..000000000 --- a/sources/shiboken2/ApiExtractor/fileout.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef FILEOUT_H -#define FILEOUT_H - -#include <QtCore/QObject> -#include <QtCore/QTextStream> - -QT_FORWARD_DECLARE_CLASS(QFile) - -class FileOut : public QObject -{ -private: - QByteArray tmp; - QString name; - -public: - Q_DISABLE_COPY(FileOut) - - enum State { Failure, Unchanged, Success }; - - explicit FileOut(QString name); - ~FileOut(); - - QString filePath() const { return name; } - - State done(); - State done(QString *errorMessage); - - void touch() { touchFile(name); } - - static void touchFile(const QString &filePath); - - QTextStream stream; - - static bool dummy; - static bool diff; - -private: - bool isDone; -}; - -#endif // FILEOUT_H diff --git a/sources/shiboken2/ApiExtractor/graph.cpp b/sources/shiboken2/ApiExtractor/graph.cpp deleted file mode 100644 index 53e20ebba..000000000 --- a/sources/shiboken2/ApiExtractor/graph.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "graph.h" -#include <QVector> -#include <QDebug> -#include <QSet> -#include <iterator> -#include <algorithm> -#include <iostream> -#include <QFile> - -struct Graph::GraphPrivate -{ - enum Color { WHITE, GRAY, BLACK }; - using Edges = QVector<QSet<int> >; - - Edges edges; - - GraphPrivate(int numNodes) : edges(numNodes) - { - } - - void dfsVisit(int node, Graph::Indexes &result, QVector<Color> &colors) const - { - colors[node] = GRAY; - for (const auto &c : edges.at(node)) { - if (colors[c] == WHITE) - dfsVisit(c, result, colors); - else if (colors[c] == GRAY) // This is not a DAG! - return; - } - colors[node] = BLACK; - result.append(node); - } -}; - -Graph::Graph(int numNodes) : m_d(new GraphPrivate(numNodes)) -{ -} - -Graph::~Graph() -{ - delete m_d; -} - -int Graph::nodeCount() const -{ - return m_d->edges.size(); -} - -Graph::Indexes Graph::topologicalSort() const -{ - const int nodeCount = Graph::nodeCount(); - Indexes result; - result.reserve(nodeCount); - - QVector<GraphPrivate::Color> colors(nodeCount, GraphPrivate::WHITE); - - for (int i = 0; i < nodeCount; ++i) { - if (colors[i] == GraphPrivate::WHITE) - m_d->dfsVisit(i, result, colors); - } - - if (result.size() == nodeCount) - std::reverse(result.begin(), result.end()); - else - result.clear(); // Not a DAG! - return result; -} - -bool Graph::containsEdge(int from, int to) -{ - return m_d->edges[from].contains(to); -} - -void Graph::addEdge(int from, int to) -{ - Q_ASSERT(to < m_d->edges.size()); - m_d->edges[from].insert(to); -} - -void Graph::removeEdge(int from, int to) -{ - m_d->edges[from].remove(to); -} - -void Graph::dump() const -{ - for (int i = 0; i < m_d->edges.size(); ++i) { - std::cout << i << " -> "; - std::copy(m_d->edges[i].begin(), m_d->edges[i].end(), std::ostream_iterator<int>(std::cout, " ")); - std::cout << std::endl; - } -} - -void Graph::dumpDot(const QHash< int, QString >& nodeNames, const QString& fileName) const -{ - QFile output(fileName); - if (!output.open(QIODevice::WriteOnly)) - return; - QTextStream s(&output); - s << "digraph D {\n"; - for (int i = 0; i < m_d->edges.size(); ++i) { - for (auto it = m_d->edges[i].cbegin(), end = m_d->edges[i].cend(); it != end; ++it) - s << '"' << nodeNames[i] << "\" -> \"" << nodeNames[*it] << "\"\n"; - } - s << "}\n"; -} diff --git a/sources/shiboken2/ApiExtractor/graph.h b/sources/shiboken2/ApiExtractor/graph.h deleted file mode 100644 index 5dc8e21ea..000000000 --- a/sources/shiboken2/ApiExtractor/graph.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef GRAPH_H -#define GRAPH_H - -#include <QVector> -#include <QHash> -#include <QString> - -/// A graph that can have their nodes topologically sorted. -class Graph -{ -public: - Q_DISABLE_COPY(Graph) - - using Indexes = QVector<int>; - - /// Create a new graph with \p numNodes nodes. - Graph(int numNodes); - ~Graph(); - - /// Returns the numbed of nodes in this graph. - int nodeCount() const; - /// Returns true if the graph contains the edge from -> to - bool containsEdge(int from, int to); - /// Adds an edge to this graph. - void addEdge(int from, int to); - /// Removes an edge out of this graph. - void removeEdge(int from, int to); - /// Print this graph to stdout. - void dump() const; - /** - * Dumps a dot graph to a file named \p filename. - * \param nodeNames map used to translate node ids to human readable text. - * \param fileName file name where the output should be written. - */ - void dumpDot(const QHash<int, QString>& nodeNames, const QString& fileName) const; - - /** - * Topologically sort this graph. - * \return A collection with all nodes topologically sorted or an empty collection if a cyclic - * dependency was found. - */ - Indexes topologicalSort() const; -private: - - struct GraphPrivate; - GraphPrivate* m_d; -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/header_paths.h b/sources/shiboken2/ApiExtractor/header_paths.h deleted file mode 100644 index c9b5144c8..000000000 --- a/sources/shiboken2/ApiExtractor/header_paths.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef HEADER_PATHS_H -#define HEADER_PATHS_H - -#include <QByteArray> -#include <QVector> -#include <QString> - -enum class HeaderType -{ - Standard, - System, // -isystem - Framework, // macOS framework path - FrameworkSystem // macOS framework system path -}; - -class HeaderPath { -public: - QByteArray path; - HeaderType type; - - static QByteArray includeOption(const HeaderPath &p) - { - QByteArray option; - switch (p.type) { - case HeaderType::Standard: - option = QByteArrayLiteral("-I"); - break; - case HeaderType::System: - option = QByteArrayLiteral("-isystem"); - break; - case HeaderType::Framework: - option = QByteArrayLiteral("-F"); - break; - case HeaderType::FrameworkSystem: - option = QByteArrayLiteral("-iframework"); - break; - } - return option + p.path; - } -}; - -using HeaderPaths = QVector<HeaderPath>; - -#endif // HEADER_PATHS_H diff --git a/sources/shiboken2/ApiExtractor/icecc.cmake b/sources/shiboken2/ApiExtractor/icecc.cmake deleted file mode 100644 index b2bf071aa..000000000 --- a/sources/shiboken2/ApiExtractor/icecc.cmake +++ /dev/null @@ -1,11 +0,0 @@ -include (CMakeForceCompiler) -option(ENABLE_ICECC "Enable icecc checking, for distributed compilation") -if (ENABLE_ICECC) - find_program(ICECC icecc) - if (ICECC) - message(STATUS "icecc found! Distributed compilation for all!! huhuhu.") - cmake_force_cxx_compiler(${ICECC} icecc) - else(ICECC) - message(FATAL_ERROR "icecc NOT found! re-run cmake without -DENABLE_ICECC") - endif(ICECC) -endif(ENABLE_ICECC) diff --git a/sources/shiboken2/ApiExtractor/include.cpp b/sources/shiboken2/ApiExtractor/include.cpp deleted file mode 100644 index 6c2cce3a9..000000000 --- a/sources/shiboken2/ApiExtractor/include.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "include.h" -#include <QDebug> -#include <QDir> -#include <QTextStream> -#include <QHash> - -QString Include::toString() const -{ - if (m_type == IncludePath) - return QLatin1String("#include <") + m_name + QLatin1Char('>'); - if (m_type == LocalPath) - return QLatin1String("#include \"") + m_name + QLatin1Char('"'); - return QLatin1String("import ") + m_name + QLatin1Char(';'); -} - -QtCompatHashFunctionType qHash(const Include& inc) -{ - return qHash(inc.m_name); -} - -QTextStream& operator<<(QTextStream& out, const Include& include) -{ - if (include.isValid()) - out << include.toString() << Qt::endl; - return out; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const Include &i) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "Include("; - if (i.isValid()) - d << "type=" << i.type() << ", file=\"" << QDir::toNativeSeparators(i.name()) << '"'; - else - d << "invalid"; - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM diff --git a/sources/shiboken2/ApiExtractor/include.h b/sources/shiboken2/ApiExtractor/include.h deleted file mode 100644 index 2219fba55..000000000 --- a/sources/shiboken2/ApiExtractor/include.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef INCLUDE_H -#define INCLUDE_H - -#include <qtcompat.h> - -#include <QString> -#include <QVector> - -QT_BEGIN_NAMESPACE -class QTextStream; -QT_END_NAMESPACE - -class Include -{ -public: - enum IncludeType { - IncludePath, - LocalPath, - TargetLangImport, - InvalidInclude - }; - - Include() = default; - Include(IncludeType t, const QString &nam) : m_type(t), m_name(nam) {}; - - bool isValid() const - { - return !m_name.isEmpty(); - } - - IncludeType type() const - { - return m_type; - } - - QString name() const - { - return m_name; - } - - QString toString() const; - - bool operator<(const Include& other) const - { - return m_name < other.m_name; - } - - bool operator==(const Include& other) const - { - return m_type == other.m_type && m_name == other.m_name; - } - - friend QtCompatHashFunctionType qHash(const Include&); - private: - IncludeType m_type = IncludePath; - QString m_name; -}; - -QtCompatHashFunctionType qHash(const Include& inc); -QTextStream& operator<<(QTextStream& out, const Include& include); -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const Include &i); -#endif - -using IncludeList = QVector<Include>; - -#endif diff --git a/sources/shiboken2/ApiExtractor/merge.xsl b/sources/shiboken2/ApiExtractor/merge.xsl deleted file mode 100644 index c6cab5a42..000000000 --- a/sources/shiboken2/ApiExtractor/merge.xsl +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0"?> -<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - version="1.0"> - <xsl:output method="xml" indent="yes"/> - <xsl:param name="lang" /> - <xsl:param name="source" /> - - <xsl:template match="processing-instruction()" /> - - <xsl:template match="/typesystem"> - <xsl:copy> - <xsl:for-each select="@*"> - <xsl:copy> - <xsl:value-of select="." /> - </xsl:copy> - </xsl:for-each> - - <xsl:for-each select="document($source)/typesystem/@*"> - <xsl:copy> - <xsl:value-of select="." /> - </xsl:copy> - </xsl:for-each> - - <xsl:variable name="other" select="document($source)/typesystem/*[not(self::object-type | self::value-type | self::interface-type | self::namespace-type)]" /> - <xsl:if test="$other"> - <xsl:choose> - <xsl:when test="$lang != ''"> - <xsl:element name="language"> - <xsl:attribute name="name" ><xsl:value-of select="$lang" /></xsl:attribute> - <xsl:copy-of select="$other" /> - </xsl:element> - </xsl:when> - <xsl:otherwise> - <xsl:copy-of select="$other" /> - </xsl:otherwise> - </xsl:choose> - </xsl:if> - - <xsl:apply-templates select="node()" /> - - </xsl:copy> - </xsl:template> - - - - <xsl:template match="/typesystem/*[self::object-type | self::value-type | self::interface-type | self::namespace-type]"> - <xsl:variable name="name" select="name()" /> - <xsl:copy> - <xsl:for-each select="@*"> - <xsl:copy> - <xsl:value-of select="." /> - </xsl:copy> - </xsl:for-each> - - <xsl:apply-templates select="node()" /> - - <xsl:variable name="other" select="document($source)/typesystem/*[name() = $name][@name = current()/@name]" /> - <xsl:if test="$other"> - <xsl:choose> - <xsl:when test="$lang != ''"> - <xsl:element name="language"> - <xsl:attribute name="name" ><xsl:value-of select="$lang" /></xsl:attribute> - <xsl:copy-of select="$other/node()" /> - </xsl:element> - </xsl:when> - <xsl:otherwise> - <xsl:copy-of select="$other/node()" /> - </xsl:otherwise> - </xsl:choose> - </xsl:if> - </xsl:copy> - </xsl:template> - - <!-- Plain identity transform. --> - <xsl:template match="@*|node()"> - <xsl:copy> - <xsl:apply-templates select="@*"/> - <xsl:apply-templates select="node()"/> - </xsl:copy> - </xsl:template> - -</xsl:stylesheet> diff --git a/sources/shiboken2/ApiExtractor/messages.cpp b/sources/shiboken2/ApiExtractor/messages.cpp deleted file mode 100644 index 930cd2c70..000000000 --- a/sources/shiboken2/ApiExtractor/messages.cpp +++ /dev/null @@ -1,663 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "messages.h" -#include "abstractmetalang.h" -#include "sourcelocation.h" -#include "typedatabase.h" -#include "typesystem.h" -#include <codemodel.h> - -#include <QtCore/QCoreApplication> -#include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtCore/QFile> -#include <QtCore/QStringList> -#include <QtCore/QXmlStreamReader> - -static inline QString colonColon() { return QStringLiteral("::"); } - -// abstractmetabuilder.cpp - -QString msgNoFunctionForModification(const AbstractMetaClass *klass, - const QString &signature, - const QString &originalSignature, - const QStringList &possibleSignatures, - const AbstractMetaFunctionList &allFunctions) -{ - QString result; - QTextStream str(&result); - str << klass->typeEntry()->sourceLocation() << "signature '" - << signature << '\''; - if (!originalSignature.isEmpty() && originalSignature != signature) - str << " (specified as '" << originalSignature << "')"; - str << " for function modification in '" - << klass->qualifiedCppName() << "' not found."; - if (!possibleSignatures.isEmpty()) { - str << "\n Possible candidates:\n"; - for (const auto &s : possibleSignatures) - 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) - str << " " << allFunctions.at(f)->minimalSignature() << '\n'; - if (maxCount < allFunctions.size()) - str << " ...\n"; - } - return result; -} - -template <class Stream> -static void msgFormatEnumType(Stream &str, - const EnumModelItem &enumItem, - const QString &className) -{ - switch (enumItem->enumKind()) { - case CEnum: - str << "Enum '" << enumItem->qualifiedName().join(colonColon()) << '\''; - break; - case AnonymousEnum: { - const EnumeratorList &values = enumItem->enumerators(); - str << "Anonymous enum ("; - switch (values.size()) { - case 0: - break; - case 1: - str << values.constFirst()->name(); - break; - case 2: - str << values.at(0)->name() << ", " << values.at(1)->name(); - break; - default: - str << values.at(0)->name() << ", ... , " - << values.at(values.size() - 1)->name(); - break; - } - str << ')'; - } - break; - case EnumClass: - str << "Scoped enum '" << enumItem->qualifiedName().join(colonColon()) << '\''; - break; - } - if (!className.isEmpty()) - str << " (class: " << className << ')'; -} - -QString msgAddedFunctionInvalidArgType(const QString &addedFuncName, - const QString &typeName, - int pos, const QString &why) -{ - QString result; - QTextStream str(&result); - str << "Unable to translate type \"" << typeName << "\" of argument " - << pos << " of added function \"" << addedFuncName << "\": " << why; - return result; -} - -QString msgAddedFunctionInvalidReturnType(const QString &addedFuncName, - const QString &typeName, const QString &why) -{ - QString result; - QTextStream str(&result); - str << "Unable to translate return type \"" << typeName - << "\" of added function \"" << addedFuncName << "\": " - << why; - return result; -} - -QString msgNoEnumTypeEntry(const EnumModelItem &enumItem, - const QString &className) -{ - QString result; - QTextStream str(&result); - str << enumItem->sourceLocation(); - msgFormatEnumType(str, enumItem, className); - str << " does not have a type entry"; - return result; -} - -QString msgNoEnumTypeConflict(const EnumModelItem &enumItem, - const QString &className, - const TypeEntry *t) -{ - QString result; - QDebug debug(&result); // Use the debug operator for TypeEntry::Type - debug.noquote(); - debug.nospace(); - debug << enumItem->sourceLocation().toString(); - msgFormatEnumType(debug, enumItem, className); - debug << " is not an enum (type: " << t->type() << ')'; - return result; -} - -QString msgNamespaceNoTypeEntry(const NamespaceModelItem &item, - const QString &fullName) -{ - QString result; - QTextStream str(&result); - str << item->sourceLocation() << "namespace '" << fullName - << "' does not have a type entry"; - return result; -} - -QString msgAmbiguousVaryingTypesFound(const QString &qualifiedName, const TypeEntries &te) -{ - QString result = QLatin1String("Ambiguous types of varying types found for \"") + qualifiedName - + QLatin1String("\": "); - QDebug(&result) << te; - return result; -} - -QString msgAmbiguousTypesFound(const QString &qualifiedName, const TypeEntries &te) -{ - QString result = QLatin1String("Ambiguous types found for \"") + qualifiedName - + QLatin1String("\": "); - QDebug(&result) << te; - return result; -} - -QString msgUnmatchedParameterType(const ArgumentModelItem &arg, int n, - const QString &why) -{ - QString result; - QTextStream str(&result); - str << "unmatched type '" << arg->type().toString() << "' in parameter #" - << (n + 1); - if (!arg->name().isEmpty()) - str << " \"" << arg->name() << '"'; - str << ": " << why; - return result; -} - -QString msgUnmatchedReturnType(const FunctionModelItem &functionItem, - const QString &why) -{ - return QLatin1String("unmatched return type '") - + functionItem->type().toString() - + QLatin1String("': ") + why; -} - -QString msgSkippingFunction(const FunctionModelItem &functionItem, - const QString &signature, const QString &why) -{ - QString result; - QTextStream str(&result); - str << functionItem->sourceLocation() << "skipping "; - if (functionItem->isAbstract()) - str << "abstract "; - str << "function '" << signature << "', " << why; - if (functionItem->isAbstract()) { - str << "\nThis will lead to compilation errors due to not " - "being able to instantiate the wrapper."; - } - return result; -} - -QString msgSkippingField(const VariableModelItem &field, const QString &className, - const QString &type) -{ - QString result; - QTextStream str(&result); - str << field->sourceLocation() << "skipping 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 result; - QTextStream str(&result); - str << entry->sourceLocation() << "type '" <<entry->qualifiedCppName() - << "' is specified in typesystem, but not defined. " << msgCompilationError; - return result; -} - -QString msgGlobalFunctionNotDefined(const FunctionTypeEntry *fte, - const QString &signature) -{ - QString result; - QTextStream str(&result); - str << fte->sourceLocation() << "Global function '" << signature - << "' is specified in typesystem, but not defined. " << msgCompilationError; - return result; -} - -QString msgStrippingArgument(const FunctionModelItem &f, int i, - const QString &originalSignature, - const ArgumentModelItem &arg) -{ - 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() << "\"."; - return result; -} - -QString msgEnumNotDefined(const EnumTypeEntry *t) -{ - QString result; - QTextStream str(&result); - str << t->sourceLocation() << "enum '" << t->qualifiedCppName() - << "' is specified in typesystem, but not declared."; - return result; -} - -QString msgUnknownBase(const AbstractMetaClass *metaClass, const QString &baseClassName) -{ - QString result; - QTextStream str(&result); - str << metaClass->sourceLocation() << "class '" << metaClass->name() - << "' inherits from unknown base class '" << baseClassName << "'"; - return result; -} - -QString msgArrayModificationFailed(const FunctionModelItem &functionItem, - const QString &className, - const QString &errorMessage) -{ - QString result; - QTextStream str(&result); - str << functionItem->sourceLocation() << "While traversing " << className - << ": " << errorMessage; - return result; -} - -QString msgCannotResolveEntity(const QString &name, const QString &reason) -{ - return QLatin1String("Cannot resolve entity \"") + name - + QLatin1String("\": ") + 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; -} - -QString msgUnableToTranslateType(const QString &t, const QString &why) -{ - return QLatin1String("Unable to translate type \"") - + t + QLatin1String("\": ") + why; -} - -QString msgUnableToTranslateType(const TypeInfo &typeInfo, - const QString &why) -{ - return msgUnableToTranslateType(typeInfo.toString(), why); -} - -QString msgCannotFindTypeEntry(const QString &t) -{ - return QLatin1String("Cannot find type entry for \"") + t + QLatin1String("\"."); -} - -QString msgCannotFindTypeEntryForSmartPointer(const QString &t, const QString &smartPointerType) -{ - return QLatin1String("Cannot find type entry \"") + t - + QLatin1String("\" for instantiation of \"") + smartPointerType + QLatin1String("\"."); -} - -QString msgInvalidSmartPointerType(const TypeInfo &i) -{ - return QLatin1String("Invalid smart pointer type \"") + i.toString() + QLatin1String("\"."); -} - -QString msgCannotFindSmartPointerInstantion(const TypeInfo &i) -{ - return QLatin1String("Cannot find instantiation of smart pointer type for \"") - + i.toString() + QLatin1String("\"."); -} - -QString msgCannotTranslateTemplateArgument(int i, - const TypeInfo &typeInfo, - const QString &why) -{ - QString result; - QTextStream(&result) << "Unable to translate template argument " - << (i + 1) << typeInfo.toString() << ": " << why; - return result; -} - -QString msgDisallowThread(const AbstractMetaFunction *f) -{ - QString result; - QTextStream str(&result); - str <<"Disallowing threads for "; - if (auto c = f->declaringClass()) - str << c->name() << "::"; - str << f->name() << "()."; - return result; -} - -QString msgNamespaceToBeExtendedNotFound(const QString &namespaceName, const QString &packageName) -{ - return QLatin1String("The namespace '") + namespaceName - + QLatin1String("' to be extended cannot be found in package ") - + packageName + QLatin1Char('.'); -} - -// docparser.cpp - -QString msgCannotFindDocumentation(const QString &fileName, - const char *what, const QString &name, - const QString &query) -{ - QString result; - QTextStream(&result) << "Cannot find documentation for " << what - << ' ' << name << " in:\n " << QDir::toNativeSeparators(fileName) - << "\n using query:\n " << query; - 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); -} - -QString msgCannotFindDocumentation(const QString &fileName, - const AbstractMetaClass *metaClass, - const AbstractMetaEnum *e, - const QString &query) -{ - return msgCannotFindDocumentation(fileName, "enum", - metaClass->name() + QLatin1String("::") + e->name(), - query); -} - -QString msgCannotFindDocumentation(const QString &fileName, - const AbstractMetaClass *metaClass, - const AbstractMetaField *f, - const QString &query) -{ - return msgCannotFindDocumentation(fileName, "field", - metaClass->name() + QLatin1String("::") + f->name(), - query); -} - -QString msgXpathDocModificationError(const DocModificationList& mods, - const QString &what) -{ - QString result; - QTextStream str(&result); - str << "Error when applying modifications ("; - for (const DocModification &mod : mods) { - if (mod.mode() == TypeSystem::DocModificationXPathReplace) { - str << '"' << mod.xpath() << "\" -> \""; - const QString simplified = mod.code().simplified(); - if (simplified.size() > 20) - str << simplified.leftRef(20) << "..."; - else - str << simplified; - str << '"'; - } - } - str << "): " << what; - return result; -} - -// fileout.cpp - -QString msgCannotOpenForReading(const QFile &f) -{ - return QStringLiteral("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") - .arg(QDir::toNativeSeparators(f.fileName()), f.errorString()); -} - -// generator.cpp - -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."); -} - -QString msgConversionTypesDiffer(const QString &varType, const QString &conversionType) -{ - QString result; - QTextStream str(&result); - str << "Types of receiver variable ('" << varType - << "') and %%CONVERTTOCPP type system variable ('" << conversionType - << "') differ"; - QString strippedVarType = varType; - QString strippedConversionType = conversionType; - TypeInfo::stripQualifiers(&strippedVarType); - TypeInfo::stripQualifiers(&strippedConversionType); - if (strippedVarType == strippedConversionType) - str << " in qualifiers. Please make sure the type is a distinct token"; - str << '.'; - return result; -} - -QString msgCannotFindSmartPointer(const QString &instantiationType, - const AbstractMetaClassList &pointers) -{ - 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; -} - -// main.cpp - -QString msgLeftOverArguments(const QMap<QString, QString> &remainingArgs) -{ - 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(); - if (!it.value().isEmpty()) - str << ' ' << it.value(); - } - str << "\nCommand line: " << QCoreApplication::arguments().join(QLatin1Char(' ')); - return message; -} - -QString msgInvalidVersion(const QString &package, const QString &version) -{ - return QLatin1String("Invalid version \"") + version - + QLatin1String("\" specified for package ") + package + QLatin1Char('.'); -} - -QString msgCyclicDependency(const QString &funcName, const QString &graphName, - const QVector<const AbstractMetaFunction *> &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()) { - str << " Implicit conversions (" << count << "): "; - for (int i = 0; i < count; ++i) { - if (i) - str << ", \""; - str << involvedConversions.at(i)->signature() << '"'; - if (const AbstractMetaClass *c = involvedConversions.at(i)->implementingClass()) - str << '(' << c->name() << ')'; - } - } - return result; -} - -// shibokengenerator.cpp - -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(); - return result; -} - -QString msgWrongIndex(const char *varName, const QString &capture, - const AbstractMetaFunction *func) -{ - QString result; - QTextStream str(&result); - str << "Wrong index for " << varName << " variable (" << capture << ") on "; - if (const AbstractMetaClass *c = func->implementingClass()) - str << c->name() << "::"; - str << func->signature(); - return result; -} - -QString msgCannotFindType(const QString &type, const QString &variable, - const QString &why) -{ - QString result; - QTextStream(&result) << "Could not find type '" - << type << "' for use in '" << variable << "' conversion: " << why - << "\nMake sure to use the full C++ name, e.g. 'Namespace::Class'."; - return result; -} - -QString msgCannotBuildMetaType(const QString &s) -{ - return QLatin1String("Unable to build meta type for \"") - + s + QLatin1String("\": "); -} - -QString msgCouldNotFindMinimalConstructor(const QString &where, const QString &type) -{ - return where + QLatin1String(": Could not find a minimal constructor for type '") - + type + QLatin1String("'. This will result in a compilation error."); -} - -// typedatabase.cpp - -QString msgRejectReason(const TypeRejection &r, const QString &needle) -{ - 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; - case TypeRejection::Invalid: - break; - } - return result; -} - -// typesystem.cpp - -QString msgCannotFindNamespaceToExtend(const QString &name, - const QStringRef &extendsPackage) -{ - return QLatin1String("Cannot find namespace ") + name - + QLatin1String(" in package ") + extendsPackage; -} - -QString msgExtendingNamespaceRequiresPattern(const QString &name) -{ - return QLatin1String("Namespace ") + name - + QLatin1String(" requires a file pattern since it extends another namespace."); -} - -QString msgInvalidRegularExpression(const QString &pattern, const QString &why) -{ - return QLatin1String("Invalid pattern \"") + pattern + QLatin1String("\": ") + why; -} - -QString msgNoRootTypeSystemEntry() -{ - return QLatin1String("Type system entry appears out of order, there does not seem to be a root type system element."); -} - -QString msgIncorrectlyNestedName(const QString &name) -{ - return QLatin1String("Nesting types by specifying '::' is no longer supported (") - + name + QLatin1String(")."); -} - -// qtdocgenerator.cpp - -QString msgTagWarning(const QXmlStreamReader &reader, const QString &context, - const QString &tag, const QString &message) -{ - QString result; - QTextStream str(&result); - str << "While handling <"; - const QStringRef currentTag = reader.name(); - if (currentTag.isEmpty()) - str << tag; - else - str << currentTag; - str << "> in " << context << ", line "<< reader.lineNumber() - << ": " << message; - return result; -} - -QString msgFallbackWarning(const QXmlStreamReader &reader, const QString &context, - const QString &tag, const QString &location, - const QString &identifier, const QString &fallback) -{ - QString message = QLatin1String("Falling back to \"") - + QDir::toNativeSeparators(fallback) + QLatin1String("\" for \"") - + location + QLatin1Char('"'); - if (!identifier.isEmpty()) - message += QLatin1String(" [") + identifier + QLatin1Char(']'); - return msgTagWarning(reader, context, tag, message); -} diff --git a/sources/shiboken2/ApiExtractor/messages.h b/sources/shiboken2/ApiExtractor/messages.h deleted file mode 100644 index 72484050a..000000000 --- a/sources/shiboken2/ApiExtractor/messages.h +++ /dev/null @@ -1,202 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 MESSAGES_H -#define MESSAGES_H - -#include "abstractmetalang_typedefs.h" -#include "parser/codemodel_fwd.h" -#include "typesystem_typedefs.h" - -#include <QtCore/QMap> -#include <QtCore/QString> -#include <QtCore/QVector> - -class EnumTypeEntry; -class FunctionTypeEntry; -class TypeEntry; -class TypeInfo; -struct TypeRejection; - -QT_FORWARD_DECLARE_CLASS(QDir) -QT_FORWARD_DECLARE_CLASS(QFile) -QT_FORWARD_DECLARE_CLASS(QXmlStreamReader) - -QString msgAddedFunctionInvalidArgType(const QString &addedFuncName, - const QString &typeName, - int pos, const QString &why); - -QString msgAddedFunctionInvalidReturnType(const QString &addedFuncName, - const QString &typeName, const QString &why); - -QString msgNoFunctionForModification(const AbstractMetaClass *klass, - const QString &signature, - const QString &originalSignature, - const QStringList &possibleSignatures, - const AbstractMetaFunctionList &allFunctions); - -QString msgNoEnumTypeEntry(const EnumModelItem &enumItem, - const QString &className); - - -QString msgNoEnumTypeConflict(const EnumModelItem &enumItem, - const QString &className, - const TypeEntry *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 msgUnmatchedParameterType(const ArgumentModelItem &arg, int n, - const QString &why); - -QString msgUnmatchedReturnType(const FunctionModelItem &functionItem, - const QString &why); - -QString msgSkippingFunction(const FunctionModelItem &functionItem, - const QString &signature, const QString &why); - -QString msgSkippingField(const VariableModelItem &field, const QString &className, - const QString &type); - -QString msgTypeNotDefined(const TypeEntry *entry); - -QString msgGlobalFunctionNotDefined(const FunctionTypeEntry *fte, - const QString &signature); - -QString msgStrippingArgument(const FunctionModelItem &f, int i, - const QString &originalSignature, - const ArgumentModelItem &arg); - -QString msgEnumNotDefined(const EnumTypeEntry *t); - -QString msgUnknownBase(const AbstractMetaClass *metaClass, - const QString &baseClassName); - -QString msgArrayModificationFailed(const FunctionModelItem &functionItem, - const QString &className, - const QString &errorMessage); - -QString msgCannotResolveEntity(const QString &name, const QString &reason); - -QString msgCannotSetArrayUsage(const QString &function, int i, const QString &reason); - -QString msgUnableToTranslateType(const QString &t, const QString &why); - -QString msgUnableToTranslateType(const TypeInfo &typeInfo, - const QString &why); - -QString msgCannotFindTypeEntry(const QString &t); - -QString msgCannotFindTypeEntryForSmartPointer(const QString &t, const QString &smartPointerType); -QString msgInvalidSmartPointerType(const TypeInfo &i); -QString msgCannotFindSmartPointerInstantion(const TypeInfo &i); - -QString msgCannotTranslateTemplateArgument(int i, - const TypeInfo &typeInfo, - const QString &why); - -QString msgDisallowThread(const AbstractMetaFunction *f); - -QString msgNamespaceToBeExtendedNotFound(const QString &namespaceName, const QString &packageName); - -QString msgCannotFindDocumentation(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); - -QString msgCannotFindDocumentation(const QString &fileName, - const AbstractMetaClass *metaClass, - const AbstractMetaEnum *e, - const QString &query); - -QString msgCannotFindDocumentation(const QString &fileName, - const AbstractMetaClass *metaClass, - const AbstractMetaField *f, - const QString &query); - -QString msgXpathDocModificationError(const DocModificationList& mods, - const QString &what); - -QString msgCannotOpenForReading(const QFile &f); - -QString msgCannotOpenForWriting(const QFile &f); - -QString msgCannotUseEnumAsInt(const QString &name); - -QString msgConversionTypesDiffer(const QString &varType, const QString &conversionType); - -QString msgCannotFindSmartPointer(const QString &instantiationType, - const AbstractMetaClassList &pointers); - -QString msgLeftOverArguments(const QMap<QString, QString> &remainingArgs); - -QString msgInvalidVersion(const QString &package, const QString &version); - -QString msgCannotFindNamespaceToExtend(const QString &name, - const QStringRef &extendsPackage); - -QString msgExtendingNamespaceRequiresPattern(const QString &name); - -QString msgInvalidRegularExpression(const QString &pattern, const QString &why); - -QString msgNoRootTypeSystemEntry(); - -QString msgIncorrectlyNestedName(const QString &name); - -QString msgCyclicDependency(const QString &funcName, const QString &graphName, - const QVector<const AbstractMetaFunction *> &involvedConversions); - -QString msgUnknownOperator(const AbstractMetaFunction* func); - -QString msgWrongIndex(const char *varName, const QString &capture, - const AbstractMetaFunction *func); - -QString msgCannotFindType(const QString &type, const QString &variable, - const QString &why); - -QString msgCannotBuildMetaType(const QString &s); - -QString msgCouldNotFindMinimalConstructor(const QString &where, const QString &type); - -QString msgRejectReason(const TypeRejection &r, const QString &needle = QString()); - -QString msgTagWarning(const QXmlStreamReader &reader, const QString &context, - const QString &tag, const QString &message); - -QString msgFallbackWarning(const QXmlStreamReader &reader, const QString &context, - const QString &tag, const QString &location, - const QString &identifier, const QString &fallback); - -#endif // MESSAGES_H diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp b/sources/shiboken2/ApiExtractor/parser/codemodel.cpp deleted file mode 100644 index e5a6e074c..000000000 --- a/sources/shiboken2/ApiExtractor/parser/codemodel.cpp +++ /dev/null @@ -1,1557 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - - -#include "codemodel.h" - -#include <sourcelocation.h> -#include <clangparser/clangutils.h> - -#include <algorithm> -#include <functional> -#include <iostream> -#include <QDebug> -#include <QDir> -#include <QtCore/QStack> - -// Predicate to find an item by name in a list of QSharedPointer<Item> -template <class T> class ModelItemNamePredicate -{ -public: - explicit ModelItemNamePredicate(const QString &name) : m_name(name) {} - bool operator()(const QSharedPointer<T> &item) const { return item->name() == m_name; } - -private: - const QString m_name; -}; - -template <class T> -static QSharedPointer<T> findModelItem(const QVector<QSharedPointer<T> > &list, const QString &name) -{ - const auto it = std::find_if(list.cbegin(), list.cend(), ModelItemNamePredicate<T>(name)); - return it != list.cend() ? *it : QSharedPointer<T>(); -} - -// --------------------------------------------------------------------------- - -CodeModel::CodeModel() : m_globalNamespace(new _NamespaceModelItem(this)) -{ -} - -CodeModel::~CodeModel() = default; - -NamespaceModelItem CodeModel::globalNamespace() const -{ - return m_globalNamespace; -} - -void CodeModel::addFile(const FileModelItem &item) -{ - m_files.append(item); -} - -FileModelItem CodeModel::findFile(const QString &name) const -{ - return findModelItem(m_files, name); -} - -static CodeModelItem findRecursion(const ScopeModelItem &scope, - const QStringList &qualifiedName, int segment = 0) -{ - const QString &nameSegment = qualifiedName.at(segment); - if (segment == qualifiedName.size() - 1) { // Leaf item - if (ClassModelItem cs = scope->findClass(nameSegment)) - return cs; - if (EnumModelItem es = scope->findEnum(nameSegment)) - return es; - if (TypeDefModelItem tp = scope->findTypeDef(nameSegment)) - return tp; - if (TemplateTypeAliasModelItem tta = scope->findTemplateTypeAlias(nameSegment)) - return tta; - return CodeModelItem(); - } - if (auto nestedClass = scope->findClass(nameSegment)) - return findRecursion(nestedClass, qualifiedName, segment + 1); - if (auto namespaceItem = qSharedPointerDynamicCast<_NamespaceModelItem>(scope)) { - for (const auto &nestedNamespace : namespaceItem->namespaces()) { - if (nestedNamespace->name() == nameSegment) { - if (auto item = findRecursion(nestedNamespace, qualifiedName, segment + 1)) - return item; - } - } - } - return CodeModelItem(); -} - -CodeModelItem CodeModel::findItem(const QStringList &qualifiedName, const ScopeModelItem &scope) const -{ - return findRecursion(scope, qualifiedName); -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const CodeModel *m) -{ - QDebugStateSaver s(d); - d.noquote(); - d.nospace(); - d << "CodeModel("; - if (m) { - const NamespaceModelItem globalNamespaceP = m->globalNamespace(); - if (globalNamespaceP.data()) - globalNamespaceP->formatDebug(d); - } else { - d << '0'; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -// --------------------------------------------------------------------------- -TypeInfo TypeInfo::combine(const TypeInfo &__lhs, const TypeInfo &__rhs) -{ - TypeInfo __result = __lhs; - - __result.setConstant(__result.isConstant() || __rhs.isConstant()); - __result.setVolatile(__result.isVolatile() || __rhs.isVolatile()); - if (__rhs.referenceType() > __result.referenceType()) - __result.setReferenceType(__rhs.referenceType()); - __result.m_indirections.append(__rhs.m_indirections); - __result.setArrayElements(__result.arrayElements() + __rhs.arrayElements()); - __result.m_instantiations.append(__rhs.m_instantiations); - - return __result; -} - -bool TypeInfo::isVoid() const -{ - return m_indirections.isEmpty() && m_referenceType == NoReference - && m_arguments.isEmpty() && m_arrayElements.isEmpty() - && m_instantiations.isEmpty() - && m_qualifiedName.size() == 1 - && m_qualifiedName.constFirst() == QLatin1String("void"); -} - -TypeInfo TypeInfo::resolveType(TypeInfo const &__type, const ScopeModelItem &__scope) -{ - CodeModel *__model = __scope->model(); - Q_ASSERT(__model != nullptr); - - return TypeInfo::resolveType(__model->findItem(__type.qualifiedName(), __scope), __type, __scope); -} - -TypeInfo TypeInfo::resolveType(CodeModelItem __item, TypeInfo const &__type, const ScopeModelItem &__scope) -{ - // Copy the type and replace with the proper qualified name. This - // only makes sence to do if we're actually getting a resolved - // type with a namespace. We only get this if the returned type - // has more than 2 entries in the qualified name... This test - // could be improved by returning if the type was found or not. - TypeInfo otherType(__type); - if (__item && __item->qualifiedName().size() > 1) { - otherType.setQualifiedName(__item->qualifiedName()); - } - - if (TypeDefModelItem __typedef = qSharedPointerDynamicCast<_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()) { - std::cerr << "** WARNING Bailing out recursion of " << __FUNCTION__ - << "() on " << qPrintable(__type.qualifiedName().join(QLatin1String("::"))) - << std::endl; - return otherType; - } - return resolveType(nextItem, combined, __scope); - } - - if (TemplateTypeAliasModelItem templateTypeAlias = qSharedPointerDynamicCast<_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(); - auto concreteInstantiations = otherType.instantiations(); - const int count = qMin(aliasInstantiations.size(), concreteInstantiations.size()); - for (int i = 0; i < count; ++i) - aliasInstantiations[i] = concreteInstantiations[i]; - combined.setInstantiations(aliasInstantiations); - const CodeModelItem nextItem = __scope->model()->findItem(combined.qualifiedName(), __scope); - if (!nextItem) - return combined; - return resolveType(nextItem, combined, __scope); - } - - return otherType; -} - -// Handler for clang::parseTemplateArgumentList() that populates -// TypeInfo::m_instantiations -class TypeInfoTemplateArgumentHandler -{ -public: - explicit TypeInfoTemplateArgumentHandler(TypeInfo *t) - { - m_parseStack.append(t); - } - - void operator()(int level, const QStringRef &name) - { - if (level > m_parseStack.size()) { - Q_ASSERT(!top()->m_instantiations.isEmpty()); - m_parseStack.push(&top()->m_instantiations.back()); - } - while (level < m_parseStack.size()) - m_parseStack.pop(); - TypeInfo instantiation; - instantiation.setQualifiedName(qualifiedName(name)); - top()->addInstantiation(instantiation); - } - -private: - TypeInfo *top() const { return m_parseStack.back(); } - - static QStringList qualifiedName(const QStringRef &name) - { - QStringList result; - const QVector<QStringRef> nameParts = name.split(QLatin1String("::")); - result.reserve(nameParts.size()); - for (const QStringRef &p : nameParts) - result.append(p.toString()); - return result; - } - - QStack<TypeInfo *> m_parseStack; -}; - -QPair<int, int> TypeInfo::parseTemplateArgumentList(const QString &l, int from) -{ - return clang::parseTemplateArgumentList(l, clang::TemplateArgumentHandler(TypeInfoTemplateArgumentHandler(this)), from); -} - -QString TypeInfo::toString() const -{ - QString tmp; - if (isConstant()) - tmp += QLatin1String("const "); - - if (isVolatile()) - tmp += QLatin1String("volatile "); - - tmp += m_qualifiedName.join(QLatin1String("::")); - - if (const int instantiationCount = m_instantiations.size()) { - tmp += QLatin1Char('<'); - for (int i = 0; i < instantiationCount; ++i) { - if (i) - tmp += QLatin1String(", "); - tmp += m_instantiations.at(i).toString(); - } - if (tmp.endsWith(QLatin1Char('>'))) - tmp += QLatin1Char(' '); - tmp += QLatin1Char('>'); - } - - for (Indirection i : m_indirections) - tmp.append(indirectionKeyword(i)); - - switch (referenceType()) { - case NoReference: - break; - case LValueReference: - tmp += QLatin1Char('&'); - break; - case RValueReference: - tmp += QLatin1String("&&"); - break; - } - - if (isFunctionPointer()) { - tmp += QLatin1String(" (*)("); - for (int i = 0; i < m_arguments.count(); ++i) { - if (i != 0) - tmp += QLatin1String(", "); - - tmp += m_arguments.at(i).toString(); - } - tmp += QLatin1Char(')'); - } - - for (const QString &elt : m_arrayElements) { - tmp += QLatin1Char('['); - tmp += elt; - tmp += QLatin1Char(']'); - } - - return tmp; -} - -bool TypeInfo::operator==(const TypeInfo &other) const -{ - if (arrayElements().count() != other.arrayElements().count()) - return false; - -#if defined (RXX_CHECK_ARRAY_ELEMENTS) // ### it'll break - for (int i = 0; i < arrayElements().count(); ++i) { - QString elt1 = arrayElements().at(i).trimmed(); - QString elt2 = other.arrayElements().at(i).trimmed(); - - if (elt1 != elt2) - return false; - } -#endif - - return flags == other.flags - && m_qualifiedName == other.m_qualifiedName - && (!m_functionPointer || m_arguments == other.m_arguments) - && m_instantiations == other.m_instantiations; -} - -QString TypeInfo::indirectionKeyword(Indirection i) -{ - return i == Indirection::Pointer - ? QStringLiteral("*") : QStringLiteral("*const"); -} - -static inline QString constQualifier() { return QStringLiteral("const"); } -static inline QString volatileQualifier() { return QStringLiteral("volatile"); } - -bool TypeInfo::stripLeadingConst(QString *s) -{ - return stripLeadingQualifier(constQualifier(), s); -} - -bool TypeInfo::stripLeadingVolatile(QString *s) -{ - return stripLeadingQualifier(volatileQualifier(), s); -} - -bool TypeInfo::stripLeadingQualifier(const QString &qualifier, QString *s) -{ - // "const int x" - const int qualifierSize = qualifier.size(); - if (s->size() < qualifierSize + 1 || !s->startsWith(qualifier) - || !s->at(qualifierSize).isSpace()) { - return false; - } - s->remove(0, qualifierSize + 1); - while (!s->isEmpty() && s->at(0).isSpace()) - s->remove(0, 1); - return true; -} - -// Strip all const/volatile/*/& -void TypeInfo::stripQualifiers(QString *s) -{ - stripLeadingConst(s); - stripLeadingVolatile(s); - while (s->endsWith(QLatin1Char('&')) || s->endsWith(QLatin1Char('*')) - || s->endsWith(QLatin1Char(' '))) { - s->chop(1); - } -} - -// Helper functionality to simplify a raw standard type as returned by -// clang_getCanonicalType() for g++ standard containers from -// "std::__cxx11::list<int, std::allocator<int> >" or -// "std::__1::list<int, std::allocator<int> >" -> "std::list<int>". - -bool TypeInfo::isStdType() const -{ - return m_qualifiedName.size() > 1 - && m_qualifiedName.constFirst() == QLatin1String("std"); -} - -static inline bool discardStdType(const QString &name) -{ - return name == QLatin1String("allocator") || name == QLatin1String("less"); -} - -void TypeInfo::simplifyStdType() -{ - if (isStdType()) { - if (m_qualifiedName.at(1).startsWith(QLatin1String("__"))) - m_qualifiedName.removeAt(1); - for (int t = m_instantiations.size() - 1; t >= 0; --t) { - if (m_instantiations.at(t).isStdType()) { - if (discardStdType(m_instantiations.at(t).m_qualifiedName.constLast())) - m_instantiations.removeAt(t); - else - m_instantiations[t].simplifyStdType(); - } - } - } -} - -void TypeInfo::formatTypeSystemSignature(QTextStream &str) const -{ - if (m_constant) - str << "const "; - str << m_qualifiedName.join(QLatin1String("::")); - switch (m_referenceType) { - case NoReference: - break; - case LValueReference: - str << '&'; - break; - case RValueReference: - str << "&&"; - break; - } - for (auto i : m_indirections) { - switch (i) { - case Indirection::Pointer: - str << '*'; - break; - case Indirection::ConstPointer: - str << "* const"; - break; - } - } -} - -#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 &d) const -{ - d << '"'; - formatSequence(d, m_qualifiedName.begin(), m_qualifiedName.end(), "\", \""); - d << '"'; - if (m_constant) - d << ", [const]"; - if (m_volatile) - d << ", [volatile]"; - if (!m_indirections.isEmpty()) { - d << ", indirections="; - for (auto i : m_indirections) - d << ' ' << TypeInfo::indirectionKeyword(i); - } - switch (m_referenceType) { - case NoReference: - break; - case LValueReference: - d << ", [ref]"; - break; - case RValueReference: - d << ", [rvalref]"; - break; - } - if (!m_instantiations.isEmpty()) { - d << ", template<"; - formatSequence(d, m_instantiations.begin(), m_instantiations.end()); - d << '>'; - } - if (m_functionPointer) { - d << ", function ptr("; - formatSequence(d, m_arguments.begin(), m_arguments.end()); - d << ')'; - } - if (!m_arrayElements.isEmpty()) { - d << ", array[" << m_arrayElements.size() << "]["; - formatSequence(d, m_arrayElements.begin(), m_arrayElements.end()); - d << ']'; - } -} - -QDebug operator<<(QDebug d, const TypeInfo &t) -{ - QDebugStateSaver s(d); -#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) - const int verbosity = d.verbosity(); -#else - const int verbosity = 0; -#endif - d.noquote(); - d.nospace(); - d << "TypeInfo("; - if (verbosity > 2) - t.formatDebug(d); - else - d << t.toString(); - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -// --------------------------------------------------------------------------- -_CodeModelItem::_CodeModelItem(CodeModel *model, int kind) - : m_model(model), - m_kind(kind), - m_startLine(0), - m_startColumn(0), - m_endLine(0), - m_endColumn(0) -{ -} - -_CodeModelItem::_CodeModelItem(CodeModel *model, const QString &name, int kind) - : m_model(model), - m_kind(kind), - m_startLine(0), - m_startColumn(0), - m_endLine(0), - m_endColumn(0), - m_name(name) -{ -} - -_CodeModelItem::~_CodeModelItem() = default; - -int _CodeModelItem::kind() const -{ - return m_kind; -} - -QStringList _CodeModelItem::qualifiedName() const -{ - QStringList q = scope(); - - if (!name().isEmpty()) - q += name(); - - return q; -} - -QString _CodeModelItem::name() const -{ - return m_name; -} - -void _CodeModelItem::setName(const QString &name) -{ - m_name = name; -} - -QStringList _CodeModelItem::scope() const -{ - return m_scope; -} - -void _CodeModelItem::setScope(const QStringList &scope) -{ - m_scope = scope; -} - -QString _CodeModelItem::fileName() const -{ - return m_fileName; -} - -void _CodeModelItem::setFileName(const QString &fileName) -{ - m_fileName = fileName; -} - -FileModelItem _CodeModelItem::file() const -{ - return model()->findFile(fileName()); -} - -void _CodeModelItem::getStartPosition(int *line, int *column) -{ - *line = m_startLine; - *column = m_startColumn; -} - -void _CodeModelItem::setStartPosition(int line, int column) -{ - m_startLine = line; - m_startColumn = column; -} - -void _CodeModelItem::getEndPosition(int *line, int *column) -{ - *line = m_endLine; - *column = m_endColumn; -} - -void _CodeModelItem::setEndPosition(int line, int column) -{ - m_endLine = line; - m_endColumn = column; -} - -SourceLocation _CodeModelItem::sourceLocation() const -{ - return SourceLocation(m_fileName, m_startLine); -} - -#ifndef QT_NO_DEBUG_STREAM -template <class It> -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->data(); - } -} - -void _CodeModelItem::formatKind(QDebug &d, int k) -{ - switch (k) { - case Kind_Argument: - d << "ArgumentModelItem"; - break; - case Kind_Class: - d << "ClassModelItem"; - break; - case Kind_Enum: - d << "EnumModelItem"; - break; - case Kind_Enumerator: - d << "EnumeratorModelItem"; - break; - case Kind_File: - d << "FileModelItem"; - break; - case Kind_Function: - d << "FunctionModelItem"; - break; - case Kind_Member: - d << "MemberModelItem"; - break; - case Kind_Namespace: - d << "NamespaceModelItem"; - break; - case Kind_Variable: - d << "VariableModelItem"; - break; - case Kind_Scope: - d << "ScopeModelItem"; - break; - case Kind_TemplateParameter: - d << "TemplateParameter"; - break; - case Kind_TypeDef: - d << "TypeDefModelItem"; - break; - case Kind_TemplateTypeAlias: - d << "TemplateTypeAliasModelItem"; - break; - default: - d << "CodeModelItem"; - break; - } -} - -void _CodeModelItem::formatDebug(QDebug &d) const -{ - d << "(\"" << name() << '"'; - if (!m_scope.isEmpty()) { - d << ", scope="; - formatSequence(d, m_scope.cbegin(), m_scope.cend(), "::"); - } - if (!m_fileName.isEmpty()) { - d << ", file=\"" << QDir::toNativeSeparators(m_fileName); - if (m_startLine > 0) - d << ':' << m_startLine; - d << '"'; - } -} - -QDebug operator<<(QDebug d, const _CodeModelItem *t) -{ - QDebugStateSaver s(d); - d.noquote(); - d.nospace(); - if (!t) { - d << "CodeModelItem(0)"; - return d; - } - _CodeModelItem::formatKind(d, t->kind()); - t->formatDebug(d); - switch (t->kind()) { - case _CodeModelItem::Kind_Class: - d << " /* class " << t->name() << " */"; - break; - case _CodeModelItem::Kind_Namespace: - d << " /* namespace " << t->name() << " */"; - break; - } - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -// --------------------------------------------------------------------------- -_ClassModelItem::~_ClassModelItem() = default; - -TemplateParameterList _ClassModelItem::templateParameters() const -{ - return m_templateParameters; -} - -void _ClassModelItem::setTemplateParameters(const TemplateParameterList &templateParameters) -{ - m_templateParameters = templateParameters; -} - -void _ClassModelItem::addBaseClass(const QString &name, CodeModel::AccessPolicy 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) { - if (bc.name == name) - return true; - } - return false; -} - -void _ClassModelItem::setClassType(CodeModel::ClassType type) -{ - m_classType = type; -} - -CodeModel::ClassType _ClassModelItem::classType() const -{ - return m_classType; -} - -void _ClassModelItem::addPropertyDeclaration(const QString &propertyDeclaration) -{ - m_propertyDeclarations << propertyDeclaration; -} - -#ifndef QT_NO_DEBUG_STREAM -template <class List> -static void formatModelItemList(QDebug &d, const char *prefix, const List &l, - const char *separator = ", ") -{ - if (const int size = l.size()) { - d << prefix << '[' << size << "]("; - for (int i = 0; i < size; ++i) { - if (i) - d << separator; - l.at(i)->formatDebug(d); - } - d << ')'; - } -} - -void _ClassModelItem::formatDebug(QDebug &d) const -{ - _ScopeModelItem::formatDebug(d); - if (!m_baseClasses.isEmpty()) { - if (m_final) - d << " [final]"; - d << ", inherits="; - d << ", inherits="; - for (int i = 0, size = m_baseClasses.size(); i < size; ++i) { - if (i) - d << ", "; - d << m_baseClasses.at(i).name << " (" << m_baseClasses.at(i).accessPolicy << ')'; - } - } - formatModelItemList(d, ", templateParameters=", m_templateParameters); - formatScopeItemsDebug(d); -} -#endif // !QT_NO_DEBUG_STREAM - -// --------------------------------------------------------------------------- -FunctionModelItem _ScopeModelItem::declaredFunction(const FunctionModelItem &item) -{ - for (const FunctionModelItem &fun : qAsConst(m_functions)) { - if (fun->name() == item->name() && fun->isSimilar(item)) - return fun; - - } - return FunctionModelItem(); -} - -_ScopeModelItem::~_ScopeModelItem() = default; - -void _ScopeModelItem::addEnumsDeclaration(const QString &enumsDeclaration) -{ - m_enumsDeclarations << enumsDeclaration; -} - -void _ScopeModelItem::addClass(const ClassModelItem &item) -{ - m_classes.append(item); -} - -void _ScopeModelItem::addFunction(const FunctionModelItem &item) -{ - m_functions.append(item); -} - -void _ScopeModelItem::addVariable(const VariableModelItem &item) -{ - m_variables.append(item); -} - -void _ScopeModelItem::addTypeDef(const TypeDefModelItem &item) -{ - m_typeDefs.append(item); -} - -void _ScopeModelItem::addTemplateTypeAlias(const TemplateTypeAliasModelItem &item) -{ - m_templateTypeAliases.append(item); -} - -void _ScopeModelItem::addEnum(const EnumModelItem &item) -{ - m_enums.append(item); -} - -void _ScopeModelItem::appendScope(const _ScopeModelItem &other) -{ - m_classes += other.m_classes; - m_enums += other.m_enums; - m_typeDefs += other.m_typeDefs; - m_templateTypeAliases += other.m_templateTypeAliases; - m_variables += other.m_variables; - m_functions += other.m_functions; - m_enumsDeclarations += other.m_enumsDeclarations; -} - -#ifndef QT_NO_DEBUG_STREAM -template <class Hash> -static void formatScopeHash(QDebug &d, const char *prefix, const Hash &h, - const char *separator = ", ", - bool trailingNewLine = false) -{ - if (!h.isEmpty()) { - d << prefix << '[' << h.size() << "]("; - const auto begin = h.cbegin(); - for (auto it = begin, end = h.cend(); it != end; ++it) { // Omit the names as they are repeated - if (it != begin) - d << separator; - d << it.value().data(); - } - d << ')'; - if (trailingNewLine) - d << '\n'; - } -} - -template <class List> -static void formatScopeList(QDebug &d, const char *prefix, const List &l, - const char *separator = ", ", - bool trailingNewLine = false) -{ - if (!l.isEmpty()) { - d << prefix << '[' << l.size() << "]("; - formatPtrSequence(d, l.begin(), l.end(), separator); - d << ')'; - if (trailingNewLine) - d << '\n'; - } -} - -void _ScopeModelItem::formatScopeItemsDebug(QDebug &d) const -{ - formatScopeList(d, ", classes=", m_classes, "\n", true); - formatScopeList(d, ", enums=", m_enums, "\n", true); - formatScopeList(d, ", aliases=", m_typeDefs, "\n", true); - formatScopeList(d, ", template type aliases=", m_templateTypeAliases, "\n", true); - formatScopeList(d, ", functions=", m_functions, "\n", true); - formatScopeList(d, ", variables=", m_variables); -} - -void _ScopeModelItem::formatDebug(QDebug &d) const -{ - _CodeModelItem::formatDebug(d); - formatScopeItemsDebug(d); -} -#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 -{ -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 - -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)); - return it != m_classes.end() ? *it : ClassModelItem(); -} - -VariableModelItem _ScopeModelItem::findVariable(const QString &name) const -{ - return findModelItem(m_variables, name); -} - -TypeDefModelItem _ScopeModelItem::findTypeDef(const QString &name) const -{ - return findModelItem(m_typeDefs, name); -} - -TemplateTypeAliasModelItem _ScopeModelItem::findTemplateTypeAlias(const QString &name) const -{ - return findModelItem(m_templateTypeAliases, name); -} - -EnumModelItem _ScopeModelItem::findEnum(const QString &name) const -{ - return findModelItem(m_enums, name); -} - -FunctionList _ScopeModelItem::findFunctions(const QString &name) const -{ - FunctionList result; - for (const FunctionModelItem &func : m_functions) { - if (func->name() == name) - result.append(func); - } - return result; -} - -// --------------------------------------------------------------------------- -_NamespaceModelItem::~_NamespaceModelItem() -{ -} - -void _NamespaceModelItem::addNamespace(NamespaceModelItem item) -{ - m_namespaces.append(item); -} - -NamespaceModelItem _NamespaceModelItem::findNamespace(const QString &name) const -{ - return findModelItem(m_namespaces, name); -} - -_FileModelItem::~_FileModelItem() = default; - -void _NamespaceModelItem::appendNamespace(const _NamespaceModelItem &other) -{ - appendScope(other); - m_namespaces += other.m_namespaces; -} - -#ifndef QT_NO_DEBUG_STREAM -void _NamespaceModelItem::formatDebug(QDebug &d) const -{ - _ScopeModelItem::formatDebug(d); - switch (m_type) { - case NamespaceType::Default: - break; - case NamespaceType::Anonymous: - d << ", anonymous"; - break; - case NamespaceType::Inline: - d << ", inline"; - break; - } - formatScopeList(d, ", namespaces=", m_namespaces); -} -#endif // !QT_NO_DEBUG_STREAM - -// --------------------------------------------------------------------------- -_ArgumentModelItem::~_ArgumentModelItem() -{ -} - -TypeInfo _ArgumentModelItem::type() const -{ - return m_type; -} - -void _ArgumentModelItem::setType(const TypeInfo &type) -{ - m_type = type; -} - -bool _ArgumentModelItem::defaultValue() const -{ - return m_defaultValue; -} - -void _ArgumentModelItem::setDefaultValue(bool defaultValue) -{ - m_defaultValue = defaultValue; -} - -#ifndef QT_NO_DEBUG_STREAM -void _ArgumentModelItem::formatDebug(QDebug &d) const -{ - _CodeModelItem::formatDebug(d); - d << ", type=" << m_type; - if (m_defaultValue) - d << ", defaultValue=\"" << m_defaultValueExpression << '"'; -} -#endif // !QT_NO_DEBUG_STREAM -// --------------------------------------------------------------------------- -_FunctionModelItem::~_FunctionModelItem() = default; - -bool _FunctionModelItem::isSimilar(const FunctionModelItem &other) const -{ - if (name() != other->name()) - return false; - - if (isConstant() != other->isConstant()) - return false; - - if (isVariadics() != other->isVariadics()) - return false; - - if (arguments().count() != other->arguments().count()) - return false; - - // ### check the template parameters - - for (int i = 0; i < arguments().count(); ++i) { - ArgumentModelItem arg1 = arguments().at(i); - ArgumentModelItem arg2 = other->arguments().at(i); - - if (arg1->type() != arg2->type()) - return false; - } - - return true; -} - -ArgumentList _FunctionModelItem::arguments() const -{ - return m_arguments; -} - -void _FunctionModelItem::addArgument(const ArgumentModelItem& item) -{ - m_arguments.append(item); -} - -CodeModel::FunctionType _FunctionModelItem::functionType() const -{ - return m_functionType; -} - -void _FunctionModelItem::setFunctionType(CodeModel::FunctionType functionType) -{ - m_functionType = functionType; -} - -bool _FunctionModelItem::isVariadics() const -{ - return m_isVariadics; -} - -void _FunctionModelItem::setVariadics(bool isVariadics) -{ - m_isVariadics = isVariadics; -} - -bool _FunctionModelItem::isNoExcept() const -{ - return m_exceptionSpecification == ExceptionSpecification::NoExcept; -} - -ExceptionSpecification _FunctionModelItem::exceptionSpecification() const -{ - return m_exceptionSpecification; -} - -void _FunctionModelItem::setExceptionSpecification(ExceptionSpecification e) -{ - m_exceptionSpecification = e; -} - -bool _FunctionModelItem::isDeleted() const -{ - return m_isDeleted; -} - -void _FunctionModelItem::setDeleted(bool d) -{ - m_isDeleted = d; -} - -bool _FunctionModelItem::isDeprecated() const -{ - return m_isDeprecated; -} - -void _FunctionModelItem::setDeprecated(bool d) -{ - m_isDeprecated = d; -} - -bool _FunctionModelItem::isVirtual() const -{ - return m_isVirtual; -} - -void _FunctionModelItem::setVirtual(bool isVirtual) -{ - m_isVirtual = isVirtual; -} - -bool _FunctionModelItem::isInline() const -{ - return m_isInline; -} - -bool _FunctionModelItem::isOverride() const -{ - return m_isOverride; -} - -void _FunctionModelItem::setOverride(bool o) -{ - m_isOverride = o; -} - -bool _FunctionModelItem::isFinal() const -{ - return m_isFinal; -} - -void _FunctionModelItem::setFinal(bool f) -{ - m_isFinal = f; -} - -void _FunctionModelItem::setInline(bool isInline) -{ - m_isInline = isInline; -} - -bool _FunctionModelItem::isExplicit() const -{ - return m_isExplicit; -} - -void _FunctionModelItem::setExplicit(bool isExplicit) -{ - m_isExplicit = isExplicit; -} - -bool _FunctionModelItem::isAbstract() const -{ - return m_isAbstract; -} - -void _FunctionModelItem::setAbstract(bool isAbstract) -{ - m_isAbstract = isAbstract; -} - -// Qt -bool _FunctionModelItem::isInvokable() const -{ - return m_isInvokable; -} - -void _FunctionModelItem::setInvokable(bool isInvokable) -{ - m_isInvokable = isInvokable; -} - -QString _FunctionModelItem::typeSystemSignature() const // For dumping out type system files -{ - QString result; - QTextStream str(&result); - str << name() << '('; - for (int a = 0, size = m_arguments.size(); a < size; ++a) { - if (a) - str << ','; - m_arguments.at(a)->type().formatTypeSystemSignature(str); - } - str << ')'; - return result; -} - -#ifndef QT_NO_DEBUG_STREAM -void _FunctionModelItem::formatDebug(QDebug &d) const -{ - _MemberModelItem::formatDebug(d); - d << ", type=" << m_functionType << ", exspec=" << int(m_exceptionSpecification); - if (m_isDeleted) - d << " [deleted!]"; - if (m_isInline) - d << " [inline]"; - if (m_isVirtual) - d << " [virtual]"; - if (m_isOverride) - d << " [override]"; - if (m_isDeprecated) - d << " [deprecated]"; - if (m_isFinal) - d << " [final]"; - if (m_isAbstract) - d << " [abstract]"; - if (m_isExplicit) - d << " [explicit]"; - if (m_isInvokable) - d << " [invokable]"; - formatModelItemList(d, ", arguments=", m_arguments); - if (m_isVariadics) - d << ",..."; -} -#endif // !QT_NO_DEBUG_STREAM - -// --------------------------------------------------------------------------- -TypeInfo _TypeDefModelItem::type() const -{ - return m_type; -} - -void _TypeDefModelItem::setType(const TypeInfo &type) -{ - m_type = type; -} - -#ifndef QT_NO_DEBUG_STREAM -void _TypeDefModelItem::formatDebug(QDebug &d) const -{ - _CodeModelItem::formatDebug(d); - d << ", type=" << m_type; -} -#endif // !QT_NO_DEBUG_STREAM - -// --------------------------------------------------------------------------- - -_TemplateTypeAliasModelItem::_TemplateTypeAliasModelItem(CodeModel *model, int kind) - : _CodeModelItem(model, kind) {} - -_TemplateTypeAliasModelItem::_TemplateTypeAliasModelItem(CodeModel *model, const QString &name, int kind) - : _CodeModelItem(model, name, kind) {} - -TemplateParameterList _TemplateTypeAliasModelItem::templateParameters() const -{ - return m_templateParameters; -} - -void _TemplateTypeAliasModelItem::addTemplateParameter(const TemplateParameterModelItem &templateParameter) -{ - m_templateParameters.append(templateParameter); -} - -TypeInfo _TemplateTypeAliasModelItem::type() const -{ - return m_type; -} - -void _TemplateTypeAliasModelItem::setType(const TypeInfo &type) -{ - m_type = type; -} - -#ifndef QT_NO_DEBUG_STREAM -void _TemplateTypeAliasModelItem::formatDebug(QDebug &d) const -{ - _CodeModelItem::formatDebug(d); - d << ", <"; - for (int i = 0, count = m_templateParameters.size(); i < count; ++i) { - if (i) - d << ", "; - d << m_templateParameters.at(i)->name(); - } - d << ">, type=" << m_type; -} -#endif // !QT_NO_DEBUG_STREAM - -// --------------------------------------------------------------------------- -CodeModel::AccessPolicy _EnumModelItem::accessPolicy() const -{ - return m_accessPolicy; -} - -_EnumModelItem::~_EnumModelItem() = default; - -void _EnumModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy) -{ - m_accessPolicy = accessPolicy; -} - -EnumeratorList _EnumModelItem::enumerators() const -{ - return m_enumerators; -} - -void _EnumModelItem::addEnumerator(const EnumeratorModelItem &item) -{ - m_enumerators.append(item); -} - -bool _EnumModelItem::isSigned() const -{ - return m_signed; -} - -void _EnumModelItem::setSigned(bool s) -{ - m_signed = s; -} - -#ifndef QT_NO_DEBUG_STREAM -void _EnumModelItem::formatDebug(QDebug &d) const -{ - _CodeModelItem::formatDebug(d); - switch (m_enumKind) { - case CEnum: - break; - case AnonymousEnum: - d << " (anonymous)"; - break; - case EnumClass: - d << " (class)"; - break; - } - if (!m_signed) - d << " (unsigned)"; - formatModelItemList(d, ", enumerators=", m_enumerators); -} -#endif // !QT_NO_DEBUG_STREAM - -// --------------------------------------------------------------------------- -_EnumeratorModelItem::~_EnumeratorModelItem() = default; - -QString _EnumeratorModelItem::stringValue() const -{ - return m_stringValue; -} - -void _EnumeratorModelItem::setStringValue(const QString &value) -{ - m_stringValue = value; -} - -#ifndef QT_NO_DEBUG_STREAM -void _EnumeratorModelItem::formatDebug(QDebug &d) const -{ - _CodeModelItem::formatDebug(d); - d << ", value=" << m_value << ", stringValue=\"" << m_stringValue << '"'; -} -#endif // !QT_NO_DEBUG_STREAM - -// --------------------------------------------------------------------------- -_TemplateParameterModelItem::~_TemplateParameterModelItem() = default; - -TypeInfo _TemplateParameterModelItem::type() const -{ - return m_type; -} - -void _TemplateParameterModelItem::setType(const TypeInfo &type) -{ - m_type = type; -} - -bool _TemplateParameterModelItem::defaultValue() const -{ - return m_defaultValue; -} - -void _TemplateParameterModelItem::setDefaultValue(bool defaultValue) -{ - m_defaultValue = defaultValue; -} - -#ifndef QT_NO_DEBUG_STREAM -void _TemplateParameterModelItem::formatDebug(QDebug &d) const -{ - _CodeModelItem::formatDebug(d); - d << ", type=" << m_type; - if (m_defaultValue) - d << " [defaultValue]"; -} -#endif // !QT_NO_DEBUG_STREAM - -// --------------------------------------------------------------------------- -TypeInfo _MemberModelItem::type() const -{ - return m_type; -} - -void _MemberModelItem::setType(const TypeInfo &type) -{ - m_type = type; -} - -CodeModel::AccessPolicy _MemberModelItem::accessPolicy() const -{ - return m_accessPolicy; -} - -_MemberModelItem::~_MemberModelItem() = default; - -void _MemberModelItem::setAccessPolicy(CodeModel::AccessPolicy accessPolicy) -{ - m_accessPolicy = accessPolicy; -} - -bool _MemberModelItem::isStatic() const -{ - return m_isStatic; -} - -void _MemberModelItem::setStatic(bool isStatic) -{ - m_isStatic = isStatic; -} - -bool _MemberModelItem::isConstant() const -{ - return m_isConstant; -} - -void _MemberModelItem::setConstant(bool isConstant) -{ - m_isConstant = isConstant; -} - -bool _MemberModelItem::isVolatile() const -{ - return m_isVolatile; -} - -void _MemberModelItem::setVolatile(bool isVolatile) -{ - m_isVolatile = isVolatile; -} - -bool _MemberModelItem::isAuto() const -{ - return m_isAuto; -} - -void _MemberModelItem::setAuto(bool isAuto) -{ - m_isAuto = isAuto; -} - -bool _MemberModelItem::isFriend() const -{ - return m_isFriend; -} - -void _MemberModelItem::setFriend(bool isFriend) -{ - m_isFriend = isFriend; -} - -bool _MemberModelItem::isRegister() const -{ - return m_isRegister; -} - -void _MemberModelItem::setRegister(bool isRegister) -{ - m_isRegister = isRegister; -} - -bool _MemberModelItem::isExtern() const -{ - return m_isExtern; -} - -void _MemberModelItem::setExtern(bool isExtern) -{ - m_isExtern = isExtern; -} - -bool _MemberModelItem::isMutable() const -{ - return m_isMutable; -} - -void _MemberModelItem::setMutable(bool isMutable) -{ - m_isMutable = isMutable; -} - -#ifndef QT_NO_DEBUG_STREAM -void _MemberModelItem::formatDebug(QDebug &d) const -{ - _CodeModelItem::formatDebug(d); - switch (m_accessPolicy) { - case CodeModel::Public: - d << ", public"; - break; - case CodeModel::Protected: - d << ", protected"; - break; - case CodeModel::Private: - d << ", private"; - break; - } - d << ", type="; - if (m_isConstant) - d << "const "; - if (m_isVolatile) - d << "volatile "; - if (m_isStatic) - d << "static "; - if (m_isAuto) - d << "auto "; - if (m_isFriend) - d << "friend "; - if (m_isRegister) - d << "register "; - if (m_isExtern) - d << "extern "; - if (m_isMutable) - d << "mutable "; - d << m_type; - formatScopeList(d, ", templateParameters", m_templateParameters); -} -#endif // !QT_NO_DEBUG_STREAM - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel.h b/sources/shiboken2/ApiExtractor/parser/codemodel.h deleted file mode 100644 index ea9cdc30d..000000000 --- a/sources/shiboken2/ApiExtractor/parser/codemodel.h +++ /dev/null @@ -1,808 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - - -#ifndef CODEMODEL_H -#define CODEMODEL_H - -#include "codemodel_fwd.h" -#include "codemodel_enums.h" -#include "enumvalue.h" - -#include <QtCore/QHash> -#include <QtCore/QPair> -#include <QtCore/QSet> -#include <QtCore/QString> -#include <QtCore/QStringList> -#include <QtCore/QVector> - -QT_FORWARD_DECLARE_CLASS(QDebug) - -#define DECLARE_MODEL_NODE(k) \ - enum { __node_kind = Kind_##k }; - -class SourceLocation; - -class CodeModel -{ -public: - Q_DISABLE_COPY(CodeModel) - - enum AccessPolicy { - Public, - Protected, - Private - }; - - enum FunctionType { - Normal, - Constructor, - CopyConstructor, - MoveConstructor, - Destructor, - Signal, - Slot - }; - - enum ClassType { - Class, - Struct, - Union - }; - -public: - CodeModel(); - virtual ~CodeModel(); - - FileList files() const { return m_files; } - NamespaceModelItem globalNamespace() const; - - void addFile(const FileModelItem &item); - FileModelItem findFile(const QString &name) const; - - CodeModelItem findItem(const QStringList &qualifiedName, const ScopeModelItem &scope) const; - -private: - FileList m_files; - NamespaceModelItem m_globalNamespace; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const CodeModel *m); -#endif - -class TypeInfo -{ - friend class TypeParser; -public: - using Indirections = QVector<Indirection>; - - TypeInfo() : flags(0), m_referenceType(NoReference) {} - - QStringList qualifiedName() const - { - return m_qualifiedName; - } - - void setQualifiedName(const QStringList &qualified_name) - { - m_qualifiedName = qualified_name; - } - - bool isVoid() const; - - bool isConstant() const - { - return m_constant; - } - - void setConstant(bool is) - { - m_constant = is; - } - - bool isVolatile() const - { - return m_volatile; - } - - void setVolatile(bool is) - { - m_volatile = is; - } - - ReferenceType referenceType() const { return m_referenceType; } - void setReferenceType(ReferenceType r) { m_referenceType = r; } - - Indirections indirectionsV() const { return m_indirections; } - void setIndirectionsV(const Indirections &i) { m_indirections = i; } - void addIndirection(Indirection i) { m_indirections.append(i); } - - // "Legacy", rename? - int indirections() const { return m_indirections.size(); } - - void setIndirections(int indirections) - { - m_indirections = Indirections(indirections, Indirection::Pointer); - } - - bool isFunctionPointer() const - { - return m_functionPointer; - } - void setFunctionPointer(bool is) - { - m_functionPointer = is; - } - - QStringList arrayElements() const - { - return m_arrayElements; - } - void setArrayElements(const QStringList &arrayElements) - { - m_arrayElements = arrayElements; - } - - void addArrayElement(const QString &a) { m_arrayElements.append(a); } - - QVector<TypeInfo> arguments() const { return m_arguments; } - - void setArguments(const QVector<TypeInfo> &arguments); - - void addArgument(const TypeInfo &arg) - { - m_arguments.append(arg); - } - - QVector<TypeInfo> instantiations() const { return m_instantiations; } - void setInstantiations(const QVector<TypeInfo> &i) { m_instantiations = i; } - void addInstantiation(const TypeInfo &i) { m_instantiations.append(i); } - void clearInstantiations() { m_instantiations.clear(); } - - bool isStdType() const; - - QPair<int, int> parseTemplateArgumentList(const QString &l, int from = 0); - - bool operator==(const TypeInfo &other) const; - - bool operator!=(const TypeInfo &other) const - { - return !(*this == other); - } - - // ### arrays and templates?? - - QString toString() const; - - static TypeInfo combine(const TypeInfo &__lhs, const TypeInfo &__rhs); - static TypeInfo resolveType(TypeInfo const &__type, const ScopeModelItem &__scope); - - void formatTypeSystemSignature(QTextStream &str) const; - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const; -#endif - - static QString indirectionKeyword(Indirection i); - - static bool stripLeadingConst(QString *s); - static bool stripLeadingVolatile(QString *s); - static bool stripLeadingQualifier(const QString &qualifier, QString *s); - static void stripQualifiers(QString *s); - - void simplifyStdType(); - -private: - friend class TypeInfoTemplateArgumentHandler; - - static TypeInfo resolveType(CodeModelItem item, TypeInfo const &__type, const ScopeModelItem &__scope); - - QStringList m_qualifiedName; - QStringList m_arrayElements; - QVector<TypeInfo> m_arguments; - QVector<TypeInfo> m_instantiations; - Indirections m_indirections; - - union { - uint flags; - - struct { - uint m_constant: 1; - uint m_volatile: 1; - uint m_functionPointer: 1; - uint m_padding: 29; - }; - }; - - ReferenceType m_referenceType; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const TypeInfo &t); -#endif - -class _CodeModelItem -{ - Q_DISABLE_COPY(_CodeModelItem) -public: - enum Kind { - /* These are bit-flags resembling inheritance */ - Kind_Scope = 0x1, - Kind_Namespace = 0x2 | Kind_Scope, - Kind_Member = 0x4, - Kind_Function = 0x8 | Kind_Member, - KindMask = 0xf, - - /* These are for classes that are not inherited from */ - FirstKind = 0x8, - Kind_Argument = 1 << FirstKind, - Kind_Class = 2 << FirstKind | Kind_Scope, - Kind_Enum = 3 << FirstKind, - Kind_Enumerator = 4 << FirstKind, - Kind_File = 5 << FirstKind | Kind_Namespace, - Kind_TemplateParameter = 7 << FirstKind, - Kind_TypeDef = 8 << FirstKind, - Kind_TemplateTypeAlias = 9 << FirstKind, - Kind_Variable = 10 << FirstKind | Kind_Member - }; - -public: - virtual ~_CodeModelItem(); - - int kind() const; - - QStringList qualifiedName() const; - - QString name() const; - void setName(const QString &name); - - QStringList scope() const; - void setScope(const QStringList &scope); - - QString fileName() const; - void setFileName(const QString &fileName); - - FileModelItem file() const; - - void getStartPosition(int *line, int *column); - int startLine() const { return m_startLine; } - void setStartPosition(int line, int column); - - void getEndPosition(int *line, int *column); - void setEndPosition(int line, int column); - - SourceLocation sourceLocation() const; - - inline CodeModel *model() const { return m_model; } - -#ifndef QT_NO_DEBUG_STREAM - static void formatKind(QDebug &d, int k); - virtual void formatDebug(QDebug &d) const; -#endif - -protected: - explicit _CodeModelItem(CodeModel *model, int kind); - explicit _CodeModelItem(CodeModel *model, const QString &name, int kind); - -private: - CodeModel *m_model; - int m_kind; - int m_startLine; - int m_startColumn; - int m_endLine; - int m_endColumn; - QString m_name; - QString m_fileName; - QStringList m_scope; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const _CodeModelItem *t); -#endif - -class _ScopeModelItem: public _CodeModelItem -{ -public: - DECLARE_MODEL_NODE(Scope) - - ~_ScopeModelItem(); - - ClassList classes() const { return m_classes; } - EnumList enums() const { return m_enums; } - inline FunctionList functions() const { return m_functions; } - TypeDefList typeDefs() const { return m_typeDefs; } - TemplateTypeAliasList templateTypeAliases() const { return m_templateTypeAliases; } - VariableList variables() const { return m_variables; } - - void addClass(const ClassModelItem &item); - void addEnum(const EnumModelItem &item); - void addFunction(const FunctionModelItem &item); - void addTypeDef(const TypeDefModelItem &item); - void addTemplateTypeAlias(const TemplateTypeAliasModelItem &item); - 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; - - void addEnumsDeclaration(const QString &enumsDeclaration); - QStringList enumsDeclarations() const { return m_enumsDeclarations; } - - FunctionModelItem declaredFunction(const FunctionModelItem &item); - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#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) {} - - void appendScope(const _ScopeModelItem &other); - -#ifndef QT_NO_DEBUG_STREAM - void formatScopeItemsDebug(QDebug &d) const; -#endif - -private: - ClassList m_classes; - EnumList m_enums; - TypeDefList m_typeDefs; - TemplateTypeAliasList m_templateTypeAliases; - VariableList m_variables; - FunctionList m_functions; - -private: - QStringList m_enumsDeclarations; -}; - -class _ClassModelItem: public _ScopeModelItem -{ -public: - DECLARE_MODEL_NODE(Class) - - struct BaseClass - { - QString name; - CodeModel::AccessPolicy accessPolicy = CodeModel::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) {} - ~_ClassModelItem(); - - QVector<BaseClass> baseClasses() const { return m_baseClasses; } - - void addBaseClass(const QString &name, CodeModel::AccessPolicy accessPolicy); - - TemplateParameterList templateParameters() const; - void setTemplateParameters(const TemplateParameterList &templateParameters); - - bool extendsClass(const QString &name) const; - - void setClassType(CodeModel::ClassType type); - CodeModel::ClassType classType() const; - - void addPropertyDeclaration(const QString &propertyDeclaration); - QStringList propertyDeclarations() const { return m_propertyDeclarations; } - - bool isFinal() const { return m_final; } - void setFinal(bool f) { m_final = f; } - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif - -private: - QVector<BaseClass> m_baseClasses; - TemplateParameterList m_templateParameters; - CodeModel::ClassType m_classType; - - QStringList m_propertyDeclarations; - bool m_final = false; -}; - -class _NamespaceModelItem: public _ScopeModelItem -{ -public: - 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) {} - ~_NamespaceModelItem(); - - const NamespaceList &namespaces() const { return m_namespaces; } - - NamespaceType type() const { return m_type; } - void setType(NamespaceType t) { m_type = t; } - - void addNamespace(NamespaceModelItem item); - - NamespaceModelItem findNamespace(const QString &name) const; - - void appendNamespace(const _NamespaceModelItem &other); - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif - -private: - NamespaceList m_namespaces; - NamespaceType m_type = NamespaceType::Default; -}; - -class _FileModelItem: public _NamespaceModelItem -{ -public: - 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) {} - ~_FileModelItem(); -}; - -class _ArgumentModelItem: public _CodeModelItem -{ -public: - 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) {} - ~_ArgumentModelItem(); - - TypeInfo type() const; - void setType(const TypeInfo &type); - - bool defaultValue() const; - void setDefaultValue(bool defaultValue); - - QString defaultValueExpression() const { return m_defaultValueExpression; } - void setDefaultValueExpression(const QString &expr) { m_defaultValueExpression = expr; } - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif - -private: - TypeInfo m_type; - QString m_defaultValueExpression; - bool m_defaultValue; -}; - -class _MemberModelItem: public _CodeModelItem -{ -public: - DECLARE_MODEL_NODE(Member) - - explicit _MemberModelItem(CodeModel *model, int kind = __node_kind) - : _CodeModelItem(model, kind), m_accessPolicy(CodeModel::Public), m_flags(0) {} - explicit _MemberModelItem(CodeModel *model, const QString &name, int kind = __node_kind) - : _CodeModelItem(model, name, kind), m_accessPolicy(CodeModel::Public), m_flags(0) {} - ~_MemberModelItem(); - - bool isConstant() const; - void setConstant(bool isConstant); - - bool isVolatile() const; - void setVolatile(bool isVolatile); - - bool isStatic() const; - void setStatic(bool isStatic); - - bool isAuto() const; - void setAuto(bool isAuto); - - bool isFriend() const; - void setFriend(bool isFriend); - - bool isRegister() const; - void setRegister(bool isRegister); - - bool isExtern() const; - void setExtern(bool isExtern); - - bool isMutable() const; - void setMutable(bool isMutable); - - CodeModel::AccessPolicy accessPolicy() const; - void setAccessPolicy(CodeModel::AccessPolicy accessPolicy); - - TemplateParameterList templateParameters() const { return m_templateParameters; } - void setTemplateParameters(const TemplateParameterList &templateParameters) { m_templateParameters = templateParameters; } - - TypeInfo type() const; - void setType(const TypeInfo &type); - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif - -private: - TemplateParameterList m_templateParameters; - TypeInfo m_type; - CodeModel::AccessPolicy m_accessPolicy; - union { - struct { - uint m_isConstant: 1; - uint m_isVolatile: 1; - uint m_isStatic: 1; - uint m_isAuto: 1; - uint m_isFriend: 1; - uint m_isRegister: 1; - uint m_isExtern: 1; - uint m_isMutable: 1; - }; - uint m_flags; - }; - -}; - -class _FunctionModelItem: public _MemberModelItem -{ -public: - 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) {} - ~_FunctionModelItem(); - - ArgumentList arguments() const; - - void addArgument(const ArgumentModelItem& item); - - CodeModel::FunctionType functionType() const; - void setFunctionType(CodeModel::FunctionType functionType); - - 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 isVariadics() const; - void setVariadics(bool isVariadics); - - - bool isSimilar(const FunctionModelItem &other) const; - - bool isNoExcept() const; - - ExceptionSpecification exceptionSpecification() const; - void setExceptionSpecification(ExceptionSpecification e); - - QString typeSystemSignature() const; // For dumping out type system files - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif - -private: - ArgumentList m_arguments; - CodeModel::FunctionType m_functionType; - 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_isInvokable : 1; // Qt - }; - uint m_flags; - }; - ExceptionSpecification m_exceptionSpecification = ExceptionSpecification::Unknown; -}; - -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) {} -}; - -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) {} - - TypeInfo type() const; - void setType(const TypeInfo &type); - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif - -private: - TypeInfo m_type; -}; - -class _TemplateTypeAliasModelItem : public _CodeModelItem -{ -public: - DECLARE_MODEL_NODE(TemplateTypeAlias) - - explicit _TemplateTypeAliasModelItem(CodeModel *model, int kind = __node_kind); - explicit _TemplateTypeAliasModelItem(CodeModel *model, const QString &name, - int kind = __node_kind); - - TemplateParameterList templateParameters() const; - void addTemplateParameter(const TemplateParameterModelItem &templateParameter); - - TypeInfo type() const; - void setType(const TypeInfo &type); - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif - -private: - TemplateParameterList m_templateParameters; - TypeInfo m_type; -}; - -class _EnumModelItem: public _CodeModelItem -{ -public: - 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) {} - ~_EnumModelItem(); - - CodeModel::AccessPolicy accessPolicy() const; - void setAccessPolicy(CodeModel::AccessPolicy accessPolicy); - - bool hasValues() const { return !m_enumerators.isEmpty(); } - EnumeratorList enumerators() const; - void addEnumerator(const EnumeratorModelItem &item); - - EnumKind enumKind() const { return m_enumKind; } - void setEnumKind(EnumKind kind) { m_enumKind = kind; } - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif - - bool isSigned() const; - void setSigned(bool s); - -private: - CodeModel::AccessPolicy m_accessPolicy = CodeModel::Public; - EnumeratorList m_enumerators; - EnumKind m_enumKind = CEnum; - bool m_signed = true; -}; - -class _EnumeratorModelItem: public _CodeModelItem -{ -public: - 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) {} - ~_EnumeratorModelItem(); - - QString stringValue() const; - void setStringValue(const QString &stringValue); - - EnumValue value() const { return m_value; } - void setValue(EnumValue v) { m_value = v; } - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif - -private: - QString m_stringValue; - EnumValue m_value; -}; - -class _TemplateParameterModelItem: public _CodeModelItem -{ -public: - 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) {} - ~_TemplateParameterModelItem(); - - TypeInfo type() const; - void setType(const TypeInfo &type); - - bool defaultValue() const; - void setDefaultValue(bool defaultValue); - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif - -private: - TypeInfo m_type; - bool m_defaultValue; -}; - -#endif // CODEMODEL_H - -// kate: space-indent on; indent-width 2; replace-tabs on; diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h b/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h deleted file mode 100644 index aebd59879..000000000 --- a/sources/shiboken2/ApiExtractor/parser/codemodel_enums.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef CODEMODEL_ENUMS_H -#define CODEMODEL_ENUMS_H - -enum ReferenceType { - NoReference, - LValueReference, - RValueReference -}; - -enum EnumKind { - CEnum, // Standard C: enum Foo { value1, value2 } - AnonymousEnum, // enum { value1, value2 } - EnumClass // C++ 11 : enum class Foo { value1, value2 } -}; - -enum class Indirection -{ - Pointer, // int * - ConstPointer // int *const -}; - -enum class ExceptionSpecification -{ - Unknown, - NoExcept, - Throws -}; - -enum class NamespaceType -{ - Default, - Anonymous, - Inline -}; - -#endif // CODEMODEL_ENUMS_H diff --git a/sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h b/sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h deleted file mode 100644 index 87fea5cde..000000000 --- a/sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h +++ /dev/null @@ -1,85 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - - -#ifndef CODEMODEL_FWD_H -#define CODEMODEL_FWD_H - -#include <QtCore/QVector> -#include <QtCore/QSharedPointer> - -// forward declarations -class CodeModel; -class _ArgumentModelItem; -class _ClassModelItem; -class _CodeModelItem; -class _EnumModelItem; -class _EnumeratorModelItem; -class _FileModelItem; -class _FunctionModelItem; -class _NamespaceModelItem; -class _ScopeModelItem; -class _TemplateParameterModelItem; -class _TypeDefModelItem; -class _TemplateTypeAliasModelItem; -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 ArgumentList = QVector<ArgumentModelItem>; -using ClassList = QVector<ClassModelItem>; -using ItemList = QVector<CodeModelItem>; -using EnumList = QVector<EnumModelItem>; -using EnumeratorList = QVector<EnumeratorModelItem>; -using FileList = QVector<FileModelItem>; -using FunctionList = QVector<FunctionModelItem>; -using NamespaceList = QVector<NamespaceModelItem>; -using ScopeList = QVector<ScopeModelItem>; -using TemplateParameterList = QVector<TemplateParameterModelItem>; -using TypeDefList = QVector<TypeDefModelItem>; -using TemplateTypeAliasList = QVector<TemplateTypeAliasModelItem>; -using VariableList = QVector<VariableModelItem>; -using MemberList = QVector<MemberModelItem>; - -#endif // CODEMODEL_FWD_H diff --git a/sources/shiboken2/ApiExtractor/parser/enumvalue.cpp b/sources/shiboken2/ApiExtractor/parser/enumvalue.cpp deleted file mode 100644 index 513bb3532..000000000 --- a/sources/shiboken2/ApiExtractor/parser/enumvalue.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "enumvalue.h" - -#include <QtCore/QDebug> -#include <QtCore/QString> -#include <QtCore/QTextStream> - -QString EnumValue::toString() const -{ - return m_type == EnumValue::Signed - ? QString::number(m_value) : QString::number(m_unsignedValue); -} - -void EnumValue::setValue(qint64 v) -{ - m_value = v; - m_type = Signed; -} - -void EnumValue::setUnsignedValue(quint64 v) -{ - m_unsignedValue = v; - m_type = Unsigned; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d,const EnumValue &v) -{ - QDebugStateSaver saver(d); - d.nospace(); - d.noquote(); - d << "EnumValue("; - if (v.m_type == EnumValue::Signed) - d << v.m_value; - else - d << v.m_unsignedValue << 'u'; - d << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -QTextStream &operator<<(QTextStream &s, const EnumValue &v) -{ - if (v.m_type == EnumValue::Signed) - s << v.m_value; - else - s << v.m_unsignedValue; - return s; -} diff --git a/sources/shiboken2/ApiExtractor/parser/enumvalue.h b/sources/shiboken2/ApiExtractor/parser/enumvalue.h deleted file mode 100644 index ea30c39bb..000000000 --- a/sources/shiboken2/ApiExtractor/parser/enumvalue.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 ENUMVALUE_H -#define ENUMVALUE_H - -#include <QtCore/QtGlobal> - -QT_FORWARD_DECLARE_CLASS(QDebug) -QT_FORWARD_DECLARE_CLASS(QString) -QT_FORWARD_DECLARE_CLASS(QTextStream) - -class EnumValue -{ -public: - enum Type - { - Signed, - Unsigned - }; - - QString toString() 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; } - - void setValue(qint64 v); - void setUnsignedValue(quint64 v); - -private: -#ifndef QT_NO_DEBUG_STREAM - friend QDebug operator<<(QDebug, const EnumValue &); -#endif - friend QTextStream &operator<<(QTextStream &, const EnumValue &); - - union - { - qint64 m_value = 0; - quint64 m_unsignedValue; - }; - Type m_type = Signed; -}; - -#endif // ENUMVALUE_H diff --git a/sources/shiboken2/ApiExtractor/qtcompat.h b/sources/shiboken2/ApiExtractor/qtcompat.h deleted file mode 100644 index 89a1db008..000000000 --- a/sources/shiboken2/ApiExtractor/qtcompat.h +++ /dev/null @@ -1,40 +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 QTCOMPAT_H -#define QTCOMPAT_H - -#include <QtCore/QtGlobal> - -#if QT_VERSION >= 0x060000 -using QtCompatHashFunctionType = size_t; -#else -using QtCompatHashFunctionType = uint; -#endif - -#endif // QTCOMPAT_H diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.cpp b/sources/shiboken2/ApiExtractor/qtdocparser.cpp deleted file mode 100644 index 512473131..000000000 --- a/sources/shiboken2/ApiExtractor/qtdocparser.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qtdocparser.h" -#include "abstractmetalang.h" -#include "messages.h" -#include "reporthandler.h" -#include "typesystem.h" -#include "xmlutils.h" - -#include <QtCore/QDir> -#include <QtCore/QFile> -#include <QtCore/QTextStream> -#include <QtCore/QXmlStreamAttributes> -#include <QtCore/QXmlStreamReader> -#include <QUrl> - -Documentation QtDocParser::retrieveModuleDocumentation() -{ - return retrieveModuleDocumentation(packageName()); -} - -static void formatFunctionArgTypeQuery(QTextStream &str, const AbstractMetaArgument *arg) -{ - const AbstractMetaType *metaType = arg->type(); - if (metaType->isConstant()) - str << "const " ; - 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()); - QString name = flagsEntry->qualifiedCppName(); - if (name.endsWith(QLatin1Char('>')) && name.startsWith(QLatin1String("QFlags<"))) { - const int lastColon = name.lastIndexOf(QLatin1Char(':')); - if (lastColon != -1) { - name.replace(lastColon + 1, name.size() - lastColon - 1, metaType->name()); - name.remove(0, 7); - } else { - name = metaType->name(); // QFlags<> of enum in global namespace - } - } - str << name; - } - break; - case AbstractMetaType::ContainerPattern: { // QVector<int> - str << metaType->typeEntry()->qualifiedCppName() << '<'; - const auto instantiations = metaType->instantiations(); - for (int i = 0, size = instantiations.size(); i < size; ++i) { - if (i) - str << ", "; - str << instantiations.at(i)->typeEntry()->qualifiedCppName(); - } - str << '>'; - } - break; - default: // Fully qualify enums (Qt::AlignmentFlag), nested classes, etc. - 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 AbstractMetaFunction *func, - unsigned matchFlags = MatchArgumentCount | MatchArgumentType - | DescriptionOnly) -{ - 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"; - return result; -} - -static QStringList signaturesFromWebXml(QString w) -{ - 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; -} - -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; -} - -QString QtDocParser::queryFunctionDocumentation(const QString &sourceFileName, - const AbstractMetaClass* metaClass, - const QString &classQuery, - const AbstractMetaFunction *func, - const DocModificationList &signedModifs, - const XQueryPtr &xquery, - QString *errorMessage) -{ - DocModificationList funcModifs; - for (const DocModification &funcModif : signedModifs) { - if (funcModif.signature() == func->minimalSignature()) - funcModifs.append(funcModif); - } - - // Properties - if (func->isPropertyReader() || func->isPropertyWriter() || func->isPropertyResetter()) { - const QString propertyQuery = classQuery + QLatin1String("/property[@name=\"") - + func->propertySpec()->name() + QLatin1String("\"]/description"); - const QString properyDocumentation = getDocumentation(xquery, propertyQuery, funcModifs); - if (properyDocumentation.isEmpty()) - *errorMessage = msgCannotFindDocumentation(sourceFileName, metaClass, func, propertyQuery); - return properyDocumentation; - } - - // 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, 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); - } - *errorMessage += msgArgumentCountMatch(func, signatures); - return result; -} - -void QtDocParser::fillDocumentation(AbstractMetaClass* metaClass) -{ - if (!metaClass) - return; - - const AbstractMetaClass* context = metaClass->enclosingClass(); - while(context) { - if (context->enclosingClass() == nullptr) - break; - context = context->enclosingClass(); - } - - QString sourceFileRoot = documentationDataDirectory() + QLatin1Char('/') - + metaClass->qualifiedCppName().toLower(); - sourceFileRoot.replace(QLatin1String("::"), QLatin1String("-")); - - QFileInfo sourceFile(sourceFileRoot + QStringLiteral(".webxml")); - if (!sourceFile.exists()) - sourceFile.setFile(sourceFileRoot + QStringLiteral(".xml")); - if (!sourceFile.exists()) { - qCWarning(lcShibokenDoc).noquote().nospace() - << "Can't find qdoc file for class " << metaClass->name() << ", tried: " - << QDir::toNativeSeparators(sourceFile.absoluteFilePath()); - return; - } - - const QString sourceFileName = sourceFile.absoluteFilePath(); - QString errorMessage; - XQueryPtr xquery = XQuery::create(sourceFileName, &errorMessage); - if (xquery.isNull()) { - 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); - } - - Documentation doc(getDocumentation(xquery, query, classModifs)); - if (doc.isEmpty()) - qCWarning(lcShibokenDoc, "%s", qPrintable(msgCannotFindDocumentation(sourceFileName, "class", className, query))); - metaClass->setDocumentation(doc); - - //Functions Documentation - const AbstractMetaFunctionList &funcs = DocParser::documentableFunctions(metaClass); - for (AbstractMetaFunction *func : funcs) { - const QString documentation = - queryFunctionDocumentation(sourceFileName, metaClass, classQuery, - func, signedModifs, xquery, &errorMessage); - if (!errorMessage.isEmpty()) - qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage)); - func->setDocumentation(Documentation(documentation)); - } -#if 0 - // Fields - const AbstractMetaFieldList &fields = metaClass->fields(); - for (AbstractMetaField *field : fields) { - if (field->isPrivate()) - return; - - QString query = "/doxygen/compounddef/sectiondef/memberdef/name[text()=\"" + field->name() + "\"]/.."; - Documentation doc = getDocumentation(DocModificationList(), xquery, query); - field->setDocumentation(doc); - } -#endif - // Enums - const AbstractMetaEnumList &enums = metaClass->enums(); - for (AbstractMetaEnum *meta_enum : enums) { - query.clear(); - QTextStream(&query) << classQuery << "/enum[@name=\"" - << meta_enum->name() << "\"]/description"; - doc.setValue(getDocumentation(xquery, query, DocModificationList())); - if (doc.isEmpty()) { - qCWarning(lcShibokenDoc, "%s", - qPrintable(msgCannotFindDocumentation(sourceFileName, metaClass, meta_enum, query))); - } - meta_enum->setDocumentation(doc); - } -} - -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\"" - << ">QML types</link>.</para>"; - return result; -} - -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.toLower(); - QString sourceFile = prefix + QLatin1String(".xml"); - - if (!QFile::exists(sourceFile)) - sourceFile = prefix + QLatin1String("-module.webxml"); - if (!QFile::exists(sourceFile)) { - qCWarning(lcShibokenDoc).noquote().nospace() - << "Can't find qdoc file for module " << name << ", tried: " - << QDir::toNativeSeparators(sourceFile); - return Documentation(); - } - - QString errorMessage; - XQueryPtr xquery = XQuery::create(sourceFile, &errorMessage); - if (xquery.isNull()) { - qCWarning(lcShibokenDoc, "%s", qPrintable(errorMessage)); - return {}; - } - - // Module documentation - QString query = QLatin1String("/WebXML/document/module[@name=\"") - + moduleName + QLatin1String("\"]/description"); - Documentation doc = getDocumentation(xquery, query, DocModificationList()); - if (doc.isEmpty()) { - qCWarning(lcShibokenDoc, "%s", qPrintable(msgCannotFindDocumentation(sourceFile, "module", name, query))); - return doc; - } - - // If a QML module info file exists, insert a link to the Qt docs. - const QFileInfo qmlModuleFi(prefix + QLatin1String("-qmlmodule.webxml")); - if (qmlModuleFi.isFile()) { - QString docString = doc.value(); - const int pos = docString.lastIndexOf(QLatin1String("</description>")); - if (pos != -1) { - docString.insert(pos, qmlReferenceLink(qmlModuleFi)); - doc.setValue(docString); - } - } - - return doc; -} diff --git a/sources/shiboken2/ApiExtractor/qtdocparser.h b/sources/shiboken2/ApiExtractor/qtdocparser.h deleted file mode 100644 index b01139de6..000000000 --- a/sources/shiboken2/ApiExtractor/qtdocparser.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTDOCPARSER_H -#define QTDOCPARSER_H - -#include "docparser.h" - -class QtDocParser : public DocParser -{ -public: - QtDocParser() = default; - void fillDocumentation(AbstractMetaClass* metaClass) override; - Documentation retrieveModuleDocumentation() override; - Documentation retrieveModuleDocumentation(const QString& name) override; - -private: - QString queryFunctionDocumentation(const QString &sourceFileName, - const AbstractMetaClass* metaClass, - const QString &classQuery, - const AbstractMetaFunction *func, - const DocModificationList &signedModifs, - const XQueryPtr &xquery, - QString *errorMessage); -}; - -#endif // QTDOCPARSER_H - diff --git a/sources/shiboken2/ApiExtractor/reporthandler.cpp b/sources/shiboken2/ApiExtractor/reporthandler.cpp deleted file mode 100644 index 2c6ab444b..000000000 --- a/sources/shiboken2/ApiExtractor/reporthandler.cpp +++ /dev/null @@ -1,198 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "reporthandler.h" -#include "typesystem.h" -#include "typedatabase.h" -#include <QtCore/QElapsedTimer> -#include <QtCore/QSet> -#include <cstring> -#include <cstdarg> -#include <cstdio> - -#if defined(_WINDOWS) || defined(NOCOLOR) - #define COLOR_END "" - #define COLOR_WHITE "" - #define COLOR_YELLOW "" - #define COLOR_GREEN "" -#else - #define COLOR_END "\033[0m" - #define COLOR_WHITE "\033[1;37m" - #define COLOR_YELLOW "\033[1;33m" - #define COLOR_GREEN "\033[0;32m" -#endif - -static bool m_silent = false; -static int m_warningCount = 0; -static int m_suppressedCount = 0; -static ReportHandler::DebugLevel m_debugLevel = ReportHandler::NoDebug; -static QSet<QString> m_reportedWarnings; -static QString m_prefix; -static bool m_withinProgress = false; -static int m_step_warning = 0; -static QElapsedTimer m_timer; - -Q_LOGGING_CATEGORY(lcShiboken, "qt.shiboken") -Q_LOGGING_CATEGORY(lcShibokenDoc, "qt.shiboken.doc") - -void ReportHandler::install() -{ - qInstallMessageHandler(ReportHandler::messageOutput); - startTimer(); -} - -void ReportHandler::startTimer() -{ - m_timer.start(); -} - -ReportHandler::DebugLevel ReportHandler::debugLevel() -{ - return m_debugLevel; -} - -void ReportHandler::setDebugLevel(ReportHandler::DebugLevel level) -{ - m_debugLevel = level; -} - -bool ReportHandler::setDebugLevelFromArg(const QString &level) -{ - bool result = true; - if (level == QLatin1String("sparse")) - ReportHandler::setDebugLevel(ReportHandler::SparseDebug); - else if (level == QLatin1String("medium")) - ReportHandler::setDebugLevel(ReportHandler::MediumDebug); - else if (level == QLatin1String("full")) - ReportHandler::setDebugLevel(ReportHandler::FullDebug); - else - result = false; - return result; -} - -int ReportHandler::suppressedCount() -{ - return m_suppressedCount; -} - -int ReportHandler::warningCount() -{ - return m_warningCount; -} - -bool ReportHandler::isSilent() -{ - return m_silent; -} - -void ReportHandler::setSilent(bool silent) -{ - m_silent = silent; -} - -void ReportHandler::setPrefix(const QString &p) -{ - m_prefix = 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")); - if (type == QtWarningMsg) { - if (m_silent || m_reportedWarnings.contains(text)) - return; - if (auto db = TypeDatabase::instance()) { - const bool suppressed = fileLocationPos >= 0 - ? db->isSuppressedWarning(text.midRef(fileLocationPos + 2)) - : db->isSuppressedWarning(text); - if (suppressed) { - ++m_suppressedCount; - return; - } - } - ++m_warningCount; - ++m_step_warning; - m_reportedWarnings.insert(text); - } - QString message = m_prefix; - if (!message.isEmpty()) - message.append(QLatin1Char(' ')); - const int prefixLength = message.size(); - message.append(text); - // Replace file location tab by space - if (fileLocationPos >= 0) - message[prefixLength + fileLocationPos + 1] = QLatin1Char(' '); - fprintf(stderr, "%s\n", qPrintable(qFormatLogMessage(type, context, message))); -} - -static QByteArray timeStamp() -{ - const qint64 elapsed = m_timer.elapsed(); - return elapsed > 5000 - ? QByteArray::number(elapsed / 1000) + 's' - : QByteArray::number(elapsed) + "ms"; -} - -void ReportHandler::startProgress(const QByteArray& str) -{ - if (m_silent) - return; - - if (m_withinProgress) - endProgress(); - - m_withinProgress = true; - const auto ts = '[' + timeStamp() + ']'; - std::printf("%s %8s %-60s", qPrintable(m_prefix), ts.constData(), str.constData()); - std::fflush(stdout); -} - -void ReportHandler::endProgress() -{ - if (m_silent) - return; - - m_withinProgress = false; - 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_step_warning = 0; -} - -QByteArray ReportHandler::doneMessage() -{ - QByteArray result = "Done, " + m_prefix.toUtf8() + ' ' + timeStamp(); - if (m_warningCount) - result += ", " + QByteArray::number(m_warningCount) + " warnings"; - if (m_suppressedCount) - result += " (" + QByteArray::number(m_suppressedCount) + " known issues)"; - return result; -} diff --git a/sources/shiboken2/ApiExtractor/reporthandler.h b/sources/shiboken2/ApiExtractor/reporthandler.h deleted file mode 100644 index 21f0e8933..000000000 --- a/sources/shiboken2/ApiExtractor/reporthandler.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef REPORTHANDLER_H -#define REPORTHANDLER_H - -#include <QLoggingCategory> -#include <QString> - -Q_DECLARE_LOGGING_CATEGORY(lcShiboken) -Q_DECLARE_LOGGING_CATEGORY(lcShibokenDoc) - -class ReportHandler -{ -public: - enum DebugLevel { NoDebug, SparseDebug, MediumDebug, FullDebug }; - - static void install(); - static void startTimer(); - - static DebugLevel debugLevel(); - static void setDebugLevel(DebugLevel level); - static bool setDebugLevelFromArg(const QString &); - - static int warningCount(); - - static int suppressedCount(); - - static void startProgress(const QByteArray &str); - static void endProgress(); - - static bool isDebug(DebugLevel level) - { return debugLevel() >= level; } - - static bool isSilent(); - static void setSilent(bool silent); - - static void setPrefix(const QString &p); - - static QByteArray doneMessage(); - -private: - static void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg); -}; - -#endif // REPORTHANDLER_H diff --git a/sources/shiboken2/ApiExtractor/sourcelocation.cpp b/sources/shiboken2/ApiExtractor/sourcelocation.cpp deleted file mode 100644 index 1ba66e05b..000000000 --- a/sources/shiboken2/ApiExtractor/sourcelocation.cpp +++ /dev/null @@ -1,100 +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$ -** -****************************************************************************/ - -#include "sourcelocation.h" -#include <QtCore/QDir> -#include <QtCore/QDebug> - -SourceLocation::SourceLocation() = default; - -SourceLocation::SourceLocation(const QString &file, int l) - : m_fileName(file), m_lineNumber(l) -{ -} - -bool SourceLocation::isValid() const -{ - return m_lineNumber >= 0 && !m_fileName.isEmpty(); -} - -QString SourceLocation::fileName() const -{ - return m_fileName; -} - -void SourceLocation::setFileName(const QString &fileName) -{ - m_fileName = fileName; -} - -int SourceLocation::lineNumber() const -{ - return m_lineNumber; -} - -void SourceLocation::setLineNumber(int lineNumber) -{ - m_lineNumber = lineNumber; -} - -QString SourceLocation::toString() const -{ - QString result; - QTextStream s(&result); - format(s); - return result; -} - -template<class Stream> -void SourceLocation::format(Stream &s) const -{ - if (isValid()) - s << QDir::toNativeSeparators(m_fileName) << ':' << m_lineNumber << ':'; - else - s << "<unknown>"; -} - -QTextStream &operator<<(QTextStream &s, const SourceLocation &l) -{ - if (l.isValid()) { - l.format(s); - s << '\t'; // ":\t" is used by ReportHandler for filtering suppressions - } - return s; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const SourceLocation &l) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - l.format(d); - return d; -} -#endif diff --git a/sources/shiboken2/ApiExtractor/sourcelocation.h b/sources/shiboken2/ApiExtractor/sourcelocation.h deleted file mode 100644 index 630a841d8..000000000 --- a/sources/shiboken2/ApiExtractor/sourcelocation.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 SOURCE_LOCATION_H -#define SOURCE_LOCATION_H - -#include <QString> - -QT_FORWARD_DECLARE_CLASS(QDebug) -QT_FORWARD_DECLARE_CLASS(QTextStream) - -class SourceLocation -{ -public: - explicit SourceLocation(const QString &file, int l); - SourceLocation(); - - bool isValid() const; - - QString fileName() const; - void setFileName(const QString &fileName); - - int lineNumber() const; - void setLineNumber(int lineNumber); - - QString toString() const; - - template<class Stream> - void format(Stream &s) const; - -private: - QString m_fileName; - int m_lineNumber = 0; -}; - -QTextStream &operator<<(QTextStream &s, const SourceLocation &l); - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const SourceLocation &l); -#endif - -#endif // SOURCE_LOCATION_H diff --git a/sources/shiboken2/ApiExtractor/symbols.filter b/sources/shiboken2/ApiExtractor/symbols.filter deleted file mode 100644 index af6c744dd..000000000 --- a/sources/shiboken2/ApiExtractor/symbols.filter +++ /dev/null @@ -1,7 +0,0 @@ -{ -local: -_ZSt*; -_ZNSt*; -_ZNSs*; -_ZNKSt*; -}; diff --git a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt b/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt deleted file mode 100644 index 97ae0f850..000000000 --- a/sources/shiboken2/ApiExtractor/tests/CMakeLists.txt +++ /dev/null @@ -1,63 +0,0 @@ -set(CMAKE_AUTORCC ON) - -macro(declare_test testname) - # gone: qt4_automoc("${testname}.cpp") - set(SOURCES "${testname}.cpp") - if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${testname}.h") - list(APPEND SOURCES "${testname}.h") - endif () - if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${testname}.qrc") - list(APPEND SOURCES "${testname}.qrc") - endif () - - add_executable(${testname} ${SOURCES}) - target_include_directories(${testname} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ${apiextractor_SOURCE_DIR} - ) - target_link_libraries(${testname} PRIVATE apiextractor Qt${QT_MAJOR_VERSION}::Test) - add_test(${testname} ${testname}) - if (INSTALL_TESTS) - install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${testname} - DESTINATION share/apiextractor${apiextractor_SUFFIX}/tests) - endif() -endmacro(declare_test testname) - -declare_test(testabstractmetaclass) -declare_test(testabstractmetatype) -declare_test(testaddfunction) -declare_test(testarrayargument) -declare_test(testcodeinjection) -declare_test(testcontainer) -declare_test(testconversionoperator) -declare_test(testconversionruletag) -declare_test(testctorinformation) -declare_test(testdroptypeentries) -declare_test(testdtorinformation) -declare_test(testenum) -declare_test(testextrainclude) -declare_test(testfunctiontag) -declare_test(testimplicitconversions) -declare_test(testinserttemplate) -declare_test(testmodifyfunction) -declare_test(testmultipleinheritance) -declare_test(testnamespace) -declare_test(testnestedtypes) -declare_test(testnumericaltypedef) -declare_test(testprimitivetypetag) -declare_test(testrefcounttag) -declare_test(testreferencetopointer) -declare_test(testremovefield) -declare_test(testremoveimplconv) -declare_test(testremoveoperatormethod) -declare_test(testresolvetype) -declare_test(testreverseoperators) -declare_test(testtemplates) -declare_test(testtoposort) -declare_test(testvaluetypedefaultctortag) -declare_test(testvoidarg) -declare_test(testtyperevision) -if (NOT DISABLE_DOCSTRINGS) - declare_test(testmodifydocumentation) -endif() - diff --git a/sources/shiboken2/ApiExtractor/tests/a.xml b/sources/shiboken2/ApiExtractor/tests/a.xml deleted file mode 100644 index 3c09d3800..000000000 --- a/sources/shiboken2/ApiExtractor/tests/a.xml +++ /dev/null @@ -1,14 +0,0 @@ -<?xml version="1.0" ?> -<!-- Sample for testModifyDocumentation --> -<WebXML> - <document> - <class name="A"> - <description>oi - <brief>Brief description</brief> - <para>Paragraph number 1</para> - <para>Paragraph number 2</para> - <para>Paragraph number 3</para> - </description> - </class> - </document> -</WebXML> diff --git a/sources/shiboken2/ApiExtractor/tests/injectedcode.txt b/sources/shiboken2/ApiExtractor/tests/injectedcode.txt deleted file mode 100644 index 872898810..000000000 --- a/sources/shiboken2/ApiExtractor/tests/injectedcode.txt +++ /dev/null @@ -1,5 +0,0 @@ -// Bla -// @snippet label -code line -// @snippet label -// Bla diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp deleted file mode 100644 index f0aa4a318..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp +++ /dev/null @@ -1,621 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testabstractmetaclass.h" -#include "abstractmetabuilder.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestAbstractMetaClass::testClassName() -{ - const char* cppCode ="class ClassName {};"; - const char* xmlCode = "<typesystem package=\"Foo\"><value-type name=\"ClassName\"/></typesystem>"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 1); - QCOMPARE(classes[0]->name(), QLatin1String("ClassName")); -} - -void TestAbstractMetaClass::testClassNameUnderNamespace() -{ - 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()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); // 1 namespace + 1 class - if (classes.first()->name() != QLatin1String("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")); - QVERIFY(classes[1]->isNamespace()); - - // Check ctors info - QVERIFY(classes[0]->hasConstructors()); - QCOMPARE(classes[0]->functions().size(), 2); // default ctor + copy ctor - - AbstractMetaFunctionList ctors = classes[0]->queryFunctions(AbstractMetaClass::Constructors); - QCOMPARE(ctors.size(), 2); - if (ctors.first()->minimalSignature() != QLatin1String("ClassName()")) - qSwap(ctors[0], ctors[1]); - - QCOMPARE(ctors[0]->arguments().size(), 0); - QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("ClassName()")); - QCOMPARE(ctors[1]->arguments().size(), 1); - QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("ClassName(Namespace::ClassName)")); - - QVERIFY(!classes[0]->hasPrivateDestructor()); - QVERIFY(classes[0]->hasCloneOperator()); // implicit default copy ctor - QVERIFY(!classes[0]->hasHashFunction()); - - // This method is buggy and nobody wants to fix it or needs it fixed :-/ - // QVERIFY(classes[0]->hasNonPrivateConstructor()); -} - -static AbstractMetaFunctionList virtualFunctions(const AbstractMetaClass *c) -{ - AbstractMetaFunctionList result; - const AbstractMetaFunctionList &functions = c->functions(); - for (AbstractMetaFunction *f : functions) { - if (f->isVirtual()) - result.append(f); - } - return result; -} - -void TestAbstractMetaClass::testVirtualMethods() -{ - const char cppCode[] =R"CPP( -class A { -public: - virtual int pureVirtual() const = 0; -}; -class B : public A {}; -class C : public B { -public: - int pureVirtual() const override { return 0; } -}; -class F final : public C { -public: - int pureVirtual() const final { return 1; } -}; -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package="Foo"> - <primitive-type name='int'/> - <object-type name='A'/> - <object-type name='B'/> - <object-type name='C'/> - <object-type name='F'/> -</typesystem> -)XML"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - 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")); - QVERIFY(f); - - AbstractMetaClass* no_class = nullptr; - - QCOMPARE(a->baseClass(), no_class); - QCOMPARE(b->baseClass(), a); - QCOMPARE(c->baseClass(), b); - QCOMPARE(f->baseClass(), c); - - QCOMPARE(a->functions().size(), 2); // default ctor + the pure virtual method - QCOMPARE(b->functions().size(), 2); - QCOMPARE(c->functions().size(), 2); - QCOMPARE(f->functions().size(), 2); - QVERIFY(f->attributes() & AbstractMetaAttributes::FinalCppClass); - - // implementing class, ownclass, declaringclass - AbstractMetaFunction* ctorA = a->queryFunctions(AbstractMetaClass::Constructors).first(); - AbstractMetaFunction* ctorB = b->queryFunctions(AbstractMetaClass::Constructors).first(); - AbstractMetaFunction* ctorC = c->queryFunctions(AbstractMetaClass::Constructors).first(); - QVERIFY(ctorA->isConstructor()); - QVERIFY(!ctorA->isVirtual()); - QVERIFY(ctorB->isConstructor()); - QVERIFY(!ctorB->isVirtual()); - QVERIFY(ctorC->isConstructor()); - QVERIFY(!ctorC->isVirtual()); - QCOMPARE(ctorA->implementingClass(), a); - QCOMPARE(ctorA->ownerClass(), a); - QCOMPARE(ctorA->declaringClass(), a); - - const AbstractMetaFunctionList virtualFunctionsA = virtualFunctions(a); - const AbstractMetaFunctionList virtualFunctionsB = virtualFunctions(b); - const AbstractMetaFunctionList virtualFunctionsC = virtualFunctions(c); - const AbstractMetaFunctionList virtualFunctionsF = virtualFunctions(f); - QCOMPARE(virtualFunctionsA.size(), 1); // Add a pureVirtualMethods method !? - QCOMPARE(virtualFunctionsB.size(), 1); - QCOMPARE(virtualFunctionsC.size(), 1); - QCOMPARE(virtualFunctionsF.size(), 1); - - const AbstractMetaFunction* funcA = virtualFunctionsA.constFirst(); - const AbstractMetaFunction* funcB = virtualFunctionsB.constFirst(); - const AbstractMetaFunction* funcC = virtualFunctionsC.constFirst(); - const AbstractMetaFunction* funcF = virtualFunctionsF.constFirst(); - - QCOMPARE(funcA->ownerClass(), a); - QVERIFY(funcC->attributes() & AbstractMetaAttributes::VirtualCppMethod); - QCOMPARE(funcB->ownerClass(), b); - QCOMPARE(funcC->ownerClass(), c); - QVERIFY(funcC->attributes() & AbstractMetaAttributes::OverriddenCppMethod); - QVERIFY(funcF->attributes() & AbstractMetaAttributes::FinalCppMethod); - - QCOMPARE(funcA->declaringClass(), a); - QCOMPARE(funcB->declaringClass(), a); - QCOMPARE(funcC->declaringClass(), a); - - // The next two tests could return null, because it makes more sense. - // But we have too many code written relying on this behaviour where - // implementingClass is equals to declaringClass on pure virtual functions - QCOMPARE(funcA->implementingClass(), a); - QCOMPARE(funcB->implementingClass(), a); - QCOMPARE(funcC->implementingClass(), c); -} - -void TestAbstractMetaClass::testVirtualBase() -{ - const char cppCode[] =R"CPP( -class Base { -public: - virtual ~Base() = default; -}; -class Derived : public Base {}; -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package="Foo"> - <object-type name='Base'/> - <object-type name='Derived'/> -</typesystem> -)XML"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - auto base = AbstractMetaClass::findClass(classes, QLatin1String("Base")); - QVERIFY(base); - QVERIFY(base->isPolymorphic()); - auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived")); - QVERIFY(derived); - QVERIFY(derived->isPolymorphic()); -} - -void TestAbstractMetaClass::testDefaultValues() -{ - const char* cppCode ="\ - struct A {\n\ - class B {};\n\ - void method(B b = B());\n\ - };\n"; - 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()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QCOMPARE(classA->queryFunctionsByName(QLatin1String("method")).count(), 1); - AbstractMetaFunction* method = classA->queryFunctionsByName(QLatin1String("method")).first(); - AbstractMetaArgument* arg = method->arguments().first(); - QCOMPARE(arg->defaultValueExpression(), arg->originalDefaultValueExpression()); -} - -void TestAbstractMetaClass::testModifiedDefaultValues() -{ - const char* cppCode ="\ - struct A {\n\ - class B {};\n\ - void method(B b = B());\n\ - };\n"; - const char* xmlCode = R"XML( - <typesystem package="Foo"> - <value-type name='A'> - <modify-function signature='method(A::B)'> - <modify-argument index='1'> - <replace-default-expression with='Hello'/> - </modify-argument> - </modify-function> - <value-type name='B'/> - </value-type> - </typesystem>)XML"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QCOMPARE(classA->queryFunctionsByName(QLatin1String("method")).count(), 1); - AbstractMetaFunction* method = classA->queryFunctionsByName(QLatin1String("method")).first(); - AbstractMetaArgument* arg = method->arguments().first(); - QCOMPARE(arg->defaultValueExpression(), QLatin1String("Hello")); - QCOMPARE(arg->originalDefaultValueExpression(), QLatin1String("A::B()")); -} - -void TestAbstractMetaClass::testInnerClassOfAPolymorphicOne() -{ - const char* cppCode ="\ - struct A {\n\ - class B {};\n\ - virtual void method();\n\ - };\n"; - 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()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QVERIFY(classA->isPolymorphic()); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("A::B")); - QVERIFY(classB); - QVERIFY(!classB->isPolymorphic()); -} - -void TestAbstractMetaClass::testForwardDeclaredInnerClass() -{ - const char cppCode[] ="\ - class A {\n\ - class B;\n\ - };\n\ - class A::B {\n\ - public:\n\ - void foo();\n\ - };\n"; - 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()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("A::B")); - QVERIFY(classB); - const AbstractMetaFunction *fooF = classB->findFunction(QLatin1String("foo")); - QVERIFY(fooF); -} - -void TestAbstractMetaClass::testSpecialFunctions() -{ - const char cppCode[] ="\ - struct A {\n\ - A();\n\ - A(const A&);\n\ - A &operator=(const A&);\n\ - };\n\ - struct B {\n\ - B();\n\ - B(const B &);\n\ - B &operator=(B);\n\ - };\n"; - 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()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors); - QCOMPARE(ctors.size(), 2); - QCOMPARE(ctors.first()->functionType(), AbstractMetaFunction::ConstructorFunction); - QCOMPARE(ctors.at(1)->functionType(), AbstractMetaFunction::CopyConstructorFunction); - AbstractMetaFunctionList assigmentOps = classA->queryFunctionsByName(QLatin1String("operator=")); - QCOMPARE(assigmentOps.size(), 1); - QCOMPARE(assigmentOps.first()->functionType(), AbstractMetaFunction::AssignmentOperatorFunction); - - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classB); - ctors = classB->queryFunctions(AbstractMetaClass::Constructors); - QCOMPARE(ctors.size(), 2); - QCOMPARE(ctors.first()->functionType(), AbstractMetaFunction::ConstructorFunction); - QCOMPARE(ctors.at(1)->functionType(), AbstractMetaFunction::CopyConstructorFunction); - assigmentOps = classA->queryFunctionsByName(QLatin1String("operator=")); - QCOMPARE(assigmentOps.size(), 1); - QCOMPARE(assigmentOps.first()->functionType(), AbstractMetaFunction::AssignmentOperatorFunction); -} - -void TestAbstractMetaClass::testClassDefaultConstructors() -{ - const char* cppCode ="\ - struct A {};\n\ - \n\ - struct B {\n\ - B();\n\ - private: \n\ - B(const B&);\n\ - };\n\ - \n\ - struct C {\n\ - C(const C&);\n\ - };\n\ - \n\ - struct D {\n\ - private: \n\ - D(const D&);\n\ - };\n\ - \n\ - struct E {\n\ - private: \n\ - ~E();\n\ - };\n\ - \n\ - struct F {\n\ - F(int, int);\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <value-type name='A'/>\n\ - <object-type name='B'/>\n\ - <value-type name='C'/>\n\ - <object-type name='D'/>\n\ - <object-type name='E'/>\n\ - <value-type name='F'/>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 6); - - AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QCOMPARE(classA->functions().size(), 2); - - AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors); - QCOMPARE(ctors.size(), 2); - if (ctors.first()->minimalSignature() != QLatin1String("A()")) - qSwap(ctors[0], ctors[1]); - - QCOMPARE(ctors[0]->arguments().size(), 0); - QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("A()")); - QCOMPARE(ctors[1]->arguments().size(), 1); - QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("A(A)")); - - AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classB); - QCOMPARE(classB->functions().size(), 2); - QCOMPARE(classB->functions().first()->minimalSignature(), QLatin1String("B()")); - - AbstractMetaClass* classC = AbstractMetaClass::findClass(classes, QLatin1String("C")); - QVERIFY(classC); - QCOMPARE(classC->functions().size(), 1); - QCOMPARE(classC->functions().first()->minimalSignature(), QLatin1String("C(C)")); - - AbstractMetaClass* classD = AbstractMetaClass::findClass(classes, QLatin1String("D")); - QVERIFY(classD); - QCOMPARE(classD->functions().size(), 1); - QCOMPARE(classD->functions().first()->minimalSignature(), QLatin1String("D(D)")); - QVERIFY(classD->functions().first()->isPrivate()); - - AbstractMetaClass* classE = AbstractMetaClass::findClass(classes, QLatin1String("E")); - QVERIFY(classE); - QVERIFY(classE->hasPrivateDestructor()); - QCOMPARE(classE->functions().size(), 0); - - AbstractMetaClass* classF = AbstractMetaClass::findClass(classes, QLatin1String("F")); - QVERIFY(classF); - - ctors = classF->queryFunctions(AbstractMetaClass::Constructors); - QCOMPARE(ctors.size(), 2); - if (ctors.first()->minimalSignature() != QLatin1String("F(int,int)")) - qSwap(ctors[0], ctors[1]); - - QCOMPARE(ctors[0]->arguments().size(), 2); - QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("F(int,int)")); - QCOMPARE(ctors[1]->arguments().size(), 1); - QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("F(F)")); -} - -void TestAbstractMetaClass::testClassInheritedDefaultConstructors() -{ - const char* cppCode ="\ - struct A {\n\ - A();\n\ - private: \n\ - A(const A&);\n\ - };\n\ - struct B : public A {};\n"; - 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()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - - AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors); - QCOMPARE(ctors.size(), 2); - if (ctors.first()->minimalSignature() != QLatin1String("A()")) - qSwap(ctors[0], ctors[1]); - - QCOMPARE(ctors[0]->arguments().size(), 0); - QCOMPARE(ctors[0]->minimalSignature(), QLatin1String("A()")); - QCOMPARE(ctors[1]->arguments().size(), 1); - QCOMPARE(ctors[1]->minimalSignature(), QLatin1String("A(A)")); - QVERIFY(ctors[1]->isPrivate()); - - AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classB); - - ctors = classB->queryFunctions(AbstractMetaClass::Constructors); - QCOMPARE(ctors.size(), 1); - QCOMPARE(ctors.first()->arguments().size(), 0); - QCOMPARE(ctors.first()->minimalSignature(), QLatin1String("B()")); -} - -void TestAbstractMetaClass::testAbstractClassDefaultConstructors() -{ - const char* cppCode ="\ - struct A {\n\ - virtual void method() = 0;\n\ - };\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()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 1); - AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - - AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors); - QCOMPARE(ctors.size(), 1); - QCOMPARE(ctors.first()->arguments().size(), 0); - QCOMPARE(ctors.first()->minimalSignature(), QLatin1String("A()")); -} - -void TestAbstractMetaClass::testObjectTypesMustNotHaveCopyConstructors() -{ - 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()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 1); - AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - - AbstractMetaFunctionList ctors = classA->queryFunctions(AbstractMetaClass::Constructors); - QCOMPARE(ctors.size(), 1); - QCOMPARE(ctors.first()->arguments().size(), 0); - QCOMPARE(ctors.first()->minimalSignature(), QLatin1String("A()")); -} - -void TestAbstractMetaClass::testIsPolymorphic() -{ - const char* cppCode = "\ - class A\n\ - {\n\ - public:\n\ - A();\n\ - inline bool abc() const {}\n\ - };\n\ - \n\ - class B : public A\n\ - {\n\ - public:\n\ - B();\n\ - inline bool abc() const {}\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='bool'/>\n\ - <value-type name='A'/>\n\ - <value-type name='B'/>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - AbstractMetaClass* b = AbstractMetaClass::findClass(classes, QLatin1String("A")); - - QVERIFY(!b->isPolymorphic()); - AbstractMetaClass* a = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(!a->isPolymorphic()); -} - -void TestAbstractMetaClass::testClassTypedefedBaseClass() -{ - const char cppCode[] =R"CPP( -class Base { -}; - -using BaseAlias1 = Base; -using BaseAlias2 = BaseAlias1; - -class Derived : public BaseAlias2 { -}; -)CPP"; - const char xmlCode[] = R"XML( -<typesystem package='Foo'> - <object-type name='Base'/> - <object-type name='Derived'/> -</typesystem> -)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - auto base = AbstractMetaClass::findClass(classes, QLatin1String("Base")); - QVERIFY(base); - auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived")); - QVERIFY(derived); - QCOMPARE(derived->baseClasses().value(0), base); -} - -QTEST_APPLESS_MAIN(TestAbstractMetaClass) diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h b/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h deleted file mode 100644 index 1d9f8d8f6..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTABSTRACTMETACLASS_H -#define TESTABSTRACTMETACLASS_H - -#include <QObject> - -class AbstractMetaBuilder; - -class TestAbstractMetaClass : public QObject -{ - Q_OBJECT -private slots: - void testClassName(); - void testClassNameUnderNamespace(); - void testVirtualMethods(); - void testVirtualBase(); - void testDefaultValues(); - void testModifiedDefaultValues(); - void testInnerClassOfAPolymorphicOne(); - void testForwardDeclaredInnerClass(); - void testSpecialFunctions(); - void testClassDefaultConstructors(); - void testClassInheritedDefaultConstructors(); - void testAbstractClassDefaultConstructors(); - void testObjectTypesMustNotHaveCopyConstructors(); - void testIsPolymorphic(); - void testClassTypedefedBaseClass(); -}; - -#endif // TESTABSTRACTMETACLASS_H diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp deleted file mode 100644 index 63434b3a5..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testabstractmetatype.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> -#include <parser/codemodel.h> -#include <typeparser.h> - -void TestAbstractMetaType::parsing_data() -{ - QTest::addColumn<QString>("input"); - QTest::addColumn<QString>("output"); - QTest::newRow("primitive") - << QString::fromLatin1("int") << QString::fromLatin1("int"); - QTest::newRow("ref") - << QString::fromLatin1("int &") << QString::fromLatin1("int&"); - QTest::newRow("pointer") - << QString::fromLatin1("int **") << QString::fromLatin1("int**"); - QTest::newRow("const ref") - << QString::fromLatin1("const int &") << QString::fromLatin1("const int&"); - QTest::newRow("const pointer") - << QString::fromLatin1("const int **") << QString::fromLatin1("const int**"); - QTest::newRow("const pointer const") - << QString::fromLatin1("const int *const*") << QString::fromLatin1("const int*const*"); -} - -void TestAbstractMetaType::parsing() -{ - QFETCH(QString, input); - QFETCH(QString, output); - QString errorMessage; - const TypeInfo ti = TypeParser::parse(input, &errorMessage); - QVERIFY2(errorMessage.isEmpty(), qPrintable(errorMessage)); - const QString actual = ti.toString(); - QCOMPARE(actual, output); -} - -void TestAbstractMetaType::testConstCharPtrType() -{ - 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()); - QCOMPARE(builder->globalFunctions().size(), 1); - AbstractMetaFunction* func = builder->globalFunctions().first(); - AbstractMetaType* rtype = func->type(); - // Test properties of const char* - QVERIFY(rtype); - QCOMPARE(rtype->package(), QLatin1String("Foo")); - QCOMPARE(rtype->name(), QLatin1String("char")); - QVERIFY(rtype->isConstant()); - QVERIFY(!rtype->isArray()); - QVERIFY(!rtype->isContainer()); - QVERIFY(!rtype->isObject()); - QVERIFY(!rtype->isPrimitive()); // const char* differs from char, so it's not considered a primitive type by apiextractor - QVERIFY(rtype->isNativePointer()); - QCOMPARE(rtype->referenceType(), NoReference); - QVERIFY(!rtype->isValue()); - QVERIFY(!rtype->isValuePointer()); -} - -void TestAbstractMetaType::testApiVersionSupported() -{ - const char* cppCode ="class foo {}; class foo2 {};\n\ - void justAtest(); void justAtest3();\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\ - <function signature='justAtest()' since='0.1'/>\n\ - <function signature='justAtest2()' since='1.1'/>\n\ - <function signature='justAtest3()'/>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, - false, QLatin1String("1.0"))); - QVERIFY(!builder.isNull()); - - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.size(), 2); - - - AbstractMetaFunctionList functions = builder->globalFunctions(); - QCOMPARE(functions.size(), 2); -} - - -void TestAbstractMetaType::testApiVersionNotSupported() -{ - 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()); - - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.size(), 1); -} - -void TestAbstractMetaType::testCharType() -{ - 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()); - - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.size(), 1); - QCOMPARE(classes.first()->package(), QLatin1String("Foo")); - - AbstractMetaFunctionList functions = builder->globalFunctions(); - QCOMPARE(functions.size(), 1); - AbstractMetaFunction* func = functions.first(); - AbstractMetaType* rtype = func->type(); - // Test properties of const char* - QVERIFY(rtype); - QCOMPARE(rtype->package(), QLatin1String("Foo")); - QCOMPARE(rtype->name(), QLatin1String("char")); - QVERIFY(!rtype->isConstant()); - QVERIFY(!rtype->isArray()); - QVERIFY(!rtype->isContainer()); - QVERIFY(!rtype->isObject()); - QVERIFY(rtype->isPrimitive()); - QVERIFY(!rtype->isNativePointer()); - QCOMPARE(rtype->referenceType(), NoReference); - QVERIFY(!rtype->isValue()); - QVERIFY(!rtype->isValuePointer()); -} - -void TestAbstractMetaType::testTypedef() -{ - 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\ - <value-type name='C' />\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.size(), 1); - const AbstractMetaClass *c = AbstractMetaClass::findClass(classes, QLatin1String("C")); - QVERIFY(c); - QVERIFY(c->isTypeDef()); -} - -void TestAbstractMetaType::testTypedefWithTemplates() -{ - const char* cppCode ="\ - template<typename T>\n\ - class A {};\n\ - \n\ - class B {};\n\ - typedef A<B> C;\n\ - \n\ - void func(C c);\n"; - const char* xmlCode = "<typesystem package=\"Foo\">\n\ - <container-type name='A' type='list'/>\n\ - <value-type name='B' />\n\ - <function signature='func(A<B>)'/>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.size(), 1); - AbstractMetaFunctionList functions = builder->globalFunctions(); - QCOMPARE(functions.count(), 1); - AbstractMetaFunction* function = functions.first(); - AbstractMetaArgumentList args = function->arguments(); - QCOMPARE(args.count(), 1); - AbstractMetaArgument* arg = args.first(); - AbstractMetaType* metaType = arg->type(); - QCOMPARE(metaType->cppSignature(), QLatin1String("A<B >")); -} - - -void TestAbstractMetaType::testObjectTypeUsedAsValue() -{ - const char* cppCode ="\ - class A {\n\ - void method(A);\n\ - };\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()); - - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.size(), 1); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - AbstractMetaFunctionList overloads = classA->queryFunctionsByName(QLatin1String("method")); - QCOMPARE(overloads.count(), 1); - AbstractMetaFunction* method = overloads.first(); - QVERIFY(method); - AbstractMetaArgumentList args = method->arguments(); - QCOMPARE(args.count(), 1); - AbstractMetaArgument* arg = args.first(); - AbstractMetaType* metaType = arg->type(); - QCOMPARE(metaType->cppSignature(), QLatin1String("A")); - QVERIFY(metaType->isValue()); - QVERIFY(metaType->typeEntry()->isObject()); -} - -QTEST_APPLESS_MAIN(TestAbstractMetaType) diff --git a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h b/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h deleted file mode 100644 index b39a27a54..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTABSTRACTMETATYPE_H -#define TESTABSTRACTMETATYPE_H - -#include <QObject> - -class TestAbstractMetaType : public QObject -{ - Q_OBJECT -private slots: - void parsing_data(); - void parsing(); - void testConstCharPtrType(); - void testCharType(); - void testTypedef(); - void testTypedefWithTemplates(); - void testApiVersionSupported(); - void testApiVersionNotSupported(); - void testObjectTypeUsedAsValue(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp deleted file mode 100644 index ca4af9a10..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp +++ /dev/null @@ -1,467 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testaddfunction.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestAddFunction::testParsingFuncNameAndConstness() -{ - // generic test... - const char sig1[] = "func(type1, const type2, const type3* const)"; - AddedFunction f1(QLatin1String(sig1), QLatin1String("void")); - QCOMPARE(f1.name(), QLatin1String("func")); - QCOMPARE(f1.arguments().count(), 3); - AddedFunction::TypeInfo retval = f1.returnType(); - QCOMPARE(retval.name, QLatin1String("void")); - QCOMPARE(retval.indirections, 0); - QCOMPARE(retval.isConstant, false); - QCOMPARE(retval.isReference, false); - - // 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 "; - AddedFunction f2(QLatin1String(sig2), QLatin1String("const Abc<int& , C<char*> * > * *")); - QCOMPARE(f2.name(), QLatin1String("_fu__nc_")); - const auto &args = f2.arguments(); - QCOMPARE(args.count(), 4); - retval = f2.returnType(); - QCOMPARE(retval.name, QLatin1String("Abc<int& , C<char*> * >")); - QCOMPARE(retval.indirections, 2); - QCOMPARE(retval.isConstant, true); - QCOMPARE(retval.isReference, false); - retval = args.at(2).typeInfo; - QVERIFY(args.at(0).name.isEmpty()); - QVERIFY(args.at(1).name.isEmpty()); - QCOMPARE(args.at(2).name, QLatin1String("my_name")); - QVERIFY(args.at(3).name.isEmpty()); - QCOMPARE(retval.name, QLatin1String("Abc<int& , C<char*> * >")); - QCOMPARE(retval.indirections, 2); - QCOMPARE(retval.isConstant, true); - QCOMPARE(retval.isReference, false); - - // function with no args. - const char sig3[] = "func()"; - AddedFunction f3(QLatin1String(sig3), QLatin1String("void")); - QCOMPARE(f3.name(), QLatin1String("func")); - QCOMPARE(f3.arguments().count(), 0); -} - -void TestAddFunction::testAddFunction() -{ - const char cppCode[] = R"CPP( -struct B {}; -struct A { - void a(int); -};)CPP"; - const char xmlCode[] = R"XML( -<typesystem package='Foo'> - <primitive-type name='int'/> - <primitive-type name='float'/> - <value-type name='B'/> - <value-type name='A'> - <add-function signature='b(int, float = 4.6, const B&)' return-type='int' access='protected'/> - <add-function signature='operator()(int)' return-type='int' access='public'/> - </value-type> -</typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - TypeDatabase* typeDb = TypeDatabase::instance(); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QCOMPARE(classA->functions().count(), 5); // default ctor, default copy ctor, func a() and the added functions - - auto addedFunc = classA->findFunction(QLatin1String("b")); - QVERIFY(addedFunc); - QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Protected); - QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction); - QVERIFY(addedFunc->isUserAdded()); - QCOMPARE(addedFunc->ownerClass(), classA); - QCOMPARE(addedFunc->implementingClass(), classA); - QCOMPARE(addedFunc->declaringClass(), classA); - QVERIFY(!addedFunc->isVirtual()); - QVERIFY(!addedFunc->isSignal()); - QVERIFY(!addedFunc->isSlot()); - QVERIFY(!addedFunc->isStatic()); - - AbstractMetaType* returnType = addedFunc->type(); - QCOMPARE(returnType->typeEntry(), typeDb->findPrimitiveType(QLatin1String("int"))); - AbstractMetaArgumentList args = addedFunc->arguments(); - QCOMPARE(args.count(), 3); - QCOMPARE(args[0]->type()->typeEntry(), returnType->typeEntry()); - QCOMPARE(args[1]->defaultValueExpression(), QLatin1String("4.6")); - QCOMPARE(args[2]->type()->typeEntry(), typeDb->findType(QLatin1String("B"))); - - auto addedCallOperator = classA->findFunction(QLatin1String("operator()")); - QVERIFY(addedCallOperator); -} - -void TestAddFunction::testAddFunctionConstructor() -{ - const char cppCode[] = "struct A { A() {} };\n"; - const char xmlCode[] = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <value-type name='A'>\n\ - <add-function signature='A(int)'/>\n\ - </value-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QCOMPARE(classA->functions().count(), 3); // default and added ctors - AbstractMetaFunction* addedFunc = classA->functions().last(); - QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Public); - QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::ConstructorFunction); - QCOMPARE(addedFunc->arguments().size(), 1); - QVERIFY(addedFunc->isUserAdded()); - QVERIFY(!addedFunc->type()); -} - -void TestAddFunction::testAddFunctionTagDefaultValues() -{ - const char cppCode[] = "struct A {};\n"; - const char xmlCode[] = "\ - <typesystem package='Foo'>\n\ - <value-type name='A'>\n\ - <add-function signature='func()'/>\n\ - </value-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QCOMPARE(classA->functions().count(), 3); // default ctor, default copy ctor and the added function - AbstractMetaFunction* addedFunc = classA->functions().last(); - QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Public); - QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction); - QVERIFY(addedFunc->isUserAdded()); - QVERIFY(!addedFunc->type()); -} - -void TestAddFunction::testAddFunctionCodeSnippets() -{ - const char cppCode[] = "struct A {};\n"; - const char xmlCode[] = "\ - <typesystem package='Foo'>\n\ - <value-type name='A'>\n\ - <add-function signature='func()'>\n\ - <inject-code class='target' position='end'>Hi!, I am the code.</inject-code>\n\ - </add-function>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - AbstractMetaFunction* addedFunc = classA->functions().last(); - QVERIFY(addedFunc->hasInjectedCode()); -} - -void TestAddFunction::testAddFunctionWithoutParenteses() -{ - const char sig1[] = "func"; - AddedFunction f1(QLatin1String(sig1), QLatin1String("void")); - - QCOMPARE(f1.name(), QLatin1String("func")); - QCOMPARE(f1.arguments().count(), 0); - QCOMPARE(f1.isConstant(), false); - - const char cppCode[] = "struct A {};\n"; - const char xmlCode[] = "\ - <typesystem package='Foo'>\n\ - <value-type name='A'>\n\ - <add-function signature='func'>\n\ - <inject-code class='target' position='end'>Hi!, I am the code.</inject-code>\n\ - </add-function>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("func")); - QVERIFY(addedFunc); - QVERIFY(addedFunc->hasInjectedCode()); - QCOMPARE(addedFunc->injectedCodeSnips(TypeSystem::CodeSnipPositionAny, TypeSystem::TargetLangCode).count(), 1); -} - -void TestAddFunction::testAddFunctionWithDefaultArgs() -{ - const char sig1[] = "func"; - AddedFunction f1(QLatin1String(sig1), QLatin1String("void")); - - QCOMPARE(f1.name(), QLatin1String("func")); - QCOMPARE(f1.arguments().count(), 0); - QCOMPARE(f1.isConstant(), false); - - const char cppCode[] = "struct A { };\n"; - const char xmlCode[] = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <value-type name='A'>\n\ - <add-function signature='func(int, int)'>\n\ - <modify-argument index='2'>\n\ - <replace-default-expression with='2'/>\n\ - </modify-argument>\n\ - </add-function>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("func")); - QVERIFY(addedFunc); - AbstractMetaArgument *arg = addedFunc->arguments()[1]; - QCOMPARE(arg->defaultValueExpression(), QLatin1String("2")); -} - -void TestAddFunction::testAddFunctionAtModuleLevel() -{ - const char cppCode[] = "struct A { };\n"; - const char xmlCode[] = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <value-type name='A'/>\n\ - <add-function signature='func(int, int)'>\n\ - <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\ - </add-function>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - - TypeDatabase* typeDb = TypeDatabase::instance(); - - AddedFunctionList addedFuncs = typeDb->findGlobalUserFunctions(QLatin1String("func")); - - QCOMPARE(addedFuncs.size(), 1); - - const FunctionModificationList mods = addedFuncs.constFirst()->modifications; - - QCOMPARE(mods.size(), 1); - QVERIFY(mods.first().isCodeInjection()); - CodeSnip snip = mods.first().snips.first(); - QCOMPARE(snip.code().trimmed(), QLatin1String("custom_code();")); -} - -void TestAddFunction::testAddFunctionWithVarargs() -{ - const char sig1[] = "func(int,char,...)"; - AddedFunction f1( QLatin1String(sig1), QLatin1String("void")); - - QCOMPARE(f1.name(), QLatin1String("func")); - QCOMPARE(f1.arguments().count(), 3); - QVERIFY(!f1.isConstant()); - - const char cppCode[] = "struct A {};\n"; - const char xmlCode[] = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <primitive-type name='char'/>\n\ - <value-type name='A'>\n\ - <add-function signature='func(int,char,...)'/>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("func")); - QVERIFY(addedFunc); - const AbstractMetaArgument* arg = addedFunc->arguments().last(); - QVERIFY(arg->type()->isVarargs()); - QVERIFY(arg->type()->typeEntry()->isVarargs()); -} - -void TestAddFunction::testAddStaticFunction() -{ - const char cppCode[] = "struct A { };\n"; - const char xmlCode[] = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <value-type name='A'>\n\ - <add-function signature='func(int, int)' static='yes'>\n\ - <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\ - </add-function>\n\ - </value-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("func")); - QVERIFY(addedFunc); - QVERIFY(addedFunc->isStatic()); -} - -void TestAddFunction::testAddGlobalFunction() -{ - const char cppCode[] = "struct A { };struct B {};\n"; - const char xmlCode[] = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <value-type name='A'/>\n\ - <add-function signature='globalFunc(int, int)' static='yes'>\n\ - <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\ - </add-function>\n\ - <add-function signature='globalFunc2(int, int)' static='yes'>\n\ - <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\ - </add-function>\n\ - <value-type name='B'/>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaFunctionList globalFuncs = builder->globalFunctions(); - QCOMPARE(globalFuncs.count(), 2); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(builder->classes(), QLatin1String("B")); - QVERIFY(classB); - QVERIFY(!classB->findFunction(QLatin1String("globalFunc"))); - QVERIFY(!classB->findFunction(QLatin1String("globalFunc2"))); - QVERIFY(!globalFuncs[0]->injectedCodeSnips().isEmpty()); - QVERIFY(!globalFuncs[1]->injectedCodeSnips().isEmpty()); -} - -void TestAddFunction::testAddFunctionWithApiVersion() -{ - const char cppCode[] = ""; - const char xmlCode[] = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <add-function signature='globalFunc(int, int)' static='yes' since='1.3'>\n\ - <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\ - </add-function>\n\ - <add-function signature='globalFunc2(int, int)' static='yes' since='0.1'>\n\ - <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\ - </add-function>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, - true, QLatin1String("0.1"))); - QVERIFY(!builder.isNull()); - AbstractMetaFunctionList globalFuncs = builder->globalFunctions(); - QCOMPARE(globalFuncs.count(), 1); -} - -void TestAddFunction::testModifyAddedFunction() -{ - const char cppCode[] = "class Foo { };\n"; - const char xmlCode[] = "\ - <typesystem package='Package'>\n\ - <primitive-type name='float'/>\n\ - <primitive-type name='int'/>\n\ - <value-type name='Foo'>\n\ - <add-function signature='method(float, int)'>\n\ - <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\ - <modify-argument index='2'>\n\ - <replace-default-expression with='0'/>\n\ - <rename to='varName'/>\n\ - </modify-argument>\n\ - </add-function>\n\ - </value-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - AbstractMetaClass* foo = AbstractMetaClass::findClass(classes, QLatin1String("Foo")); - const AbstractMetaFunction* method = foo->findFunction(QLatin1String("method")); - QCOMPARE(method->arguments().size(), 2); - AbstractMetaArgument* arg = method->arguments().at(1); - QCOMPARE(arg->defaultValueExpression(), QLatin1String("0")); - QCOMPARE(arg->name(), QLatin1String("varName")); - QCOMPARE(method->argumentName(2), QLatin1String("varName")); -} - -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\ - </add-function>\n\ - <add-function signature='method()'>\n\ - <inject-code class='target' position='beginning'>custom_code();</inject-code>\n\ - </add-function>\n\ - </value-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - AbstractMetaClass* foo = AbstractMetaClass::findClass(classes, QLatin1String("FooInt")); - QVERIFY(foo); - QVERIFY(foo->hasNonPrivateConstructor()); - const AbstractMetaFunctionList &lst = foo->queryFunctions(AbstractMetaClass::Constructors); - for (const AbstractMetaFunction *f : lst) - QVERIFY(f->signature().startsWith(f->name())); - QCOMPARE(lst.size(), 2); - const AbstractMetaFunction* method = foo->findFunction(QLatin1String("method")); - QVERIFY(method); -} - -void TestAddFunction::testAddFunctionWithTemplateArg() -{ - const char cppCode[] = "template<class T> class Foo { };\n"; - const char xmlCode[] = "\ - <typesystem package='Package'>\n\ - <primitive-type name='int'/>\n\ - <container-type name='Foo' type='list'/>\n\ - <add-function signature='func(Foo<int>)'/>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - QCOMPARE(builder->globalFunctions().size(), 1); - AbstractMetaFunction* func = builder->globalFunctions().first(); - AbstractMetaArgument* arg = func->arguments().first(); - QCOMPARE(arg->type()->instantiations().count(), 1); -} - -QTEST_APPLESS_MAIN(TestAddFunction) - diff --git a/sources/shiboken2/ApiExtractor/tests/testaddfunction.h b/sources/shiboken2/ApiExtractor/tests/testaddfunction.h deleted file mode 100644 index d95f0ecfe..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testaddfunction.h +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTADDFUNCTION_H -#define TESTADDFUNCTION_H -#include <QObject> - -class TestAddFunction : public QObject -{ - Q_OBJECT -private slots: - void testParsingFuncNameAndConstness(); - void testAddFunction(); - void testAddFunctionConstructor(); - void testAddFunctionTagDefaultValues(); - void testAddFunctionCodeSnippets(); - void testAddFunctionWithoutParenteses(); - void testAddFunctionWithDefaultArgs(); - void testAddFunctionAtModuleLevel(); - void testAddFunctionWithVarargs(); - void testAddStaticFunction(); - void testAddGlobalFunction(); - void testAddFunctionWithApiVersion(); - void testModifyAddedFunction(); - void testAddFunctionOnTypedef(); - void testAddFunctionWithTemplateArg(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp b/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp deleted file mode 100644 index a8b9a2eff..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testarrayargument.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestArrayArgument::testArrayArgumentWithSizeDefinedByInteger() -{ - const char* cppCode ="\ - struct A {\n\ - enum SomeEnum { Value0, Value1, NValues };\n\ - void method(double[3]);\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='double'/>\n\ - <object-type name='A'>\n\ - <enum-type name='SomeEnum'/>\n\ - </object-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A")); - QVERIFY(classA); - - const AbstractMetaArgument* arg = classA->functions().last()->arguments().first(); - QVERIFY(arg->type()->isArray()); - QCOMPARE(arg->type()->arrayElementCount(), 3); - QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double")); -} - -static QString functionMinimalSignature(const AbstractMetaClass *c, const QString &name) -{ - const AbstractMetaFunction *f = c->findFunction(name); - return f ? f->minimalSignature() : QString(); -} - -void TestArrayArgument::testArraySignature() -{ - const char cppCode[] ="\ - struct A {\n\ - void mi1(int arg[5]);\n\ - void mi1c(const int arg[5]);\n\ - void mi1cu(const int arg[]);\n\ - void mc1cu(const char arg[]);\n\ - void mc1cup(const char *arg[]);\n\ - void muc2(unsigned char *arg[2][3]);\n\ - void mc2c(const char *arg[5][6]);\n\ - void mc2cu(const char arg[][2]);\n\ - };\n"; - const char xmlCode[] = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='char'/>\n\ - <primitive-type name='unsigned char'/>\n\ - <primitive-type name='int'/>\n\ - <object-type name='A'/>\n\ - </typesystem>\n"; - - 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])")); -} - -void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValue() -{ - const char* cppCode ="\ - struct A {\n\ - enum SomeEnum { Value0, Value1, NValues };\n\ - void method(double[NValues]);\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='double'/>\n\ - <object-type name='A'>\n\ - <enum-type name='SomeEnum'/>\n\ - </object-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A")); - QVERIFY(classA); - - AbstractMetaEnum* someEnum = classA->findEnum(QLatin1String("SomeEnum")); - QVERIFY(someEnum); - AbstractMetaEnumValue *nvalues = classA->findEnumValue(QLatin1String("NValues")); - QVERIFY(nvalues); - - const AbstractMetaArgument* arg = classA->functions().last()->arguments().first(); - QVERIFY(arg->type()->isArray()); - QCOMPARE(arg->type()->arrayElementCount(), nvalues->value().value()); - QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double")); -}; - -void TestArrayArgument::testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnum() -{ - const char* cppCode ="\ - enum SomeEnum { Value0, Value1, NValues };\n\ - struct A {\n\ - void method(double[NValues]);\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='double'/>\n\ - <enum-type name='SomeEnum'/>\n\ - <object-type name='A'>\n\ - </object-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A")); - QVERIFY(classA); - - AbstractMetaEnum* someEnum = builder->globalEnums().first(); - QVERIFY(someEnum); - const AbstractMetaEnumValue *nvalues = someEnum->findEnumValue(QLatin1String("NValues")); - QVERIFY(nvalues); - - const AbstractMetaArgument* arg = classA->functions().last()->arguments().first(); - QVERIFY(arg->type()->isArray()); - QCOMPARE(arg->type()->arrayElementCount(), nvalues->value().value()); - QCOMPARE(arg->type()->arrayElementType()->name(), QLatin1String("double")); -}; - -QTEST_APPLESS_MAIN(TestArrayArgument) diff --git a/sources/shiboken2/ApiExtractor/tests/testarrayargument.h b/sources/shiboken2/ApiExtractor/tests/testarrayargument.h deleted file mode 100644 index 2e58ae6ee..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testarrayargument.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTARRAYARGUMENT_H -#define TESTARRAYARGUMENT_H -#include <QObject> - -class TestArrayArgument : public QObject -{ - Q_OBJECT -private slots: - void testArrayArgumentWithSizeDefinedByInteger(); - void testArraySignature(); - void testArrayArgumentWithSizeDefinedByEnumValue(); - void testArrayArgumentWithSizeDefinedByEnumValueFromGlobalEnum(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp deleted file mode 100644 index aeca2d3f4..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testcodeinjection.h" -#include <QFileInfo> -#include <QDir> -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestCodeInjections::testReadFile_data() -{ - QTest::addColumn<QString>("filePath"); - QTest::addColumn<QString>("snippet"); - QTest::addColumn<QString>("expected"); - - QTest::newRow("utf8") - << QString::fromLatin1(":/utf8code.txt") - << QString() - << QString::fromUtf8("\xC3\xA1\xC3\xA9\xC3\xAD\xC3\xB3\xC3\xBA"); - - QTest::newRow("snippet") - << QString::fromLatin1(":/injectedcode.txt") - << QString::fromLatin1("label") - << QString::fromLatin1("code line"); -} - -void TestCodeInjections::testReadFile() -{ - QFETCH(QString, filePath); - QFETCH(QString, snippet); - QFETCH(QString, expected); - - const char* cppCode ="struct A {};\n"; - int argc = 0; - char *argv[] = {nullptr}; - QCoreApplication app(argc, argv); - - QString attribute = QLatin1String("file='") + filePath + QLatin1Char('\''); - if (!snippet.isEmpty()) - attribute += QLatin1String(" snippet='") + snippet + QLatin1Char('\''); - - QString xmlCode = QLatin1String("\ - <typesystem package=\"Foo\">\n\ - <value-type name='A'>\n\ - <conversion-rule ") + attribute + QLatin1String("/>\n\ - <inject-code class='target' ") + attribute + QLatin1String("/>\n\ - <value-type name='B'/>\n\ - </value-type>\n\ - </typesystem>\n"); - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode.toLocal8Bit().constData())); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QCOMPARE(classA->typeEntry()->codeSnips().count(), 1); - QString code = classA->typeEntry()->codeSnips().first().code(); - QVERIFY(code.indexOf(expected) != -1); - code = classA->typeEntry()->conversionRule(); - QVERIFY(code.indexOf(expected) != -1); -} - -void TestCodeInjections::testInjectWithValidApiVersion() -{ - 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\ - test Inject code\n\ - </inject-code>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, - true, QLatin1String("1.0"))); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QCOMPARE(classA->typeEntry()->codeSnips().count(), 1); -} - -void TestCodeInjections::testInjectWithInvalidApiVersion() -{ - 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\ - test Inject code\n\ - </inject-code>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, - true, QLatin1String("0.1"))); - QVERIFY(!builder.isNull()); - - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QCOMPARE(classA->typeEntry()->codeSnips().count(), 0); -} - - - -QTEST_APPLESS_MAIN(TestCodeInjections) diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h deleted file mode 100644 index 1ac873970..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.h +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTCODEINJECTIONS_H -#define TESTCODEINJECTIONS_H - -#include <QObject> - -class AbstractMetaBuilder; - -class TestCodeInjections : public QObject -{ - Q_OBJECT -private slots: - void testReadFile_data(); - void testReadFile(); - void testInjectWithValidApiVersion(); - void testInjectWithInvalidApiVersion(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc b/sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc deleted file mode 100644 index fd7616bd2..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc +++ /dev/null @@ -1,6 +0,0 @@ -<RCC> - <qresource> - <file>utf8code.txt</file> - <file>injectedcode.txt</file> - </qresource> -</RCC> diff --git a/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp b/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp deleted file mode 100644 index aaa72238c..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testcontainer.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testcontainer.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestContainer::testContainerType() -{ - const char* cppCode ="\ - namespace std {\n\ - template<class T>\n\ - class list {\n\ - T get(int x) { return 0; }\n\ - };\n\ - }\n\ - class A : public std::list<int> {\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <namespace-type name='std' generate='no' />\n\ - <container-type name='std::list' type='list' />\n\ - <object-type name='A'/>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - //search for class A - AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - auto baseContainer = classA->typeEntry()->baseContainerType(); - QVERIFY(baseContainer); - QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer)->containerKind(), - ContainerTypeEntry::ListContainer); -} - -void TestContainer::testListOfValueType() -{ - const char* cppCode ="\ - namespace std {\n\ - template<class T>\n\ - class list {\n\ - T get(int x) { return 0; }\n\ - };\n\ - }\n\ - class ValueType {};\n\ - class A : public std::list<ValueType> {\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <namespace-type name='std' generate='no'/>\n\ - <container-type name='std::list' type='list'/>\n\ - <value-type name='ValueType'/>\n\ - <value-type name='A'/>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 3); - - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QCOMPARE(classA->templateBaseClassInstantiations().count(), 1); - const AbstractMetaType* templateInstanceType = classA->templateBaseClassInstantiations().first(); - QVERIFY(templateInstanceType); - - QCOMPARE(templateInstanceType->indirections(), 0); - QVERIFY(!templateInstanceType->typeEntry()->isObject()); - QVERIFY(templateInstanceType->typeEntry()->isValue()); - QCOMPARE(templateInstanceType->referenceType(), NoReference); - QVERIFY(!templateInstanceType->isObject()); - QVERIFY(!templateInstanceType->isValuePointer()); - QVERIFY(templateInstanceType->isValue()); -} - -QTEST_APPLESS_MAIN(TestContainer) - diff --git a/sources/shiboken2/ApiExtractor/tests/testcontainer.h b/sources/shiboken2/ApiExtractor/tests/testcontainer.h deleted file mode 100644 index 44e6636aa..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testcontainer.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTCONTAINER_H -#define TESTCONTAINER_H -#include <QObject> - -class TestContainer : public QObject -{ - Q_OBJECT -private slots: - void testContainerType(); - void testListOfValueType(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp deleted file mode 100644 index 142c783a4..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testconversionoperator.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestConversionOperator::testConversionOperator() -{ - const char cppCode[] = "\ - struct A {\n\ - };\n\ - struct B {\n\ - operator A() const;\n\ - };\n\ - struct C {\n\ - operator A() const;\n\ - };\n"; - 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()); - 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")); - 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); - - AbstractMetaFunction *convOp = nullptr; - for (AbstractMetaFunction *func : classB->functions()) { - if (func->isConversionOperator()) { - convOp = func; - break; - } - } - QVERIFY(convOp); - QVERIFY(classA->externalConversionOperators().contains(convOp)); -} - -void TestConversionOperator::testConversionOperatorOfDiscardedClass() -{ - const char cppCode[] = "\ - struct A {\n\ - };\n\ - struct B {\n\ - operator A() const;\n\ - };\n"; - const char xmlCode[] = "\ - <typesystem package=\"Foo\">\n\ - <value-type name='A' />\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QCOMPARE(classA->externalConversionOperators().count(), 0); -} - -void TestConversionOperator::testRemovedConversionOperator() -{ - const char cppCode[] = "\ - struct A {\n\ - };\n\ - struct B {\n\ - operator A() const;\n\ - };\n"; - const char xmlCode[] = "\ - <typesystem package=\"Foo\">\n\ - <value-type name='A' />\n\ - <value-type name='B'>\n\ - <modify-function signature='operator A() const' remove='all'/>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("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); -} - -void TestConversionOperator::testConversionOperatorReturningReference() -{ - const char cppCode[] = "\ - struct A {};\n\ - struct B {\n\ - operator A&() const;\n\ - };\n"; - const char xmlCode[] = "\ - <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()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classA); - QVERIFY(classB); - QCOMPARE(classA->functions().count(), 2); - QCOMPARE(classB->functions().count(), 3); - QCOMPARE(classA->externalConversionOperators().count(), 1); - QCOMPARE(classA->externalConversionOperators().first()->type()->cppSignature(), QLatin1String("A")); - QCOMPARE(classA->externalConversionOperators().first()->ownerClass()->name(), QLatin1String("B")); - QCOMPARE(classA->implicitConversions().count(), 1); - QCOMPARE(classA->implicitConversions().first()->type()->cppSignature(), QLatin1String("A")); - QCOMPARE(classA->implicitConversions().first()->ownerClass()->name(), QLatin1String("B")); -} - -void TestConversionOperator::testConversionOperatorReturningConstReference() -{ - const char cppCode[] = "\ - struct A {};\n\ - struct B {\n\ - operator const A&() const;\n\ - };\n"; - const char xmlCode[] = "\ - <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()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classA); - QVERIFY(classB); - QCOMPARE(classA->functions().count(), 2); - QCOMPARE(classB->functions().count(), 3); - QCOMPARE(classA->externalConversionOperators().count(), 1); - QCOMPARE(classA->externalConversionOperators().first()->type()->cppSignature(), QLatin1String("A")); - QCOMPARE(classA->externalConversionOperators().first()->ownerClass()->name(), QLatin1String("B")); - QCOMPARE(classA->implicitConversions().count(), 1); - QCOMPARE(classA->implicitConversions().first()->type()->cppSignature(), QLatin1String("A")); - QCOMPARE(classA->implicitConversions().first()->ownerClass()->name(), QLatin1String("B")); -} - -QTEST_APPLESS_MAIN(TestConversionOperator) diff --git a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.h b/sources/shiboken2/ApiExtractor/tests/testconversionoperator.h deleted file mode 100644 index b571a57a0..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testconversionoperator.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTCONVERSIONOPERATOR_H -#define TESTCONVERSIONOPERATOR_H -#include <QObject> - -class TestConversionOperator : public QObject -{ - Q_OBJECT -private slots: - void testConversionOperator(); - void testConversionOperatorOfDiscardedClass(); - void testRemovedConversionOperator(); - void testConversionOperatorReturningReference(); - void testConversionOperatorReturningConstReference(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testconversionruletag.cpp b/sources/shiboken2/ApiExtractor/tests/testconversionruletag.cpp deleted file mode 100644 index aa2bec5d6..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testconversionruletag.cpp +++ /dev/null @@ -1,250 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testconversionruletag.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> -#include <QFile> -#include <QTemporaryFile> - -void TestConversionRuleTag::testConversionRuleTagWithFile() -{ - // temp file used later - const char conversionData[] = "Hi! I'm a conversion rule."; - QTemporaryFile file; - file.open(); - QCOMPARE(file.write(conversionData), qint64(sizeof(conversionData)-1)); - file.close(); - - const char cppCode[] = "struct A {};\n"; - QString xmlCode = QLatin1String("\ - <typesystem package='Foo'>\n\ - <value-type name='A'>\n\ - <conversion-rule file='") + file.fileName() + QLatin1String("'/>\n\ - </value-type>\n\ - </typesystem>\n"); - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode.toLocal8Bit().data())); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - const ComplexTypeEntry* typeEntry = classA->typeEntry(); - QVERIFY(typeEntry->hasConversionRule()); - QCOMPARE(typeEntry->conversionRule(), QLatin1String(conversionData)); -} - -void TestConversionRuleTag::testConversionRuleTagReplace() -{ - const char cppCode[] = "\ - struct A {\n\ - A();\n\ - A(const char*, int);\n\ - };\n\ - struct B {\n\ - A createA();\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <primitive-type name='char'/>\n\ - <primitive-type name='A'>\n\ - <conversion-rule>\n\ - <native-to-target>\n\ - DoThis();\n\ - return ConvertFromCppToPython(%IN);\n\ - </native-to-target>\n\ - <target-to-native>\n\ - <add-conversion type='TargetNone' check='%IN == Target_None'>\n\ - DoThat();\n\ - DoSomething();\n\ - %OUT = A();\n\ - </add-conversion>\n\ - <add-conversion type='B' check='CheckIfInputObjectIsB(%IN)'>\n\ - %OUT = %IN.createA();\n\ - </add-conversion>\n\ - <add-conversion type='String' check='String_Check(%IN)'>\n\ - %OUT = new A(String_AsString(%IN), String_GetSize(%IN));\n\ - </add-conversion>\n\ - </target-to-native>\n\ - </conversion-rule>\n\ - </primitive-type>\n\ - <value-type name='B'/>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - TypeDatabase* typeDb = TypeDatabase::instance(); - PrimitiveTypeEntry* typeA = typeDb->findPrimitiveType(QLatin1String("A")); - QVERIFY(typeA); - - CustomConversion* conversion = typeA->customConversion(); - QVERIFY(conversion); - - QCOMPARE(typeA, conversion->ownerType()); - QCOMPARE(conversion->nativeToTargetConversion().simplified(), - QLatin1String("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();")); - - toNative = conversion->targetToNativeConversions().at(1); - QVERIFY(toNative); - QCOMPARE(toNative->sourceTypeName(), QLatin1String("B")); - QVERIFY(!toNative->isCustomType()); - TypeEntry* typeB = typeDb->findType(QLatin1String("B")); - QVERIFY(typeB); - QCOMPARE(toNative->sourceType(), typeB); - QCOMPARE(toNative->sourceTypeCheck(), QLatin1String("CheckIfInputObjectIsB(%IN)")); - QCOMPARE(toNative->conversion().trimmed(), QLatin1String("%OUT = %IN.createA();")); - - 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));")); -} - -void TestConversionRuleTag::testConversionRuleTagAdd() -{ - const char cppCode[] = "\ - struct Date {\n\ - Date();\n\ - Date(int, int, int);\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <value-type name='Date'>\n\ - <conversion-rule>\n\ - <target-to-native replace='no'>\n\ - <add-conversion type='TargetDate' check='TargetDate_Check(%IN)'>\n\ -if (!TargetDateTimeAPI) TargetDateTime_IMPORT;\n\ -%OUT = new Date(TargetDate_Day(%IN), TargetDate_Month(%IN), TargetDate_Year(%IN));\n\ - </add-conversion>\n\ - </target-to-native>\n\ - </conversion-rule>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("Date")); - QVERIFY(classA); - - CustomConversion* conversion = classA->typeEntry()->customConversion(); - QVERIFY(conversion); - - QCOMPARE(conversion->nativeToTargetConversion(), QString()); - - QVERIFY(!conversion->replaceOriginalTargetToNativeConversions()); - QVERIFY(conversion->hasTargetToNativeConversions()); - QCOMPARE(conversion->targetToNativeConversions().size(), 1); - - CustomConversion::TargetToNativeConversion* toNative = conversion->targetToNativeConversions().first(); - 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));")); -} - -void TestConversionRuleTag::testConversionRuleTagWithInsertTemplate() -{ - const char cppCode[] = "struct A {};"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <!-- single line -->\n\ - <template name='native_to_target'>return ConvertFromCppToPython(%IN);</template>\n\ - <!-- multi-line -->\n\ - <template name='target_to_native'>\n\ -%OUT = %IN.createA();\n\ - </template>\n\ - <primitive-type name='A'>\n\ - <conversion-rule>\n\ - <native-to-target>\n\ - <insert-template name='native_to_target'/>\n\ - </native-to-target>\n\ - <target-to-native>\n\ - <add-conversion type='TargetType'>\n\ - <insert-template name='target_to_native'/>\n\ - </add-conversion>\n\ - </target-to-native>\n\ - </conversion-rule>\n\ - </primitive-type>\n\ - </typesystem>\n"; - - const char nativeToTargetExpected[] = - "// TEMPLATE - native_to_target - START\n" - "return ConvertFromCppToPython(%IN);\n" - "// TEMPLATE - native_to_target - END"; - - const char targetToNativeExpected[] = - "// TEMPLATE - target_to_native - START\n" - "%OUT = %IN.createA();\n" - "// 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(typeA); - - CustomConversion* conversion = typeA->customConversion(); - QVERIFY(conversion); - - QCOMPARE(typeA, conversion->ownerType()); - QCOMPARE(conversion->nativeToTargetConversion().trimmed(), - QLatin1String(nativeToTargetExpected)); - - QVERIFY(conversion->hasTargetToNativeConversions()); - QCOMPARE(conversion->targetToNativeConversions().size(), 1); - - CustomConversion::TargetToNativeConversion* toNative = conversion->targetToNativeConversions().first(); - QVERIFY(toNative); - QCOMPARE(toNative->conversion().trimmed(), - QLatin1String(targetToNativeExpected)); -} - -QTEST_APPLESS_MAIN(TestConversionRuleTag) diff --git a/sources/shiboken2/ApiExtractor/tests/testconversionruletag.h b/sources/shiboken2/ApiExtractor/tests/testconversionruletag.h deleted file mode 100644 index 894bd3d71..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testconversionruletag.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTCONVERSIONRULE_H -#define TESTCONVERSIONRULE_H -#include <QObject> - -class TestConversionRuleTag : public QObject -{ - Q_OBJECT -private slots: - void testConversionRuleTagWithFile(); - void testConversionRuleTagReplace(); - void testConversionRuleTagAdd(); - void testConversionRuleTagWithInsertTemplate(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testctorinformation.cpp b/sources/shiboken2/ApiExtractor/tests/testctorinformation.cpp deleted file mode 100644 index 7718d3df6..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testctorinformation.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testctorinformation.h" -#include "abstractmetabuilder.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestCtorInformation::testCtorIsPrivate() -{ - const char* cppCode = "class Control { public: Control() {} };\n\ - class Subject { private: Subject() {} };\n\ - class CtorLess { };\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()); - 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); -} - -void TestCtorInformation::testHasNonPrivateCtor() -{ - const char* cppCode = "template<typename T>\n\ - struct Base { Base(double) {} };\n\ - typedef Base<int> Derived;\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()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - const AbstractMetaClass *base = AbstractMetaClass::findClass(classes, QLatin1String("Base")); - QCOMPARE(base->hasNonPrivateConstructor(), true); - const AbstractMetaClass *derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived")); - QCOMPARE(derived->hasNonPrivateConstructor(), true); -} - -QTEST_APPLESS_MAIN(TestCtorInformation) diff --git a/sources/shiboken2/ApiExtractor/tests/testctorinformation.h b/sources/shiboken2/ApiExtractor/tests/testctorinformation.h deleted file mode 100644 index ee655d450..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testctorinformation.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTCTORINFORMATION_H -#define TESTCTORINFORMATION_H - -#include <QObject> - -class AbstractMetaBuilder; - -class TestCtorInformation: public QObject -{ - Q_OBJECT -private slots: - void testCtorIsPrivate(); - void testHasNonPrivateCtor(); -}; - -#endif // TESTCTORINFORMATION_H diff --git a/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp b/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp deleted file mode 100644 index 7b3da182f..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testdroptypeentries.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -static const char* cppCode ="\ - struct ValueA {};\n\ - struct ValueB {};\n\ - struct ObjectA {};\n\ - struct ObjectB {};\n\ - namespace NamespaceA {\n\ - struct InnerClassA {};\n\ - namespace InnerNamespaceA {}\n\ - }\n\ - namespace NamespaceB {}\n\ - enum EnumA { Value0 };\n\ - enum EnumB { Value1 };\n\ - void funcA();\n\ - void funcB();\n"; - -static const char* xmlCode = "\ -<typesystem package='Foo'>\n\ - <value-type name='ValueA'/>\n\ - <value-type name='ValueB'/>\n\ - <object-type name='ObjectA'/>\n\ - <object-type name='ObjectB'/>\n\ - <namespace-type name='NamespaceA'>\n\ - <value-type name='InnerClassA'/>\n\ - <namespace-type name='InnerNamespaceA'/>\n\ - </namespace-type>\n\ - <namespace-type name='NamespaceB'/>\n\ - <enum-type name='EnumA'/>\n\ - <enum-type name='EnumB'/>\n\ - <function signature='funcA()'/>\n\ - <function signature='funcB()'/>\n\ -</typesystem>\n"; - -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")}; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false, - QString(), droppedEntries)); - QVERIFY(!builder.isNull()); - - 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"))); - - AbstractMetaEnumList globalEnums = builder->globalEnums(); - QCOMPARE(globalEnums.count(), 1); - QCOMPARE(globalEnums.first()->name(), QLatin1String("EnumA")); - - TypeDatabase* td = TypeDatabase::instance(); - QVERIFY(td->findType(QLatin1String("funcA"))); - QVERIFY(!td->findType(QLatin1String("funcB"))); -} - -void TestDropTypeEntries::testDontDropEntries() -{ - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - - 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"))); - - QCOMPARE(builder->globalEnums().size(), 2); - - TypeDatabase* td = TypeDatabase::instance(); - QVERIFY(td->findType(QLatin1String("funcA"))); - QVERIFY(td->findType(QLatin1String("funcB"))); -} - -static const char* cppCode2 ="\ - struct ValueA {\n\ - void func();\n\ - };\n"; - -static const char* xmlCode2 = "\ -<typesystem package='Foo'>\n\ - <value-type name='ValueA'>\n\ - <modify-function signature='func()'>\n\ - <remove class='all'/>\n\ - </modify-function>\n\ - </value-type>\n\ -</typesystem>\n"; - -void TestDropTypeEntries::testDropEntryWithChildTags() -{ - QStringList droppedEntries(QLatin1String("Foo.ValueA")); - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false, - QString(), droppedEntries)); - QVERIFY(!builder.isNull()); - QVERIFY(!AbstractMetaClass::findClass(builder->classes(), QLatin1String("ValueA"))); -} - - -void TestDropTypeEntries::testDontDropEntryWithChildTags() -{ - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode2, xmlCode2, false)); - QVERIFY(!builder.isNull()); - QVERIFY(AbstractMetaClass::findClass(builder->classes(), QLatin1String("ValueA"))); -} - -QTEST_APPLESS_MAIN(TestDropTypeEntries) diff --git a/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.h b/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.h deleted file mode 100644 index 3023a1120..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testdroptypeentries.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTDROPTYPEENTRIES_H -#define TESTDROPTYPEENTRIES_H - -#include <QObject> - -class TestDropTypeEntries : public QObject -{ - Q_OBJECT - private slots: - void testDropEntries(); - void testDontDropEntries(); - void testDropEntryWithChildTags(); - void testDontDropEntryWithChildTags(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp deleted file mode 100644 index 0eee8af24..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testdtorinformation.h" -#include "abstractmetabuilder.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -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>"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->hasPrivateDestructor(), false); - QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasPrivateDestructor(), true); -} - -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>"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->hasProtectedDestructor(), false); - QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasProtectedDestructor(), true); -} - -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>"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->hasVirtualDestructor(), false); - QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->hasVirtualDestructor(), true); -} - -void TestDtorInformation::testDtorFromBaseIsVirtual() -{ - 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"/> -<value-type name="Control"/>" -<value-type name="SubjectBase"/>" -<value-type name="Subject"/> -</typesystem> -)XML"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 4); - - auto klass = AbstractMetaClass::findClass(classes, QLatin1String("ControlBase")); - QVERIFY(klass); - QVERIFY(!klass->hasVirtualDestructor()); - klass = AbstractMetaClass::findClass(classes, QLatin1String("Control")); - QVERIFY(klass); - QVERIFY(!klass->hasVirtualDestructor()); - - klass = AbstractMetaClass::findClass(classes, QLatin1String("SubjectBase")); - QVERIFY(klass); - QVERIFY(klass->hasVirtualDestructor()); - klass = AbstractMetaClass::findClass(classes, QLatin1String("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>"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Control"))->isPolymorphic(), true); - QCOMPARE(AbstractMetaClass::findClass(classes, QLatin1String("Subject"))->isPolymorphic(), true); -} - -QTEST_APPLESS_MAIN(TestDtorInformation) - - diff --git a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h b/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h deleted file mode 100644 index 0a57dd8d1..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testdtorinformation.h +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTDTORINFORMATION_H -#define TESTDTORINFORMATION_H - -#include <QObject> - -class AbstractMetaBuilder; - -class TestDtorInformation: public QObject -{ - Q_OBJECT -private slots: - void testDtorIsPrivate(); - void testDtorIsProtected(); - void testDtorIsVirtual(); - void testDtorFromBaseIsVirtual(); - void testClassWithVirtualDtorIsPolymorphic(); -}; - -#endif // TESTDTORINFORMATION_H diff --git a/sources/shiboken2/ApiExtractor/tests/testenum.cpp b/sources/shiboken2/ApiExtractor/tests/testenum.cpp deleted file mode 100644 index c04a37d9d..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testenum.cpp +++ /dev/null @@ -1,435 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testenum.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestEnum::testEnumCppSignature() -{ - const char* cppCode ="\ - enum GlobalEnum { A, B };\n\ - \n\ - struct A {\n\ - enum ClassEnum { CA, CB };\n\ - void method(ClassEnum);\n\ - };\n\ - void func(A::ClassEnum);\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <enum-type name='GlobalEnum'/>\n\ - <value-type name='A'>\n\ - <enum-type name='ClassEnum'/>\n\ - </value-type>\n\ - <function signature='func(A::ClassEnum)'/>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 1); - - AbstractMetaEnumList globalEnums = builder->globalEnums(); - QCOMPARE(globalEnums.count(), 1); - QCOMPARE(globalEnums.first()->name(), QLatin1String("GlobalEnum")); - - // enum as parameter of a function - AbstractMetaFunctionList functions = builder->globalFunctions(); - QCOMPARE(functions.count(), 1); - QCOMPARE(functions.first()->arguments().count(), 1); - QCOMPARE(functions.first()->arguments().first()->type()->cppSignature(), QLatin1String("A::ClassEnum")); - - // enum as parameter of a method - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QCOMPARE(classA->enums().count(), 1); - AbstractMetaFunctionList funcs = classA->queryFunctionsByName(QLatin1String("method")); - QVERIFY(!funcs.isEmpty()); - AbstractMetaFunction* method = funcs.first(); - QVERIFY(method); - AbstractMetaArgument* arg = method->arguments().first(); - QCOMPARE(arg->type()->name(), QLatin1String("ClassEnum")); - QCOMPARE(arg->type()->cppSignature(), QLatin1String("A::ClassEnum")); - QCOMPARE(functions.first()->arguments().count(), 1); - arg = functions.first()->arguments().first(); - QCOMPARE(arg->type()->name(), QLatin1String("ClassEnum")); - QCOMPARE(arg->type()->cppSignature(), QLatin1String("A::ClassEnum")); - - AbstractMetaEnumList classEnums = classA->enums(); - QCOMPARE(classEnums.first()->name(), QLatin1String("ClassEnum")); - AbstractMetaEnumValue *e = AbstractMetaClass::findEnumValue(classes, QLatin1String("CA")); - QVERIFY(e); - e = AbstractMetaClass::findEnumValue(classes, QLatin1String("ClassEnum::CA")); - QVERIFY(e); -} - -void TestEnum::testEnumWithApiVersion() -{ - const char* cppCode ="\ - struct A {\n\ - enum ClassEnum { EnumA, EnumB };\n\ - enum ClassEnum2 { EnumC, EnumD };\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <value-type name='A'>\n\ - <enum-type name='ClassEnum' since='0.1'/>\n\ - <enum-type name='ClassEnum2' since='0.2'/>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, - true, QLatin1String("0.1"))); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 1); - QCOMPARE(classes[0]->enums().count(), 1); -} - -void TestEnum::testAnonymousEnum() -{ - const char* cppCode ="\ - enum { Global0, Global1 };\n\ - struct A {\n\ - enum { A0, A1 };\n\ - enum { isThis = true, isThat = false };\n\ - };\n"; - 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\ - <value-type name='A'>\n\ - <!-- Uses the second value of the enum to identify it. -->\n\ - <enum-type identified-by-value='A1'/>\n\ - <enum-type identified-by-value='isThis'/>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - - AbstractMetaEnumList globalEnums = builder->globalEnums(); - QCOMPARE(globalEnums.count(), 1); - QCOMPARE(globalEnums.first()->typeEntry()->qualifiedCppName(), QLatin1String("Global0")); - QVERIFY(globalEnums.first()->isAnonymous()); - - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 1); - QCOMPARE(classes[0]->enums().count(), 2); - - AbstractMetaEnum* anonEnumA1 = classes[0]->findEnum(QLatin1String("A1")); - QVERIFY(anonEnumA1); - QVERIFY(anonEnumA1->isAnonymous()); - QCOMPARE(anonEnumA1->typeEntry()->qualifiedCppName(), QLatin1String("A::A1")); - - AbstractMetaEnumValue* enumValueA0 = anonEnumA1->values().first(); - QCOMPARE(enumValueA0->name(), QLatin1String("A0")); - QCOMPARE(enumValueA0->value().value(), 0); - QCOMPARE(enumValueA0->stringValue(), QString()); - - AbstractMetaEnumValue* enumValueA1 = anonEnumA1->values().last(); - QCOMPARE(enumValueA1->name(), QLatin1String("A1")); - QCOMPARE(enumValueA1->value().value(), 1); - QCOMPARE(enumValueA1->stringValue(), QString()); - - AbstractMetaEnum* anonEnumIsThis = classes[0]->findEnum(QLatin1String("isThis")); - QVERIFY(anonEnumIsThis); - QVERIFY(anonEnumIsThis->isAnonymous()); - QCOMPARE(anonEnumIsThis->typeEntry()->qualifiedCppName(), QLatin1String("A::isThis")); - - AbstractMetaEnumValue* enumValueIsThis = anonEnumIsThis->values().first(); - QCOMPARE(enumValueIsThis->name(), QLatin1String("isThis")); - QCOMPARE(enumValueIsThis->value().value(), static_cast<int>(true)); - QCOMPARE(enumValueIsThis->stringValue(), QLatin1String("true")); - - AbstractMetaEnumValue* enumValueIsThat = anonEnumIsThis->values().last(); - QCOMPARE(enumValueIsThat->name(), QLatin1String("isThat")); - QCOMPARE(enumValueIsThat->value().value(), static_cast<int>(false)); - QCOMPARE(enumValueIsThat->stringValue(), QLatin1String("false")); -} - -void TestEnum::testGlobalEnums() -{ - const char* cppCode ="\ - enum EnumA { A0, A1 };\n\ - enum EnumB { B0 = 2, B1 = 0x4 };\n"; - 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()); - - AbstractMetaEnumList globalEnums = builder->globalEnums(); - QCOMPARE(globalEnums.count(), 2); - - AbstractMetaEnum* enumA = globalEnums.first(); - QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QLatin1String("EnumA")); - - AbstractMetaEnumValue* enumValueA0 = enumA->values().first(); - QCOMPARE(enumValueA0->name(), QLatin1String("A0")); - QCOMPARE(enumValueA0->value().value(), 0); - QCOMPARE(enumValueA0->stringValue(), QString()); - - AbstractMetaEnumValue* enumValueA1 = enumA->values().last(); - QCOMPARE(enumValueA1->name(), QLatin1String("A1")); - QCOMPARE(enumValueA1->value().value(), 1); - QCOMPARE(enumValueA1->stringValue(), QString()); - - AbstractMetaEnum* enumB = globalEnums.last(); - QCOMPARE(enumB->typeEntry()->qualifiedCppName(), QLatin1String("EnumB")); - - AbstractMetaEnumValue* enumValueB0 = enumB->values().first(); - QCOMPARE(enumValueB0->name(), QLatin1String("B0")); - QCOMPARE(enumValueB0->value().value(), 2); - QCOMPARE(enumValueB0->stringValue(), QLatin1String("2")); - - AbstractMetaEnumValue* enumValueB1 = enumB->values().last(); - QCOMPARE(enumValueB1->name(), QLatin1String("B1")); - QCOMPARE(enumValueB1->value().value(), 4); - QCOMPARE(enumValueB1->stringValue(), QLatin1String("0x4")); -} - -void TestEnum::testEnumValueFromNeighbourEnum() -{ - const char* cppCode ="\ - namespace A {\n\ - enum EnumA { ValueA0, ValueA1 };\n\ - enum EnumB { ValueB0 = A::ValueA1, ValueB1 = ValueA0 };\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <namespace-type name='A'>\n\ - <enum-type name='EnumA'/>\n\ - <enum-type name='EnumB'/>\n\ - </namespace-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 1); - QCOMPARE(classes[0]->enums().count(), 2); - - AbstractMetaEnum* enumA = classes[0]->findEnum(QLatin1String("EnumA")); - QVERIFY(enumA); - QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumA")); - - AbstractMetaEnumValue* enumValueA0 = enumA->values().first(); - QCOMPARE(enumValueA0->name(), QLatin1String("ValueA0")); - QCOMPARE(enumValueA0->value().value(), 0); - QCOMPARE(enumValueA0->stringValue(), QString()); - - AbstractMetaEnumValue* enumValueA1 = enumA->values().last(); - QCOMPARE(enumValueA1->name(), QLatin1String("ValueA1")); - QCOMPARE(enumValueA1->value().value(), 1); - QCOMPARE(enumValueA1->stringValue(), QString()); - - AbstractMetaEnum* enumB = classes[0]->findEnum(QLatin1String("EnumB")); - QVERIFY(enumB); - QCOMPARE(enumB->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumB")); - - AbstractMetaEnumValue* enumValueB0 = enumB->values().first(); - QCOMPARE(enumValueB0->name(), QLatin1String("ValueB0")); - QCOMPARE(enumValueB0->value().value(), 1); - QCOMPARE(enumValueB0->stringValue(), QLatin1String("A::ValueA1")); - - AbstractMetaEnumValue* enumValueB1 = enumB->values().last(); - QCOMPARE(enumValueB1->name(), QLatin1String("ValueB1")); - QCOMPARE(enumValueB1->value().value(), 0); - QCOMPARE(enumValueB1->stringValue(), QLatin1String("ValueA0")); -} - -void TestEnum::testEnumValueFromExpression() -{ - const char* cppCode ="\ - struct A {\n\ - enum EnumA : unsigned {\n\ - ValueA0 = 3u,\n\ - ValueA1 = ~3u,\n\ - ValueA2 = 0xffffffff,\n\ - ValueA3 = 0xf0,\n\ - ValueA4 = 8 |ValueA3,\n\ - ValueA5 = ValueA3|32,\n\ - ValueA6 = ValueA3 >> 1,\n\ - ValueA7 = ValueA3 << 1\n\ - };\n\ - enum EnumB : int {\n\ - ValueB0 = ~3,\n\ - };\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <value-type name='A'>\n\ - <enum-type name='EnumA'/>\n\ - <enum-type name='EnumB'/>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - - AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A")); - QVERIFY(classA); - - AbstractMetaEnum* enumA = classA->findEnum(QLatin1String("EnumA")); - QVERIFY(enumA); - QVERIFY(!enumA->isSigned()); - QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QLatin1String("A::EnumA")); - - AbstractMetaEnumValue* valueA0 = enumA->values().at(0); - QCOMPARE(valueA0->name(), QLatin1String("ValueA0")); - QCOMPARE(valueA0->stringValue(), QLatin1String("3u")); - QCOMPARE(valueA0->value().unsignedValue(), 3u); - - AbstractMetaEnumValue* valueA1 = enumA->values().at(1); - QCOMPARE(valueA1->name(), QLatin1String("ValueA1")); - QCOMPARE(valueA1->stringValue(), QLatin1String("~3u")); - QCOMPARE(valueA1->value().unsignedValue(), ~3u); - - AbstractMetaEnumValue* valueA2 = enumA->values().at(2); - QCOMPARE(valueA2->name(), QLatin1String("ValueA2")); - QCOMPARE(valueA2->stringValue(), QLatin1String("0xffffffff")); - QCOMPARE(valueA2->value().unsignedValue(), 0xffffffffu); - - AbstractMetaEnumValue* valueA3 = enumA->values().at(3); - QCOMPARE(valueA3->name(), QLatin1String("ValueA3")); - QCOMPARE(valueA3->stringValue(), QLatin1String("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->value().unsignedValue(), 8|0xf0u); - - AbstractMetaEnumValue* valueA5 = enumA->values().at(5); - QCOMPARE(valueA5->name(), QLatin1String("ValueA5")); - QCOMPARE(valueA5->stringValue(), QLatin1String("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->value().unsignedValue(), 0xf0u >> 1); - - AbstractMetaEnumValue* valueA7 = enumA->values().at(7); - QCOMPARE(valueA7->name(), QLatin1String("ValueA7")); - QCOMPARE(valueA7->stringValue(), QLatin1String("ValueA3 << 1")); - QCOMPARE(valueA7->value().unsignedValue(), 0xf0u << 1); - - const AbstractMetaEnum *enumB = classA->findEnum(QLatin1String("EnumB")); - QVERIFY(enumB); - QVERIFY(enumB->isSigned()); - QCOMPARE(enumB->typeEntry()->qualifiedCppName(), QLatin1String("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->value().value(), ~3); -} - -void TestEnum::testPrivateEnum() -{ - 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 = "\ - <typesystem package=\"Foo\">\n\ - <value-type name='A'>\n\ - <enum-type name='PublicEnum'/>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - - AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A")); - QVERIFY(classA); - QCOMPARE(classA->enums().count(), 2); - - AbstractMetaEnum* privateEnum = classA->findEnum(QLatin1String("PrivateEnum")); - QVERIFY(privateEnum); - QVERIFY(privateEnum->isPrivate()); - QCOMPARE(privateEnum->typeEntry()->qualifiedCppName(), QLatin1String("A::PrivateEnum")); - - AbstractMetaEnum* publicEnum = classA->findEnum(QLatin1String("PublicEnum")); - QVERIFY(publicEnum); - QCOMPARE(publicEnum->typeEntry()->qualifiedCppName(), QLatin1String("A::PublicEnum")); - - AbstractMetaEnumValue* pub0 = publicEnum->values().first(); - QCOMPARE(pub0->name(), QLatin1String("Pub0")); - QCOMPARE(pub0->value().value(), 0x0f); - QCOMPARE(pub0->stringValue(), QLatin1String("Priv0")); - - AbstractMetaEnumValue* pub1 = publicEnum->values().last(); - QCOMPARE(pub1->name(), QLatin1String("Pub1")); - QCOMPARE(pub1->value().value(), 0xf0); - QCOMPARE(pub1->stringValue(), QLatin1String("A::Priv1")); -} - -void TestEnum::testTypedefEnum() -{ - const char* cppCode ="\ - typedef enum EnumA {\n\ - A0,\n\ - A1,\n\ - } EnumA;\n"; - 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()); - - AbstractMetaEnumList globalEnums = builder->globalEnums(); - QCOMPARE(globalEnums.count(), 1); - - AbstractMetaEnum* enumA = globalEnums.first(); - QCOMPARE(enumA->typeEntry()->qualifiedCppName(), QLatin1String("EnumA")); - - AbstractMetaEnumValue* enumValueA0 = enumA->values().first(); - QCOMPARE(enumValueA0->name(), QLatin1String("A0")); - QCOMPARE(enumValueA0->value().value(), 0); - QCOMPARE(enumValueA0->stringValue(), QLatin1String("")); - - AbstractMetaEnumValue* enumValueA1 = enumA->values().last(); - QCOMPARE(enumValueA1->name(), QLatin1String("A1")); - QCOMPARE(enumValueA1->value().value(), 1); - QCOMPARE(enumValueA1->stringValue(), QString()); -} - -QTEST_APPLESS_MAIN(TestEnum) diff --git a/sources/shiboken2/ApiExtractor/tests/testenum.h b/sources/shiboken2/ApiExtractor/tests/testenum.h deleted file mode 100644 index 312551763..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testenum.h +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTENUM_H -#define TESTENUM_H -#include <QObject> - -class TestEnum : public QObject -{ - Q_OBJECT -private slots: - void testEnumCppSignature(); - void testEnumWithApiVersion(); - void testAnonymousEnum(); - void testGlobalEnums(); - void testEnumValueFromNeighbourEnum(); - void testEnumValueFromExpression(); - void testPrivateEnum(); - void testTypedefEnum(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp b/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp deleted file mode 100644 index 7e5664842..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testextrainclude.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestExtraInclude::testClassExtraInclude() -{ - const char* cppCode ="struct A {};\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <value-type name='A'>\n\ - <extra-includes>\n\ - <include file-name='header.h' location='global'/>\n\ - </extra-includes>\n\ - </value-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - - QVector<Include> includes = classA->typeEntry()->extraIncludes(); - QCOMPARE(includes.count(), 1); - QCOMPARE(includes.first().name(), QLatin1String("header.h")); -} - -void TestExtraInclude::testGlobalExtraIncludes() -{ - const char* cppCode ="struct A {};\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <extra-includes>\n\ - <include file-name='header1.h' location='global'/>\n\ - <include file-name='header2.h' location='global'/>\n\ - </extra-includes>\n\ - <value-type name='A'/>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QVERIFY(AbstractMetaClass::findClass(classes, QLatin1String("A"))); - - TypeDatabase* td = TypeDatabase::instance(); - const TypeSystemTypeEntry *module = td->defaultTypeSystemType(); - QVERIFY(module); - QCOMPARE(module->name(), QLatin1String("Foo")); - - QVector<Include> includes = module->extraIncludes(); - QCOMPARE(includes.count(), 2); - QCOMPARE(includes.first().name(), QLatin1String("header1.h")); - QCOMPARE(includes.last().name(), QLatin1String("header2.h")); -} - -QTEST_APPLESS_MAIN(TestExtraInclude) diff --git a/sources/shiboken2/ApiExtractor/tests/testextrainclude.h b/sources/shiboken2/ApiExtractor/tests/testextrainclude.h deleted file mode 100644 index 33c5377c7..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testextrainclude.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTEXTRAINCLUDE_H -#define TESTEXTRAINCLUDE_H - -#include <QObject> - -class TestExtraInclude : public QObject -{ - Q_OBJECT - private slots: - void testClassExtraInclude(); - void testGlobalExtraIncludes(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testfunctiontag.cpp b/sources/shiboken2/ApiExtractor/tests/testfunctiontag.cpp deleted file mode 100644 index b9aee5824..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testfunctiontag.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testfunctiontag.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestFunctionTag::testFunctionTagForSpecificSignature() -{ - const char cppCode[] = "void globalFunction(int); void globalFunction(float); void dummy();\n"; - const char xmlCode[] = "\ - <typesystem package=\"Foo\">\n\ - <primitive-type name='int'/>\n\ - <primitive-type name='float'/>\n\ - <function signature='globalFunction(int)'/>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - - const TypeEntry *func = TypeDatabase::instance()->findType(QLatin1String("globalFunction")); - QVERIFY(func); - QCOMPARE(builder->globalFunctions().size(), 1); -} - -void TestFunctionTag::testFunctionTagForAllSignatures() -{ - const char cppCode[] = "void globalFunction(int); void globalFunction(float); void dummy();\n"; - const char xmlCode[] = "\ - <typesystem package=\"Foo\">\n\ - <primitive-type name='int'/>\n\ - <primitive-type name='float'/>\n\ - <function signature='globalFunction(int)'/>\n\ - <function signature='globalFunction(float)'/>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - - const TypeEntry *func = TypeDatabase::instance()->findType(QLatin1String("globalFunction")); - QVERIFY(func); - QCOMPARE(builder->globalFunctions().size(), 2); -} - -void TestFunctionTag::testRenameGlobalFunction() -{ - 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()); - - const TypeEntry *func = TypeDatabase::instance()->findType(QLatin1String("global_function_with_ugly_name")); - QVERIFY(func); - - QCOMPARE(builder->globalFunctions().size(), 1); - const AbstractMetaFunction* metaFunc = builder->globalFunctions().first(); - - QVERIFY(metaFunc); - QCOMPARE(metaFunc->modifications().size(), 1); - QVERIFY(metaFunc->modifications().first().isRenameModifier()); - QCOMPARE(metaFunc->modifications().first().renamedTo(), QLatin1String("smooth")); - - QCOMPARE(metaFunc->name(), QLatin1String("smooth")); - QCOMPARE(metaFunc->originalName(), QLatin1String("global_function_with_ugly_name")); - QCOMPARE(metaFunc->minimalSignature(), QLatin1String("global_function_with_ugly_name()")); -} - -QTEST_APPLESS_MAIN(TestFunctionTag) - diff --git a/sources/shiboken2/ApiExtractor/tests/testfunctiontag.h b/sources/shiboken2/ApiExtractor/tests/testfunctiontag.h deleted file mode 100644 index d68499cd9..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testfunctiontag.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTFUNCTIONTAG_H -#define TESTFUNCTIONTAG_H -#include <QObject> - -class TestFunctionTag : public QObject -{ - Q_OBJECT -private slots: - void testFunctionTagForSpecificSignature(); - void testFunctionTagForAllSignatures(); - void testRenameGlobalFunction(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp deleted file mode 100644 index 26fb148d5..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testimplicitconversions.h" -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> -#include <QtTest/QTest> - -void TestImplicitConversions::testWithPrivateCtors() -{ - const char* cppCode ="\ - class B;\n\ - class C;\n\ - class A {\n\ - A(const B&);\n\ - public:\n\ - A(const C&);\n\ - };\n\ - class B {};\n\ - class C {};\n"; - 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()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 3); - - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, QLatin1String("C")); - AbstractMetaFunctionList implicitConvs = classA->implicitConversions(); - QCOMPARE(implicitConvs.count(), 1); - QCOMPARE(implicitConvs.first()->arguments().first()->type()->typeEntry(), classC->typeEntry()); -} - -void TestImplicitConversions::testWithModifiedVisibility() -{ - const char* cppCode ="\ - class B;\n\ - class A {\n\ - public:\n\ - A(const B&);\n\ - };\n\ - class B {};\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <value-type name='A'>\n\ - <modify-function signature='A(const B&)'>\n\ - <access modifier='private'/>\n\ - </modify-function>\n\ - </value-type>\n\ - <value-type name='B'/>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - AbstractMetaFunctionList implicitConvs = classA->implicitConversions(); - QCOMPARE(implicitConvs.count(), 1); - QCOMPARE(implicitConvs.first()->arguments().first()->type()->typeEntry(), classB->typeEntry()); -} - - -void TestImplicitConversions::testWithAddedCtor() -{ - const char* cppCode ="\ - class B;\n\ - class A {\n\ - public:\n\ - A(const B&);\n\ - };\n\ - class B {};\n\ - class C {};\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <custom-type name='TARGETLANGTYPE'/>\n\ - <value-type name='A'>\n\ - <add-function signature='A(const C&)'/>\n\ - </value-type>\n\ - <value-type name='B'>\n\ - <add-function signature='B(TARGETLANGTYPE*)'/>\n\ - </value-type>\n\ - <value-type name='C'/>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 3); - - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - AbstractMetaFunctionList implicitConvs = classA->implicitConversions(); - QCOMPARE(implicitConvs.count(), 2); - - // Added constructors with custom types should never result in implicit converters. - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - implicitConvs = classB->implicitConversions(); - QCOMPARE(implicitConvs.count(), 0); -} - -void TestImplicitConversions::testWithExternalConversionOperator() -{ - const char* cppCode ="\ - class A {};\n\ - struct B {\n\ - operator A() const;\n\ - };\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()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - AbstractMetaFunctionList implicitConvs = classA->implicitConversions(); - QCOMPARE(implicitConvs.count(), 1); - AbstractMetaFunctionList externalConvOps = classA->externalConversionOperators(); - QCOMPARE(externalConvOps.count(), 1); - - const AbstractMetaFunction *convOp = nullptr; - for (const AbstractMetaFunction *func : classB->functions()) { - if (func->isConversionOperator()) - convOp = func; - } - QVERIFY(convOp); - QCOMPARE(implicitConvs.first(), convOp); -} - -QTEST_APPLESS_MAIN(TestImplicitConversions) diff --git a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.h b/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.h deleted file mode 100644 index da8ae4597..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testimplicitconversions.h +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTIMPLICITCONVERSIONS_H -#define TESTIMPLICITCONVERSIONS_H - -#include <QObject> - -class AbstractMetaBuilder; - -class TestImplicitConversions : public QObject -{ - Q_OBJECT -private slots: - void testWithPrivateCtors(); - void testWithModifiedVisibility(); - void testWithAddedCtor(); - void testWithExternalConversionOperator(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp b/sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp deleted file mode 100644 index 2d1692ee9..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testinserttemplate.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestInsertTemplate::testInsertTemplateOnClassInjectCode() -{ - const char* cppCode ="struct A{};\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <template name='code_template'>\n\ - code template content\n\ - </template>\n\ - <value-type name='A'>\n\ - <inject-code class='native'>\n\ - <insert-template name='code_template'/>\n\ - </inject-code>\n\ - </value-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 1); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QCOMPARE(classA->typeEntry()->codeSnips().count(), 1); - QString code = classA->typeEntry()->codeSnips().first().code(); - QVERIFY(code.contains(QLatin1String("code template content"))); -} - -void TestInsertTemplate::testInsertTemplateOnModuleInjectCode() -{ - const char* cppCode =""; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <template name='code_template'>\n\ - code template content\n\ - </template>\n\ - <inject-code class='native'>\n\ - <insert-template name='code_template'/>\n\ - </inject-code>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QVERIFY(classes.isEmpty()); - - const TypeSystemTypeEntry *module = TypeDatabase::instance()->defaultTypeSystemType(); - QVERIFY(module); - QCOMPARE(module->name(), QLatin1String("Foo")); - QVERIFY(module); - QCOMPARE(module->codeSnips().count(), 1); - QString code = module->codeSnips().first().code().trimmed(); - QVERIFY(code.contains(QLatin1String("code template content"))); -} - -QTEST_APPLESS_MAIN(TestInsertTemplate) diff --git a/sources/shiboken2/ApiExtractor/tests/testinserttemplate.h b/sources/shiboken2/ApiExtractor/tests/testinserttemplate.h deleted file mode 100644 index 99b171933..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testinserttemplate.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTINSERTTEMPLATE_H -#define TESTINSERTTEMPLATE_H - -#include <QObject> - -class TestInsertTemplate : public QObject -{ - Q_OBJECT - private slots: - void testInsertTemplateOnClassInjectCode(); - void testInsertTemplateOnModuleInjectCode(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp deleted file mode 100644 index 6acac41d5..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testmodifydocumentation.h" - -#include <QCoreApplication> -#include <QtCore/QTemporaryDir> -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> -#include <qtdocparser.h> - -void TestModifyDocumentation::testModifyDocumentation() -{ - const char* cppCode ="struct B { void b(); }; class A {};\n"; - const char xmlCode[] = -R"(<typesystem package="Foo"> - <value-type name='B'> - <modify-function signature='b()' remove='all'/> - </value-type> - <value-type name='A'> - <modify-documentation xpath='description/brief'><brief>Modified Brief</brief></modify-documentation> - <modify-documentation xpath='description/para[3]'><para>Some changed contents here</para></modify-documentation> - </value-type> -</typesystem> -)"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A")); - QVERIFY(classA); - DocModificationList docMods = classA->typeEntry()->docModifications(); - QCOMPARE(docMods.count(), 2); - QCOMPARE(docMods[0].code().trimmed(), QLatin1String("<brief>Modified Brief</brief>")); - QCOMPARE(docMods[0].signature(), QString()); - QCOMPARE(docMods[1].code().trimmed(), QLatin1String("<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")); - QVERIFY2(tempDir.isValid(), qPrintable(tempDir.errorString())); - const QString docFileName = QLatin1String("a.xml"); - QVERIFY(QFile::copy(QLatin1String(":/") + docFileName, tempDir.filePath(docFileName))); - - QtDocParser docParser; - docParser.setDocumentationDataDirectory(tempDir.path()); - docParser.fillDocumentation(classA); - - const QString actualDocSimplified = classA->documentation().value().simplified(); - QVERIFY(!actualDocSimplified.isEmpty()); - -const char expectedDoc[] = -R"(<?xml version="1.0"?> -<description>oi -<brief>Modified Brief</brief> -<para>Paragraph number 1</para> -<para>Paragraph number 2</para> -<para>Some changed contents here</para> -</description> -)"; - const QString expectedDocSimplified = QString::fromLatin1(expectedDoc).simplified(); - // Check whether the first modification worked. - QVERIFY(actualDocSimplified.contains(QLatin1String("Modified Brief"))); - -#ifndef HAVE_LIBXSLT - // QtXmlPatterns is unable to handle para[3] in style sheets, - // this only works in its XPath search. - QEXPECT_FAIL("", "QtXmlPatterns cannot handle para[3] (QTBUG-66925)", Abort); -#endif - QCOMPARE(actualDocSimplified, expectedDocSimplified); -} - -// 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 -int main(int argc, char** argv) -{ - QCoreApplication app(argc, argv); - TestModifyDocumentation tc; - return QTest::qExec(&tc, argc, argv); -} diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.h b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.h deleted file mode 100644 index 6428a5697..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTMODIFYDOCUMENTATION_H -#define TESTMODIFYDOCUMENTATION_H - -#include <QObject> - -class TestModifyDocumentation : public QObject -{ -Q_OBJECT -private slots: - void testModifyDocumentation(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc b/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc deleted file mode 100644 index 76b1bfc61..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<RCC> - <qresource> - <file>a.xml</file> - </qresource> -</RCC> diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp deleted file mode 100644 index 4fd4269f6..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp +++ /dev/null @@ -1,466 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testmodifyfunction.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestModifyFunction::testRenameArgument_data() -{ - QTest::addColumn<QByteArray>("pattern"); - QTest::newRow("fixed_string") << QByteArrayLiteral("method(int)"); - QTest::newRow("regular_expression") << QByteArrayLiteral("^method.*"); -} - -void TestModifyFunction::testRenameArgument() -{ - QFETCH(QByteArray, pattern); - - const char* cppCode ="\ - struct A {\n\ - void method(int=0);\n\ - };\n"; - const char xmlCode1[] = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <object-type name='A'>\n\ - <modify-function signature='"; - const char xmlCode2[] = "'>\n\ - <modify-argument index='1'>\n\ - <rename to='otherArg'/>\n\ - </modify-argument>\n\ - </modify-function>\n\ - </object-type>\n\ - </typesystem>\n"; - - const QByteArray xmlCode = QByteArray(xmlCode1) + pattern + QByteArray(xmlCode2); - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode.constData(), false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - const AbstractMetaFunction* func = classA->findFunction(QLatin1String("method")); - Q_ASSERT(func); - - QCOMPARE(func->argumentName(1), QLatin1String("otherArg")); -} - -void TestModifyFunction::testOwnershipTransfer() -{ - const char* cppCode ="\ - struct A {};\n\ - struct B {\n\ - virtual A* method();\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <object-type name='A' />\n\ - <object-type name='B'>\n\ - <modify-function signature='method()'>\n\ - <modify-argument index='return'>\n\ - <define-ownership owner='c++'/>\n\ - </modify-argument>\n\ - </modify-function>\n\ - </object-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - const AbstractMetaFunction* func = classB->findFunction(QLatin1String("method")); - - QCOMPARE(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0), TypeSystem::CppOwnership); -} - - -void TestModifyFunction::invalidateAfterUse() -{ - const char* cppCode ="\ - struct A {\n\ - virtual void call(int *a);\n\ - };\n\ - struct B : A {\n\ - };\n\ - struct C : B {\n\ - virtual void call2(int *a);\n\ - };\n\ - struct D : C {\n\ - virtual void call2(int *a);\n\ - };\n\ - struct E : D {\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='int'/>\n\ - <object-type name='A'>\n\ - <modify-function signature='call(int*)'>\n\ - <modify-argument index='1' invalidate-after-use='true'/>\n\ - </modify-function>\n\ - </object-type>\n\ - <object-type name='B' />\n\ - <object-type name='C'>\n\ - <modify-function signature='call2(int*)'>\n\ - <modify-argument index='1' invalidate-after-use='true'/>\n\ - </modify-function>\n\ - </object-type>\n\ - <object-type name='D'>\n\ - <modify-function signature='call2(int*)'>\n\ - <modify-argument index='1' invalidate-after-use='true'/>\n\ - </modify-function>\n\ - </object-type>\n\ - <object-type name='E' />\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, - false, QLatin1String("0.1"))); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - const AbstractMetaFunction* func = classB->findFunction(QLatin1String("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")); - QVERIFY(classC); - func = classC->findFunction(QLatin1String("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")); - 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")); - QVERIFY(classD); - func = classD->findFunction(QLatin1String("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")); - 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")); - QVERIFY(classE); - func = classE->findFunction(QLatin1String("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")); - 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); -} - -void TestModifyFunction::testWithApiVersion() -{ - const char* cppCode ="\ - struct A {};\n\ - struct B {\n\ - virtual A* method();\n\ - virtual B* methodB();\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <object-type name='A' />\n\ - <object-type name='B'>\n\ - <modify-function signature='method()' since='0.1'>\n\ - <modify-argument index='return'>\n\ - <define-ownership owner='c++'/>\n\ - </modify-argument>\n\ - </modify-function>\n\ - <modify-function signature='methodB()' since='0.2'>\n\ - <modify-argument index='return'>\n\ - <define-ownership owner='c++'/>\n\ - </modify-argument>\n\ - </modify-function>\n\ - </object-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, - false, QLatin1String("0.1"))); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - const AbstractMetaFunction* func = classB->findFunction(QLatin1String("method")); - - QCOMPARE(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0), TypeSystem::CppOwnership); - - func = classB->findFunction(QLatin1String("methodB")); - QVERIFY(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0) != TypeSystem::CppOwnership); -} - -// Modifications on class/typesystem level are tested below -// in testScopedModifications(). -void TestModifyFunction::testAllowThread() -{ - const char cppCode[] =R"CPP(\ -struct A { - void f1(); - void f2(); - void f3(); - int getter1() const; - int getter2() const; -}; -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package='Foo'> - <primitive-type name='int'/> - <object-type name='A'> - <modify-function signature='f2()' allow-thread='auto'/> - <modify-function signature='f3()' allow-thread='no'/> - <modify-function signature='getter2()const' allow-thread='yes'/> - </object-type> -</typesystem> -)XML"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, - false, QLatin1String("0.1"))); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - - // Nothing specified, true - const AbstractMetaFunction *f1 = classA->findFunction(QLatin1String("f1")); - QVERIFY(f1); - QVERIFY(!f1->allowThread()); - - // 'auto' specified, should be false for nontrivial function - const AbstractMetaFunction *f2 = classA->findFunction(QLatin1String("f2")); - QVERIFY(f2); - QVERIFY(f2->allowThread()); - - // 'no' specified, should be false - const AbstractMetaFunction *f3 = classA->findFunction(QLatin1String("f3")); - QVERIFY(f3); - QVERIFY(!f3->allowThread()); - - // Nothing specified, should be false for simple getter - const AbstractMetaFunction *getter1 = classA->findFunction(QLatin1String("getter1")); - QVERIFY(getter1); - QVERIFY(!getter1->allowThread()); - - // Forced to true simple getter - const AbstractMetaFunction *getter2 = classA->findFunction(QLatin1String("getter2")); - QVERIFY(getter2); - QVERIFY(getter2->allowThread()); // Forced to true simple getter -} - -void TestModifyFunction::testGlobalFunctionModification() -{ - const char* cppCode ="\ - struct A {};\n\ - void function(A* a = 0);\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='A'/>\n\ - <function signature='function(A*)'>\n\ - <modify-function signature='function(A*)'>\n\ - <modify-argument index='1'>\n\ - <replace-type modified-type='A'/>\n\ - <replace-default-expression with='A()'/>\n\ - </modify-argument>\n\ - </modify-function>\n\ - </function>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - QCOMPARE(builder->globalFunctions().size(), 1); - - FunctionModificationList mods = TypeDatabase::instance()->functionModifications(QLatin1String("function(A*)")); - QCOMPARE(mods.count(), 1); - QVector<ArgumentModification> argMods = mods.first().argument_mods; - QCOMPARE(argMods.count(), 1); - ArgumentModification argMod = argMods.first(); - QCOMPARE(argMod.replacedDefaultExpression, QLatin1String("A()")); - - const AbstractMetaFunction* func = builder->globalFunctions().first(); - QVERIFY(func); - QCOMPARE(func->arguments().count(), 1); - const AbstractMetaArgument* arg = func->arguments().first(); - QCOMPARE(arg->type()->cppSignature(), QLatin1String("A *")); - QCOMPARE(arg->originalDefaultValueExpression(), QLatin1String("0")); - QCOMPARE(arg->defaultValueExpression(), QLatin1String("A()")); -} - -// Tests modifications of exception handling and allow-thread -// on various levels. -void TestModifyFunction::testScopedModifications_data() -{ - QTest::addColumn<QByteArray>("cppCode"); - QTest::addColumn<QByteArray>("xmlCode"); - QTest::addColumn<bool>("expectedGenerateUnspecified"); - QTest::addColumn<bool>("expectedGenerateNonThrowing"); - QTest::addColumn<bool>("expectedGenerateThrowing"); - QTest::addColumn<bool>("expectedAllowThread"); - - const QByteArray cppCode = R"CPP( -struct Base { -}; - -struct A : public Base { - void unspecified(); - void nonThrowing() noexcept; - void throwing() throw(int); -}; -)CPP"; - - // Default: Off - QTest::newRow("none") - << cppCode - << QByteArray(R"XML( -<typesystem package= 'Foo'> - <primitive-type name='int'/> - <object-type name='Base'/> - <object-type name='A'/> -</typesystem>)XML") - << false << false << false // exception - << false; // allowthread - - // Modify one function - QTest::newRow("modify-function1") - << cppCode - << QByteArray(R"XML( -<typesystem package='Foo'> - <primitive-type name='int'/> - <object-type name='Base'/> - <object-type name='A'> - <modify-function signature='throwing()' exception-handling='auto-on'/> - </object-type> -</typesystem>)XML") - << false << false << true // exception - << false; // allowthread - - // Flip defaults by modifying functions - QTest::newRow("modify-function2") - << cppCode - << QByteArray(R"XML( -<typesystem package='Foo'> - <primitive-type name='int'/> - <object-type name='Base'/> - <object-type name='A'> - <modify-function signature='unspecified()' exception-handling='auto-on'/> - <modify-function signature='throwing()' exception-handling='off'/> - </object-type> -</typesystem>)XML") - << true << false << false // exception - << false; // allowthread - - // Activate on type system level - QTest::newRow("typesystem-on") - << cppCode - << QByteArray(R"XML( -<typesystem package='Foo' exception-handling='auto-on' allow-thread='no'> - <primitive-type name='int'/> - <object-type name='Base'/> - <object-type name='A'/> -</typesystem>)XML") - << true << false << true // exception - << false; // allowthread - - // Activate on class level - QTest::newRow("class-on") - << cppCode - << QByteArray(R"XML( -<typesystem package='Foo'> - <primitive-type name='int'/> - <object-type name='Base'/> - <object-type name='A' exception-handling='auto-on' allow-thread='no'/> -</typesystem>)XML") - << true << false << true // exception - << false; // allowthread - - // Activate on base class level - QTest::newRow("baseclass-on") - << cppCode - << QByteArray(R"XML( -<typesystem package='Foo'> - <primitive-type name='int'/> - <object-type name='Base' exception-handling='auto-on' allow-thread='no'/> - <object-type name='A'/> -</typesystem>)XML") - << true << false << true // exception - << false; // allowthread - - // Override value on class level - QTest::newRow("override-class-on") - << cppCode - << QByteArray(R"XML( -<typesystem package='Foo'> - <primitive-type name='int'/> - <object-type name='Base'/> - <object-type name='A' exception-handling='auto-on'> - <modify-function signature='throwing()' exception-handling='no'/> - </object-type> -</typesystem>)XML") - << true << false << false // exception - << false; // allowthread -} - -void TestModifyFunction::testScopedModifications() -{ - QFETCH(QByteArray, cppCode); - QFETCH(QByteArray, xmlCode); - QFETCH(bool, expectedGenerateUnspecified); - QFETCH(bool, expectedGenerateNonThrowing); - QFETCH(bool, expectedGenerateThrowing); - QFETCH(bool, expectedAllowThread); - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode.constData(), xmlCode.constData(), false)); - QVERIFY(!builder.isNull()); - - const AbstractMetaClass *classA = AbstractMetaClass::findClass(builder->classes(), QLatin1String("A")); - QVERIFY(classA); - - const AbstractMetaFunction *f = classA->findFunction(QStringLiteral("unspecified")); - QVERIFY(f); - QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::Unknown); - QCOMPARE(f->generateExceptionHandling(), expectedGenerateUnspecified); - QCOMPARE(f->allowThread(), expectedAllowThread); - - f = classA->findFunction(QStringLiteral("nonThrowing")); - QVERIFY(f); - QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::NoExcept); - QCOMPARE(f->generateExceptionHandling(), expectedGenerateNonThrowing); - - f = classA->findFunction(QStringLiteral("throwing")); - QVERIFY(f); - QCOMPARE(f->exceptionSpecification(), ExceptionSpecification::Throws); - QCOMPARE(f->generateExceptionHandling(), expectedGenerateThrowing); -} - -QTEST_APPLESS_MAIN(TestModifyFunction) diff --git a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h b/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h deleted file mode 100644 index 375111e03..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTABSTRACTMETACLASS_H -#define TESTABSTRACTMETACLASS_H - -#include <QObject> - -class TestModifyFunction : public QObject -{ - Q_OBJECT - private slots: - void testOwnershipTransfer(); - void testWithApiVersion(); - void testAllowThread(); - void testRenameArgument_data(); - void testRenameArgument(); - void invalidateAfterUse(); - void testGlobalFunctionModification(); - void testScopedModifications_data(); - void testScopedModifications(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp b/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp deleted file mode 100644 index a4e506e8c..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testmultipleinheritance.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestMultipleInheritance::testVirtualClass() -{ - const char* cppCode ="\ - struct A {\n\ - virtual ~A();\n\ - virtual void theBug();\n\ - };\n\ - struct B {\n\ - virtual ~B();\n\ - };\n\ - struct C : A, B {\n\ - };\n\ - struct D : C {\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <object-type name='A' />\n\ - <object-type name='B' />\n\ - <object-type name='C' />\n\ - <object-type name='D' />\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 4); - - const AbstractMetaClass *classD = AbstractMetaClass::findClass(classes, QLatin1String("D")); - bool functionFound = false; - const AbstractMetaFunctionList &functions = classD->functions(); - for (AbstractMetaFunction *f : functions) { - if (f->name() == QLatin1String("theBug")) { - functionFound = true; - break; - } - } - QVERIFY(functionFound); - -} - -QTEST_APPLESS_MAIN(TestMultipleInheritance) diff --git a/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.h b/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.h deleted file mode 100644 index 5ee8a21ea..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTMULTIPLEINHERITANCE_H -#define TESTMULTIPLEINHERITANCE_H - -#include <QObject> - -class AbstractMetaBuilder; - -class TestMultipleInheritance : public QObject -{ - Q_OBJECT - private slots: - void testVirtualClass(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testnamespace.cpp b/sources/shiboken2/ApiExtractor/tests/testnamespace.cpp deleted file mode 100644 index e3aad6b50..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testnamespace.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testnamespace.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void NamespaceTest::testNamespaceMembers() -{ - const char* cppCode = "\ - namespace Namespace\n\ - {\n\ - enum Option {\n\ - OpZero,\n\ - OpOne\n\ - };\n\ - void foo(Option opt);\n\ - };\n"; - 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()); - AbstractMetaClassList classes = builder->classes(); - AbstractMetaClass *ns = AbstractMetaClass::findClass(classes, QLatin1String("Namespace")); - QVERIFY(ns); - const AbstractMetaEnum* metaEnum = ns->findEnum(QLatin1String("Option")); - QVERIFY(metaEnum); - const AbstractMetaFunction* func = ns->findFunction(QLatin1String("foo")); - QVERIFY(func); -} - -void NamespaceTest::testNamespaceInnerClassMembers() -{ - const char* cppCode = "\ - namespace OuterNamespace\n\ - {\n\ - namespace InnerNamespace {\n\ - struct SomeClass {\n\ - void method();\n\ - };\n\ - };\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <namespace-type name='OuterNamespace'>\n\ - <namespace-type name='InnerNamespace'>\n\ - <value-type name='SomeClass'/>\n\ - </namespace-type>\n\ - </namespace-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *ons = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace")); - QVERIFY(ons); - const AbstractMetaClass *ins = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace")); - QVERIFY(ins); - const AbstractMetaClass *sc = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace::SomeClass")); - QVERIFY(sc); - const AbstractMetaFunction* meth = sc->findFunction(QLatin1String("method")); - QVERIFY(meth); -} - -QTEST_APPLESS_MAIN(NamespaceTest) - diff --git a/sources/shiboken2/ApiExtractor/tests/testnamespace.h b/sources/shiboken2/ApiExtractor/tests/testnamespace.h deleted file mode 100644 index 5153a28a3..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testnamespace.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTNAMESPACE_H -#define TESTNAMESPACE_H - -#include <QObject> - -// The class is named 'NamespaceTest' to avoid clashes with Qt COIN using -// '-qtnamespace TestNamespace'. -class NamespaceTest : public QObject -{ - Q_OBJECT - private slots: - void testNamespaceMembers(); - void testNamespaceInnerClassMembers(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp deleted file mode 100644 index e61418467..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testnestedtypes.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestNestedTypes::testNestedTypesModifications() -{ - const char* cppCode ="\ - namespace OuterNamespace {\n\ - namespace InnerNamespace {\n\ - struct SomeClass {\n\ - void method() {}\n\ - };\n\ - };\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <namespace-type name='OuterNamespace'>\n\ - <namespace-type name='InnerNamespace'>\n\ - <inject-code class='native'>custom_code1();</inject-code>\n\ - <add-function signature='method()' return-type='OuterNamespace::InnerNamespace::SomeClass'>\n\ - <inject-code class='target'>custom_code2();</inject-code>\n\ - </add-function>\n\ - <object-type name='SomeClass' target-lang-name='RenamedSomeClass'>\n\ - <modify-function signature='method()' remove='all'/>\n\ - </object-type>\n\ - </namespace-type>\n\ - </namespace-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - - const AbstractMetaClass *ons = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace")); - QVERIFY(ons); - - const AbstractMetaClass *ins = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace")); - QVERIFY(ins); - QCOMPARE(ins->functions().count(), 1); - QCOMPARE(ins->typeEntry()->codeSnips().count(), 1); - CodeSnip snip = ins->typeEntry()->codeSnips().first(); - QCOMPARE(snip.code().trimmed(), QLatin1String("custom_code1();")); - - AbstractMetaFunction* addedFunc = ins->functions().first(); - QVERIFY(addedFunc->isUserAdded()); - QCOMPARE(addedFunc->visibility(), AbstractMetaFunction::Public); - QCOMPARE(addedFunc->functionType(), AbstractMetaFunction::NormalFunction); - QCOMPARE(addedFunc->type()->minimalSignature(), QLatin1String("OuterNamespace::InnerNamespace::SomeClass")); - - QCOMPARE(addedFunc->modifications().size(), 1); - QVERIFY(addedFunc->modifications().first().isCodeInjection()); - snip = addedFunc->modifications().first().snips.first(); - QCOMPARE(snip.code().trimmed(), QLatin1String("custom_code2();")); - - const AbstractMetaClass *sc = AbstractMetaClass::findClass(classes, QLatin1String("OuterNamespace::InnerNamespace::SomeClass")); - QVERIFY(ins); - QCOMPARE(sc->functions().count(), 2); // default constructor and removed method - AbstractMetaFunction* removedFunc = sc->functions().last(); - QVERIFY(removedFunc->isModifiedRemoved()); -} - - -void TestNestedTypes::testDuplicationOfNestedTypes() -{ - const char* cppCode ="\ - namespace Namespace {\n\ - class SomeClass {};\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <namespace-type name='Namespace'>\n\ - <value-type name='SomeClass'>\n\ - <add-function signature='createSomeClass(Namespace::SomeClass)'/>\n\ - </value-type>\n\ - </namespace-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 2); - const AbstractMetaClass *nspace = AbstractMetaClass::findClass(classes, QLatin1String("Namespace")); - QVERIFY(nspace); - const AbstractMetaClass *cls1 = AbstractMetaClass::findClass(classes, QLatin1String("SomeClass")); - QVERIFY(cls1); - const AbstractMetaClass *cls2 = AbstractMetaClass::findClass(classes, QLatin1String("Namespace::SomeClass")); - QVERIFY(cls2); - QCOMPARE(cls1, cls2); - QCOMPARE(cls1->name(), QLatin1String("SomeClass")); - QCOMPARE(cls1->qualifiedCppName(), QLatin1String("Namespace::SomeClass")); - - TypeEntry* t1 = TypeDatabase::instance()->findType(QLatin1String("Namespace::SomeClass")); - QVERIFY(t1); - TypeEntry* t2 = TypeDatabase::instance()->findType(QLatin1String("SomeClass")); - QVERIFY(!t2); -} - -QTEST_APPLESS_MAIN(TestNestedTypes) diff --git a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.h b/sources/shiboken2/ApiExtractor/tests/testnestedtypes.h deleted file mode 100644 index a870511ff..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testnestedtypes.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTNESTEDTYPES_H -#define TESTNESTEDTYPES_H -#include <QObject> - -class TestNestedTypes : public QObject -{ - Q_OBJECT -private slots: - void testNestedTypesModifications(); - void testDuplicationOfNestedTypes(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp b/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp deleted file mode 100644 index 4f0b0e10f..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testnumericaltypedef.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestNumericalTypedef::testNumericalTypedef() -{ - const char* cppCode ="\ - typedef double real;\n\ - void funcDouble(double);\n\ - void funcReal(real);\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='double'/>\n\ - <primitive-type name='real'/>\n\ - <function signature='funcDouble(double)'/>\n\ - <function signature='funcReal(real)'/>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - - QCOMPARE(builder->globalFunctions().size(), 2); - const AbstractMetaFunction* funcDouble = builder->globalFunctions().first(); - QVERIFY(funcDouble); - const AbstractMetaFunction* funcReal = builder->globalFunctions().last(); - QVERIFY(funcReal); - - if (funcDouble->name() == QLatin1String("funcReal")) - std::swap(funcDouble, funcReal); - - QCOMPARE(funcDouble->minimalSignature(), QLatin1String("funcDouble(double)")); - QCOMPARE(funcReal->minimalSignature(), QLatin1String("funcReal(real)")); - - const AbstractMetaType* doubleType = funcDouble->arguments().first()->type(); - QVERIFY(doubleType); - QCOMPARE(doubleType->cppSignature(), QLatin1String("double")); - QVERIFY(doubleType->isPrimitive()); - QVERIFY(doubleType->typeEntry()->isCppPrimitive()); - - const AbstractMetaType* realType = funcReal->arguments().first()->type(); - QVERIFY(realType); - QCOMPARE(realType->cppSignature(), QLatin1String("real")); - QVERIFY(realType->isPrimitive()); - QVERIFY(realType->typeEntry()->isCppPrimitive()); -} - -void TestNumericalTypedef::testUnsignedNumericalTypedef() -{ - const char* cppCode ="\ - typedef unsigned short ushort;\n\ - void funcUnsignedShort(unsigned short);\n\ - void funcUShort(ushort);\n"; - const char* xmlCode = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='short'/>\n\ - <primitive-type name='unsigned short'/>\n\ - <primitive-type name='ushort'/>\n\ - <function signature='funcUnsignedShort(unsigned short)'/>\n\ - <function signature='funcUShort(ushort)'/>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - - QCOMPARE(builder->globalFunctions().size(), 2); - const AbstractMetaFunction* funcUnsignedShort = builder->globalFunctions().first(); - QVERIFY(funcUnsignedShort); - const AbstractMetaFunction* funcUShort = builder->globalFunctions().last(); - QVERIFY(funcUShort); - - if (funcUnsignedShort->name() == QLatin1String("funcUShort")) - std::swap(funcUnsignedShort, funcUShort); - - QCOMPARE(funcUnsignedShort->minimalSignature(), QLatin1String("funcUnsignedShort(unsigned short)")); - QCOMPARE(funcUShort->minimalSignature(), QLatin1String("funcUShort(ushort)")); - - const AbstractMetaType* unsignedShortType = funcUnsignedShort->arguments().first()->type(); - QVERIFY(unsignedShortType); - QCOMPARE(unsignedShortType->cppSignature(), QLatin1String("unsigned short")); - QVERIFY(unsignedShortType->isPrimitive()); - QVERIFY(unsignedShortType->typeEntry()->isCppPrimitive()); - - const AbstractMetaType* ushortType = funcUShort->arguments().first()->type(); - QVERIFY(ushortType); - QCOMPARE(ushortType->cppSignature(), QLatin1String("ushort")); - QVERIFY(ushortType->isPrimitive()); - QVERIFY(ushortType->typeEntry()->isCppPrimitive()); -} - -QTEST_APPLESS_MAIN(TestNumericalTypedef) - diff --git a/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.h b/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.h deleted file mode 100644 index e4e051077..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTNUMERICALTYPEDEF_H -#define TESTNUMERICALTYPEDEF_H - -#include <QObject> - -class TestNumericalTypedef : public QObject -{ - Q_OBJECT - private slots: - void testNumericalTypedef(); - void testUnsignedNumericalTypedef(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.cpp b/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.cpp deleted file mode 100644 index e78f9f274..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testprimitivetypetag.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestPrimitiveTypeTag::testPrimitiveTypeDefaultConstructor() -{ - const char* cppCode ="\ - struct A {};\n\ - struct B {};\n"; - 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()); - - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 1); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classB); - - PrimitiveTypeEntry* typeEntry = TypeDatabase::instance()->findPrimitiveType(QLatin1String("A")); - QVERIFY(typeEntry); - QVERIFY(typeEntry->hasDefaultConstructor()); - QCOMPARE(typeEntry->defaultConstructor(), QLatin1String("A()")); -} - -QTEST_APPLESS_MAIN(TestPrimitiveTypeTag) - diff --git a/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.h b/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.h deleted file mode 100644 index ee5f5159f..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTPRIMITIVETYPETAG_H -#define TESTPRIMITIVETYPETAG_H - -#include <QObject> - -class TestPrimitiveTypeTag : public QObject -{ - Q_OBJECT - private slots: - void testPrimitiveTypeDefaultConstructor(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp b/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp deleted file mode 100644 index 38099c455..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testrefcounttag.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestRefCountTag::testReferenceCountTag() -{ - const char* cppCode ="\ - struct A {};\n\ - struct B {\n\ - void keepObject(B* b);\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <object-type name='A'/>\n\ - <object-type name='B'>\n\ - <modify-function signature='keepObject(B*)'>\n\ - <modify-argument index='1'>\n\ - <reference-count action='add'/>\n\ - </modify-argument>\n\ - </modify-function>\n\ - </object-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - const AbstractMetaFunction* func = classB->findFunction(QLatin1String("keepObject")); - QVERIFY(func); - ReferenceCount refCount = func->modifications().first().argument_mods.first().referenceCounts.first(); - QCOMPARE(refCount.action, ReferenceCount::Add); -} - -void TestRefCountTag::testWithApiVersion() -{ - const char* cppCode ="\ - struct A {};\n\ - struct B {\n\ - void keepObject(B*, B*);\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <object-type name='A'/>\n\ - <object-type name='B'>\n\ - <modify-function signature='keepObject(B*, B*)'>\n\ - <modify-argument index='1' since='0.1'>\n\ - <reference-count action='add'/>\n\ - </modify-argument>\n\ - <modify-argument index='2' since='0.2'>\n\ - <reference-count action='add'/>\n\ - </modify-argument>\n\ - </modify-function>\n\ - </object-type>\n\ - </typesystem>\n"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, - false, QLatin1String("0.1"))); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - const AbstractMetaFunction* func = classB->findFunction(QLatin1String("keepObject")); - QVERIFY(func); - ReferenceCount refCount = func->modifications().first().argument_mods.first().referenceCounts.first(); - QCOMPARE(refCount.action, ReferenceCount::Add); - - QCOMPARE(func->modifications().size(), 1); -} - - -QTEST_APPLESS_MAIN(TestRefCountTag) - - diff --git a/sources/shiboken2/ApiExtractor/tests/testrefcounttag.h b/sources/shiboken2/ApiExtractor/tests/testrefcounttag.h deleted file mode 100644 index 4acbddcfc..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testrefcounttag.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTREFCOUNTTAG_H -#define TESTREFCOUNTTAG_H - -#include <QObject> - -class TestRefCountTag : public QObject -{ - Q_OBJECT - private slots: - void testReferenceCountTag(); - void testWithApiVersion(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp b/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp deleted file mode 100644 index c7b4abe9a..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testreferencetopointer.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestReferenceToPointer::testReferenceToPointerArgument() -{ - const char* cppCode ="\ - struct A {};\n\ - struct B {\n\ - void dummy(A*&);\n\ - };\n"; - 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()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classB); - const AbstractMetaFunction* func = classB->findFunction(QLatin1String("dummy")); - QVERIFY(func); - QCOMPARE(func->arguments().first()->type()->minimalSignature(), QLatin1String("A*&")); -} - -QTEST_APPLESS_MAIN(TestReferenceToPointer) - - diff --git a/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.h b/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.h deleted file mode 100644 index 0f717b55d..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testreferencetopointer.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTREFERENCETOPOINTER_H -#define TESTREFERENCETOPOINTER_H - -#include <QObject> - -class TestReferenceToPointer : public QObject -{ - Q_OBJECT - private slots: - void testReferenceToPointerArgument(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testremovefield.cpp b/sources/shiboken2/ApiExtractor/tests/testremovefield.cpp deleted file mode 100644 index b586fd711..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testremovefield.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testremovefield.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestRemoveField::testRemoveField() -{ - const char* cppCode ="\ - struct A {\n\ - int fieldA;\n\ - int fieldB;\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <primitive-type name='int'/>\n\ - <value-type name='A'>\n\ - <modify-field name='fieldB' remove='all'/>\n\ - </value-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QCOMPARE(classA->fields().size(), 1); - const AbstractMetaField* fieldA = classA->fields().first(); - QVERIFY(fieldA); - QCOMPARE(fieldA->name(), QLatin1String("fieldA")); -} - -QTEST_APPLESS_MAIN(TestRemoveField) - - diff --git a/sources/shiboken2/ApiExtractor/tests/testremovefield.h b/sources/shiboken2/ApiExtractor/tests/testremovefield.h deleted file mode 100644 index 8b52cc32f..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testremovefield.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTREMOVEFIELD_H -#define TESTREMOVEFIELD_H - -#include <QObject> - -class TestRemoveField : public QObject -{ - Q_OBJECT - private slots: - void testRemoveField(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp b/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp deleted file mode 100644 index 96090d1cc..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testremoveimplconv.h" -#include "testutil.h" -#include <QtTest/QTest> -#include <abstractmetalang.h> -#include <typesystem.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 ="\ - struct A {};\n\ - struct B {};\n\ - struct C {\n\ - C(const A&);\n\ - C(const B&);\n\ - };\n"; - const char* xmlCode = "\ - <typesystem package=\"Foo\">\n\ - <value-type name='A'/>\n\ - <value-type name='B'/>\n\ - <value-type name='C'>\n\ - <modify-function signature='C(const A&)' remove='all'/>\n\ - </value-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 3); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classB); - const AbstractMetaClass *classC = AbstractMetaClass::findClass(classes, QLatin1String("C")); - QVERIFY(classC); - AbstractMetaFunctionList implConv = classC->implicitConversions(); - QCOMPARE(implConv.count(), 1); - QCOMPARE(implConv.first()->arguments().first()->type()->typeEntry(), classB->typeEntry()); -} - -QTEST_APPLESS_MAIN(TestRemoveImplConv) diff --git a/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.h b/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.h deleted file mode 100644 index 9e96dc2e9..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testremoveimplconv.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTREMOVEIMPLCONV_H -#define TESTREMOVEIMPLCONV_H - -#include <QObject> - -class TestRemoveImplConv : public QObject -{ -Q_OBJECT -private slots: - void testRemoveImplConv(); -}; - -#endif // TESTREMOVEIMPLCONV_H diff --git a/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp b/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp deleted file mode 100644 index a6d28ccf5..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testremoveoperatormethod.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -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 = "\ - <typesystem package='Foo'>\n\ - <primitive-type name='char'/>\n\ - <primitive-type name='short'/>\n\ - <primitive-type name='unsigned short'/>\n\ - <primitive-type name='int'/>\n\ - <primitive-type name='unsigned int'/>\n\ - <primitive-type name='int64_t'/>\n\ - <primitive-type name='uint64_t'/>\n\ - <primitive-type name='float'/>\n\ - <primitive-type name='double'/>\n\ - <primitive-type name='Char'/>\n\ - <primitive-type name='String'/>\n\ - <value-type name='ByteArray'/>\n\ - <object-type name='A'>\n\ - <modify-function signature='operator>>(char&)' remove='all'/>\n\ - <modify-function signature='operator>>(char*)' remove='all'/>\n\ - <modify-function signature='operator>>(short&)' remove='all'/>\n\ - <modify-function signature='operator>>(unsigned short&)' remove='all'/>\n\ - <modify-function signature='operator>>(int&)' remove='all'/>\n\ - <modify-function signature='operator>>(unsigned int&)' remove='all'/>\n\ - <modify-function signature='operator>>(int64_t&)' remove='all'/>\n\ - <modify-function signature='operator>>(uint64_t&)' remove='all'/>\n\ - <modify-function signature='operator>>(float&)' remove='all'/>\n\ - <modify-function signature='operator>>(double&)' remove='all'/>\n\ - <modify-function signature='operator>>(Char&)' remove='all'/>\n\ - <modify-function signature='operator>>(String&)' remove='all'/>\n\ - </object-type>\n\ - </typesystem>\n"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("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(); - const AbstractMetaFunctionList &functions = classA->functions(); - for (const AbstractMetaFunction *f : functions) { - QCOMPARE(f->isModifiedRemoved(), bool(removedSignatures.contains(f->minimalSignature()))); - notRemoved -= int(f->isModifiedRemoved()); - } - QCOMPARE(notRemoved, 2); -} - -QTEST_APPLESS_MAIN(TestRemoveOperatorMethod) - diff --git a/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.h b/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.h deleted file mode 100644 index 23c3e5144..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTREMOVEOPERATORMETHOD_H -#define TESTREMOVEOPERATORMETHOD_H - -#include <QObject> - -class TestRemoveOperatorMethod : public QObject -{ - Q_OBJECT - private slots: - void testRemoveOperatorMethod(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp b/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp deleted file mode 100644 index 2203f3648..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testresolvetype.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestResolveType::testResolveReturnTypeFromParentScope() -{ - const char* cppCode = "\n\ - namespace A {\n\ - struct B {\n\ - struct C {};\n\ - };\n\ - struct D : public B::C {\n\ - C* foo = 0;\n\ - C* method();\n\ - };\n\ - };"; - const char* xmlCode = R"XML( - <typesystem package='Foo'> - <namespace-type name='A'> - <value-type name='B'> - <value-type name='C'/> - </value-type> - <value-type name='D'/> - </namespace-type> - </typesystem>)XML"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classD = AbstractMetaClass::findClass(classes, QLatin1String("A::D")); - QVERIFY(classD); - const AbstractMetaFunction* meth = classD->findFunction(QLatin1String("method")); - QVERIFY(meth); -} - -QTEST_APPLESS_MAIN(TestResolveType) - diff --git a/sources/shiboken2/ApiExtractor/tests/testresolvetype.h b/sources/shiboken2/ApiExtractor/tests/testresolvetype.h deleted file mode 100644 index 62c08bcd7..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testresolvetype.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTRESOLVETYPE_H -#define TESTRESOLVETYPE_H - -#include <QObject> - -class TestResolveType : public QObject -{ - Q_OBJECT - private slots: - void testResolveReturnTypeFromParentScope(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp b/sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp deleted file mode 100644 index dc4801e18..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testreverseoperators.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestReverseOperators::testReverseSum() -{ - const char cppCode[] = "struct A {\n\ - A& operator+(int);\n\ - };\n\ - A& operator+(int, const A&);"; - const char xmlCode[] = "\n\ - <typesystem package=\"Foo\">\n\ - <primitive-type name='int' />\n\ - <value-type name='A' />\n\ - </typesystem>"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - AbstractMetaClass* classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QCOMPARE(classA->functions().count(), 4); - - const AbstractMetaFunction* reverseOp = nullptr; - const AbstractMetaFunction* normalOp = 0; - for (const AbstractMetaFunction *func : classA->functions()) { - if (func->name() == QLatin1String("operator+")) { - if (func->isReverseOperator()) - reverseOp = func; - else - normalOp = func; - } - } - - QVERIFY(normalOp); - QVERIFY(!normalOp->isReverseOperator()); - QCOMPARE(normalOp->arguments().count(), 1); - QVERIFY(reverseOp); - QVERIFY(reverseOp->isReverseOperator()); - QCOMPARE(reverseOp->arguments().count(), 1); -} - -void TestReverseOperators::testReverseSumWithAmbiguity() -{ - const char cppCode[] = "\n\ - struct A { A operator+(int); };\n\ - A operator+(int, const A&);\n\ - struct B {};\n\ - B operator+(const A&, const B&);\n\ - B operator+(const B&, const A&);\n\ - int operator-(int, const A*);\n\ - int operator/(const A*, int);\n\ - "; - const char xmlCode[] = "\n\ - <typesystem package=\"Foo\">\n\ - <primitive-type name='int' />\n\ - <value-type name='A' />\n\ - <value-type name='B' />\n\ - </typesystem>"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QEXPECT_FAIL("", "Clang: Does not compile", Abort); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QCOMPARE(classA->functions().count(), 6); - - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classB); - QCOMPARE(classB->functions().count(), 4); - - const AbstractMetaFunction *reverseOp = nullptr; - const AbstractMetaFunction *normalOp = nullptr; - for (const AbstractMetaFunction *func : classB->functions()) { - if (func->name() == QLatin1String("operator+")) { - if (func->isReverseOperator()) - reverseOp = func; - else - normalOp = func; - } - } - QVERIFY(normalOp); - QVERIFY(!normalOp->isReverseOperator()); - QCOMPARE(normalOp->arguments().count(), 1); - QCOMPARE(normalOp->minimalSignature(), QLatin1String("operator+(B,A)")); - QVERIFY(reverseOp); - QVERIFY(reverseOp->isReverseOperator()); - QCOMPARE(reverseOp->arguments().count(), 1); - QCOMPARE(reverseOp->minimalSignature(), QLatin1String("operator+(A,B)")); - - reverseOp = classA->findFunction(QLatin1String("operator-")); - QVERIFY(reverseOp); - QCOMPARE(reverseOp->arguments().count(), 1); - QVERIFY(reverseOp->isPointerOperator()); - QVERIFY(reverseOp->isReverseOperator()); - - normalOp = classA->findFunction(QLatin1String("operator/")); - QVERIFY(normalOp); - QCOMPARE(normalOp->arguments().count(), 1); - QVERIFY(normalOp->isPointerOperator()); - QVERIFY(!normalOp->isReverseOperator()); - -} - - - -QTEST_APPLESS_MAIN(TestReverseOperators) - diff --git a/sources/shiboken2/ApiExtractor/tests/testreverseoperators.h b/sources/shiboken2/ApiExtractor/tests/testreverseoperators.h deleted file mode 100644 index ba3b43cfb..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testreverseoperators.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTREVERSEOPERATORS_H -#define TESTREVERSEOPERATORS_H -#include <QObject> - -class TestReverseOperators : public QObject -{ - Q_OBJECT -private slots: - void testReverseSum(); - void testReverseSumWithAmbiguity(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp b/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp deleted file mode 100644 index ec3ddb8b2..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testtemplates.cpp +++ /dev/null @@ -1,644 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testtemplates.h" -#include <QtTest/QTest> -#include <QtCore/QTextStream> -#include <QTemporaryFile> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestTemplates::testTemplateWithNamespace() -{ - const char cppCode[] = R"CPP( -template<typename T> struct QList {}; -struct Url { - void name(); -}; -namespace Internet { - struct Url{}; - struct Bookmarks { - QList<Url> list(); - }; -}; -)CPP"; - - const char xmlCode0[] = R"XML( -<typesystem package='Package.Network'> - <value-type name='Url'/> -</typesystem>)XML"; - - QTemporaryFile file; - QVERIFY(file.open()); - file.write(xmlCode0); - file.close(); - - QString xmlCode1 = QString::fromLatin1(R"XML( -<typesystem package='Package.Internet'> - <load-typesystem name='%1' generate='no'/> - <container-type name='QList' type='list'/> - <namespace-type name='Internet' generate='no'> - <value-type name='Url'/> - <value-type name='Bookmarks'/> - </namespace-type> -</typesystem>)XML").arg(file.fileName()); - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, qPrintable(xmlCode1), false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - - AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("Bookmarks")); - QVERIFY(classB); - const AbstractMetaFunction* func = classB->findFunction(QLatin1String("list")); - AbstractMetaType* funcType = func->type(); - QVERIFY(funcType); - QCOMPARE(funcType->cppSignature(), QLatin1String("QList<Internet::Url >")); -} - -void TestTemplates::testTemplateOnContainers() -{ - const char cppCode[] = R"CPP( -struct Base {}; -template<typename T> struct QList {}; -namespace Namespace { - enum SomeEnum { E1, E2 }; - template<SomeEnum type> struct A { - A<type> foo(const QList<A<type> >& a); - }; - typedef A<E1> B; -} -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package="Package"> - <container-type name='QList' type='list'/> - <namespace-type name='Namespace'> - <enum-type name='SomeEnum'/> - <object-type name='A' generate='no'/> - <object-type name='B'/> - </namespace-type> - <object-type name='Base'/> -</typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - - AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classB); - QVERIFY(!classB->baseClass()); - QVERIFY(classB->baseClassName().isEmpty()); - const AbstractMetaFunction* func = classB->findFunction(QLatin1String("foo")); - AbstractMetaType* argType = func->arguments().first()->type(); - QCOMPARE(argType->instantiations().count(), 1); - QCOMPARE(argType->typeEntry()->qualifiedCppName(), QLatin1String("QList")); - - const AbstractMetaType* instance1 = argType->instantiations().first(); - QCOMPARE(instance1->instantiations().count(), 1); - QCOMPARE(instance1->typeEntry()->qualifiedCppName(), QLatin1String("Namespace::A")); - - const AbstractMetaType* instance2 = instance1->instantiations().first(); - QCOMPARE(instance2->instantiations().count(), 0); - QCOMPARE(instance2->typeEntry()->qualifiedCppName(), QLatin1String("Namespace::E1")); -} - -void TestTemplates::testTemplateValueAsArgument() -{ - const char cppCode[] = R"CPP( -template<typename T> struct List {}; -void func(List<int> arg) {} -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package='Package'> - <primitive-type name='int'/> - <container-type name='List' type='list'/> - <function signature='func(List<int>)'/> -</typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaFunctionList globalFuncs = builder->globalFunctions(); - QCOMPARE(globalFuncs.count(), 1); - - AbstractMetaFunction* func = globalFuncs.first(); - QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>)")); - QCOMPARE(func->arguments().first()->type()->cppSignature(), QLatin1String("List<int >")); -} - -void TestTemplates::testTemplatePointerAsArgument() -{ - const char cppCode[] = R"CPP( -template<typename T> struct List {}; -void func(List<int>* arg) {} -)CPP"; - - const char xmlCode[] = R"XML( - <typesystem package='Package'> - <primitive-type name='int'/> - <container-type name='List' type='list'/> - <function signature='func(List<int>*)'/> - </typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaFunctionList globalFuncs = builder->globalFunctions(); - QCOMPARE(globalFuncs.count(), 1); - - AbstractMetaFunction* func = globalFuncs.first(); - QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>*)")); - QCOMPARE(func->arguments().first()->type()->cppSignature(), QLatin1String("List<int > *")); -} - -void TestTemplates::testTemplateReferenceAsArgument() -{ - const char cppCode[] = R"CPP( -template<typename T> struct List {}; -void func(List<int>& arg) {} - )CPP"; - - const char xmlCode[] = R"XML( -<typesystem package='Package'> - <primitive-type name='int'/> - <container-type name='List' type='list'/> - <function signature='func(List<int>&)'/> -</typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaFunctionList globalFuncs = builder->globalFunctions(); - QCOMPARE(globalFuncs.count(), 1); - - AbstractMetaFunction* func = globalFuncs.first(); - QCOMPARE(func->minimalSignature(), QLatin1String("func(List<int>&)")); - QCOMPARE(func->arguments().first()->type()->cppSignature(), QLatin1String("List<int > &")); -} - -void TestTemplates::testTemplateParameterFixup() -{ - const char cppCode[] = R"CPP( -template<typename T> -struct List { - struct Iterator {}; - void append(List l); - void erase(List::Iterator it); -}; -)CPP"; - - const char xmlCode[] = R"XML( - <typesystem package='Package'> - <container-type name='List' type='list'> - <value-type name='Iterator'/> - </container-type> - </typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - const AbstractMetaClassList templates = builder->templates(); - - QCOMPARE(templates.count(), 1); - const AbstractMetaClass *list = templates.first(); - // Verify that the parameter of "void append(List l)" gets fixed to "List<T >" - const AbstractMetaFunction *append = list->findFunction(QStringLiteral("append")); - QVERIFY(append); - QCOMPARE(append->arguments().size(), 1); - QCOMPARE(append->arguments().at(0)->type()->cppSignature(), QLatin1String("List<T >")); - // Verify that the parameter of "void erase(Iterator)" is not modified - const AbstractMetaFunction *erase = list->findFunction(QStringLiteral("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")); -} - -void TestTemplates::testInheritanceFromContainterTemplate() -{ - const char cppCode[] = R"CPP( -template<typename T> -struct ListContainer { - inline void push_front(const T& t); - inline T& front(); -}; -struct FooBar {}; -struct FooBars : public ListContainer<FooBar> {}; -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package='Package'> - <container-type name='ListContainer' type='list'/> - <value-type name='FooBar'/> - <value-type name='FooBars'> - <modify-function signature='push_front(FooBar)' remove='all'/> - <modify-function signature='front()' remove='all'/> - </value-type> -</typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - AbstractMetaClassList templates = builder->templates(); - QCOMPARE(classes.count(), 2); - QCOMPARE(templates.count(), 1); - - const AbstractMetaClass* foobars = AbstractMetaClass::findClass(classes, QLatin1String("FooBars")); - QCOMPARE(foobars->functions().count(), 4); - - const AbstractMetaClass* lc = templates.first(); - QCOMPARE(lc->functions().count(), 2); -} - -void TestTemplates::testTemplateInheritanceMixedWithForwardDeclaration() -{ - const char cppCode[] = R"CPP( -enum SomeEnum { E1, E2 }; -template<SomeEnum type> struct Future; -template<SomeEnum type> -struct A { - A(); - void method(); - friend struct Future<type>; -}; -typedef A<E1> B; -template<SomeEnum type> struct Future {}; -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package='Package'> - <enum-type name='SomeEnum'/> - <value-type name='A' generate='no'/> - <value-type name='B'/> - <value-type name='Future' generate='no'/> -</typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - - AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classB); - QVERIFY(!classB->baseClass()); - QVERIFY(classB->baseClassName().isEmpty()); - // 3 functions: simple constructor, copy constructor and "method()". - QCOMPARE(classB->functions().count(), 3); -} - -void TestTemplates::testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration() -{ - const char cppCode[] = R"CPP( -namespace Namespace { -enum SomeEnum { E1, E2 }; -template<SomeEnum type> struct Future; -template<SomeEnum type> -struct A { - A(); - void method(); - friend struct Future<type>; -}; -typedef A<E1> B; -template<SomeEnum type> struct Future {}; -}; -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package='Package'> - <namespace-type name='Namespace'> - <enum-type name='SomeEnum'/> - <value-type name='A' generate='no'/> - <value-type name='B'/> - <value-type name='Future' generate='no'/> - </namespace-type> -</typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - - AbstractMetaClass* classB = AbstractMetaClass::findClass(classes, QLatin1String("Namespace::B")); - QVERIFY(classB); - QVERIFY(!classB->baseClass()); - QVERIFY(classB->baseClassName().isEmpty()); - // 3 functions: simple constructor, copy constructor and "method()". - QCOMPARE(classB->functions().count(), 3); -} - -void TestTemplates::testTypedefOfInstantiationOfTemplateClass() -{ - const char cppCode[] = R"CPP( -namespace NSpace { -enum ClassType { - TypeOne -}; -template<ClassType CLASS_TYPE> -struct BaseTemplateClass { - inline ClassType getClassType() const { CLASS_TYPE; } -}; -typedef BaseTemplateClass<TypeOne> TypeOneClass; -} -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package='Package'> - <namespace-type name='NSpace'> - <enum-type name='ClassType'/> - <object-type name='BaseTemplateClass' generate='no'/> - <object-type name='TypeOneClass'/> - </namespace-type> -</typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, false)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 3); - - const AbstractMetaClass* base = AbstractMetaClass::findClass(classes, QLatin1String("BaseTemplateClass")); - QVERIFY(base); - const AbstractMetaClass* one = AbstractMetaClass::findClass(classes, QLatin1String("TypeOneClass")); - QVERIFY(one); - QCOMPARE(one->templateBaseClass(), base); - QCOMPARE(one->functions().count(), base->functions().count()); - QVERIFY(one->isTypeDef()); - const ComplexTypeEntry* oneType = one->typeEntry(); - const ComplexTypeEntry* baseType = base->typeEntry(); - QCOMPARE(oneType->baseContainerType(), baseType); - QCOMPARE(one->baseClassNames(), QStringList(QLatin1String("BaseTemplateClass<TypeOne>"))); - - QVERIFY(one->hasTemplateBaseClassInstantiations()); - AbstractMetaTypeList instantiations = one->templateBaseClassInstantiations(); - QCOMPARE(instantiations.count(), 1); - const AbstractMetaType* inst = instantiations.first(); - QVERIFY(inst); - QVERIFY(!inst->isEnum()); - QVERIFY(!inst->typeEntry()->isEnum()); - QVERIFY(inst->typeEntry()->isEnumValue()); - QCOMPARE(inst->cppSignature(), QLatin1String("NSpace::TypeOne")); -} - -void TestTemplates::testContainerTypeIncompleteArgument() -{ - const char cppCode[] = R"CPP( -template<typename T> -class Vector { - void method(const Vector& vector); - Vector otherMethod(); -}; -template <typename T> -void Vector<T>::method(const Vector<T>& vector) {} -template <typename T> -Vector<T> Vector<T>::otherMethod() { return Vector<T>(); } -typedef Vector<int> IntVector; -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package='Foo'> - <primitive-type name='int'/> - <container-type name='Vector' type='vector'/> - <value-type name='IntVector'/> -</typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - QCOMPARE(classes.count(), 1); - - AbstractMetaClass* vector = AbstractMetaClass::findClass(classes, QLatin1String("IntVector")); - QVERIFY(vector); - auto baseContainer = vector->typeEntry()->baseContainerType(); - QVERIFY(baseContainer); - QCOMPARE(reinterpret_cast<const ContainerTypeEntry*>(baseContainer)->containerKind(), - ContainerTypeEntry::VectorContainer); - QCOMPARE(vector->functions().count(), 4); - - const AbstractMetaFunction* method = vector->findFunction(QLatin1String("method")); - QVERIFY(method); - QCOMPARE(method->signature(), QLatin1String("method(const Vector<int > & vector)")); - - const AbstractMetaFunction* otherMethod = vector->findFunction(QLatin1String("otherMethod")); - QVERIFY(otherMethod); - QCOMPARE(otherMethod->signature(), QLatin1String("otherMethod()")); - QVERIFY(otherMethod->type()); - QCOMPARE(otherMethod->type()->cppSignature(), QLatin1String("Vector<int >")); -} - -void TestTemplates::testNonTypeTemplates() -{ - // PYSIDe-1296, functions with non type templates parameters. - const char cppCode[] = R"CPP( -template <class T, int Size> -class Array { - T array[Size]; -}; - -Array<int, 2> foo(); - -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package='Foo'> - <primitive-type name='int'/> - <container-type name='Array' type='vector'/> - <function signature="foo()"/> -</typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true)); - QVERIFY(!builder.isNull()); - auto functions = builder->globalFunctions(); - QCOMPARE(functions.count(), 1); - auto foo = functions.constFirst(); - QCOMPARE(foo->name(), QLatin1String("foo")); - QCOMPARE(foo->type()->name(), QLatin1String("Array")); -} - -// Perform checks on template inheritance; a typedef of a template class -// should result in rewritten types. -void TestTemplates::testTemplateTypeDefs_data() -{ - QTest::addColumn<QString>("cpp"); - QTest::addColumn<QString>("xml"); - - const char optionalClassDef[] = R"CPP( -template<class T> // Some value type similar to std::optional -class Optional { -public: - T value() const { return m_value; } - operator bool() const { return m_success; } - - T m_value; - bool m_success = false; -}; -)CPP"; - - const char xmlPrefix[] = R"XML( -<typesystem package='Foo'> - <primitive-type name='int'/> - <primitive-type name='bool'/> -)XML"; - - const char xmlOptionalDecl[] = "<value-type name='Optional' generate='no'/>\n"; - const char xmlOptionalIntDecl[] = "<value-type name='IntOptional'/>\n"; - const char xmlPostFix[] = "</typesystem>\n"; - - // Flat, global namespace - QString cpp; - QTextStream(&cpp) << optionalClassDef - << "typedef Optional<int> IntOptional;\n"; - QString xml; - QTextStream(&xml) << xmlPrefix << xmlOptionalDecl << xmlOptionalIntDecl - << "<typedef-type name='XmlIntOptional' source='Optional<int>'/>" - << xmlPostFix; - QTest::newRow("global-namespace") - << cpp << xml; - - // Typedef from namespace Std - cpp.clear(); - QTextStream(&cpp) << "namespace Std {\n" << optionalClassDef << "}\n" - << "typedef Std::Optional<int> IntOptional;\n"; - xml.clear(); - QTextStream(&xml) << xmlPrefix - << "<namespace-type name='Std'>\n" << xmlOptionalDecl - << "</namespace-type>\n" << xmlOptionalIntDecl - << "<typedef-type name='XmlIntOptional' source='Std::Optional<int>'/>" - << xmlPostFix; - QTest::newRow("namespace-Std") - << cpp << xml; - - // Typedef from nested class - cpp.clear(); - QTextStream(&cpp) << "class Outer {\npublic:\n" << optionalClassDef << "\n};\n" - << "typedef Outer::Optional<int> IntOptional;\n"; - xml.clear(); - QTextStream(&xml) << xmlPrefix - << "<object-type name='Outer'>\n" << xmlOptionalDecl - << "</object-type>\n" << xmlOptionalIntDecl - << "<typedef-type name='XmlIntOptional' source='Outer::Optional<int>'/>" - << xmlPostFix; - QTest::newRow("nested-class") - << cpp << xml; -} - -void TestTemplates::testTemplateTypeDefs() -{ - QFETCH(QString, cpp); - QFETCH(QString, xml); - - const QByteArray cppBa = cpp.toLocal8Bit(); - const QByteArray xmlBa = xml.toLocal8Bit(); - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppBa.constData(), xmlBa.constData(), true)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - - const AbstractMetaClass *optional = AbstractMetaClass::findClass(classes, QLatin1String("Optional")); - QVERIFY(optional); - - // Find the typedef'ed class - const AbstractMetaClass *optionalInt = - AbstractMetaClass::findClass(classes, QLatin1String("IntOptional")); - QVERIFY(optionalInt); - QCOMPARE(optionalInt->templateBaseClass(), optional); - - // Find the class typedef'ed in the typesystem XML - const AbstractMetaClass *xmlOptionalInt = - AbstractMetaClass::findClass(classes, QLatin1String("XmlIntOptional")); - QVERIFY(xmlOptionalInt); - QCOMPARE(xmlOptionalInt->templateBaseClass(), optional); - - // Check whether the value() method now has an 'int' return - const AbstractMetaFunction *valueMethod = - optionalInt->findFunction(QLatin1String("value")); - QVERIFY(valueMethod); - QCOMPARE(valueMethod->type()->cppSignature(), QLatin1String("int")); - - // ditto for typesystem XML - const AbstractMetaFunction *xmlValueMethod = - xmlOptionalInt->findFunction(QLatin1String("value")); - QVERIFY(xmlValueMethod); - QCOMPARE(xmlValueMethod->type()->cppSignature(), QLatin1String("int")); - - // Check whether the m_value field is of type 'int' - const AbstractMetaField *valueField = - optionalInt->findField(QLatin1String("m_value")); - QVERIFY(valueField); - QCOMPARE(valueField->type()->cppSignature(), QLatin1String("int")); - - // ditto for typesystem XML - const AbstractMetaField *xmlValueField = - xmlOptionalInt->findField(QLatin1String("m_value")); - QVERIFY(xmlValueField); - QCOMPARE(xmlValueField->type()->cppSignature(), QLatin1String("int")); -} - -void TestTemplates::testTemplateTypeAliases() -{ - // Model Qt 6's "template<typename T> using QList = QVector<T>" - const char cppCode[] = R"CPP( -template<typename T> -class Container1 { }; - -template<typename T> -using Container2 = Container1<T>; - -class Test -{ -public: - Container2<int> m_intContainer; -}; - -class Derived : public Container2<int> -{ -public: -}; -)CPP"; - - const char xmlCode[] = R"XML( -<typesystem package='Foo'> - <primitive-type name='int'/> - <value-type name='Container1'/> - <value-type name='Derived'/> - <object-type name='Test'/> -</typesystem>)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true)); - QVERIFY(!builder.isNull()); - - AbstractMetaClassList classes = builder->classes(); - auto testClass = AbstractMetaClass::findClass(classes, QLatin1String("Test")); - QVERIFY(testClass); - - auto fields = testClass->fields(); - QCOMPARE(fields.count(), 1); - auto fieldType = testClass->fields().at(0)->type(); - QCOMPARE(fieldType->name(), QLatin1String("Container1")); - QCOMPARE(fieldType->instantiations().size(), 1); - - auto derived = AbstractMetaClass::findClass(classes, QLatin1String("Derived")); - QVERIFY(derived); - auto base = derived->templateBaseClass(); - QCOMPARE(base->name(), QLatin1String("Container1")); -} - -QTEST_APPLESS_MAIN(TestTemplates) diff --git a/sources/shiboken2/ApiExtractor/tests/testtemplates.h b/sources/shiboken2/ApiExtractor/tests/testtemplates.h deleted file mode 100644 index c96e7fe4a..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testtemplates.h +++ /dev/null @@ -1,55 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTTEMPLATES_H -#define TESTTEMPLATES_H - -#include <QObject> - -class TestTemplates : public QObject -{ - Q_OBJECT -private slots: - void testTemplateOnContainers(); - void testTemplateWithNamespace(); - void testTemplateValueAsArgument(); - void testTemplatePointerAsArgument(); - void testTemplateReferenceAsArgument(); - void testTemplateParameterFixup(); - void testInheritanceFromContainterTemplate(); - void testTemplateInheritanceMixedWithForwardDeclaration(); - void testTemplateInheritanceMixedWithNamespaceAndForwardDeclaration(); - void testTypedefOfInstantiationOfTemplateClass(); - void testContainerTypeIncompleteArgument(); - void testNonTypeTemplates(); - void testTemplateTypeDefs_data(); - void testTemplateTypeDefs(); - void testTemplateTypeAliases(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testtoposort.cpp b/sources/shiboken2/ApiExtractor/tests/testtoposort.cpp deleted file mode 100644 index c59fa8c3d..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testtoposort.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testtoposort.h" -#include <QtTest/QTest> -#include "graph.h" -#include <QDebug> - -void TestTopoSort::testTopoSort() -{ - { - Graph g(3); - g.addEdge(1, 2); - g.addEdge(0, 1); - const auto result = g.topologicalSort(); - QCOMPARE(result.size(), 3); - auto it = result.begin(); - QCOMPARE(*it, 0); - QCOMPARE(*(++it), 1); - QCOMPARE(*(++it), 2); - } - { - Graph g(2); - const auto result = g.topologicalSort(); - QCOMPARE(result.size(), 2); - auto it = result.begin(); - QCOMPARE(*it, 1); - QCOMPARE(*(++it), 0); - } -} - -void TestTopoSort::testCiclicGraph() -{ - Graph g(3); - g.addEdge(0, 1); - g.addEdge(1, 2); - g.addEdge(2, 0); - const auto result = g.topologicalSort(); - QVERIFY(result.isEmpty()); -} - -QTEST_APPLESS_MAIN(TestTopoSort) - diff --git a/sources/shiboken2/ApiExtractor/tests/testtoposort.h b/sources/shiboken2/ApiExtractor/tests/testtoposort.h deleted file mode 100644 index 0770a8d0e..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testtoposort.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTTOPOSORT_H -#define TESTTOPOSORT_H - -#include <QObject> - -class TestTopoSort : public QObject -{ -Q_OBJECT -private slots: - void testTopoSort(); - void testCiclicGraph(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp b/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp deleted file mode 100644 index 10bf35d59..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testtyperevision.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> -#include <typedatabase.h> - -void TestTypeRevision::testRevisionAttr() -{ - 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\">" - "<value-type name=\"Rev_0\"/>" - "<value-type name=\"Rev_1\" revision=\"1\"/>" - "<object-type name=\"Rev_2\" revision=\"2\">" - " <enum-type name=\"Rev_3\" revision=\"3\" flags=\"Flag_4\" flags-revision=\"4\" />" - " <enum-type name=\"Rev_5\" revision=\"5\" flags=\"Flag_5\" />" - "</object-type>" - "</typesystem>"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *rev0 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_0")); - QCOMPARE(rev0->typeEntry()->revision(), 0); - - const AbstractMetaClass *rev1 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_1")); - QCOMPARE(rev1->typeEntry()->revision(), 1); - - AbstractMetaClass *rev2 = AbstractMetaClass::findClass(classes, QLatin1String("Rev_2")); - QCOMPARE(rev2->typeEntry()->revision(), 2); - - AbstractMetaEnum* rev3 = rev2->findEnum(QLatin1String("Rev_3")); - QCOMPARE(rev3->typeEntry()->revision(), 3); - FlagsTypeEntry* rev4 = rev3->typeEntry()->flags(); - QCOMPARE(rev4->revision(), 4); - AbstractMetaEnum* rev5 = rev2->findEnum(QLatin1String("Rev_5")); - const EnumTypeEntry *revEnumTypeEntry = rev5->typeEntry(); - QCOMPARE(revEnumTypeEntry->revision(), 5); - QCOMPARE(revEnumTypeEntry->flags()->revision(), 5); -} - - -void TestTypeRevision::testVersion_data() -{ - QTest::addColumn<QString>("version"); - QTest::addColumn<int>("expectedClassCount"); - - QTest::newRow("none") << QString() << 2; - QTest::newRow("1.0") << QString::fromLatin1("1.0") << 1; // Bar20 excluded - QTest::newRow("2.0") << QString::fromLatin1("2.0") << 2; - QTest::newRow("3.0") << QString::fromLatin1("3.0") << 1; // Bar excluded by "until" -} - -void TestTypeRevision::testVersion() -{ - QFETCH(QString, version); - QFETCH(int, expectedClassCount); - - const char cppCode[] = R"CPP( -class Bar {}; -class Bar20 {}; -)CPP"; - const char xmlCode[] = R"XML( -<typesystem package="Foo"> - <value-type name="Bar" until="2.0"/> - <value-type name="Bar20" since="2.0"/> -</typesystem> -)XML"; - - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode, true, version)); - QVERIFY(!builder.isNull()); - - QCOMPARE(builder->classes().size(), expectedClassCount); -} - -QTEST_APPLESS_MAIN(TestTypeRevision) - - diff --git a/sources/shiboken2/ApiExtractor/tests/testtyperevision.h b/sources/shiboken2/ApiExtractor/tests/testtyperevision.h deleted file mode 100644 index 3832c3883..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testtyperevision.h +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTTYPEREVISION_H -#define TESTTYPEREVISION_H - -#include <QObject> - -class TestTypeRevision : public QObject -{ - Q_OBJECT - -private slots: - void testRevisionAttr(); - void testVersion_data(); - void testVersion(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testutil.h b/sources/shiboken2/ApiExtractor/tests/testutil.h deleted file mode 100644 index e24e54365..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testutil.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTUTIL_H -#define TESTUTIL_H -#include <QtCore/QBuffer> -#include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtCore/QTemporaryFile> -#include "abstractmetabuilder.h" -#include "reporthandler.h" -#include "typedatabase.h" - -namespace TestUtil -{ - static AbstractMetaBuilder *parse(const char *cppCode, const char *xmlCode, - bool silent = true, - const QString &apiVersion = QString(), - const QStringList &dropTypeEntries = QStringList()) - { - ReportHandler::setSilent(silent); - ReportHandler::startTimer(); - TypeDatabase* td = TypeDatabase::instance(true); - if (apiVersion.isEmpty()) - TypeDatabase::clearApiVersions(); - else if (!TypeDatabase::setApiVersion(QLatin1String("*"), apiVersion)) - return nullptr; - td->setDropTypeEntries(dropTypeEntries); - QBuffer buffer; - // parse typesystem - buffer.setData(xmlCode); - if (!buffer.open(QIODevice::ReadOnly)) - return Q_NULLPTR; - if (!td->parseFile(&buffer)) - return nullptr; - buffer.close(); - // parse C++ code - QTemporaryFile tempSource(QDir::tempPath() + QLatin1String("/st_XXXXXX_main.cpp")); - if (!tempSource.open()) { - qWarning().noquote().nospace() << "Creation of temporary file failed: " - << tempSource.errorString(); - return nullptr; - } - QByteArrayList arguments; - arguments.append(QFile::encodeName(tempSource.fileName())); - tempSource.write(cppCode, qint64(strlen(cppCode))); - tempSource.close(); - auto *builder = new AbstractMetaBuilder; - if (!builder->build(arguments)) { - delete builder; - return Q_NULLPTR; - } - return builder; - } -} // namespace TestUtil - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.cpp b/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.cpp deleted file mode 100644 index 1850025d6..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testvaluetypedefaultctortag.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestValueTypeDefaultCtorTag::testValueTypeDefaultCtorTagArgument() -{ - const char* cppCode ="\n\ - struct A {\n\ - A(int,int);\n\ - };\n\ - struct B {};\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()); - - AbstractMetaClassList classes = builder->classes(); - - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - QVERIFY(classA->typeEntry()->hasDefaultConstructor()); - QCOMPARE(classA->typeEntry()->defaultConstructor(), QLatin1String("A(0, 0)")); - - const AbstractMetaClass *classB = AbstractMetaClass::findClass(classes, QLatin1String("B")); - QVERIFY(classB); - QVERIFY(!classB->typeEntry()->hasDefaultConstructor()); -} - -QTEST_APPLESS_MAIN(TestValueTypeDefaultCtorTag) diff --git a/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.h b/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.h deleted file mode 100644 index 244181707..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.h +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTVALUETYPEDEFAULTCTORTAG_H -#define TESTVALUETYPEDEFAULTCTORTAG_H - -#include <QObject> - -class TestValueTypeDefaultCtorTag : public QObject -{ - Q_OBJECT - private slots: - void testValueTypeDefaultCtorTagArgument(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/testvoidarg.cpp b/sources/shiboken2/ApiExtractor/tests/testvoidarg.cpp deleted file mode 100644 index 68681550f..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testvoidarg.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 "testvoidarg.h" -#include <QtTest/QTest> -#include "testutil.h" -#include <abstractmetalang.h> -#include <typesystem.h> - -void TestVoidArg::testVoidParsedFunction() -{ - const char cppCode[] = "struct A { void a(void); };"; - const char xmlCode[] = "\n\ - <typesystem package=\"Foo\">\n\ - <value-type name='A'/>\n\ - </typesystem>"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("a")); - QCOMPARE(addedFunc->arguments().count(), 0); -} - -void TestVoidArg::testVoidAddedFunction() -{ - const char cppCode[] = "struct A { };"; - const char xmlCode[] = "\n\ - <typesystem package=\"Foo\">\n\ - <value-type name='A' >\n\ - <add-function signature=\"a(void)\"/>\n\ - </value-type>\n\ - </typesystem>"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("a")); - QCOMPARE(addedFunc->arguments().count(), 0); - -} - -void TestVoidArg::testVoidPointerParsedFunction() -{ - const char cppCode[] = "struct A { void a(void*); };"; - const char xmlCode[] = "\n\ - <typesystem package=\"Foo\">\n\ - <value-type name='A' />\n\ - </typesystem>"; - QScopedPointer<AbstractMetaBuilder> builder(TestUtil::parse(cppCode, xmlCode)); - QVERIFY(!builder.isNull()); - AbstractMetaClassList classes = builder->classes(); - const AbstractMetaClass *classA = AbstractMetaClass::findClass(classes, QLatin1String("A")); - QVERIFY(classA); - const AbstractMetaFunction* addedFunc = classA->findFunction(QLatin1String("a")); - QCOMPARE(addedFunc->arguments().count(), 1); - -} - -QTEST_APPLESS_MAIN(TestVoidArg) diff --git a/sources/shiboken2/ApiExtractor/tests/testvoidarg.h b/sources/shiboken2/ApiExtractor/tests/testvoidarg.h deleted file mode 100644 index 44d90d075..000000000 --- a/sources/shiboken2/ApiExtractor/tests/testvoidarg.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the test suite of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** 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 TESTVOIDARG_H -#define TESTVOIDARG_H -#include <QObject> - -class TestVoidArg : public QObject -{ - Q_OBJECT -private slots: - void testVoidParsedFunction(); - void testVoidPointerParsedFunction(); - void testVoidAddedFunction(); -}; - -#endif diff --git a/sources/shiboken2/ApiExtractor/tests/utf8code.txt b/sources/shiboken2/ApiExtractor/tests/utf8code.txt deleted file mode 100644 index 6d5fa9dcf..000000000 --- a/sources/shiboken2/ApiExtractor/tests/utf8code.txt +++ /dev/null @@ -1 +0,0 @@ -áéÃóú
\ No newline at end of file diff --git a/sources/shiboken2/ApiExtractor/typedatabase.cpp b/sources/shiboken2/ApiExtractor/typedatabase.cpp deleted file mode 100644 index 0cfde1c66..000000000 --- a/sources/shiboken2/ApiExtractor/typedatabase.cpp +++ /dev/null @@ -1,1047 +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$ -** -****************************************************************************/ - -#include "typedatabase.h" -#include "typesystem.h" -#include "typesystemparser.h" - -#include <QtCore/QFile> -#include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtCore/QPair> -#include <QtCore/QVector> -#include <QtCore/QRegularExpression> -#include <QtCore/QVersionNumber> -#include <QtCore/QXmlStreamReader> -#include "reporthandler.h" -// #include <tr1/tuple> -#include <algorithm> - -// package -> api-version - -static QString wildcardToRegExp(QString w) -{ - w.replace(QLatin1Char('?'), QLatin1Char('.')); - w.replace(QLatin1Char('*'), QStringLiteral(".*")); - return w; -} - -using ApiVersion =QPair<QRegularExpression, QVersionNumber>; -using ApiVersions = QVector<ApiVersion>; - -Q_GLOBAL_STATIC(ApiVersions, apiVersions) - -TypeDatabase::TypeDatabase() -{ - addType(new VoidTypeEntry()); - addType(new VarargsTypeEntry()); -} - -TypeDatabase::~TypeDatabase() = default; - -TypeDatabase* TypeDatabase::instance(bool newInstance) -{ - static TypeDatabase *db = nullptr; - if (!db || newInstance) { - delete db; - db = new TypeDatabase; - } - return db; -} - -// A list of regex/replacements to fix int types like "ushort" to "unsigned short" -// unless present in TypeDatabase -struct IntTypeNormalizationEntry -{ - QRegularExpression regex; - QString replacement; -}; - -using IntTypeNormalizationEntries = QVector<IntTypeNormalizationEntry>; - -static const IntTypeNormalizationEntries &intTypeNormalizationEntries() -{ - static IntTypeNormalizationEntries result; - 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)) { - IntTypeNormalizationEntry entry; - entry.replacement = QStringLiteral("unsigned ") + intType; - entry.regex.setPattern(QStringLiteral("\\bu") + intType + QStringLiteral("\\b")); - Q_ASSERT(entry.regex.isValid()); - result.append(entry); - } - } - } - return result; -} - -QString TypeDatabase::normalizedSignature(const QString &signature) -{ - QString normalized = QLatin1String(QMetaObject::normalizedSignature(signature.toUtf8().constData())); - - if (instance() && signature.contains(QLatin1String("unsigned"))) { - const IntTypeNormalizationEntries &entries = intTypeNormalizationEntries(); - for (const auto &entry : entries) - normalized.replace(entry.regex, entry.replacement); - } - - return normalized; -} - -QStringList TypeDatabase::requiredTargetImports() const -{ - return 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)); -} - -IncludeList TypeDatabase::extraIncludes(const QString& className) const -{ - ComplexTypeEntry* typeEntry = findComplexType(className); - return typeEntry ? typeEntry->extraIncludes() : IncludeList(); -} - -void TypeDatabase::addSystemInclude(const QString &name) -{ - m_systemIncludes.append(name.toUtf8()); -} - -// 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) -{ - QVector<TypeEntry *> additionalEntries; // Store before modifying the hash - for (TypeEntry *entry : m_entries) { - if (entry->isChildOf(n)) - additionalEntries.append(entry); - } - for (const auto &ae : additionalEntries) - m_entries.insert(ae->shortName(), ae); -} - -ContainerTypeEntry* TypeDatabase::findContainerType(const QString &name) const -{ - QString template_name = name; - - int pos = name.indexOf(QLatin1Char('<')); - if (pos > 0) - template_name = name.left(pos); - - TypeEntry* type_entry = findType(template_name); - if (type_entry && type_entry->isContainer()) - return static_cast<ContainerTypeEntry*>(type_entry); - return nullptr; -} - -static bool inline useType(const TypeEntry *t) -{ - return !t->isPrimitive() - || static_cast<const PrimitiveTypeEntry *>(t)->preferredTargetLangType(); -} - -FunctionTypeEntry* TypeDatabase::findFunctionType(const QString& name) const -{ - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (entry->type() == TypeEntry::FunctionType && useType(entry)) - return static_cast<FunctionTypeEntry*>(entry); - } - return nullptr; -} - -void TypeDatabase::addTypeSystemType(const TypeSystemTypeEntry *e) -{ - m_typeSystemEntries.append(e); -} - -const TypeSystemTypeEntry *TypeDatabase::findTypeSystemType(const QString &name) const -{ - for (auto entry : m_typeSystemEntries) { - if (entry->name() == name) - return entry; - } - return nullptr; -} - -const TypeSystemTypeEntry *TypeDatabase::defaultTypeSystemType() const -{ - return m_typeSystemEntries.value(0, nullptr); -} - -QString TypeDatabase::defaultPackageName() const -{ - Q_ASSERT(!m_typeSystemEntries.isEmpty()); - return m_typeSystemEntries.constFirst()->name(); -} - -TypeEntry* TypeDatabase::findType(const QString& name) const -{ - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (useType(entry)) - return entry; - } - return nullptr; -} - -template <class Predicate> -TypeEntries TypeDatabase::findTypesHelper(const QString &name, Predicate pred) const -{ - TypeEntries result; - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (pred(entry)) - result.append(entry); - } - return result; -} - -TypeEntries TypeDatabase::findTypes(const QString &name) const -{ - return findTypesHelper(name, useType); -} - -static bool useCppType(const TypeEntry *t) -{ - bool result = false; - switch (t->type()) { - case TypeEntry::PrimitiveType: - case TypeEntry::VoidType: - case TypeEntry::FlagsType: - case TypeEntry::EnumType: - case TypeEntry::TemplateArgumentType: - case TypeEntry::BasicValueType: - case TypeEntry::ContainerType: - case TypeEntry::ObjectType: - case TypeEntry::ArrayType: - case TypeEntry::CustomType: - case TypeEntry::SmartPointerType: - case TypeEntry::TypedefType: - result = useType(t); - break; - default: - break; - } - return result; -} - -TypeEntries TypeDatabase::findCppTypes(const QString &name) const -{ - return findTypesHelper(name, useCppType); -} - -TypeEntryMultiMapConstIteratorRange TypeDatabase::findTypeRange(const QString &name) const -{ - const auto range = m_entries.equal_range(name); - return {range.first, range.second}; -} - -PrimitiveTypeEntryList 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; -} - -ContainerTypeEntryList 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; -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const TypeRejection &r) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "TypeRejection(type=" << r.matchType << ", class=" - << r.className.pattern() << ", pattern=" << r.pattern.pattern() << ')'; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -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; - case TypeRejection::Invalid: - break; - } - return result; -} - -// Match class name only -bool TypeDatabase::isClassRejected(const QString& className, QString *reason) const -{ - for (const TypeRejection& r : m_rejections) { - if (r.matchType == TypeRejection::ExcludeClass && r.className.match(className).hasMatch()) { - if (reason) - *reason = msgRejectReason(r); - return true; - } - } - return false; -} - -// Match class name and function/enum/field -static bool findRejection(const QVector<TypeRejection> &rejections, - TypeRejection::MatchType matchType, - const QString& className, const QString& name, - QString *reason = nullptr) -{ - Q_ASSERT(matchType != TypeRejection::ExcludeClass); - for (const TypeRejection& r : rejections) { - if (r.matchType == matchType && r.pattern.match(name).hasMatch() - && r.className.match(className).hasMatch()) { - if (reason) - *reason = msgRejectReason(r, name); - return true; - } - } - return false; -} - -bool TypeDatabase::isEnumRejected(const QString& className, const QString& enumName, QString *reason) const -{ - return findRejection(m_rejections, TypeRejection::Enum, className, enumName, reason); -} - -TypeEntry *TypeDatabase::resolveTypeDefEntry(TypedefEntry *typedefEntry, - QString *errorMessage) -{ - QString sourceName = typedefEntry->sourceType(); - const int lessThanPos = sourceName.indexOf(QLatin1Char('<')); - if (lessThanPos != -1) - sourceName.truncate(lessThanPos); - ComplexTypeEntry *source = nullptr; - for (TypeEntry *e : findTypeRange(sourceName)) { - switch (e->type()) { - case TypeEntry::BasicValueType: - case TypeEntry::ContainerType: - case TypeEntry::ObjectType: - case TypeEntry::SmartPointerType: - source = dynamic_cast<ComplexTypeEntry *>(e); - Q_ASSERT(source); - break; - default: - break; - } - } - if (!source) { - if (errorMessage) - *errorMessage = QLatin1String("Unable to resolve typedef \"") - + typedefEntry->sourceType() + QLatin1Char('"'); - return nullptr; - } - - auto *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) -{ - if (e->type() == TypeEntry::TypedefType) { - e = resolveTypeDefEntry(static_cast<TypedefEntry *>(e), errorMessage); - if (Q_UNLIKELY(!e)) - return false; - } - m_entries.insert(e->qualifiedCppName(), e); - return true; -} - -// Add a dummy value entry for non-type template parameters -ConstantValueTypeEntry * - TypeDatabase::addConstantValueTypeEntry(const QString &value, - const TypeEntry *parent) -{ - auto result = new ConstantValueTypeEntry(value, parent); - result->setCodeGeneration(0); - addType(result); - return result; -} - -bool TypeDatabase::isFunctionRejected(const QString& className, const QString& functionName, - QString *reason) const -{ - return findRejection(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); -} - -bool TypeDatabase::isArgumentTypeRejected(const QString& className, const QString& typeName, - QString *reason) const -{ - return findRejection(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); -} - -FlagsTypeEntry* TypeDatabase::findFlagsType(const QString &name) const -{ - TypeEntry *fte = findType(name); - if (!fte) { - fte = 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) { - if (it.key().endsWith(name)) { - fte = it.value(); - break; - } - } - } - } - return static_cast<FlagsTypeEntry *>(fte); -} - -void TypeDatabase::addFlagsType(FlagsTypeEntry *fte) -{ - m_flagsEntries[fte->originalName()] = fte; -} - -void TypeDatabase::addTemplate(TemplateEntry *t) -{ - m_templates[t->name()] = t; -} - -void TypeDatabase::addGlobalUserFunctions(const AddedFunctionList &functions) -{ - m_globalUserFunctions << functions; -} - -AddedFunctionList TypeDatabase::findGlobalUserFunctions(const QString& name) const -{ - AddedFunctionList addedFunctions; - for (const AddedFunctionPtr &func : m_globalUserFunctions) { - if (func->name() == name) - addedFunctions.append(func); - } - return addedFunctions; -} - -void TypeDatabase::addGlobalUserFunctionModifications(const FunctionModificationList &functionModifications) -{ - m_functionMods << functionModifications; -} - -QString TypeDatabase::globalNamespaceClassName(const TypeEntry * /*entry*/) -{ - return QLatin1String("Global"); -} - -FunctionModificationList TypeDatabase::functionModifications(const QString& signature) const -{ - FunctionModificationList lst; - for (int i = 0; i < m_functionMods.count(); ++i) { - const FunctionModification& mod = m_functionMods.at(i); - if (mod.matches(signature)) - lst << mod; - } - - return lst; -} - -bool TypeDatabase::addSuppressedWarning(const QString &warning, QString *errorMessage) -{ - QString pattern; - if (warning.startsWith(QLatin1Char('^')) && warning.endsWith(QLatin1Char('$'))) { - pattern = warning; - } else { - // Legacy syntax: Use wildcards '*' (unless escaped by '\') - QVector<int> asteriskPositions; - const int warningSize = warning.size(); - for (int i = 0; i < warningSize; ++i) { - if (warning.at(i) == QLatin1Char('\\')) - ++i; - else if (warning.at(i) == QLatin1Char('*')) - asteriskPositions.append(i); - } - asteriskPositions.append(warningSize); - - pattern.append(QLatin1Char('^')); - int lastPos = 0; - for (int a = 0, aSize = asteriskPositions.size(); a < aSize; ++a) { - if (a) - pattern.append(QStringLiteral(".*")); - const int nextPos = asteriskPositions.at(a); - if (nextPos > lastPos) - pattern.append(QRegularExpression::escape(warning.mid(lastPos, nextPos - lastPos))); - lastPos = nextPos + 1; - } - pattern.append(QLatin1Char('$')); - } - - QRegularExpression expression(pattern); - if (!expression.isValid()) { - *errorMessage = QLatin1String("Invalid message pattern \"") + warning - + QLatin1String("\": ") + expression.errorString(); - return false; - } - expression.setPatternOptions(expression.patternOptions() | QRegularExpression::MultilineOption); - - m_suppressedWarnings.append(expression); - return true; -} - -template <class String> // QString, QStringRef -bool TypeDatabase::isSuppressedWarningHelper(const String &s) const -{ - if (!m_suppressWarnings) - return false; - return std::any_of(m_suppressedWarnings.cbegin(), m_suppressedWarnings.end(), - [&s] (const QRegularExpression &e) { - return e.match(s).hasMatch(); - }); -} - -bool TypeDatabase::isSuppressedWarning(const QString &s) const -{ - return isSuppressedWarningHelper(s); -} - -bool TypeDatabase::isSuppressedWarning(const QStringRef &s) const -{ - return isSuppressedWarningHelper(s); -} - -QString TypeDatabase::modifiedTypesystemFilepath(const QString& tsFile, const QString ¤tPath) 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); - if (fi.isFile()) - return fi.absoluteFilePath(); - } - for (const QString &path : m_typesystemPaths) { - const QFileInfo fi(path + QLatin1Char('/') + tsFile); - if (fi.isFile()) - return fi.absoluteFilePath(); - } - return tsFile; -} - -bool TypeDatabase::parseFile(const QString &filename, bool generate) -{ - return parseFile(filename, QString(), generate); -} - -bool TypeDatabase::parseFile(const QString &filename, const QString ¤tPath, bool generate) -{ - - QString filepath = modifiedTypesystemFilepath(filename, currentPath); - if (m_parsedTypesystemFiles.contains(filepath)) - return m_parsedTypesystemFiles[filepath]; - - m_parsedTypesystemFiles[filepath] = true; // Prevent recursion when including self. - - QFile file(filepath); - if (!file.exists()) { - m_parsedTypesystemFiles[filepath] = false; - QString message = QLatin1String("Can't find ") + filename; - if (!currentPath.isEmpty()) - message += QLatin1String(", current path: ") + currentPath; - message += QLatin1String(", typesystem paths: ") + m_typesystemPaths.join(QLatin1String(", ")); - qCWarning(lcShiboken).noquote().nospace() << 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(); - return false; - } - - bool ok = parseFile(&file, generate); - m_parsedTypesystemFiles[filepath] = ok; - return ok; -} - -bool TypeDatabase::parseFile(QIODevice* device, bool generate) -{ - QXmlStreamReader reader(device); - TypeSystemParser handler(this, generate); - const bool result = handler.parse(reader); - if (!result) - qCWarning(lcShiboken, "%s", qPrintable(handler.errorString())); - return result; -} - -PrimitiveTypeEntry *TypeDatabase::findPrimitiveType(const QString& name) const -{ - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (entry->isPrimitive()) { - auto *pe = static_cast<PrimitiveTypeEntry *>(entry); - if (pe->preferredTargetLangType()) - return pe; - } - } - - return nullptr; -} - -ComplexTypeEntry* TypeDatabase::findComplexType(const QString& name) const -{ - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (entry->isComplex() && useType(entry)) - return static_cast<ComplexTypeEntry*>(entry); - } - return nullptr; -} - -ObjectTypeEntry* TypeDatabase::findObjectType(const QString& name) const -{ - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (entry && entry->isObject() && useType(entry)) - return static_cast<ObjectTypeEntry*>(entry); - } - return nullptr; -} - -NamespaceTypeEntryList TypeDatabase::findNamespaceTypes(const QString& name) const -{ - NamespaceTypeEntryList result; - const auto entries = findTypeRange(name); - for (TypeEntry *entry : entries) { - if (entry->isNamespace()) - result.append(static_cast<NamespaceTypeEntry*>(entry)); - } - return result; -} - -NamespaceTypeEntry *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) { - if (entry->hasPattern() && entry->matchesFile(fileName)) - return entry; - } - } - for (NamespaceTypeEntry *entry : entries) { - if (!entry->hasPattern()) - return entry; - } - return nullptr; -} - -bool TypeDatabase::shouldDropTypeEntry(const QString& fullTypeName) const -{ - return m_dropTypeEntries.contains(fullTypeName); -} - -void TypeDatabase::setDropTypeEntries(QStringList dropTypeEntries) -{ - m_dropTypeEntries = dropTypeEntries; - m_dropTypeEntries.sort(); -} - -static bool computeTypeIndexes = true; -static int maxTypeIndex; - -static bool typeEntryLessThan(const TypeEntry* t1, const TypeEntry* t2) -{ - if (t1->revision() < t2->revision()) - return true; - return t1->revision() == t2->revision() - && t1->qualifiedCppName() < t2->qualifiedCppName(); -} - -static void _computeTypeIndexes() -{ - TypeDatabase* tdb = TypeDatabase::instance(); - - TypeEntryList list; - - // Group type entries by revision numbers - const auto &allEntries = tdb->entries(); - list.reserve(allEntries.size()); - for (auto tit = allEntries.cbegin(), end = allEntries.cend(); tit != end; ++tit) { - TypeEntry *entry = tit.value(); - if (entry->isPrimitive() - || entry->isContainer() - || entry->isFunction() - || !entry->generateCode() - || entry->isEnumValue() - || entry->isVarargs() - || entry->isTypeSystem() - || entry->isVoid() - || entry->isCustom()) - continue; - if (!list.contains(entry)) // Remove duplicates - list.append(entry); - } - - // Sort the type entries by revision, name - std::sort(list.begin(), list.end(), typeEntryLessThan); - - maxTypeIndex = 0; - for (TypeEntry *e : qAsConst(list)) - e->setSbkIndex(maxTypeIndex++); - computeTypeIndexes = false; -} - -// Build the C++ name excluding any inline namespaces -// ("std::__1::shared_ptr" -> "std::shared_ptr" -QString TypeEntry::shortName() const -{ - if (m_cachedShortName.isEmpty()) { - QVarLengthArray<const TypeEntry *> 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()) { - foundInlineNamespace = true; - } else { - parents.append(p); - } - } - if (foundInlineNamespace) { - m_cachedShortName.reserve(m_name.size()); - for (int i = parents.size() - 1; i >= 0; --i) { - m_cachedShortName.append(parents.at(i)->entryName()); - m_cachedShortName.append(QLatin1String("::")); - } - m_cachedShortName.append(m_entryName); - } else { - m_cachedShortName = m_name; - } - } - return m_cachedShortName; -} - -void TypeEntry::setRevision(int r) -{ - if (m_revision != r) { - m_revision = r; - computeTypeIndexes = true; - } -} - -int TypeEntry::sbkIndex() const -{ - if (computeTypeIndexes) - _computeTypeIndexes(); - return m_sbkIndex; -} - -int getMaxTypeIndex() -{ - if (computeTypeIndexes) - _computeTypeIndexes(); - return maxTypeIndex; -} - -void TypeDatabase::clearApiVersions() -{ - apiVersions()->clear(); -} - -bool TypeDatabase::setApiVersion(const QString& packageWildcardPattern, const QString &version) -{ - const QString packagePattern = wildcardToRegExp(packageWildcardPattern.trimmed()); - const QVersionNumber versionNumber = QVersionNumber::fromString(version); - if (versionNumber.isNull()) - return false; - ApiVersions &versions = *apiVersions(); - for (int i = 0, size = versions.size(); i < size; ++i) { - if (versions.at(i).first.pattern() == packagePattern) { - versions[i].second = versionNumber; - return true; - } - } - const QRegularExpression packageRegex(packagePattern); - if (!packageRegex.isValid()) - return false; - versions.append(qMakePair(packageRegex, versionNumber)); - return true; -} - -bool TypeDatabase::checkApiVersion(const QString &package, - const VersionRange &vr) -{ - const ApiVersions &versions = *apiVersions(); - if (versions.isEmpty()) // Nothing specified: use latest. - return true; - for (int 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; - } - return false; -} - -#ifndef QT_NO_DEBUG_STREAM - -#define FORMAT_BOOL(name, var) \ - if (var) \ - d << ", [" << name << ']'; - -#define FORMAT_NONEMPTY_STRING(name, var) \ - if (!var.isEmpty()) \ - d << ", " << name << "=\"" << var << '"'; - -#define FORMAT_LIST_SIZE(name, var) \ - if (!var.isEmpty()) \ - d << ", " << 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 &d) const -{ - const QString cppName = qualifiedCppName(); - d << '"' << m_name << '"'; - if (m_name != cppName) - d << "\", cppName=\"" << cppName << '"'; - d << ", type=" << m_type << ", codeGeneration=0x" - << Qt::hex << m_codeGeneration << Qt::dec - << ", target=\"" << targetLangName() << '"'; - FORMAT_NONEMPTY_STRING("package", m_targetLangPackage) - FORMAT_BOOL("stream", m_stream) - FORMAT_LIST_SIZE("codeSnips", m_codeSnips) - FORMAT_NONEMPTY_STRING("conversionRule", m_conversionRule) - if (!m_version.isNull() && m_version > QVersionNumber(0, 0)) - d << ", version=" << m_version; - if (m_revision) - d << ", revision=" << m_revision; - if (m_sbkIndex) - d << ", sbkIndex=" << m_sbkIndex; - if (m_include.isValid()) - d << ", include=" << m_include; - formatList(d, "extraIncludes", m_extraIncludes, ", "); -} - -void ComplexTypeEntry::formatDebug(QDebug &d) const -{ - TypeEntry::formatDebug(d); - FORMAT_BOOL("polymorphicBase", m_polymorphicBase) - FORMAT_BOOL("genericClass", m_genericClass) - FORMAT_BOOL("deleteInMainThread", m_deleteInMainThread) - if (m_typeFlags != 0) - d << ", typeFlags=" << m_typeFlags; - d << ", copyableFlag=" << m_copyableFlag - << ", except=" << int(m_exceptionHandling); - FORMAT_NONEMPTY_STRING("defaultSuperclass", m_defaultSuperclass) - FORMAT_NONEMPTY_STRING("polymorphicIdValue", m_polymorphicIdValue) - FORMAT_NONEMPTY_STRING("targetType", m_targetType) - FORMAT_NONEMPTY_STRING("hash", m_hashFunction) - FORMAT_LIST_SIZE("addedFunctions", m_addedFunctions) - formatList(d, "functionMods", m_functionMods, ", "); - FORMAT_LIST_SIZE("fieldMods", m_fieldMods) -} - -void TypedefEntry::formatDebug(QDebug &d) const -{ - ComplexTypeEntry::formatDebug(d); - d << ", sourceType=\"" << m_sourceType << '"' - << ", source=" << m_source << ", target=" << m_target; -} - -void EnumTypeEntry::formatDebug(QDebug &d) const -{ - TypeEntry::formatDebug(d); - if (m_flags) - d << ", flags=(" << m_flags << ')'; -} - -void NamespaceTypeEntry::formatDebug(QDebug &d) const -{ - ComplexTypeEntry::formatDebug(d); - auto pattern = m_filePattern.pattern(); - FORMAT_NONEMPTY_STRING("pattern", pattern) - d << ",visibility=" << m_visibility; - if (m_inlineNamespace) - d << "[inline]"; -} - -void ContainerTypeEntry::formatDebug(QDebug &d) const -{ - ComplexTypeEntry::formatDebug(d); - d << ", type=" << m_containerKind << ",\"" << typeName() << '"'; -} - -void SmartPointerTypeEntry::formatDebug(QDebug &d) const -{ - ComplexTypeEntry::formatDebug(d); - if (!m_instantiations.isEmpty()) { - d << ", instantiations[" << m_instantiations.size() << "]=("; - for (auto i : m_instantiations) - d << i->name() << ','; - d << ')'; - } -} - -QDebug operator<<(QDebug d, const TypeEntry *te) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "TypeEntry("; - if (te) - te->formatDebug(d); - else - d << '0'; - d << ')'; - return d; -} - -QDebug operator<<(QDebug d, const TemplateEntry *te) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "TemplateEntry("; - if (te) { - d << '"' << te->name() << '"'; - } else { - d << '0'; - } - d << ')'; - return d; -} - -void TypeDatabase::formatDebug(QDebug &d) const -{ - d << "TypeDatabase(" - << "entries[" << m_entries.size() << "]="; - for (auto it = m_entries.cbegin(), end = m_entries.cend(); it != end; ++it) - d << " " << it.value() << '\n'; - if (!m_templates.isEmpty()) { - d << "templates[" << m_templates.size() << "]=("; - const auto begin = m_templates.cbegin(); - for (auto it = begin, end = m_templates.cend(); it != end; ++it) { - if (it != begin) - d << ", "; - d << it.value(); - } - d << ")\n"; - } - if (!m_flagsEntries.isEmpty()) { - d << "flags[" << m_flagsEntries.size() << "]=("; - const auto begin = m_flagsEntries.cbegin(); - for (auto it = begin, end = m_flagsEntries.cend(); it != end; ++it) { - if (it != begin) - d << ", "; - d << it.value(); - } - d << ")\n"; - } - d <<"\nglobalUserFunctions=" << m_globalUserFunctions << '\n'; - formatList(d, "globalFunctionMods", m_functionMods, '\n'); - d << ')'; -} - -QDebug operator<<(QDebug d, const TypeDatabase &db) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - db.formatDebug(d); - return d; -} -#endif // !QT_NO_DEBUG_STREAM diff --git a/sources/shiboken2/ApiExtractor/typedatabase.h b/sources/shiboken2/ApiExtractor/typedatabase.h deleted file mode 100644 index 7981febf3..000000000 --- a/sources/shiboken2/ApiExtractor/typedatabase.h +++ /dev/null @@ -1,225 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TYPEDATABASE_H -#define TYPEDATABASE_H - -#include "apiextractormacros.h" -#include "include.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) - -class ComplexTypeEntry; -class ContainerTypeEntry; -class FlagsTypeEntry; -class FunctionTypeEntry; -class NamespaceTypeEntry; -class ObjectTypeEntry; -class TemplateEntry; -class TypeEntry; - -struct TypeRejection; - -QT_FORWARD_DECLARE_CLASS(QDebug) - -int getMaxTypeIndex(); - -class ContainerTypeEntry; -class PrimitiveTypeEntry; -class TypeSystemTypeEntry; - -struct VersionRange -{ - bool isNull() const - { - return since.majorVersion() == 0 && since.minorVersion() == 0 - && until.majorVersion() == 9999 && until.minorVersion() == 9999; - } - - QVersionNumber since{0, 0}; - QVersionNumber until{9999, 9999}; -}; - -class TypeDatabase -{ - TypeDatabase(); - Q_DISABLE_COPY(TypeDatabase) -public: - ~TypeDatabase(); - - /** - * Return the type system instance. - * \param newInstance This parameter is useful just for unit testing, because singletons causes - * too many side effects on unit testing. - */ - static TypeDatabase *instance(bool newInstance = false); - - static QString normalizedSignature(const QString &signature); - - QStringList requiredTargetImports() const; - - void addRequiredTargetImport(const QString &moduleName); - - void addTypesystemPath(const QString &typesystem_paths); - - IncludeList extraIncludes(const QString &className) const; - - const QByteArrayList &systemIncludes() const { return m_systemIncludes; } - void addSystemInclude(const QString &name); - - void addInlineNamespaceLookups(const NamespaceTypeEntry *n); - - PrimitiveTypeEntry *findPrimitiveType(const QString &name) const; - ComplexTypeEntry *findComplexType(const QString &name) const; - ObjectTypeEntry *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; - QString defaultPackageName() const; - - TypeEntry *findType(const QString &name) const; - TypeEntries findTypes(const QString &name) const; - TypeEntries findCppTypes(const QString &name) const; - - const TypeEntryMultiMap &entries() const { return m_entries; } - const TypedefEntryMap &typedefEntries() const { return m_typedefEntries; } - - PrimitiveTypeEntryList primitiveTypes() const; - - ContainerTypeEntryList containerTypes() const; - - void addRejection(const TypeRejection &); - bool isClassRejected(const QString &className, QString *reason = nullptr) const; - bool isFunctionRejected(const QString &className, const QString &functionName, - QString *reason = nullptr) const; - bool isFieldRejected(const QString &className, const QString &fieldName, - QString *reason = nullptr) const; - bool isEnumRejected(const QString &className, const QString &enumName, - QString *reason = nullptr) const; - bool isArgumentTypeRejected(const QString &className, const QString &typeName, - QString *reason = nullptr) const; - 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); - - FlagsTypeEntry *findFlagsType(const QString &name) const; - void addFlagsType(FlagsTypeEntry *fte); - - TemplateEntry *findTemplate(const QString &name) const { return m_templates[name]; } - - void addTemplate(TemplateEntry *t); - - AddedFunctionList globalUserFunctions() const { return m_globalUserFunctions; } - - void addGlobalUserFunctions(const AddedFunctionList &functions); - - AddedFunctionList findGlobalUserFunctions(const QString &name) const; - - void addGlobalUserFunctionModifications(const FunctionModificationList &functionModifications); - - FunctionModificationList functionModifications(const QString &signature) const; - - void setSuppressWarnings(bool on) { m_suppressWarnings = on; } - - bool addSuppressedWarning(const QString &warning, QString *errorMessage); - - bool isSuppressedWarning(const QString &s) const; - bool isSuppressedWarning(const QStringRef &s) const; - - static QString globalNamespaceClassName(const TypeEntry *te); - - bool parseFile(const QString &filename, bool generate = true); - bool parseFile(const QString &filename, const QString ¤tPath, bool generate); - - bool parseFile(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 shouldDropTypeEntry(const QString &fullTypeName) const; - - void setDropTypeEntries(QStringList dropTypeEntries); - - QString modifiedTypesystemFilepath(const QString &tsFile, const QString ¤tPath = QString()) const; - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const; -#endif -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; - QVector<QRegularExpression> m_suppressedWarnings; - QVector<const TypeSystemTypeEntry *> m_typeSystemEntries; // maintain order, default is first. - - AddedFunctionList m_globalUserFunctions; - FunctionModificationList m_functionMods; - - QStringList m_requiredTargetImports; - - QStringList m_typesystemPaths; - QHash<QString, bool> m_parsedTypesystemFiles; - - QVector<TypeRejection> m_rejections; - - QStringList m_dropTypeEntries; - QByteArrayList m_systemIncludes; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const TypeEntry *te); -QDebug operator<<(QDebug d, const TypeDatabase &db); -#endif -#endif // TYPEDATABASE_H diff --git a/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h b/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h deleted file mode 100644 index f9e6c669e..000000000 --- a/sources/shiboken2/ApiExtractor/typedatabase_typedefs.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef TYPEDATABASE_TYPEDEFS_H -#define TYPEDATABASE_TYPEDEFS_H - -#include <QtCore/QMultiMap> -#include <QtCore/QString> -#include <QtCore/QVector> - -class ConstantValueTypeEntry; -class ContainerTypeEntry; -class NamespaceTypeEntry; -class PrimitiveTypeEntry; -class TemplateEntry; -class TypeEntry; -class TypedefEntry; - -using TypeEntryList = QVector<TypeEntry *>; -using TemplateEntryMap =QMap<QString, TemplateEntry *>; - -template <class Key, class Value> -struct QMultiMapConstIteratorRange // A range of iterator for a range-based for loop -{ - using ConstIterator = typename QMultiMap<Key, Value>::const_iterator; - - ConstIterator begin() const { return m_begin; } - ConstIterator end() const { return m_end; } - - ConstIterator m_begin; - ConstIterator m_end; -}; - -using TypeEntryMultiMap = QMultiMap<QString, TypeEntry *>; -using TypeEntryMultiMapConstIteratorRange = QMultiMapConstIteratorRange<QString, TypeEntry *>; - -using TypeEntryMap = QMap<QString, TypeEntry *>; -using TypedefEntryMap = QMap<QString, TypedefEntry *>; - -using ContainerTypeEntryList = QVector<const ContainerTypeEntry *>; -using NamespaceTypeEntryList = QVector<NamespaceTypeEntry *>; -using PrimitiveTypeEntryList = QVector<const PrimitiveTypeEntry *>; - -#endif // TYPEDATABASE_TYPEDEFS_H diff --git a/sources/shiboken2/ApiExtractor/typeparser.cpp b/sources/shiboken2/ApiExtractor/typeparser.cpp deleted file mode 100644 index c440fb66d..000000000 --- a/sources/shiboken2/ApiExtractor/typeparser.cpp +++ /dev/null @@ -1,305 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "typeparser.h" -#include <codemodel.h> - -#include <QtCore/QDebug> -#include <QtCore/QStack> -#include <QtCore/QTextStream> - -class Scanner -{ -public: - enum Token { - StarToken, - AmpersandToken, - LessThanToken, - ColonToken, - CommaToken, - OpenParenToken, - CloseParenToken, - SquareBegin, - SquareEnd, - GreaterThanToken, - - ConstToken, - VolatileToken, - Identifier, - NoToken, - InvalidToken - }; - - Scanner(const QString &s) - : m_pos(0), m_length(s.length()), m_tokenStart(-1), m_chars(s.constData()) - { - } - - Token nextToken(QString *errorMessage = Q_NULLPTR); - QString identifier() const; - - QString msgParseError(const QString &why) const; - -private: - int m_pos; - int m_length; - int m_tokenStart; - const QChar *m_chars; -}; - -QString Scanner::identifier() const -{ - return QString(m_chars + m_tokenStart, m_pos - m_tokenStart); -} - -Scanner::Token Scanner::nextToken(QString *errorMessage) -{ - Token tok = NoToken; - - // remove whitespace - while (m_pos < m_length && m_chars[m_pos] == QLatin1Char(' ')) - ++m_pos; - - m_tokenStart = m_pos; - - while (m_pos < m_length) { - - const QChar &c = m_chars[m_pos]; - - if (tok == NoToken) { - switch (c.toLatin1()) { - case '*': tok = StarToken; break; - case '&': tok = AmpersandToken; break; - case '<': tok = LessThanToken; break; - case '>': tok = GreaterThanToken; break; - case ',': tok = CommaToken; break; - case '(': tok = OpenParenToken; break; - case ')': tok = CloseParenToken; break; - case '[': tok = SquareBegin; break; - case ']' : tok = SquareEnd; break; - case ':': - tok = ColonToken; - Q_ASSERT(m_pos + 1 < m_length); - ++m_pos; - break; - default: - if (c.isLetterOrNumber() || c == QLatin1Char('_')) { - tok = Identifier; - } else { - QString message; - QTextStream (&message) << ": Unrecognized character in lexer at " - << m_pos << " : '" << c << '\''; - message = msgParseError(message); - if (errorMessage) - *errorMessage = message; - else - qWarning().noquote().nospace() << message; - return InvalidToken; - } - break; - } - } - - if (tok <= GreaterThanToken) { - ++m_pos; - break; - } - - if (tok == Identifier) { - if (c.isLetterOrNumber() || c == QLatin1Char('_')) - ++m_pos; - else - break; - } - } - - 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')) { - 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')) { - tok = VolatileToken; - } - break; - } - } - - return tok; - -} - -QString Scanner::msgParseError(const QString &why) const -{ - return QStringLiteral("TypeParser: Unable to parse \"") - + QString(m_chars, m_length) + QStringLiteral("\": ") + why; -} - -TypeInfo TypeParser::parse(const QString &str, QString *errorMessage) -{ - Scanner scanner(str); - - TypeInfo info; - QStack<TypeInfo *> stack; - stack.push(&info); - - bool colon_prefix = false; - bool in_array = false; - QString array; - bool seenStar = false; - - Scanner::Token tok = scanner.nextToken(errorMessage); - while (tok != Scanner::NoToken) { - if (tok == Scanner::InvalidToken) - return TypeInfo(); - -// switch (tok) { -// case Scanner::StarToken: printf(" - *\n"); break; -// case Scanner::AmpersandToken: printf(" - &\n"); break; -// case Scanner::LessThanToken: printf(" - <\n"); break; -// case Scanner::GreaterThanToken: printf(" - >\n"); break; -// case Scanner::ColonToken: printf(" - ::\n"); break; -// case Scanner::CommaToken: printf(" - ,\n"); break; -// case Scanner::ConstToken: printf(" - const\n"); break; -// case Scanner::SquareBegin: printf(" - [\n"); break; -// case Scanner::SquareEnd: printf(" - ]\n"); break; -// case Scanner::Identifier: printf(" - '%s'\n", qPrintable(scanner.identifier())); break; -// default: -// break; -// } - - switch (tok) { - - case Scanner::StarToken: - seenStar = true; - stack.top()->addIndirection(Indirection::Pointer); - break; - - case Scanner::AmpersandToken: - switch (stack.top()->referenceType()) { - case NoReference: - stack.top()->setReferenceType(LValueReference); - break; - case LValueReference: - stack.top()->setReferenceType(RValueReference); - break; - case RValueReference: - const QString message = scanner.msgParseError(QStringLiteral("Too many '&' qualifiers")); - if (errorMessage) - *errorMessage = message; - else - qWarning().noquote().nospace() << message; - return TypeInfo(); - } - break; - case Scanner::LessThanToken: - stack.top()->m_instantiations << TypeInfo(); - stack.push(&stack.top()->m_instantiations.last()); - break; - - case Scanner::CommaToken: - stack.pop(); - stack.top()->m_instantiations << TypeInfo(); - stack.push(&stack.top()->m_instantiations.last()); - break; - - case Scanner::GreaterThanToken: - stack.pop(); - break; - - case Scanner::ColonToken: - colon_prefix = true; - break; - - case Scanner::ConstToken: - if (seenStar) { // "int *const": Last indirection is const. - Q_ASSERT(!stack.top()->m_indirections.isEmpty()); - *stack.top()->m_indirections.rbegin() = Indirection::ConstPointer; - } else { - stack.top()->m_constant = true; - } - break; - - case Scanner::VolatileToken: - stack.top()->m_volatile = true; - break; - - case Scanner::OpenParenToken: // function pointers not supported - case Scanner::CloseParenToken: { - const QString message = scanner.msgParseError(QStringLiteral("Function pointers are not supported")); - if (errorMessage) - *errorMessage = message; - else - qWarning().noquote().nospace() << message; - return TypeInfo(); - } - - case Scanner::Identifier: - if (in_array) { - array = scanner.identifier(); - } else if (colon_prefix || stack.top()->m_qualifiedName.isEmpty()) { - stack.top()->m_qualifiedName << scanner.identifier(); - colon_prefix = false; - } else { - stack.top()->m_qualifiedName.last().append(QLatin1Char(' ') + scanner.identifier()); - } - break; - - case Scanner::SquareBegin: - in_array = true; - break; - - case Scanner::SquareEnd: - in_array = false; - stack.top()->m_arrayElements += array; - break; - - - default: - break; - } - - tok = scanner.nextToken(); - } - - return info; -} diff --git a/sources/shiboken2/ApiExtractor/typeparser.h b/sources/shiboken2/ApiExtractor/typeparser.h deleted file mode 100644 index 3b538017a..000000000 --- a/sources/shiboken2/ApiExtractor/typeparser.h +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TYPEPARSER_H -#define TYPEPARSER_H - -#include "parser/codemodel_enums.h" - -#include <QtCore/QString> -#include <QtCore/QVector> - -class TypeInfo; - -class TypeParser -{ -public: - static TypeInfo parse(const QString &str, QString *errorMessage = nullptr); -}; - -#endif // TYPEPARSER_H diff --git a/sources/shiboken2/ApiExtractor/typesystem.cpp b/sources/shiboken2/ApiExtractor/typesystem.cpp deleted file mode 100644 index 5634aa515..000000000 --- a/sources/shiboken2/ApiExtractor/typesystem.cpp +++ /dev/null @@ -1,1278 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "typesystem.h" -#include "typedatabase.h" -#include "messages.h" -#include <QtCore/QDebug> -#include <QtCore/QRegularExpression> -#include <QtCore/QSet> - -#include <algorithm> -#include <limits> - -static QString strings_Object = QLatin1String("Object"); -static QString strings_String = QLatin1String("String"); -static QString strings_char = QLatin1String("char"); -static QString strings_jchar = QLatin1String("jchar"); -static QString strings_jobject = QLatin1String("jobject"); - -static inline QString callOperator() { return QStringLiteral("operator()"); } - -PrimitiveTypeEntry::PrimitiveTypeEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent) : - TypeEntry(entryName, PrimitiveType, vr, parent), - m_preferredTargetLangType(true) -{ -} - -QString PrimitiveTypeEntry::targetLangApiName() const -{ - return m_targetLangApiName; -} - -PrimitiveTypeEntry *PrimitiveTypeEntry::basicReferencedTypeEntry() const -{ - if (!m_referencedTypeEntry) - return nullptr; - - PrimitiveTypeEntry *baseReferencedTypeEntry = m_referencedTypeEntry->basicReferencedTypeEntry(); - return baseReferencedTypeEntry ? baseReferencedTypeEntry : m_referencedTypeEntry; -} - -TypeEntry *PrimitiveTypeEntry::clone() const -{ - return new PrimitiveTypeEntry(*this); -} - -PrimitiveTypeEntry::PrimitiveTypeEntry(const PrimitiveTypeEntry &) = default; - -CodeSnipList TypeEntry::codeSnips() const -{ - return m_codeSnips; -} - -void TypeEntry::addExtraInclude(const Include &newInclude) -{ - if (!m_extraIncludes.contains(newInclude)) - m_extraIncludes.append(newInclude); -} - -QString Modification::accessModifierString() const -{ - if (isPrivate()) return QLatin1String("private"); - if (isProtected()) return QLatin1String("protected"); - if (isPublic()) return QLatin1String("public"); - if (isFriendly()) return QLatin1String("friendly"); - return QString(); -} - -FunctionModificationList ComplexTypeEntry::functionModifications(const QString &signature) const -{ - FunctionModificationList lst; - for (int i = 0; i < m_functionMods.count(); ++i) { - const FunctionModification &mod = m_functionMods.at(i); - if (mod.matches(signature)) - lst << mod; - } - return lst; -} - -FieldModification ComplexTypeEntry::fieldModification(const QString &name) const -{ - for (const auto &fieldMod : m_fieldMods) { - if (fieldMod.name == name) - return fieldMod; - } - FieldModification mod; - mod.name = name; - mod.modifiers = FieldModification::Readable | FieldModification::Writable; - return mod; -} - -void ComplexTypeEntry::setDefaultConstructor(const QString& defaultConstructor) -{ - m_defaultConstructor = defaultConstructor; -} -QString ComplexTypeEntry::defaultConstructor() const -{ - return m_defaultConstructor; -} -bool ComplexTypeEntry::hasDefaultConstructor() const -{ - return !m_defaultConstructor.isEmpty(); -} - -TypeEntry *ComplexTypeEntry::clone() const -{ - return new ComplexTypeEntry(*this); -} - -// Take over parameters relevant for typedefs -void ComplexTypeEntry::useAsTypedef(const ComplexTypeEntry *source) -{ - TypeEntry::useAsTypedef(source); - m_qualifiedCppName = source->m_qualifiedCppName; - m_targetType = source->m_targetType; -} - -ComplexTypeEntry::ComplexTypeEntry(const ComplexTypeEntry &) = default; - -QString ContainerTypeEntry::qualifiedCppName() const -{ - if (m_containerKind == StringListContainer) - return QLatin1String("QStringList"); - return ComplexTypeEntry::qualifiedCppName(); -} - -TypeEntry *ContainerTypeEntry::clone() const -{ - return new ContainerTypeEntry(*this); -} - -ContainerTypeEntry::ContainerTypeEntry(const ContainerTypeEntry &) = default; - -QString EnumTypeEntry::targetLangQualifier() const -{ - const QString q = qualifier(); - if (!q.isEmpty()) { - if (auto te = TypeDatabase::instance()->findType(q)) - return te->targetLangName(); - } - return q; -} - -QString EnumTypeEntry::qualifier() const -{ - auto parentEntry = parent(); - return parentEntry && parentEntry->type() != TypeEntry::TypeSystemType ? - parentEntry->name() : QString(); -} - -QString EnumTypeEntry::targetLangApiName() const -{ - return QLatin1String("jint"); -} - -QString FlagsTypeEntry::targetLangApiName() const -{ - return QLatin1String("jint"); -} - -TypeEntry *EnumTypeEntry::clone() const -{ - return new EnumTypeEntry(*this); -} - -EnumTypeEntry::EnumTypeEntry(const EnumTypeEntry &) = default; - -TypeEntry *FlagsTypeEntry::clone() const -{ - return new FlagsTypeEntry(*this); -} - -FlagsTypeEntry::FlagsTypeEntry(const FlagsTypeEntry &) = default; - -QString TemplateInstance::expandCode() const -{ - TemplateEntry *templateEntry = TypeDatabase::instance()->findTemplate(m_name); - if (!templateEntry) - qFatal("<insert-template> referring to non-existing template '%s'.", qPrintable(m_name)); - - 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; -} - - -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))); -} - -template <class String> // QString, QStringRef -static inline int firstNonBlank(const String &s) -{ - const auto it = std::find_if(s.cbegin(), s.cend(), - [] (QChar c) { return !c.isSpace(); }); - return int(it - s.cbegin()); -} - -template <class String> // QString, QStringRef -static inline bool isEmpty(const String &s) -{ - return s.isEmpty() - || std::all_of(s.cbegin(), s.cend(), - [] (QChar c) { return c.isSpace(); }); -} - -QString CodeSnipAbstract::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'))) - return code.trimmed(); - const auto lines = code.splitRef(QLatin1Char('\n')); - int spacesToRemove = std::numeric_limits<int>::max(); - for (const auto &line : lines) { - if (!isEmpty(line)) { - const int nonSpacePos = firstNonBlank(line); - if (nonSpacePos < spacesToRemove) - spacesToRemove = nonSpacePos; - if (spacesToRemove == 0) - return code; - } - } - QString result; - for (const auto &line : lines) { - if (!isEmpty(line) && spacesToRemove < line.size()) - result += line.mid(spacesToRemove).toString(); - result += QLatin1Char('\n'); - } - return result; -} - -QString CodeSnipAbstract::fixSpaces(QString code) -{ - code.remove(QLatin1Char('\r')); - // Check for XML <tag>\n<space>bla... - if (code.startsWith(QLatin1String("\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')); - return code; -} - -// Prepend a line to the code, observing indentation -void CodeSnipAbstract::prependCode(QString *code, QString firstLine) -{ - while (!code->isEmpty() && code->front() == QLatin1Char('\n')) - code->remove(0, 1); - if (!code->isEmpty() && code->front().isSpace()) { - const int indent = firstNonBlank(*code); - firstLine.prepend(QString(indent, QLatin1Char(' '))); - } - if (!firstLine.endsWith(QLatin1Char('\n'))) - firstLine += QLatin1Char('\n'); - code->prepend(firstLine); -} - -QString CodeSnipFragment::code() const -{ - return m_instance ? m_instance->expandCode() : m_code; -} - -bool FunctionModification::setSignature(const QString &s, QString *errorMessage) -{ - if (s.startsWith(QLatin1Char('^'))) { - m_signaturePattern.setPattern(s); - if (!m_signaturePattern.isValid()) { - if (errorMessage) { - *errorMessage = QLatin1String("Invalid signature pattern: \"") - + s + QLatin1String("\": ") + m_signaturePattern.errorString(); - } - return false; - } - } else { - m_signature = s; - } - return true; -} - -QString FunctionModification::toString() const -{ - QString str = signature() + QLatin1String("->"); - if (modifiers & AccessModifierMask) { - switch (modifiers & AccessModifierMask) { - case Private: str += QLatin1String("private"); break; - case Protected: str += QLatin1String("protected"); break; - case Public: str += QLatin1String("public"); break; - case Friendly: str += QLatin1String("friendly"); break; - } - } - - if (modifiers & Final) str += QLatin1String("final"); - if (modifiers & NonFinal) str += QLatin1String("non-final"); - - if (modifiers & Readable) str += QLatin1String("readable"); - if (modifiers & Writable) str += QLatin1String("writable"); - - if (modifiers & CodeInjection) { - for (const CodeSnip &s : snips) { - str += QLatin1String("\n//code injection:\n"); - str += s.code(); - } - } - - if (modifiers & Rename) str += QLatin1String("renamed:") + renamedToName; - - if (modifiers & Deprecated) str += QLatin1String("deprecate"); - - if (modifiers & ReplaceExpression) str += QLatin1String("replace-expression"); - - return str; -} - -static AddedFunction::TypeInfo parseType(const QString& signature, - int startPos = 0, int *endPos = nullptr, - QString *argumentName = nullptr) -{ - AddedFunction::TypeInfo result; - static const QRegularExpression regex(QLatin1String("\\w")); - Q_ASSERT(regex.isValid()); - int length = signature.length(); - int start = signature.indexOf(regex, startPos); - if (start == -1) { - if (signature.midRef(startPos + 1, 3) == QLatin1String("...")) { // varargs - if (endPos) - *endPos = startPos + 4; - result.name = QLatin1String("..."); - } else { // error - if (endPos) - *endPos = length; - } - return result; - } - - int cantStop = 0; - QString paramString; - QChar c; - int i = start; - for (; i < length; ++i) { - c = signature[i]; - if (c == QLatin1Char('<')) - cantStop++; - if (c == QLatin1Char('>')) - cantStop--; - if (cantStop < 0) - break; // FIXME: report error? - if ((c == QLatin1Char(')') || c == QLatin1Char(',')) && !cantStop) - break; - paramString += signature[i]; - } - if (endPos) - *endPos = i; - - // Check default value - if (paramString.contains(QLatin1Char('='))) { - QStringList lst = paramString.split(QLatin1Char('=')); - paramString = lst[0].trimmed(); - result.defaultValue = lst[1].trimmed(); - } - - // check constness - if (paramString.startsWith(QLatin1String("const "))) { - result.isConstant = true; - paramString.remove(0, sizeof("const")/sizeof(char)); - paramString = paramString.trimmed(); - } - - // Extract argument name from "T<bla,blub>* @foo@" - const int nameStartPos = paramString.indexOf(QLatin1Char('@')); - if (nameStartPos != -1) { - const int nameEndPos = paramString.indexOf(QLatin1Char('@'), nameStartPos + 1); - if (nameEndPos > nameStartPos) { - if (argumentName) - *argumentName = paramString.mid(nameStartPos + 1, nameEndPos - nameStartPos - 1); - paramString.remove(nameStartPos, nameEndPos - nameStartPos + 1); - paramString = paramString.trimmed(); - } - } - - // check reference - if (paramString.endsWith(QLatin1Char('&'))) { - result.isReference = true; - paramString.chop(1); - paramString = paramString.trimmed(); - } - // check Indirections - while (paramString.endsWith(QLatin1Char('*'))) { - result.indirections++; - paramString.chop(1); - paramString = paramString.trimmed(); - } - result.name = paramString; - - return result; -} - -AddedFunction::AddedFunction(QString signature, const QString &returnType) : - m_access(Public) -{ - Q_ASSERT(!returnType.isEmpty()); - m_returnType = parseType(returnType); - signature = signature.trimmed(); - // Skip past "operator()(...)" - const int parenStartPos = signature.startsWith(callOperator()) - ? callOperator().size() : 0; - int endPos = signature.indexOf(QLatin1Char('('), parenStartPos); - if (endPos < 0) { - m_isConst = false; - m_name = signature; - } else { - m_name = signature.left(endPos).trimmed(); - int signatureLength = signature.length(); - while (endPos < signatureLength) { - QString argumentName; - TypeInfo arg = parseType(signature, endPos, &endPos, &argumentName); - if (!arg.name.isEmpty()) - m_arguments.append({argumentName, arg}); - // end of parameters... - if (endPos >= signatureLength || signature[endPos] == QLatin1Char(')')) - break; - } - // is const? - m_isConst = signature.rightRef(signatureLength - endPos).contains(QLatin1String("const")); - } -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const ReferenceCount &r) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "ReferenceCount(" << r.varName << ", action=" << r.action << ')'; - return d; -} - -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 = code.splitRef(QLatin1Char('\n')); - for (int i = 0, size = lines.size(); i < size; ++i) { - if (i) - d << "\\n"; - d << lines.at(i).trimmed(); - } - } - d << '"'; - if (!s.argumentMap.isEmpty()) { - d << ", argumentMap{"; - for (auto it = s.argumentMap.cbegin(), end = s.argumentMap.cend(); it != end; ++it) - d << it.key() << "->\"" << it.value() << '"'; - d << '}'; - } - d << ')'; - return d; -} - -void Modification::formatDebug(QDebug &d) const -{ - d << "modifiers=" << Qt::hex << Qt::showbase << modifiers << Qt::noshowbase << Qt::dec; - if (removal) - d << ", removal"; - if (!renamedToName.isEmpty()) - d << ", renamedToName=\"" << renamedToName << '"'; -} - -void FunctionModification::formatDebug(QDebug &d) const -{ - if (m_signature.isEmpty()) - d << "pattern=\"" << m_signaturePattern.pattern(); - else - d << "signature=\"" << m_signature; - d << "\", "; - Modification::formatDebug(d); - if (!association.isEmpty()) - d << ", association=\"" << association << '"'; - if (m_allowThread != TypeSystem::AllowThread::Unspecified) - d << ", allowThread=" << int(m_allowThread); - if (m_thread) - d << ", thread"; - if (m_exceptionHandling != TypeSystem::ExceptionHandling::Unspecified) - d << ", exceptionHandling=" << int(m_exceptionHandling); - if (!snips.isEmpty()) - d << ", snips=(" << snips << ')'; - if (!argument_mods.isEmpty()) - d << ", argument_mods=(" << argument_mods << ')'; -} - -QDebug operator<<(QDebug d, const ArgumentOwner &a) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "ArgumentOwner(index=" << a.index << ", action=" << a.action << ')'; - return d; -} - -QDebug operator<<(QDebug d, const ArgumentModification &a) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "ArgumentModification(index=" << a.index; - if (a.removedDefaultExpression) - d << ", removedDefaultExpression"; - if (a.removed) - d << ", removed"; - if (a.noNullPointers) - d << ", noNullPointers"; - if (a.array) - d << ", array"; - if (!a.referenceCounts.isEmpty()) - d << ", referenceCounts=" << a.referenceCounts; - if (!a.modified_type.isEmpty()) - d << ", modified_type=\"" << a.modified_type << '"'; - if (!a.replace_value.isEmpty()) - d << ", replace_value=\"" << a.replace_value << '"'; - if (!a.replacedDefaultExpression.isEmpty()) - d << ", replacedDefaultExpression=\"" << a.replacedDefaultExpression << '"'; - if (!a.ownerships.isEmpty()) - d << ", ownerships=" << a.ownerships; - if (!a.renamed_to.isEmpty()) - d << ", renamed_to=\"" << a.renamed_to << '"'; - d << ", owner=" << a.owner << ')'; - return d; -} - -QDebug operator<<(QDebug d, const FunctionModification &fm) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "FunctionModification("; - fm.formatDebug(d); - d << ')'; - return d; -} - -QDebug operator<<(QDebug d, const AddedFunction::TypeInfo &ti) -{ - QDebugStateSaver saver(d); - d.noquote(); - d.nospace(); - d << "TypeInfo("; - if (ti.isConstant) - d << "const"; - if (ti.indirections) - d << QByteArray(ti.indirections, '*'); - if (ti.isReference) - d << " &"; - d << ti.name; - if (!ti.defaultValue.isEmpty()) - d << " = " << ti.defaultValue; - 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; - 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"; - return d; -} -#endif // !QT_NO_DEBUG_STREAM - -AddedFunction::TypeInfo AddedFunction::TypeInfo::fromSignature(const QString& signature) -{ - return parseType(signature); -} - -static QString buildName(const QString &entryName, const TypeEntry *parent) -{ - return parent == nullptr || parent->type() == TypeEntry::TypeSystemType - ? entryName : parent->name() + QLatin1String("::") + entryName; -} - -ComplexTypeEntry::ComplexTypeEntry(const QString &entryName, TypeEntry::Type t, - const QVersionNumber &vr, - const TypeEntry *parent) : - TypeEntry(entryName, t, vr, parent), - m_qualifiedCppName(buildName(entryName, parent)), - m_polymorphicBase(false), - m_genericClass(false), - m_deleteInMainThread(false) -{ -} - -bool ComplexTypeEntry::isComplex() const -{ - return true; -} - -QString ComplexTypeEntry::targetLangApiName() const -{ - return strings_jobject; -} - -QString ContainerTypeEntry::typeName() const -{ - switch (m_containerKind) { - case LinkedListContainer: - return QLatin1String("linked-list"); - case ListContainer: - return QLatin1String("list"); - case StringListContainer: - return QLatin1String("string-list"); - case VectorContainer: - return QLatin1String("vector"); - case StackContainer: - return QLatin1String("stack"); - case QueueContainer: - return QLatin1String("queue"); - case SetContainer: - return QLatin1String("set"); - case MapContainer: - return QLatin1String("map"); - case MultiMapContainer: - return QLatin1String("multi-map"); - case HashContainer: - return QLatin1String("hash"); - case MultiHashContainer: - return QLatin1String("multi-hash"); - case PairContainer: - return QLatin1String("pair"); - case NoContainer: - default: - return QLatin1String("?"); - } -} - -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; -} - -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"))) { - QString path = inc.name(); - path.remove(QLatin1String("_impl")); - m_include = Include(inc.type(), path); - } else { - m_include = inc; - } -} - -bool TypeEntry::isCppPrimitive() const -{ - if (!isPrimitive()) - return false; - - if (m_type == VoidType) - return true; - - const PrimitiveTypeEntry *referencedType = - static_cast<const PrimitiveTypeEntry *>(this)->basicReferencedTypeEntry(); - const QString &typeName = referencedType ? referencedType->name() : m_name; - return typeName.contains(QLatin1Char(' ')) || primitiveCppTypes().contains(typeName); -} - -TypeEntry::TypeEntry(const QString &entryName, TypeEntry::Type t, const QVersionNumber &vr, - const TypeEntry *parent) : - m_parent(parent), - m_name(buildName(entryName, parent)), - m_entryName(entryName), - m_version(vr), - m_type(t) -{ -} - -TypeEntry::~TypeEntry() -{ - delete m_customConversion; -} - -bool TypeEntry::isChildOf(const TypeEntry *p) const -{ - for (auto e = m_parent; e; e = e->parent()) { - if (e == p) - return true; - } - return false; -} - -const TypeSystemTypeEntry *TypeEntry::typeSystemTypeEntry() const -{ - for (auto e = this; e; e = e->parent()) { - if (e->type() == TypeEntry::TypeSystemType) - return static_cast<const TypeSystemTypeEntry *>(e); - } - return nullptr; -} - -const TypeEntry *TypeEntry::targetLangEnclosingEntry() const -{ - auto result = m_parent; - while (result && result->type() != TypeEntry::TypeSystemType - && !NamespaceTypeEntry::isVisibleScope(result)) { - result = result->parent(); - } - return result; -} - -QString TypeEntry::targetLangName() const -{ - if (m_cachedTargetLangName.isEmpty()) - m_cachedTargetLangName = buildTargetLangName(); - return m_cachedTargetLangName; -} - -QString TypeEntry::buildTargetLangName() const -{ - QString result = m_entryName; - for (auto p = parent(); p && p->type() != TypeEntry::TypeSystemType; p = p->parent()) { - if (NamespaceTypeEntry::isVisibleScope(p)) { - if (!result.isEmpty()) - result.prepend(QLatin1Char('.')); - QString n = p->m_entryName; - n.replace(QLatin1String("::"), QLatin1String(".")); // Primitive types may have "std::" - result.prepend(n); - } - } - return result; -} - -SourceLocation TypeEntry::sourceLocation() const -{ - return m_sourceLocation; -} - -void TypeEntry::setSourceLocation(const SourceLocation &sourceLocation) -{ - m_sourceLocation = sourceLocation; -} - -QString TypeEntry::targetLangEntryName() const -{ - if (m_cachedTargetLangEntryName.isEmpty()) { - m_cachedTargetLangEntryName = targetLangName(); - const int lastDot = m_cachedTargetLangEntryName.lastIndexOf(QLatin1Char('.')); - if (lastDot != -1) - m_cachedTargetLangEntryName.remove(0, lastDot + 1); - } - return m_cachedTargetLangEntryName; -} - -QString TypeEntry::qualifiedTargetLangName() const -{ - return targetLangPackage() + QLatin1Char('.') + targetLangName(); -} - -bool TypeEntry::hasCustomConversion() const -{ - return m_customConversion != nullptr; -} - -void TypeEntry::setCustomConversion(CustomConversion* customConversion) -{ - m_customConversion = customConversion; -} - -CustomConversion* TypeEntry::customConversion() const -{ - return m_customConversion; -} - -TypeEntry *TypeEntry::clone() const -{ - return new TypeEntry(*this); -} - -// Take over parameters relevant for typedefs -void TypeEntry::useAsTypedef(const TypeEntry *source) -{ - // XML Typedefs are in the global namespace for now. - m_parent = source->typeSystemTypeEntry(); - m_entryName = source->m_entryName; - m_name = source->m_name; - m_targetLangPackage = source->m_targetLangPackage; - m_codeGeneration = source->m_codeGeneration; - m_version = source->m_version; -} - -TypeEntry::TypeEntry(const TypeEntry &) = default; - -TypeSystemTypeEntry::TypeSystemTypeEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent) : - TypeEntry(entryName, TypeSystemType, vr, parent) -{ -} - -TypeEntry *TypeSystemTypeEntry::clone() const -{ - return new TypeSystemTypeEntry(*this); -} - -TypeSystemTypeEntry::TypeSystemTypeEntry(const TypeSystemTypeEntry &) = default; - -VoidTypeEntry::VoidTypeEntry() : - TypeEntry(QLatin1String("void"), VoidType, QVersionNumber(0, 0), nullptr) -{ -} - -TypeEntry *VoidTypeEntry::clone() const -{ - return new VoidTypeEntry(*this); -} - -VoidTypeEntry::VoidTypeEntry(const VoidTypeEntry &) = default; - -VarargsTypeEntry::VarargsTypeEntry() : - TypeEntry(QLatin1String("..."), VarargsType, QVersionNumber(0, 0), nullptr) -{ -} - -TypeEntry *VarargsTypeEntry::clone() const -{ - return new VarargsTypeEntry(*this); -} - -VarargsTypeEntry::VarargsTypeEntry(const VarargsTypeEntry &) = default; - -TemplateArgumentEntry::TemplateArgumentEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent) : - TypeEntry(entryName, TemplateArgumentType, vr, parent) -{ -} - -TypeEntry *TemplateArgumentEntry::clone() const -{ - return new TemplateArgumentEntry(*this); -} - -TemplateArgumentEntry::TemplateArgumentEntry(const TemplateArgumentEntry &) = default; - -ArrayTypeEntry::ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr, - const TypeEntry *parent) : - TypeEntry(QLatin1String("Array"), ArrayType, vr, parent), - m_nestedType(nested_type) -{ - Q_ASSERT(m_nestedType); -} - -QString ArrayTypeEntry::buildTargetLangName() const -{ - return m_nestedType->targetLangName() + QLatin1String("[]"); -} - -QString ArrayTypeEntry::targetLangApiName() const -{ - return m_nestedType->isPrimitive() - ? m_nestedType->targetLangApiName() + QLatin1String("Array") - : QLatin1String("jobjectArray"); -} - -TypeEntry *ArrayTypeEntry::clone() const -{ - return new ArrayTypeEntry(*this); -} - -ArrayTypeEntry::ArrayTypeEntry(const ArrayTypeEntry &) = default; - -EnumTypeEntry::EnumTypeEntry(const QString &entryName, - const QVersionNumber &vr, - const TypeEntry *parent) : - TypeEntry(entryName, EnumType, vr, parent) -{ -} - -EnumValueTypeEntry::EnumValueTypeEntry(const QString &name, const QString &value, - const EnumTypeEntry *enclosingEnum, - bool isScopedEnum, - const QVersionNumber &vr) : - TypeEntry(name, TypeEntry::EnumValue, vr, - isScopedEnum ? enclosingEnum : enclosingEnum->parent()), - m_value(value), - m_enclosingEnum(enclosingEnum) -{ -} - -TypeEntry *EnumValueTypeEntry::clone() const -{ - return new EnumValueTypeEntry(*this); -} - -EnumValueTypeEntry::EnumValueTypeEntry(const EnumValueTypeEntry &) = default; - -FlagsTypeEntry::FlagsTypeEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent) : - TypeEntry(entryName, FlagsType, vr, parent) -{ -} - -QString FlagsTypeEntry::buildTargetLangName() const -{ - QString on = m_originalName; - on.replace(QLatin1String("::"), QLatin1String(".")); - return on; -} - -ConstantValueTypeEntry::ConstantValueTypeEntry(const QString& name, - const TypeEntry *parent) : - TypeEntry(name, ConstantValueType, QVersionNumber(0, 0), parent) -{ -} - -TypeEntry *ConstantValueTypeEntry::clone() const -{ - return new ConstantValueTypeEntry(*this); -} - -ConstantValueTypeEntry::ConstantValueTypeEntry(const ConstantValueTypeEntry &) = default; - -/* A typedef entry allows for specifying template specializations in the - * typesystem XML file. */ -TypedefEntry::TypedefEntry(const QString &entryName, const QString &sourceType, - const QVersionNumber &vr, const TypeEntry *parent) : - ComplexTypeEntry(entryName, TypedefType, vr, parent), - m_sourceType(sourceType) -{ -} - -TypeEntry *TypedefEntry::clone() const -{ - return new TypedefEntry(*this); -} - -TypedefEntry::TypedefEntry(const TypedefEntry &) = default; - -ContainerTypeEntry::ContainerTypeEntry(const QString &entryName, ContainerKind containerKind, - const QVersionNumber &vr, - const TypeEntry *parent) : - ComplexTypeEntry(entryName, ContainerType, vr, parent), - m_containerKind(containerKind) -{ - setCodeGeneration(GenerateForSubclass); -} - -SmartPointerTypeEntry::SmartPointerTypeEntry(const QString &entryName, - const QString &getterName, - const QString &smartPointerType, - const QString &refCountMethodName, - const QVersionNumber &vr, const TypeEntry *parent) : - ComplexTypeEntry(entryName, SmartPointerType, vr, parent), - m_getterName(getterName), - m_smartPointerType(smartPointerType), - m_refCountMethodName(refCountMethodName) -{ -} - -TypeEntry *SmartPointerTypeEntry::clone() const -{ - return new SmartPointerTypeEntry(*this); -} - -SmartPointerTypeEntry::SmartPointerTypeEntry(const SmartPointerTypeEntry &) = default; - -bool SmartPointerTypeEntry::matchesInstantiation(const TypeEntry *e) const -{ - return m_instantiations.isEmpty() || m_instantiations.contains(e); -} - -NamespaceTypeEntry::NamespaceTypeEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent) : - ComplexTypeEntry(entryName, NamespaceType, vr, parent) -{ -} - -TypeEntry *NamespaceTypeEntry::clone() const -{ - return new NamespaceTypeEntry(*this); -} - -void NamespaceTypeEntry::setFilePattern(const QRegularExpression &r) -{ - m_filePattern = r; - m_hasPattern = !m_filePattern.pattern().isEmpty(); - if (m_hasPattern) - m_filePattern.optimize(); -} - -NamespaceTypeEntry::NamespaceTypeEntry(const NamespaceTypeEntry &) = default; - -bool NamespaceTypeEntry::matchesFile(const QString &needle) const -{ - return m_filePattern.match(needle).hasMatch(); -} - -bool NamespaceTypeEntry::isVisible() const -{ - return m_visibility == TypeSystem::Visibility::Visible - || (m_visibility == TypeSystem::Visibility::Auto && !m_inlineNamespace); -} - -bool NamespaceTypeEntry::isVisibleScope(const TypeEntry *e) -{ - return e->type() != TypeEntry::NamespaceType - || static_cast<const NamespaceTypeEntry *>(e)->isVisible(); -} - -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 -{ - return new ValueTypeEntry(*this); -} - -ValueTypeEntry::ValueTypeEntry(const ValueTypeEntry &) = default; - -ValueTypeEntry::ValueTypeEntry(const QString &entryName, Type t, const QVersionNumber &vr, - const TypeEntry *parent) : - ComplexTypeEntry(entryName, t, vr, parent) -{ -} - -struct CustomConversion::CustomConversionPrivate -{ - CustomConversionPrivate(const TypeEntry* ownerType) - : ownerType(ownerType), replaceOriginalTargetToNativeConversions(false) - { - } - const TypeEntry* ownerType; - QString nativeToTargetConversion; - bool replaceOriginalTargetToNativeConversions; - TargetToNativeConversions targetToNativeConversions; -}; - -struct CustomConversion::TargetToNativeConversion::TargetToNativeConversionPrivate -{ - TargetToNativeConversionPrivate() - : sourceType(nullptr) - { - } - const TypeEntry* sourceType; - QString sourceTypeName; - QString sourceTypeCheck; - QString conversion; -}; - -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 -{ - return m_d->targetToNativeConversions; -} - -void CustomConversion::addTargetToNativeConversion(const QString& sourceTypeName, - const QString& sourceTypeCheck, - const QString& conversion) -{ - m_d->targetToNativeConversions.append(new TargetToNativeConversion(sourceTypeName, sourceTypeCheck, conversion)); -} - -CustomConversion::TargetToNativeConversion::TargetToNativeConversion(const QString& sourceTypeName, - const QString& sourceTypeCheck, - const QString& conversion) -{ - m_d = new TargetToNativeConversionPrivate; - m_d->sourceTypeName = sourceTypeName; - m_d->sourceTypeCheck = sourceTypeCheck; - m_d->conversion = conversion; -} - -CustomConversion::TargetToNativeConversion::~TargetToNativeConversion() -{ - delete m_d; -} - -const TypeEntry* CustomConversion::TargetToNativeConversion::sourceType() const -{ - return m_d->sourceType; -} - -void CustomConversion::TargetToNativeConversion::setSourceType(const TypeEntry* sourceType) -{ - m_d->sourceType = sourceType; -} - -bool CustomConversion::TargetToNativeConversion::isCustomType() const -{ - return !(m_d->sourceType); -} - -QString CustomConversion::TargetToNativeConversion::sourceTypeName() const -{ - return m_d->sourceTypeName; -} - -QString CustomConversion::TargetToNativeConversion::sourceTypeCheck() const -{ - return m_d->sourceTypeCheck; -} - -QString CustomConversion::TargetToNativeConversion::conversion() const -{ - return m_d->conversion; -} - -void CustomConversion::TargetToNativeConversion::setConversion(const QString& conversion) -{ - m_d->conversion = conversion; -} - -FunctionTypeEntry::FunctionTypeEntry(const QString &entryName, const QString &signature, - const QVersionNumber &vr, - const TypeEntry *parent) : - TypeEntry(entryName, FunctionType, vr, parent) -{ - addSignature(signature); -} - -TypeEntry *FunctionTypeEntry::clone() const -{ - return new FunctionTypeEntry(*this); -} - -FunctionTypeEntry::FunctionTypeEntry(const FunctionTypeEntry &) = default; - -ObjectTypeEntry::ObjectTypeEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent) - : ComplexTypeEntry(entryName, ObjectType, vr, parent) -{ -} - -TypeEntry *ObjectTypeEntry::clone() const -{ - return new ObjectTypeEntry(*this); -} - -ObjectTypeEntry::ObjectTypeEntry(const ObjectTypeEntry &) = default; - -void DocModification::setCode(const QString &code) -{ - m_code = CodeSnipAbstract::fixSpaces(code); -} diff --git a/sources/shiboken2/ApiExtractor/typesystem.h b/sources/shiboken2/ApiExtractor/typesystem.h deleted file mode 100644 index 9d97f5c93..000000000 --- a/sources/shiboken2/ApiExtractor/typesystem.h +++ /dev/null @@ -1,1671 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt for Python. -** -** $QT_BEGIN_LICENSE:GPL-EXCEPT$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef TYPESYSTEM_H -#define TYPESYSTEM_H - -#include "typesystem_enums.h" -#include "typesystem_typedefs.h" -#include "include.h" -#include "sourcelocation.h" - -#include <QtCore/QHash> -#include <QtCore/qobjectdefs.h> -#include <QtCore/QRegularExpression> -#include <QtCore/QString> -#include <QtCore/QStringList> -#include <QtCore/QMap> -#include <QtCore/QVector> -#include <QtCore/QVersionNumber> - -//Used to identify the conversion rule to avoid break API -extern const char *TARGET_CONVERSION_RULE_FLAG; -extern const char *NATIVE_CONVERSION_RULE_FLAG; - -class AbstractMetaType; -QT_BEGIN_NAMESPACE -class QDebug; -class QTextStream; -QT_END_NAMESPACE - -class EnumTypeEntry; -class FlagsTypeEntry; - -using ArgumentMap = QMap<int, QString>; - -class TemplateInstance; - -struct ReferenceCount -{ - enum Action { // 0x01 - 0xff - Invalid = 0x00, - Add = 0x01, - AddAll = 0x02, - Remove = 0x04, - Set = 0x08, - Ignore = 0x10, - - ActionsMask = 0xff, - - Padding = 0xffffffff - }; - - QString varName; - Action action = Invalid; -}; - -struct ArgumentOwner -{ - enum Action { - Invalid = 0x00, - Add = 0x01, - Remove = 0x02 - }; - enum { - InvalidIndex = -2, - ThisIndex = -1, - ReturnIndex = 0, - FirstArgumentIndex = 1 - }; - - Action action = Invalid; - 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: - QString code() const; - - void addCode(const QString &code); - void addCode(const QStringRef &code) { addCode(code.toString()); } - - void addTemplateInstance(TemplateInstance *ti) - { - codeList.append(CodeSnipFragment(ti)); - } - - QVector<CodeSnipFragment> codeList; - - static QString fixSpaces(QString code); - static QString dedent(const QString &code); - static void prependCode(QString *code, QString firstLine); -}; - -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 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; -}; - - -class CodeSnip : public CodeSnipAbstract -{ -public: - CodeSnip() = default; - explicit CodeSnip(TypeSystem::Language lang) : language(lang) {} - - TypeSystem::Language language = TypeSystem::TargetLangCode; - TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionAny; - ArgumentMap argumentMap; -}; - -struct ArgumentModification -{ - ArgumentModification() : removedDefaultExpression(false), removed(false), - noNullPointers(false), resetAfterUse(false), array(false) {} - explicit ArgumentModification(int idx) : index(idx), removedDefaultExpression(false), removed(false), - noNullPointers(false), resetAfterUse(false), array(false) {} - - // Should the default expression be removed? - - - // Reference count flags for this argument - QVector<ReferenceCount> referenceCounts; - - // The text given for the new type of the argument - QString modified_type; - - QString replace_value; - - // The text of the new default expression of the argument - QString replacedDefaultExpression; - - // The new definition of ownership for a specific argument - QHash<TypeSystem::Language, TypeSystem::Ownership> ownerships; - - // Different conversion rules - CodeSnipList conversion_rules; - - //QObject parent(owner) of this argument - ArgumentOwner owner; - - //New name - QString renamed_to; - - // The index of this argument - int index = -1; - - uint removedDefaultExpression : 1; - uint removed : 1; - uint noNullPointers : 1; - uint resetAfterUse : 1; - uint array : 1; // consider "int*" to be "int[]" -}; - -struct Modification -{ - enum Modifiers : uint { - InvalidModifier = 0x0000, - Private = 0x0001, - Protected = 0x0002, - Public = 0x0003, - Friendly = 0x0004, - AccessModifierMask = 0x000f, - - Final = 0x0010, - NonFinal = 0x0020, - FinalMask = Final | NonFinal, - - Readable = 0x0100, - Writable = 0x0200, - - CodeInjection = 0x1000, - Rename = 0x2000, - Deprecated = 0x4000, - ReplaceExpression = 0x8000 - }; - - bool isAccessModifier() const - { - return modifiers & AccessModifierMask; - } - Modifiers accessModifier() const - { - return Modifiers(modifiers & AccessModifierMask); - } - bool isPrivate() const - { - return accessModifier() == Private; - } - bool isProtected() const - { - return accessModifier() == Protected; - } - bool isPublic() const - { - return accessModifier() == Public; - } - bool isFriendly() const - { - return accessModifier() == Friendly; - } - bool isFinal() const - { - return modifiers & Final; - } - bool isNonFinal() const - { - return modifiers & NonFinal; - } - QString accessModifierString() const; - - bool isDeprecated() const - { - return modifiers & Deprecated; - } - - void setRenamedTo(const QString &name) - { - renamedToName = name; - } - QString renamedTo() const - { - return renamedToName; - } - bool isRenameModifier() const - { - return modifiers & Rename; - } - - bool isRemoveModifier() const - { - return removal != TypeSystem::NoLanguage; - } - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const; -#endif - - QString renamedToName; - uint modifiers = 0; - TypeSystem::Language removal = TypeSystem::NoLanguage; -}; - -struct FunctionModification: public Modification -{ - using AllowThread = TypeSystem::AllowThread; - - bool isCodeInjection() const - { - return modifiers & CodeInjection; - } - void setIsThread(bool flag) - { - m_thread = flag; - } - bool isThread() const - { - return m_thread; - } - - AllowThread allowThread() const { return m_allowThread; } - void setAllowThread(AllowThread allow) { m_allowThread = allow; } - - bool matches(const QString &functionSignature) const - { - return m_signature.isEmpty() - ? m_signaturePattern.match(functionSignature).hasMatch() - : m_signature == functionSignature; - } - - bool setSignature(const QString &s, QString *errorMessage = nullptr); - QString signature() const { return m_signature.isEmpty() ? m_signaturePattern.pattern() : m_signature; } - - void setOriginalSignature(const QString &s) { m_originalSignature = s; } - QString originalSignature() const { return m_originalSignature; } - - TypeSystem::ExceptionHandling exceptionHandling() const { return m_exceptionHandling; } - void setExceptionHandling(TypeSystem::ExceptionHandling e) { m_exceptionHandling = e; } - - QString toString() const; - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const; -#endif - - QString association; - CodeSnipList snips; - - QVector<ArgumentModification> argument_mods; - -private: - QString m_signature; - QString m_originalSignature; - QRegularExpression m_signaturePattern; - bool m_thread = false; - AllowThread m_allowThread = AllowThread::Unspecified; - TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const ReferenceCount &); -QDebug operator<<(QDebug d, const ArgumentOwner &a); -QDebug operator<<(QDebug d, const ArgumentModification &a); -QDebug operator<<(QDebug d, const FunctionModification &fm); -#endif - -struct FieldModification: public Modification -{ - bool isReadable() const - { - return modifiers & Readable; - } - bool isWritable() const - { - return modifiers & Writable; - } - - QString name; -}; - -/** -* \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 -{ - /// Function access types. - enum Access { - InvalidAccess = 0, - Protected = 0x1, - Public = 0x2 - }; - - /** - * \internal - * Internal struct used to store information about arguments and return type of the - * functions added by the type system. This information is later used to create - * AbstractMetaType and AbstractMetaArgument for the AbstractMetaFunctions. - */ - struct TypeInfo { - TypeInfo() = default; - static TypeInfo fromSignature(const QString& signature); - - QString name; - QString defaultValue; - int indirections = 0; - bool isConstant = false; - bool isReference = false; - }; - - struct Argument - { - QString name; - TypeInfo typeInfo; - }; - - /// Creates a new AddedFunction with a signature and a return type. - explicit AddedFunction(QString signature, const QString &returnType); - 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 QVector<Argument> &arguments() const - { - return m_arguments; - } - - /// Returns true if this is a constant method. - bool isConstant() const - { - return m_isConst; - } - - /// Set this method static. - void setStatic(bool value) - { - m_isStatic = value; - } - - /// Returns true if this is a static method. - bool isStatic() const - { - return m_isStatic; - } - - FunctionModificationList modifications; - -private: - QString m_name; - QVector<Argument> m_arguments; - TypeInfo m_returnType; - Access m_access = Protected; - bool m_isConst = false; - bool m_isStatic = false; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const AddedFunction::TypeInfo &ti); -QDebug operator<<(QDebug d, const AddedFunction::Argument &a); -QDebug operator<<(QDebug d, const AddedFunction &af); -#endif - -class ObjectTypeEntry; - -class DocModification -{ -public: - DocModification() = default; - explicit DocModification(const QString& xpath, const QString& signature) : - m_xpath(xpath), m_signature(signature) {} - explicit DocModification(TypeSystem::DocModificationMode mode, const QString& signature) : - m_signature(signature), m_mode(mode) {} - - void setCode(const QString& code); - void setCode(const QStringRef& code) { setCode(code.toString()); } - - QString code() const - { - return m_code; - } - QString xpath() const - { - return m_xpath; - } - QString signature() const - { - return m_signature; - } - TypeSystem::DocModificationMode mode() const - { - return m_mode; - } - - TypeSystem::Language format() const { return m_format; } - void setFormat(TypeSystem::Language f) { m_format = f; } - -private: - QString m_code; - QString m_xpath; - QString m_signature; - TypeSystem::DocModificationMode m_mode = TypeSystem::DocModificationXPathReplace; - TypeSystem::Language m_format = TypeSystem::NativeCode; -}; - -class CustomConversion; -class TypeSystemTypeEntry; - -class TypeEntry -{ - Q_GADGET -public: - TypeEntry &operator=(const TypeEntry &) = delete; - TypeEntry &operator=(TypeEntry &&) = delete; - TypeEntry(TypeEntry &&) = delete; - - enum Type { - PrimitiveType, - VoidType, - VarargsType, - FlagsType, - EnumType, - EnumValue, - ConstantValueType, - TemplateArgumentType, - BasicValueType, - ContainerType, - ObjectType, - NamespaceType, - ArrayType, - TypeSystemType, - CustomType, - FunctionType, - SmartPointerType, - TypedefType - }; - Q_ENUM(Type) - - enum CodeGeneration { - GenerateTargetLang = 0x0001, - GenerateCpp = 0x0002, - GenerateForSubclass = 0x0004, - - GenerateNothing = 0, - GenerateAll = 0xffff, - GenerateCode = GenerateTargetLang | GenerateCpp - }; - Q_ENUM(CodeGeneration) - - explicit TypeEntry(const QString &entryName, Type t, const QVersionNumber &vr, - const TypeEntry *parent); - - virtual ~TypeEntry(); - - Type type() const - { - return m_type; - } - - const TypeEntry *parent() const { return m_parent; } - void setParent(const TypeEntry *p) { m_parent = p; } - bool isChildOf(const TypeEntry *p) const; - const TypeSystemTypeEntry *typeSystemTypeEntry() const; - // cf AbstractMetaClass::targetLangEnclosingClass() - const TypeEntry *targetLangEnclosingEntry() const; - - bool isPrimitive() const - { - return m_type == PrimitiveType; - } - bool isEnum() const - { - return m_type == EnumType; - } - bool isFlags() const - { - return m_type == FlagsType; - } - bool isObject() const - { - return m_type == ObjectType; - } - bool isNamespace() const - { - return m_type == NamespaceType; - } - bool isContainer() const - { - return m_type == ContainerType; - } - bool isSmartPointer() const - { - return m_type == SmartPointerType; - } - bool isArray() const - { - return m_type == ArrayType; - } - bool isTemplateArgument() const - { - return m_type == TemplateArgumentType; - } - bool isVoid() const - { - return m_type == VoidType; - } - bool isVarargs() const - { - return m_type == VarargsType; - } - bool isCustom() const - { - return m_type == CustomType; - } - bool isTypeSystem() const - { - return m_type == TypeSystemType; - } - bool isFunction() const - { - return m_type == FunctionType; - } - bool isEnumValue() const - { - return m_type == EnumValue; - } - - bool stream() const - { - return m_stream; - } - - void setStream(bool b) - { - m_stream = b; - } - - // The type's name in C++, fully qualified - QString name() const { return m_name; } - // C++ excluding inline namespaces - QString shortName() const; - // Name as specified in XML - QString entryName() const { return m_entryName; } - - uint codeGeneration() const - { - return m_codeGeneration; - } - void setCodeGeneration(uint cg) - { - m_codeGeneration = cg; - } - - // Returns true if code must be generated for this entry, - // it will return false in case of types coming from typesystems - // included for reference only. - // NOTE: 'GenerateForSubclass' means 'generate="no"' - // on 'load-typesystem' tag - inline bool generateCode() const - { - return m_codeGeneration != TypeEntry::GenerateForSubclass - && m_codeGeneration != TypeEntry::GenerateNothing; - } - - int revision() const { return m_revision; } - void setRevision(int r); // see typedatabase.cpp - int sbkIndex() const; - void setSbkIndex(int i) { m_sbkIndex = i; } - - virtual QString qualifiedCppName() const - { - return m_name; - } - - /** - * Its type's name in target language API - * The target language API name represents how this type is - * referred on low level code for the target language. - * Examples: for Java this would be a JNI name, for Python - * it should represent the CPython type name. - * /return string representing the target language API name - * for this type entry - */ - virtual QString targetLangApiName() const - { - return m_name; - } - - // The type's name in TargetLang - QString targetLangName() const; // "Foo.Bar" - void setTargetLangName(const QString &n) { m_cachedTargetLangName = n; } - QString targetLangEntryName() const; // "Bar" - - // The package - QString targetLangPackage() const { return m_targetLangPackage; } - void setTargetLangPackage(const QString &p) { m_targetLangPackage = p; } - - QString qualifiedTargetLangName() const; - - void setCustomConstructor(const CustomFunction &func) - { - m_customConstructor = func; - } - CustomFunction customConstructor() const - { - return m_customConstructor; - } - - void setCustomDestructor(const CustomFunction &func) - { - m_customDestructor = func; - } - CustomFunction customDestructor() const - { - return m_customDestructor; - } - - virtual bool isValue() const - { - return false; - } - virtual bool isComplex() const - { - return false; - } - - CodeSnipList codeSnips() const; - void setCodeSnips(const CodeSnipList &codeSnips) - { - m_codeSnips = codeSnips; - } - void addCodeSnip(const CodeSnip &codeSnip) - { - m_codeSnips << codeSnip; - } - - void setDocModification(const DocModificationList& docMods) - { - m_docModifications << docMods; - } - DocModificationList docModifications() const - { - return m_docModifications; - } - - IncludeList extraIncludes() const - { - return m_extraIncludes; - } - void setExtraIncludes(const IncludeList &includes) - { - m_extraIncludes = includes; - } - void addExtraInclude(const Include &newInclude); - - Include include() const - { - return m_include; - } - void setInclude(const Include &inc); - - // Replace conversionRule arg to CodeSnip in future version - /// Set the type convertion rule - void setConversionRule(const QString& conversionRule) - { - m_conversionRule = conversionRule; - } - - /// Returns the type convertion rule - QString conversionRule() const - { - //skip conversions flag - return m_conversionRule.mid(1); - } - - /// Returns true if there are any conversiton rule for this type, false otherwise. - bool hasConversionRule() const - { - return !m_conversionRule.isEmpty(); - } - - QVersionNumber version() const - { - return m_version; - } - - /// TODO-CONVERTER: mark as deprecated - bool hasNativeConversionRule() const - { - return m_conversionRule.startsWith(QLatin1String(NATIVE_CONVERSION_RULE_FLAG)); - } - - /// TODO-CONVERTER: mark as deprecated - bool hasTargetConversionRule() const - { - return m_conversionRule.startsWith(QLatin1String(TARGET_CONVERSION_RULE_FLAG)); - } - - bool isCppPrimitive() const; - - bool hasCustomConversion() const; - void setCustomConversion(CustomConversion* customConversion); - CustomConversion* customConversion() const; - - virtual TypeEntry *clone() const; - - void useAsTypedef(const TypeEntry *source); - - SourceLocation sourceLocation() const; - void setSourceLocation(const SourceLocation &sourceLocation); - -#ifndef QT_NO_DEBUG_STREAM - virtual void formatDebug(QDebug &d) const; -#endif - -protected: - TypeEntry(const TypeEntry &); - - virtual QString buildTargetLangName() const; - -private: - const TypeEntry *m_parent; - QString m_name; // C++ fully qualified - mutable QString m_cachedShortName; // C++ excluding inline namespaces - QString m_entryName; - QString m_targetLangPackage; - mutable QString m_cachedTargetLangName; // "Foo.Bar" - mutable QString m_cachedTargetLangEntryName; // "Bar" - CustomFunction m_customConstructor; - CustomFunction m_customDestructor; - CodeSnipList m_codeSnips; - DocModificationList m_docModifications; - IncludeList m_extraIncludes; - Include m_include; - QString m_conversionRule; - QVersionNumber m_version; - CustomConversion *m_customConversion = nullptr; - SourceLocation m_sourceLocation; // XML file - uint m_codeGeneration = GenerateAll; - int m_revision = 0; - int m_sbkIndex = 0; - Type m_type; - bool m_stream = false; -}; - -class TypeSystemTypeEntry : public TypeEntry -{ -public: - explicit TypeSystemTypeEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent); - - TypeEntry *clone() const override; - -protected: - TypeSystemTypeEntry(const TypeSystemTypeEntry &); -}; - -class VoidTypeEntry : public TypeEntry -{ -public: - VoidTypeEntry(); - - TypeEntry *clone() const override; - -protected: - VoidTypeEntry(const VoidTypeEntry &); -}; - -class VarargsTypeEntry : public TypeEntry -{ -public: - VarargsTypeEntry(); - - TypeEntry *clone() const override; - -protected: - VarargsTypeEntry(const VarargsTypeEntry &); -}; - -class TemplateArgumentEntry : public TypeEntry -{ -public: - explicit TemplateArgumentEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent); - - int ordinal() const - { - return m_ordinal; - } - void setOrdinal(int o) - { - m_ordinal = o; - } - - TypeEntry *clone() const override; - -protected: - TemplateArgumentEntry(const TemplateArgumentEntry &); - -private: - int m_ordinal = 0; -}; - -class ArrayTypeEntry : public TypeEntry -{ -public: - explicit ArrayTypeEntry(const TypeEntry *nested_type, const QVersionNumber &vr, - const TypeEntry *parent); - - void setNestedTypeEntry(TypeEntry *nested) - { - m_nestedType = nested; - } - const TypeEntry *nestedTypeEntry() const - { - return m_nestedType; - } - - QString targetLangApiName() const override; - - TypeEntry *clone() const override; - -protected: - ArrayTypeEntry(const ArrayTypeEntry &); - - QString buildTargetLangName() const override; - -private: - const TypeEntry *m_nestedType; -}; - - -class PrimitiveTypeEntry : public TypeEntry -{ -public: - explicit PrimitiveTypeEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent); - - QString targetLangApiName() const override; - void setTargetLangApiName(const QString &targetLangApiName) - { - m_targetLangApiName = targetLangApiName; - } - - QString defaultConstructor() const - { - return m_defaultConstructor; - } - void setDefaultConstructor(const QString& defaultConstructor) - { - m_defaultConstructor = defaultConstructor; - } - bool hasDefaultConstructor() const - { - return !m_defaultConstructor.isEmpty(); - } - - /** - * 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 { return m_referencedTypeEntry; } - - /** - * Defines type referenced by this entry. - * /param referencedTypeEntry type referenced by this entry - */ - void setReferencedTypeEntry(PrimitiveTypeEntry* referencedTypeEntry) - { - m_referencedTypeEntry = 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 - { - return m_preferredTargetLangType; - } - void setPreferredTargetLangType(bool b) - { - m_preferredTargetLangType = b; - } - - TypeEntry *clone() const override; - -protected: - PrimitiveTypeEntry(const PrimitiveTypeEntry &); - -private: - QString m_targetLangApiName; - QString m_defaultConstructor; - uint m_preferredTargetLangType : 1; - PrimitiveTypeEntry* m_referencedTypeEntry = nullptr; -}; - -class EnumValueTypeEntry; - -class EnumTypeEntry : public TypeEntry -{ -public: - explicit EnumTypeEntry(const QString &entryName, - const QVersionNumber &vr, - const TypeEntry *parent); - - QString targetLangQualifier() const; - - QString targetLangApiName() const override; - - QString qualifier() const; - - const EnumValueTypeEntry *nullValue() const { return m_nullValue; } - void setNullValue(const EnumValueTypeEntry *n) { m_nullValue = n; } - - void setFlags(FlagsTypeEntry *flags) - { - m_flags = flags; - } - FlagsTypeEntry *flags() const - { - return m_flags; - } - - bool isEnumValueRejected(const QString &name) const - { - return m_rejectedEnums.contains(name); - } - void addEnumValueRejection(const QString &name) - { - m_rejectedEnums << name; - } - QStringList enumValueRejections() const - { - return m_rejectedEnums; - } - - TypeEntry *clone() const override; -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif -protected: - EnumTypeEntry(const EnumTypeEntry &); - -private: - const EnumValueTypeEntry *m_nullValue = nullptr; - - QStringList m_rejectedEnums; - - FlagsTypeEntry *m_flags = nullptr; -}; - -// 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 { return m_value; } - const EnumTypeEntry* enclosingEnum() const { return m_enclosingEnum; } - - TypeEntry *clone() const override; - -protected: - EnumValueTypeEntry(const EnumValueTypeEntry &); - -private: - QString m_value; - const EnumTypeEntry* m_enclosingEnum; -}; - -class FlagsTypeEntry : public TypeEntry -{ -public: - explicit FlagsTypeEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent); - - QString targetLangApiName() const override; - - QString originalName() const - { - return m_originalName; - } - void setOriginalName(const QString &s) - { - m_originalName = s; - } - - QString flagsName() const - { - return m_flagsName; - } - void setFlagsName(const QString &name) - { - m_flagsName = name; - } - - EnumTypeEntry *originator() const - { - return m_enum; - } - void setOriginator(EnumTypeEntry *e) - { - m_enum = e; - } - - TypeEntry *clone() const override; - -protected: - FlagsTypeEntry(const FlagsTypeEntry &); - - QString buildTargetLangName() const override; - -private: - QString m_originalName; - QString m_flagsName; - EnumTypeEntry *m_enum = nullptr; -}; - -// 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: - ConstantValueTypeEntry(const ConstantValueTypeEntry &); -}; - -class ComplexTypeEntry : public TypeEntry -{ -public: - enum TypeFlag { - Deprecated = 0x4 - }; - 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; - - QString targetLangApiName() const override; - - void setTypeFlags(TypeFlags flags) - { - m_typeFlags = flags; - } - - TypeFlags typeFlags() const - { - return m_typeFlags; - } - - FunctionModificationList functionModifications() const - { - return m_functionMods; - } - void setFunctionModifications(const FunctionModificationList &functionModifications) - { - m_functionMods = functionModifications; - } - void addFunctionModification(const FunctionModification &functionModification) - { - m_functionMods << functionModification; - } - FunctionModificationList functionModifications(const QString &signature) const; - - AddedFunctionList addedFunctions() const - { - return m_addedFunctions; - } - void setAddedFunctions(const AddedFunctionList &addedFunctions) - { - m_addedFunctions = addedFunctions; - } - void addNewFunction(const AddedFunctionPtr &addedFunction) - { - m_addedFunctions << addedFunction; - } - - FieldModification fieldModification(const QString &name) const; - void setFieldModifications(const FieldModificationList &mods) - { - m_fieldMods = mods; - } - FieldModificationList fieldModifications() const - { - return m_fieldMods; - } - - QString defaultSuperclass() const - { - return m_defaultSuperclass; - } - void setDefaultSuperclass(const QString &sc) - { - m_defaultSuperclass = sc; - } - - QString qualifiedCppName() const override - { - return m_qualifiedCppName; - } - - - void setIsPolymorphicBase(bool on) - { - m_polymorphicBase = on; - } - bool isPolymorphicBase() const - { - return m_polymorphicBase; - } - - void setPolymorphicIdValue(const QString &value) - { - m_polymorphicIdValue = value; - } - QString polymorphicIdValue() const - { - return m_polymorphicIdValue; - } - - QString targetType() const - { - return m_targetType; - } - void setTargetType(const QString &code) - { - m_targetType = code; - } - - bool isGenericClass() const - { - return m_genericClass; - } - void setGenericClass(bool isGeneric) - { - m_genericClass = isGeneric; - } - - bool deleteInMainThread() const { return m_deleteInMainThread; } - void setDeleteInMainThread(bool d) { m_deleteInMainThread = d; } - - CopyableFlag copyable() const - { - return m_copyableFlag; - } - void setCopyable(CopyableFlag flag) - { - m_copyableFlag = flag; - } - - QString hashFunction() const - { - return m_hashFunction; - } - void setHashFunction(const QString &hashFunction) - { - m_hashFunction = hashFunction; - } - - void setBaseContainerType(const ComplexTypeEntry *baseContainer) - { - m_baseContainerType = baseContainer; - } - - const ComplexTypeEntry* baseContainerType() const - { - return m_baseContainerType; - } - - TypeSystem::ExceptionHandling exceptionHandling() const { return m_exceptionHandling; } - void setExceptionHandling(TypeSystem::ExceptionHandling e) { m_exceptionHandling = e; } - - TypeSystem::AllowThread allowThread() const { return m_allowThread; } - void setAllowThread(TypeSystem::AllowThread allowThread) { m_allowThread = allowThread; } - - QString defaultConstructor() const; - void setDefaultConstructor(const QString& defaultConstructor); - bool hasDefaultConstructor() const; - - TypeEntry *clone() const override; - - void useAsTypedef(const ComplexTypeEntry *source); - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif -protected: - ComplexTypeEntry(const ComplexTypeEntry &); - -private: - AddedFunctionList m_addedFunctions; - FunctionModificationList m_functionMods; - FieldModificationList m_fieldMods; - QString m_defaultConstructor; - QString m_defaultSuperclass; - QString m_qualifiedCppName; - - uint m_polymorphicBase : 1; - uint m_genericClass : 1; - uint m_deleteInMainThread : 1; - - QString m_polymorphicIdValue; - QString m_targetType; - TypeFlags m_typeFlags; - CopyableFlag m_copyableFlag = Unknown; - QString m_hashFunction; - - const ComplexTypeEntry* m_baseContainerType = nullptr; - // For class functions - TypeSystem::ExceptionHandling m_exceptionHandling = TypeSystem::ExceptionHandling::Unspecified; - TypeSystem::AllowThread m_allowThread = TypeSystem::AllowThread::Unspecified; -}; - -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 { return m_sourceType; } - void setSourceType(const QString &s) { m_sourceType =s; } - - TypeEntry *clone() const override; - - ComplexTypeEntry *source() const { return m_source; } - void setSource(ComplexTypeEntry *source) { m_source = source; } - - ComplexTypeEntry *target() const { return m_target; } - void setTarget(ComplexTypeEntry *target) { m_target = target; } - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif -protected: - TypedefEntry(const TypedefEntry &); - -private: - QString m_sourceType; - ComplexTypeEntry *m_source = nullptr; - ComplexTypeEntry *m_target = nullptr; -}; - -class ContainerTypeEntry : public ComplexTypeEntry -{ - Q_GADGET -public: - enum ContainerKind { - NoContainer, - ListContainer, - StringListContainer, - LinkedListContainer, - VectorContainer, - StackContainer, - QueueContainer, - SetContainer, - MapContainer, - MultiMapContainer, - HashContainer, - MultiHashContainer, - PairContainer, - }; - Q_ENUM(ContainerKind) - - explicit ContainerTypeEntry(const QString &entryName, ContainerKind containerKind, - const QVersionNumber &vr, const TypeEntry *parent); - - ContainerKind containerKind() const - { - return m_containerKind; - } - - QString typeName() const; - QString qualifiedCppName() const override; - - TypeEntry *clone() const override; - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif -protected: - ContainerTypeEntry(const ContainerTypeEntry &); - -private: - ContainerKind m_containerKind; -}; - -class SmartPointerTypeEntry : public ComplexTypeEntry -{ -public: - using Instantiations = QVector<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 - { - return m_getterName; - } - - QString refCountMethodName() const - { - return m_refCountMethodName; - } - - TypeEntry *clone() const override; - - Instantiations instantiations() const { return m_instantiations; } - void setInstantiations(const Instantiations &i) { m_instantiations = i; } - bool matchesInstantiation(const TypeEntry *e) const; - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif -protected: - SmartPointerTypeEntry(const SmartPointerTypeEntry &); - -private: - QString m_getterName; - QString m_smartPointerType; - QString m_refCountMethodName; - Instantiations m_instantiations; -}; - -class NamespaceTypeEntry : public ComplexTypeEntry -{ -public: - explicit NamespaceTypeEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent); - - TypeEntry *clone() const override; - - const NamespaceTypeEntry *extends() const { return m_extends; } - void setExtends(const NamespaceTypeEntry *e) { m_extends = e; } - - const QRegularExpression &filePattern() const { return m_filePattern; } // restrict files - void setFilePattern(const QRegularExpression &r); - - bool hasPattern() const { return m_hasPattern; } - - bool matchesFile(const QString &needle) const; - - bool isVisible() const; - void setVisibility(TypeSystem::Visibility v) { m_visibility = v; } - - // C++ 11 inline namespace, from code model - bool isInlineNamespace() const { return m_inlineNamespace; } - void setInlineNamespace(bool i) { m_inlineNamespace = i; } - - static bool isVisibleScope(const TypeEntry *e); - -#ifndef QT_NO_DEBUG_STREAM - void formatDebug(QDebug &d) const override; -#endif - -protected: - NamespaceTypeEntry(const NamespaceTypeEntry &); - -private: - QRegularExpression m_filePattern; - const NamespaceTypeEntry *m_extends = nullptr; - TypeSystem::Visibility m_visibility = TypeSystem::Visibility::Auto; - bool m_hasPattern = false; - bool m_inlineNamespace = false; -}; - -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); - ValueTypeEntry(const ValueTypeEntry &); -}; - -class FunctionTypeEntry : public TypeEntry -{ -public: - explicit FunctionTypeEntry(const QString& name, const QString& signature, - const QVersionNumber &vr, - const TypeEntry *parent); - void addSignature(const QString& signature) - { - m_signatures << signature; - } - - QStringList signatures() const - { - return m_signatures; - } - - bool hasSignature(const QString& signature) const - { - return m_signatures.contains(signature); - } - - TypeEntry *clone() const override; - -protected: - FunctionTypeEntry(const FunctionTypeEntry &); - -private: - QStringList m_signatures; -}; - -class ObjectTypeEntry : public ComplexTypeEntry -{ -public: - explicit ObjectTypeEntry(const QString &entryName, const QVersionNumber &vr, - const TypeEntry *parent); - - TypeEntry *clone() const override; - -protected: - ObjectTypeEntry(const ObjectTypeEntry &); -}; - -struct TypeRejection -{ - enum MatchType - { - ExcludeClass, // Match className only - Function, // Match className and function name - Field, // Match className and field name - Enum, // Match className and enum name - ArgumentType, // Match className and argument type - ReturnType, // Match className and return type - Invalid - }; - - QRegularExpression className; - QRegularExpression pattern; - MatchType matchType = Invalid; -}; - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug d, const TypeRejection &r); -#endif - -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 = QVector<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; -}; - -#endif // TYPESYSTEM_H diff --git a/sources/shiboken2/ApiExtractor/typesystem_enums.h b/sources/shiboken2/ApiExtractor/typesystem_enums.h deleted file mode 100644 index f6b4b6fa6..000000000 --- a/sources/shiboken2/ApiExtractor/typesystem_enums.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef TYPESYSTEM_ENUMS_H -#define TYPESYSTEM_ENUMS_H - -namespace TypeSystem -{ -enum Language { - NoLanguage = 0x0000, - TargetLangCode = 0x0001, - NativeCode = 0x0002, - ShellCode = 0x0004, - - // masks - All = TargetLangCode | NativeCode | ShellCode, - - TargetLangAndNativeCode = TargetLangCode | NativeCode -}; - -enum class AllowThread { - Allow, - Disallow, - Auto, - Unspecified -}; - -enum Ownership { - InvalidOwnership, - DefaultOwnership, - TargetLangOwnership, - CppOwnership -}; - -enum CodeSnipPosition { - CodeSnipPositionBeginning, - CodeSnipPositionEnd, - CodeSnipPositionDeclaration, - CodeSnipPositionAny, - CodeSnipPositionInvalid -}; - -enum DocModificationMode { - DocModificationAppend, - DocModificationPrepend, - DocModificationReplace, - DocModificationXPathReplace, - DocModificationInvalid -}; - -enum class ExceptionHandling { - Unspecified, - Off, - AutoDefaultToOff, - AutoDefaultToOn, - On -}; - -enum Visibility { // For namespaces - Unspecified, - Visible, - Invisible, - Auto -}; - -} // namespace TypeSystem - -#endif // TYPESYSTEM_ENUMS_H diff --git a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h b/sources/shiboken2/ApiExtractor/typesystem_typedefs.h deleted file mode 100644 index 73f92b294..000000000 --- a/sources/shiboken2/ApiExtractor/typesystem_typedefs.h +++ /dev/null @@ -1,53 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef TYPESYSTEM_TYPEDEFS_H -#define TYPESYSTEM_TYPEDEFS_H - -#include <QtCore/QHash> -#include <QtCore/QList> -#include <QtCore/QSharedPointer> -#include <QtCore/QVector> - -class CodeSnip; -class DocModification; - -struct AddedFunction; -struct FieldModification; -struct FunctionModification; -class TypeEntry; - -using AddedFunctionPtr = QSharedPointer<AddedFunction>; -using AddedFunctionList = QVector<AddedFunctionPtr>; -using CodeSnipList = QVector<CodeSnip>; -using DocModificationList = QVector<DocModification>; -using FieldModificationList = QVector<FieldModification>; -using FunctionModificationList = QVector<FunctionModification>; -using TypeEntries = QVector<const TypeEntry *>; - -#endif // TYPESYSTEM_TYPEDEFS_H diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.cpp b/sources/shiboken2/ApiExtractor/typesystemparser.cpp deleted file mode 100644 index 207c99c7a..000000000 --- a/sources/shiboken2/ApiExtractor/typesystemparser.cpp +++ /dev/null @@ -1,3067 +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$ -** -****************************************************************************/ - -#include "typesystemparser.h" -#include "typedatabase.h" -#include "messages.h" -#include "reporthandler.h" -#include <QtCore/QDir> -#include <QtCore/QFile> -#include <QtCore/QFileInfo> -#include <QtCore/QRegularExpression> -#include <QtCore/QSet> -#include <QtCore/QStringView> -#include <QtCore/QStringAlgorithms> -#include <QtCore/QXmlStreamAttributes> -#include <QtCore/QXmlStreamReader> -#include <QtCore/QXmlStreamEntityResolver> - -#include <algorithm> - -const char *TARGET_CONVERSION_RULE_FLAG = "0"; -const char *NATIVE_CONVERSION_RULE_FLAG = "1"; - -static inline QString allowThreadAttribute() { return QStringLiteral("allow-thread"); } -static inline QString colonColon() { return QStringLiteral("::"); } -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 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 classAttribute() { return QStringLiteral("class"); } -static inline QString generateAttribute() { return QStringLiteral("generate"); } -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 locationAttribute() { return QStringLiteral("location"); } -static inline QString modifiedTypeAttribute() { return QStringLiteral("modified-type"); } -static inline QString modifierAttribute() { return QStringLiteral("modifier"); } -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 staticAttribute() { return QStringLiteral("static"); } -static inline QString threadAttribute() { return QStringLiteral("thread"); } -static inline QString sourceAttribute() { return QStringLiteral("source"); } -static inline QString streamAttribute() { return QStringLiteral("stream"); } -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 QVector<CustomConversion *> customConversionsForReview; - -// Set a regular expression for rejection from text. By legacy, those are fixed -// strings, except for '*' meaning 'match all'. Enclosing in "^..$" -// indicates regular expression. -static bool setRejectionRegularExpression(const QString &patternIn, - QRegularExpression *re, - QString *errorMessage) -{ - QString pattern; - if (patternIn.startsWith(QLatin1Char('^')) && patternIn.endsWith(QLatin1Char('$'))) - pattern = patternIn; - else if (patternIn == QLatin1String("*")) - pattern = QStringLiteral("^.*$"); - else - pattern = QLatin1Char('^') + QRegularExpression::escape(patternIn) + QLatin1Char('$'); - re->setPattern(pattern); - if (!re->isValid()) { - *errorMessage = msgInvalidRegularExpression(patternIn, re->errorString()); - return false; - } - return true; -} - -// Extract a snippet from a file within annotation "// @snippet label". -static QString extractSnippet(const QString &code, const QString &snippetLabel) -{ - if (snippetLabel.isEmpty()) - return code; - const QString pattern = QStringLiteral(R"(^\s*//\s*@snippet\s+)") - + QRegularExpression::escape(snippetLabel) - + QStringLiteral(R"(\s*$)"); - const QRegularExpression snippetRe(pattern); - Q_ASSERT(snippetRe.isValid()); - - bool useLine = false; - QString result; - const auto lines = code.splitRef(QLatin1Char('\n')); - for (const QStringRef &line : lines) { - if (snippetRe.match(line).hasMatch()) { - useLine = !useLine; - if (!useLine) - break; // End of snippet reached - } else if (useLine) - result += line.toString() + QLatin1Char('\n'); - } - return CodeSnipAbstract::fixSpaces(result); -} - -template <class EnumType, Qt::CaseSensitivity cs = Qt::CaseInsensitive> -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, defaultReturnValue) \ -static EnumType functionName(QStringView needle, EnumType defaultValue = defaultReturnValue) \ -{ \ - typedef EnumLookup<EnumType, caseSensitivity> HaystackEntry; \ - 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, defaultValue}); \ - return it != end ? it->value : defaultValue; \ -} - -#define ENUM_LOOKUP_BINARY_SEARCH() \ - const auto end = haystack + sizeof(haystack) / sizeof(haystack[0]); \ - const HaystackEntry needleEntry{needle, defaultValue}; \ - const auto lb = std::lower_bound(haystack, end, needleEntry); \ - return lb != end && *lb == needleEntry ? lb->value : defaultValue; \ -} - -ENUM_LOOKUP_BEGIN(TypeSystem::AllowThread, Qt::CaseInsensitive, - allowThreadFromAttribute, TypeSystem::AllowThread::Unspecified) - { - {u"yes", TypeSystem::AllowThread::Allow}, - {u"true", TypeSystem::AllowThread::Allow}, - {u"auto", TypeSystem::AllowThread::Auto}, - {u"no", TypeSystem::AllowThread::Disallow}, - {u"false", TypeSystem::AllowThread::Disallow}, - }; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(TypeSystem::Language, Qt::CaseInsensitive, - languageFromAttribute, TypeSystem::NoLanguage) - { - {u"all", TypeSystem::All}, // sorted! - {u"native", TypeSystem::NativeCode}, // em algum lugar do cpp - {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_BEGIN(TypeSystem::Ownership, Qt::CaseInsensitive, - ownershipFromFromAttribute, TypeSystem::InvalidOwnership) - { - {u"target", TypeSystem::TargetLangOwnership}, - {u"c++", TypeSystem::CppOwnership}, - {u"default", TypeSystem::DefaultOwnership} - }; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(AddedFunction::Access, Qt::CaseInsensitive, - addedFunctionAccessFromAttribute, AddedFunction::InvalidAccess) - { - {u"public", AddedFunction::Public}, - {u"protected", AddedFunction::Protected}, - }; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(Modification::Modifiers, Qt::CaseSensitive, - modifierFromAttribute, Modification::InvalidModifier) - { - {u"private", Modification::Private}, - {u"public", Modification::Public}, - {u"protected", Modification::Protected}, - {u"friendly", Modification::Friendly}, - {u"rename", Modification::Rename}, - {u"final", Modification::Final}, - {u"non-final", Modification::NonFinal} - }; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(ReferenceCount::Action, Qt::CaseInsensitive, - referenceCountFromAttribute, ReferenceCount::Invalid) - { - {u"add", ReferenceCount::Add}, - {u"add-all", ReferenceCount::AddAll}, - {u"remove", ReferenceCount::Remove}, - {u"set", ReferenceCount::Set}, - {u"ignore", ReferenceCount::Ignore} - }; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(ArgumentOwner::Action, Qt::CaseInsensitive, - argumentOwnerActionFromAttribute, ArgumentOwner::Invalid) - { - {u"add", ArgumentOwner::Add}, - {u"remove", ArgumentOwner::Remove} - }; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(TypeSystem::CodeSnipPosition, Qt::CaseInsensitive, - codeSnipPositionFromAttribute, TypeSystem::CodeSnipPositionInvalid) - { - {u"beginning", TypeSystem::CodeSnipPositionBeginning}, - {u"end", TypeSystem::CodeSnipPositionEnd}, - {u"declaration", TypeSystem::CodeSnipPositionDeclaration} - }; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(Include::IncludeType, Qt::CaseInsensitive, - locationFromAttribute, Include::InvalidInclude) - { - {u"global", Include::IncludePath}, - {u"local", Include::LocalPath}, - {u"target", Include::TargetLangImport} - }; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(TypeSystem::DocModificationMode, Qt::CaseInsensitive, - docModificationFromAttribute, TypeSystem::DocModificationInvalid) - { - {u"append", TypeSystem::DocModificationAppend}, - {u"prepend", TypeSystem::DocModificationPrepend}, - {u"replace", TypeSystem::DocModificationReplace} - }; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(ContainerTypeEntry::ContainerKind, Qt::CaseSensitive, - containerTypeFromAttribute, ContainerTypeEntry::NoContainer) - { - {u"list", ContainerTypeEntry::ListContainer}, - {u"string-list", ContainerTypeEntry::StringListContainer}, - {u"linked-list", ContainerTypeEntry::LinkedListContainer}, - {u"vector", ContainerTypeEntry::VectorContainer}, - {u"stack", ContainerTypeEntry::StackContainer}, - {u"queue", ContainerTypeEntry::QueueContainer}, - {u"set", ContainerTypeEntry::SetContainer}, - {u"map", ContainerTypeEntry::MapContainer}, - {u"multi-map", ContainerTypeEntry::MultiMapContainer}, - {u"hash", ContainerTypeEntry::HashContainer}, - {u"multi-hash", ContainerTypeEntry::MultiHashContainer}, - {u"pair", ContainerTypeEntry::PairContainer} - }; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(TypeRejection::MatchType, Qt::CaseSensitive, - typeRejectionFromAttribute, TypeRejection::Invalid) - { - {u"class", TypeRejection::ExcludeClass}, - {u"function-name", TypeRejection::Function}, - {u"field-name", TypeRejection::Field}, - {u"enum-name", TypeRejection::Enum }, - {u"argument-type", TypeRejection::ArgumentType}, - {u"return-type", TypeRejection::ReturnType} - }; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(TypeSystem::ExceptionHandling, Qt::CaseSensitive, - exceptionHandlingFromAttribute, TypeSystem::ExceptionHandling::Unspecified) -{ - {u"no", TypeSystem::ExceptionHandling::Off}, - {u"false", TypeSystem::ExceptionHandling::Off}, - {u"auto-off", TypeSystem::ExceptionHandling::AutoDefaultToOff}, - {u"auto-on", TypeSystem::ExceptionHandling::AutoDefaultToOn}, - {u"yes", TypeSystem::ExceptionHandling::On}, - {u"true", TypeSystem::ExceptionHandling::On}, -}; -ENUM_LOOKUP_LINEAR_SEARCH() - -ENUM_LOOKUP_BEGIN(StackElement::ElementType, Qt::CaseInsensitive, - elementFromTag, StackElement::None) - { - {u"access", StackElement::Access}, // sorted! - {u"add-conversion", StackElement::AddConversion}, - {u"add-function", StackElement::AddFunction}, - {u"argument-map", StackElement::ArgumentMap}, - {u"array", StackElement::Array}, - {u"container-type", StackElement::ContainerTypeEntry}, - {u"conversion-rule", StackElement::ConversionRule}, - {u"custom-constructor", StackElement::CustomMetaConstructor}, - {u"custom-destructor", StackElement::CustomMetaDestructor}, - {u"custom-type", StackElement::CustomTypeEntry}, - {u"define-ownership", StackElement::DefineOwnership}, - {u"enum-type", StackElement::EnumTypeEntry}, - {u"extra-includes", StackElement::ExtraIncludes}, - {u"function", StackElement::FunctionTypeEntry}, - {u"include", StackElement::Include}, - {u"inject-code", StackElement::InjectCode}, - {u"inject-documentation", StackElement::InjectDocumentation}, - {u"insert-template", StackElement::TemplateInstanceEnum}, - {u"interface-type", StackElement::InterfaceTypeEntry}, - {u"load-typesystem", StackElement::LoadTypesystem}, - {u"modify-argument", StackElement::ModifyArgument}, - {u"modify-documentation", StackElement::ModifyDocumentation}, - {u"modify-field", StackElement::ModifyField}, - {u"modify-function", StackElement::ModifyFunction}, - {u"namespace-type", StackElement::NamespaceTypeEntry}, - {u"native-to-target", StackElement::NativeToTarget}, - {u"no-null-pointer", StackElement::NoNullPointers}, - {u"object-type", StackElement::ObjectTypeEntry}, - {u"parent", StackElement::ParentOwner}, - {u"primitive-type", StackElement::PrimitiveTypeEntry}, - {u"reference-count", StackElement::ReferenceCount}, - {u"reject-enum-value", StackElement::RejectEnumValue}, - {u"rejection", StackElement::Rejection}, - {u"remove", StackElement::Removal}, - {u"remove-argument", StackElement::RemoveArgument}, - {u"remove-default-expression", StackElement::RemoveDefaultExpression}, - {u"rename", StackElement::Rename}, - {u"replace", StackElement::Replace}, - {u"replace-default-expression", StackElement::ReplaceDefaultExpression}, - {u"replace-type", StackElement::ReplaceType}, - {u"smart-pointer-type", StackElement::SmartPointerTypeEntry}, - {u"suppress-warning", StackElement::SuppressedWarning}, - {u"system-include", StackElement::SystemInclude}, - {u"target-to-native", StackElement::TargetToNative}, - {u"template", StackElement::Template}, - {u"typedef-type", StackElement::TypedefTypeEntry}, - {u"typesystem", StackElement::Root}, - {u"value-type", StackElement::ValueTypeEntry}, - }; -ENUM_LOOKUP_BINARY_SEARCH() - -ENUM_LOOKUP_BEGIN(TypeSystem::Visibility, Qt::CaseSensitive, - visibilityFromAttribute, TypeSystem::Visibility::Unspecified) -{ - {u"no", TypeSystem::Visibility::Invisible}, - {u"false", TypeSystem::Visibility::Invisible}, - {u"auto", TypeSystem::Visibility::Auto}, - {u"yes", TypeSystem::Visibility::Visible}, - {u"true", TypeSystem::Visibility::Visible}, -}; -ENUM_LOOKUP_LINEAR_SEARCH() - -static int indexOfAttribute(const QXmlStreamAttributes &atts, - QStringView name) -{ - for (int i = 0, size = atts.size(); i < size; ++i) { - if (atts.at(i).qualifiedName() == name) - return i; - } - return -1; -} - -static QString msgMissingAttribute(const QString &a) -{ - return QLatin1String("Required attribute '") + a - + QLatin1String("' missing."); -} - -QTextStream &operator<<(QTextStream &str, const QXmlStreamAttribute &attribute) -{ - str << attribute.qualifiedName() << "=\"" << attribute.value() << '"'; - return str; -} - -static QString msgInvalidAttributeValue(const QXmlStreamAttribute &attribute) -{ - QString result; - QTextStream(&result) << "Invalid attribute value:" << attribute; - return result; -} - -static QString msgUnusedAttributes(const QStringRef &tag, const QXmlStreamAttributes &attributes) -{ - QString result; - QTextStream str(&result); - str << attributes.size() << " attributes(s) unused on <" << tag << ">: "; - for (int i = 0, size = attributes.size(); i < size; ++i) { - if (i) - str << ", "; - str << attributes.at(i); - } - return result; -} - -// QXmlStreamEntityResolver::resolveEntity(publicId, systemId) is not -// implemented; resolve via undeclared entities instead. -class TypeSystemEntityResolver : public QXmlStreamEntityResolver -{ -public: - explicit TypeSystemEntityResolver(const QString ¤tPath) : - m_currentPath(currentPath) {} - - QString resolveUndeclaredEntity(const QString &name) override; - -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"); - QString path = TypeDatabase::instance()->modifiedTypesystemFilepath(fileName, m_currentPath); - if (!QFileInfo::exists(path)) // PySide2-specific hack - fileName.prepend(QLatin1String("typesystem_")); - path = TypeDatabase::instance()->modifiedTypesystemFilepath(fileName, m_currentPath); - if (!QFileInfo::exists(path)) { - *errorMessage = QLatin1String("Unable to resolve: ") + entityName; - return QString(); - } - QFile file(path); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - *errorMessage = msgCannotOpenForReading(file); - return QString(); - } - 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 (commentEnd != -1) { - result.remove(0, commentEnd + 3); - result = result.trimmed(); - } - } - return result; -} - -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))); - } - } - return it.value(); -} - -TypeSystemParser::TypeSystemParser(TypeDatabase *database, bool generate) : - m_database(database), - m_generate(generate ? TypeEntry::GenerateAll : TypeEntry::GenerateForSubclass) -{ -} - -TypeSystemParser::~TypeSystemParser() = default; - -static QString readerFileName(const QXmlStreamReader &reader) -{ - const auto *file = qobject_cast<const QFile *>(reader.device()); - return file != nullptr ? file->fileName() : QString(); -} - -static QString msgReaderMessage(const QXmlStreamReader &reader, - const char *type, - const QString &what) -{ - QString message; - QTextStream str(&message); - const QString fileName = readerFileName(reader); - if (fileName.isEmpty()) - str << "<stdin>:"; - else - str << QDir::toNativeSeparators(fileName) << ':'; - // Use a tab separator like SourceLocation for suppression detection - str << reader.lineNumber() << ':' << reader.columnNumber() - << ":\t" << type << ": " << what; - return message; -} - -static QString msgReaderWarning(const QXmlStreamReader &reader, const QString &what) -{ - return msgReaderMessage(reader, "Warning", what); -} - -static QString msgReaderError(const QXmlStreamReader &reader, const QString &what) -{ - return msgReaderMessage(reader, "Error", what); -} - -static QString msgUnimplementedElementWarning(const QXmlStreamReader &reader, - const QStringRef &name) -{ - const QString message = QLatin1String("The element \"") + - name + QLatin1String("\" is not implemented."); - return msgReaderMessage(reader, "Warning", message); -} - -static QString msgUnimplementedAttributeWarning(const QXmlStreamReader &reader, - const QStringRef &name) -{ - const QString message = QLatin1String("The attribute \"") + - name + QLatin1String("\" is not implemented."); - return msgReaderMessage(reader, "Warning", message); -} - -static inline QString msgUnimplementedAttributeWarning(const QXmlStreamReader &reader, - const QXmlStreamAttribute &attribute) -{ - return msgUnimplementedAttributeWarning(reader, attribute.qualifiedName()); -} - -static QString - msgUnimplementedAttributeValueWarning(const QXmlStreamReader &reader, - QStringView name, QStringView value) -{ - QString message; - QTextStream(&message) << "The value \"" << value - << "\" of the attribute \"" << name << "\" is not implemented."; - return msgReaderMessage(reader, "Warning", message); -} - -static inline - QString msgUnimplementedAttributeValueWarning(const QXmlStreamReader &reader, - const QXmlStreamAttribute &attribute) -{ - return msgUnimplementedAttributeValueWarning(reader, - attribute.qualifiedName(), - attribute.value()); -} - -static bool addRejection(TypeDatabase *database, QXmlStreamAttributes *attributes, - QString *errorMessage) -{ - const int classIndex = indexOfAttribute(*attributes, classAttribute()); - if (classIndex == -1) { - *errorMessage = msgMissingAttribute(classAttribute()); - return false; - } - - TypeRejection rejection; - 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) { - const QStringRef name = attributes->at(i).qualifiedName(); - const TypeRejection::MatchType type = typeRejectionFromAttribute(name); - switch (type) { - case TypeRejection::Function: - case TypeRejection::Field: - case TypeRejection::Enum: - case TypeRejection::ArgumentType: - case TypeRejection::ReturnType: { - const QString pattern = attributes->takeAt(i).value().toString(); - if (!setRejectionRegularExpression(pattern, &rejection.pattern, errorMessage)) - return false; - rejection.matchType = type; - database->addRejection(rejection); - return true; - } - default: - break; - } - } - - // 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"); - return false; - } - rejection.matchType = TypeRejection::ExcludeClass; - database->addRejection(rejection); - return true; -} - -bool TypeSystemParser::parse(QXmlStreamReader &reader) -{ - m_error.clear(); - m_currentPath.clear(); - m_currentFile.clear(); - m_smartPointerInstantiations.clear(); - const bool result = parseXml(reader) && setupSmartPointerInstantiations(); - m_smartPointerInstantiations.clear(); - return result; -} - -bool TypeSystemParser::parseXml(QXmlStreamReader &reader) -{ - const QString fileName = readerFileName(reader); - if (!fileName.isEmpty()) { - QFileInfo fi(fileName); - m_currentPath = fi.absolutePath(); - m_currentFile = fi.absoluteFilePath(); - } - m_entityResolver.reset(new TypeSystemEntityResolver(m_currentPath)); - reader.setEntityResolver(m_entityResolver.data()); - - while (!reader.atEnd()) { - switch (reader.readNext()) { - case QXmlStreamReader::NoToken: - case QXmlStreamReader::Invalid: - m_error = msgReaderError(reader, reader.errorString()); - return false; - case QXmlStreamReader::StartElement: - if (!startElement(reader)) { - m_error = msgReaderError(reader, m_error); - return false; - } - - break; - case QXmlStreamReader::EndElement: - if (!endElement(reader.name())) { - m_error = msgReaderError(reader, m_error); - return false; - } - break; - case QXmlStreamReader::Characters: - if (!characters(reader.text())) { - m_error = msgReaderError(reader, m_error); - return false; - } - break; - case QXmlStreamReader::StartDocument: - case QXmlStreamReader::EndDocument: - case QXmlStreamReader::Comment: - case QXmlStreamReader::DTD: - case QXmlStreamReader::EntityReference: - case QXmlStreamReader::ProcessingInstruction: - break; - } - } - 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(const QStringRef &localName) -{ - 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; - } - return true; - } - - if (!localName.compare(QLatin1String("import-file"), Qt::CaseInsensitive)) - return true; - - if (!m_current) - return true; - - switch (m_current->type) { - case StackElement::Root: - if (m_generate == TypeEntry::GenerateAll) { - 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())); - } - } - break; - case StackElement::ObjectTypeEntry: - case StackElement::ValueTypeEntry: - case StackElement::InterfaceTypeEntry: - case StackElement::NamespaceTypeEntry: { - auto *centry = static_cast<ComplexTypeEntry *>(m_current->entry); - centry->setAddedFunctions(m_contextStack.top()->addedFunctions); - centry->setFunctionModifications(m_contextStack.top()->functionMods); - centry->setFieldModifications(m_contextStack.top()->fieldMods); - centry->setCodeSnips(m_contextStack.top()->codeSnips); - centry->setDocModification(m_contextStack.top()->docModifications); - } - break; - case StackElement::AddFunction: { - // 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)); - } - 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."); - 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; - } - 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().conversion_rules.last().addTemplateInstance(m_current->value.templateInstance); - break; - case StackElement::InjectCodeInFunction: - m_contextStack.top()->functionMods.last().snips.last().addTemplateInstance(m_current->value.templateInstance); - break; - default: - break; // nada - } - 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: - delete m_contextStack.pop(); - break; - default: - break; - } - - StackElement *child = m_current; - m_current = m_current->parent; - delete(child); - - return true; -} - -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); - return true; - } - - if (m_current->type == StackElement::CustomMetaConstructor || m_current->type == StackElement::CustomMetaDestructor) { - m_current->value.customFunction->addCode(ch); - return true; - } - - if (m_current->type == StackElement::ConversionRule - && m_current->parent->type == StackElement::ModifyArgument) { - m_contextStack.top()->functionMods.last().argument_mods.last().conversion_rules.last().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_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().modifiers |= 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 (m_current->type & StackElement::DocumentationMask) - m_contextStack.top()->docModifications.last().setCode(ch); - - return true; -} - -bool TypeSystemParser::importFileElement(const QXmlStreamAttributes &atts) -{ - const QString fileName = atts.value(nameAttribute()).toString(); - if (fileName.isEmpty()) { - m_error = QLatin1String("Required attribute 'name' missing for include-file tag."); - return false; - } - - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - file.setFileName(QLatin1String(":/trolltech/generator/") + fileName); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - m_error = QString::fromLatin1("Could not open file: '%1'").arg(QDir::toNativeSeparators(fileName)); - return false; - } - } - - const QStringRef quoteFrom = atts.value(quoteAfterLineAttribute()); - bool foundFromOk = quoteFrom.isEmpty(); - bool from = quoteFrom.isEmpty(); - - const QStringRef quoteTo = atts.value(quoteBeforeLineAttribute()); - bool foundToOk = quoteTo.isEmpty(); - bool to = true; - - QTextStream in(&file); - while (!in.atEnd()) { - QString line = in.readLine(); - if (from && to && line.contains(quoteTo)) { - to = false; - foundToOk = true; - break; - } - if (from && to) - characters(line + QLatin1Char('\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); - - if (!foundToOk) - m_error = toError; - if (!foundFromOk) - m_error = fromError; - if (!foundFromOk && !foundToOk) - m_error = fromError + QLatin1Char(' ') + toError; - return false; - } - - return true; -} - -static bool convertBoolean(QStringView value, const QString &attributeName, bool defaultValue) -{ -#ifdef QTBUG_69389_FIXED - 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) { - return false; - } -#else - if (QtPrivate::compareStrings(value, trueAttributeValue(), Qt::CaseInsensitive) == 0 - || QtPrivate::compareStrings(value, yesAttributeValue(), Qt::CaseInsensitive) == 0) { - return true; - } - if (QtPrivate::compareStrings(value, falseAttributeValue(), Qt::CaseInsensitive) == 0 - || QtPrivate::compareStrings(value, noAttributeValue(), Qt::CaseInsensitive) == 0) { - return false; - } -#endif - 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; - return defaultValue; -} - -static bool convertRemovalAttribute(QStringView remove, Modification& mod, QString& errorMsg) -{ - if (remove.isEmpty()) - return true; -#ifdef QTBUG_69389_FIXED - if (remove.compare(u"all", Qt::CaseInsensitive) == 0) { -#else - if (QtPrivate::compareStrings(remove, u"all", Qt::CaseInsensitive) == 0) { -#endif - mod.removal = TypeSystem::All; - return true; - } -#ifdef QTBUG_69389_FIXED - if (remove.compare(u"target", Qt::CaseInsensitive) == 0) { -#else - if (QtPrivate::compareStrings(remove, u"target", Qt::CaseInsensitive) == 0) { -#endif - mod.removal = TypeSystem::TargetLangAndNativeCode; - return true; - } - errorMsg = QString::fromLatin1("Bad removal type '%1'").arg(remove); - return 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, - QString name) -{ - for (auto e = element->parent; e ; e = e->parent) { - if (e->entry) { - if (e->entry->type() == TypeEntry::TypeSystemType) { - if (db->shouldDropTypeEntry(name)) // Unqualified - return true; - } - name.prepend(QLatin1Char('.')); - name.prepend(e->entry->name()); - } - } - return db->shouldDropTypeEntry(name); -} - -// 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")); - Q_ASSERT(whiteSpace.isValid()); - if (!funcName.startsWith(QLatin1String("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.") - .arg(tag, signature); - } - return QString(); -} - -inline const TypeEntry *TypeSystemParser::currentParentTypeEntry() const -{ - return m_current ? m_current->entry : nullptr; -} - -bool TypeSystemParser::checkRootElement() -{ - const bool ok = currentParentTypeEntry() != nullptr; - if (!ok) - m_error = msgNoRootTypeSystemEntry(); - return ok; -} - -void TypeSystemParser::applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type, - QXmlStreamAttributes *attributes) const -{ - type->setSourceLocation(SourceLocation(m_currentFile, - reader.lineNumber())); - type->setCodeGeneration(m_generate); - const int revisionIndex = - indexOfAttribute(*attributes, u"revision"); - if (revisionIndex != -1) - type->setRevision(attributes->takeAt(revisionIndex).value().toInt()); -} - -FlagsTypeEntry * - TypeSystemParser::parseFlagsEntry(const QXmlStreamReader &reader, - EnumTypeEntry *enumEntry, QString flagName, - const QVersionNumber &since, - QXmlStreamAttributes *attributes) - -{ - if (!checkRootElement()) - return nullptr; - auto ftype = new FlagsTypeEntry(QLatin1String("QFlags<") + enumEntry->name() + QLatin1Char('>'), - since, - currentParentTypeEntry()->typeSystemTypeEntry()); - ftype->setOriginator(enumEntry); - ftype->setTargetLangPackage(enumEntry->targetLangPackage()); - // Try toenumEntry get the guess the qualified flag name - if (!flagName.contains(colonColon())) { - auto eq = enumEntry->qualifier(); - if (!eq.isEmpty()) - flagName.prepend(eq + colonColon()); - } - - ftype->setOriginalName(flagName); - applyCommonAttributes(reader, ftype, attributes); - - QStringList lst = flagName.split(colonColon()); - const QString targetLangFlagName = QStringList(lst.mid(0, lst.size() - 1)).join(QLatin1Char('.')); - 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); - } - - ftype->setFlagsName(lst.constLast()); - enumEntry->setFlags(ftype); - - m_database->addFlagsType(ftype); - m_database->addType(ftype); - - const int revisionIndex = - indexOfAttribute(*attributes, u"flags-revision"); - ftype->setRevision(revisionIndex != -1 - ? attributes->takeAt(revisionIndex).value().toInt() - : enumEntry->revision()); - return ftype; -} - -SmartPointerTypeEntry * - TypeSystemParser::parseSmartPointerEntry(const QXmlStreamReader &reader, - const QString &name, const QVersionNumber &since, - QXmlStreamAttributes *attributes) -{ - if (!checkRootElement()) - return nullptr; - QString smartPointerType; - QString getter; - QString refCountMethodName; - QString instantiations; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == QLatin1String("type")) { - smartPointerType = attributes->takeAt(i).value().toString(); - } else if (name == QLatin1String("getter")) { - getter = attributes->takeAt(i).value().toString(); - } else if (name == QLatin1String("ref-count-method")) { - refCountMethodName = attributes->takeAt(i).value().toString(); - } else if (name == QLatin1String("instantiations")) { - instantiations = 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."); - return nullptr; - } - - QString signature = getter + QLatin1String("()"); - signature = TypeDatabase::normalizedSignature(signature); - if (signature.isEmpty()) { - m_error = QLatin1String("No signature for the smart pointer getter found."); - return nullptr; - } - - QString errorString = checkSignatureError(signature, - QLatin1String("smart-pointer-type")); - if (!errorString.isEmpty()) { - m_error = errorString; - return nullptr; - } - - auto *type = new SmartPointerTypeEntry(name, getter, smartPointerType, - refCountMethodName, since, currentParentTypeEntry()); - applyCommonAttributes(reader, type, attributes); - m_smartPointerInstantiations.insert(type, instantiations); - return type; -} - -PrimitiveTypeEntry * - TypeSystemParser::parsePrimitiveTypeEntry(const QXmlStreamReader &reader, - const QString &name, const QVersionNumber &since, - QXmlStreamAttributes *attributes) -{ - if (!checkRootElement()) - return nullptr; - auto *type = new PrimitiveTypeEntry(name, since, currentParentTypeEntry()); - applyCommonAttributes(reader, type, attributes); - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - 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()) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - } else if (name == preferredTargetLangTypeAttribute()) { - const bool v = convertBoolean(attributes->takeAt(i).value(), - preferredTargetLangTypeAttribute(), true); - type->setPreferredTargetLangType(v); - } else if (name == QLatin1String("default-constructor")) { - type->setDefaultConstructor(attributes->takeAt(i).value().toString()); - } - } - - if (type->targetLangApiName().isEmpty()) - type->setTargetLangApiName(type->name()); - type->setTargetLangPackage(m_defaultPackage); - return type; -} - -ContainerTypeEntry * - TypeSystemParser::parseContainerTypeEntry(const QXmlStreamReader &reader, - const QString &name, const QVersionNumber &since, - QXmlStreamAttributes *attributes) -{ - if (!checkRootElement()) - return nullptr; - const int typeIndex = indexOfAttribute(*attributes, u"type"); - if (typeIndex == -1) { - m_error = QLatin1String("no 'type' attribute specified"); - return nullptr; - } - const QStringRef typeName = attributes->takeAt(typeIndex).value(); - ContainerTypeEntry::ContainerKind containerType = containerTypeFromAttribute(typeName); - if (containerType == ContainerTypeEntry::NoContainer) { - m_error = QLatin1String("there is no container of type ") + typeName.toString(); - return nullptr; - } - auto *type = new ContainerTypeEntry(name, containerType, since, currentParentTypeEntry()); - applyCommonAttributes(reader, type, attributes); - return type; -} - -EnumTypeEntry * - TypeSystemParser::parseEnumTypeEntry(const QXmlStreamReader &reader, - const QString &name, const QVersionNumber &since, - QXmlStreamAttributes *attributes) -{ - if (!checkRootElement()) - return nullptr; - auto *entry = new EnumTypeEntry(name, since, currentParentTypeEntry()); - applyCommonAttributes(reader, entry, attributes); - entry->setTargetLangPackage(m_defaultPackage); - - QString flagNames; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == QLatin1String("upper-bound")) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - } else if (name == QLatin1String("lower-bound")) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - } else if (name == forceIntegerAttribute()) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - } else if (name == extensibleAttribute()) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - } else if (name == flagsAttribute()) { - flagNames = attributes->takeAt(i).value().toString(); - } - } - - // put in the flags parallel... - if (!flagNames.isEmpty()) { - const QStringList &flagNameList = flagNames.split(QLatin1Char(',')); - for (const QString &flagName : flagNameList) - parseFlagsEntry(reader, entry, flagName.trimmed(), since, attributes); - } - return entry; -} - - -NamespaceTypeEntry * - TypeSystemParser::parseNamespaceTypeEntry(const QXmlStreamReader &reader, - const QString &name, const QVersionNumber &since, - QXmlStreamAttributes *attributes) -{ - if (!checkRootElement()) - return nullptr; - QScopedPointer<NamespaceTypeEntry> result(new NamespaceTypeEntry(name, since, currentParentTypeEntry())); - auto visibility = TypeSystem::Visibility::Unspecified; - applyCommonAttributes(reader, result.data(), attributes); - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef attributeName = attributes->at(i).qualifiedName(); - if (attributeName == QLatin1String("files")) { - const QString pattern = attributes->takeAt(i).value().toString(); - QRegularExpression re(pattern); - if (!re.isValid()) { - m_error = msgInvalidRegularExpression(pattern, re.errorString()); - return nullptr; - } - result->setFilePattern(re); - } else if (attributeName == QLatin1String("extends")) { - const auto extendsPackageName = attributes->takeAt(i).value(); - auto allEntries = TypeDatabase::instance()->findNamespaceTypes(name); - auto extendsIt = std::find_if(allEntries.cbegin(), allEntries.cend(), - [extendsPackageName] (const NamespaceTypeEntry *e) { - return e->targetLangPackage() == extendsPackageName; - }); - if (extendsIt == allEntries.cend()) { - m_error = msgCannotFindNamespaceToExtend(name, extendsPackageName); - return nullptr; - } - result->setExtends(*extendsIt); - } else if (attributeName == visibleAttribute()) { - const auto attribute = attributes->takeAt(i); - visibility = visibilityFromAttribute(attribute.value()); - if (visibility == TypeSystem::Visibility::Unspecified) { - qCWarning(lcShiboken, "%s", - qPrintable(msgInvalidAttributeValue(attribute))); - } - } else if (attributeName == generateAttribute()) { - if (!convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true)) - visibility = TypeSystem::Visibility::Invisible; - } - } - - if (visibility != TypeSystem::Visibility::Unspecified) - result->setVisibility(visibility); - // Handle legacy "generate" before the common handling - applyComplexTypeAttributes(reader, result.data(), attributes); - - if (result->extends() && !result->hasPattern()) { - m_error = msgExtendingNamespaceRequiresPattern(name); - return nullptr; - } - - return result.take(); -} - -ValueTypeEntry * - TypeSystemParser::parseValueTypeEntry(const QXmlStreamReader &reader, - const QString &name, const QVersionNumber &since, - QXmlStreamAttributes *attributes) -{ - if (!checkRootElement()) - return nullptr; - auto *typeEntry = new ValueTypeEntry(name, since, currentParentTypeEntry()); - applyCommonAttributes(reader, typeEntry, attributes); - const int defaultCtIndex = - indexOfAttribute(*attributes, u"default-constructor"); - if (defaultCtIndex != -1) - typeEntry->setDefaultConstructor(attributes->takeAt(defaultCtIndex).value().toString()); - return typeEntry; -} - -FunctionTypeEntry * - TypeSystemParser::parseFunctionTypeEntry(const QXmlStreamReader &reader, - const QString &name, const QVersionNumber &since, - QXmlStreamAttributes *attributes) -{ - if (!checkRootElement()) - return nullptr; - const int signatureIndex = indexOfAttribute(*attributes, signatureAttribute()); - if (signatureIndex == -1) { - m_error = msgMissingAttribute(signatureAttribute()); - return nullptr; - } - const QString signature = - TypeDatabase::normalizedSignature(attributes->takeAt(signatureIndex).value().toString()); - - TypeEntry *existingType = m_database->findType(name); - - if (!existingType) { - auto *result = new FunctionTypeEntry(name, signature, since, currentParentTypeEntry()); - 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); - return nullptr; - } - - auto *result = reinterpret_cast<FunctionTypeEntry *>(existingType); - result->addSignature(signature); - return result; -} - -TypedefEntry * - TypeSystemParser::parseTypedefEntry(const QXmlStreamReader &reader, - const QString &name, - 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."); - return nullptr; - } - const int sourceIndex = indexOfAttribute(*attributes, sourceAttribute()); - if (sourceIndex == -1) { - 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); - return result; -} - -void TypeSystemParser::applyComplexTypeAttributes(const QXmlStreamReader &reader, - ComplexTypeEntry *ctype, - QXmlStreamAttributes *attributes) const -{ - bool generate = true; - ctype->setCopyable(ComplexTypeEntry::Unknown); - auto exceptionHandling = m_exceptionHandling; - auto allowThread = m_allowThread; - - QString package = m_defaultPackage; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == streamAttribute()) { - ctype->setStream(convertBoolean(attributes->takeAt(i).value(), streamAttribute(), 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()) { - ctype->setDefaultSuperclass(attributes->takeAt(i).value().toString()); - } else if (name == genericClassAttribute()) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - const bool v = convertBoolean(attributes->takeAt(i).value(), genericClassAttribute(), false); - ctype->setGenericClass(v); - } 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")) { - ctype->setPolymorphicIdValue(attributes->takeAt(i).value().toString()); - } 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()) { - const auto attribute = attributes->takeAt(i); - const auto v = exceptionHandlingFromAttribute(attribute.value()); - if (v != TypeSystem::ExceptionHandling::Unspecified) { - exceptionHandling = v; - } else { - qCWarning(lcShiboken, "%s", - qPrintable(msgInvalidAttributeValue(attribute))); - } - } else if (name == allowThreadAttribute()) { - const auto attribute = attributes->takeAt(i); - const auto v = allowThreadFromAttribute(attribute.value()); - if (v != TypeSystem::AllowThread::Unspecified) { - allowThread = v; - } else { - qCWarning(lcShiboken, "%s", - qPrintable(msgInvalidAttributeValue(attribute))); - } - } else if (name == QLatin1String("held-type")) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - } else if (name == QLatin1String("hash-function")) { - ctype->setHashFunction(attributes->takeAt(i).value().toString()); - } else if (name == forceAbstractAttribute()) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - } else if (name == deprecatedAttribute()) { - if (convertBoolean(attributes->takeAt(i).value(), deprecatedAttribute(), false)) - ctype->setTypeFlags(ctype->typeFlags() | ComplexTypeEntry::Deprecated); - } else if (name == deleteInMainThreadAttribute()) { - if (convertBoolean(attributes->takeAt(i).value(), deleteInMainThreadAttribute(), false)) - ctype->setDeleteInMainThread(true); - } else if (name == QLatin1String("target-type")) { - ctype->setTargetType(attributes->takeAt(i).value().toString()); - } - } - - if (exceptionHandling != TypeSystem::ExceptionHandling::Unspecified) - ctype->setExceptionHandling(exceptionHandling); - if (allowThread != TypeSystem::AllowThread::Unspecified) - ctype->setAllowThread(allowThread); - - // The generator code relies on container's package being empty. - if (ctype->type() != TypeEntry::ContainerType) - ctype->setTargetLangPackage(package); - - if (generate) - ctype->setCodeGeneration(m_generate); - else - ctype->setCodeGeneration(TypeEntry::GenerateForSubclass); -} - -bool TypeSystemParser::parseRenameFunction(const QXmlStreamReader &, - QString *name, QXmlStreamAttributes *attributes) -{ - QString signature; - QString rename; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - 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()) { - rename = attributes->takeAt(i).value().toString(); - } - } - - if (signature.isEmpty()) { - m_error = msgMissingAttribute(signatureAttribute()); - return false; - } - - *name = signature.left(signature.indexOf(QLatin1Char('('))).trimmed(); - - QString errorString = checkSignatureError(signature, QLatin1String("function")); - if (!errorString.isEmpty()) { - m_error = errorString; - return false; - } - - if (!rename.isEmpty()) { - static const QRegularExpression functionNameRegExp(QLatin1String("^[a-zA-Z_][a-zA-Z0-9_]*$")); - 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"); - return false; - } - FunctionModification mod; - if (!mod.setSignature(signature, &m_error)) - return false; - mod.renamedToName = rename; - mod.modifiers |= Modification::Rename; - m_contextStack.top()->functionMods << mod; - } - return true; -} - -bool TypeSystemParser::parseInjectDocumentation(const QXmlStreamReader &, - 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"); - return false; - } - - TypeSystem::DocModificationMode mode = TypeSystem::DocModificationReplace; - TypeSystem::Language lang = TypeSystem::NativeCode; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == QLatin1String("mode")) { - const QStringRef modeName = attributes->takeAt(i).value(); - mode = docModificationFromAttribute(modeName); - if (mode == TypeSystem::DocModificationInvalid) { - m_error = QLatin1String("Unknown documentation injection mode: ") + modeName; - return false; - } - } else if (name == formatAttribute()) { - const QStringRef format = attributes->takeAt(i).value(); - lang = languageFromAttribute(format); - if (lang != TypeSystem::TargetLangCode && lang != TypeSystem::NativeCode) { - m_error = QStringLiteral("unsupported class attribute: '%1'").arg(format); - return false; - } - } - } - - QString signature = m_current->type & StackElement::TypeEntryMask - ? QString() : m_currentSignature; - DocModification mod(mode, signature); - mod.setFormat(lang); - m_contextStack.top()->docModifications << mod; - return true; -} - -bool TypeSystemParser::parseModifyDocumentation(const QXmlStreamReader &, - 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"); - return false; - } - - const int xpathIndex = indexOfAttribute(*attributes, xPathAttribute()); - if (xpathIndex == -1) { - m_error = msgMissingAttribute(xPathAttribute()); - return false; - } - - const QString xpath = attributes->takeAt(xpathIndex).value().toString(); - QString signature = (m_current->type & StackElement::TypeEntryMask) ? QString() : m_currentSignature; - m_contextStack.top()->docModifications - << DocModification(xpath, signature); - return true; -} - -// m_exceptionHandling -TypeSystemTypeEntry *TypeSystemParser::parseRootElement(const QXmlStreamReader &, - const QVersionNumber &since, - QXmlStreamAttributes *attributes) -{ - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == packageAttribute()) { - m_defaultPackage = attributes->takeAt(i).value().toString(); - } else if (name == defaultSuperclassAttribute()) { - m_defaultSuperclass = attributes->takeAt(i).value().toString(); - } else if (name == exceptionHandlingAttribute()) { - const auto attribute = attributes->takeAt(i); - const auto v = exceptionHandlingFromAttribute(attribute.value()); - if (v != TypeSystem::ExceptionHandling::Unspecified) { - m_exceptionHandling = v; - } else { - qCWarning(lcShiboken, "%s", - qPrintable(msgInvalidAttributeValue(attribute))); - } - } else if (name == allowThreadAttribute()) { - const auto attribute = attributes->takeAt(i); - const auto v = allowThreadFromAttribute(attribute.value()); - if (v != TypeSystem::AllowThread::Unspecified) { - m_allowThread = v; - } else { - qCWarning(lcShiboken, "%s", - qPrintable(msgInvalidAttributeValue(attribute))); - } - } - } - - auto *moduleEntry = - const_cast<TypeSystemTypeEntry *>(m_database->findTypeSystemType(m_defaultPackage)); - const bool add = moduleEntry == nullptr; - if (add) { - moduleEntry = new TypeSystemTypeEntry(m_defaultPackage, since, - currentParentTypeEntry()); - } - moduleEntry->setCodeGeneration(m_generate); - - if ((m_generate == TypeEntry::GenerateForSubclass || - m_generate == TypeEntry::GenerateNothing) && !m_defaultPackage.isEmpty()) - TypeDatabase::instance()->addRequiredTargetImport(m_defaultPackage); - - if (add) - m_database->addTypeSystemType(moduleEntry); - return moduleEntry; -} - -bool TypeSystemParser::loadTypesystem(const QXmlStreamReader &, - QXmlStreamAttributes *attributes) -{ - QString typeSystemName; - bool generateChild = true; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == nameAttribute()) - typeSystemName = attributes->takeAt(i).value().toString(); - else if (name == generateAttribute()) - generateChild = convertBoolean(attributes->takeAt(i).value(), generateAttribute(), true); - } - if (typeSystemName.isEmpty()) { - m_error = QLatin1String("No typesystem name specified"); - return false; - } - const bool result = - m_database->parseFile(typeSystemName, m_currentPath, generateChild - && m_generate == TypeEntry::GenerateAll); - if (!result) - m_error = QStringLiteral("Failed to parse: '%1'").arg(typeSystemName); - return result; -} - -bool TypeSystemParser::parseRejectEnumValue(const QXmlStreamReader &, - QXmlStreamAttributes *attributes) -{ - if (!m_currentEnum) { - m_error = QLatin1String("<reject-enum-value> node must be used inside a <enum-type> node"); - return false; - } - const int nameIndex = indexOfAttribute(*attributes, nameAttribute()); - if (nameIndex == -1) { - m_error = msgMissingAttribute(nameAttribute()); - return false; - } - m_currentEnum->addEnumValueRejection(attributes->takeAt(nameIndex).value().toString()); - return true; -} - -bool TypeSystemParser::parseReplaceArgumentType(const QXmlStreamReader &, - const StackElement &topElement, - QXmlStreamAttributes *attributes) -{ - if (topElement.type != StackElement::ModifyArgument) { - m_error = QLatin1String("Type replacement can only be specified for argument modifications"); - return false; - } - const int modifiedTypeIndex = indexOfAttribute(*attributes, modifiedTypeAttribute()); - if (modifiedTypeIndex == -1) { - m_error = QLatin1String("Type replacement requires 'modified-type' attribute"); - return false; - } - m_contextStack.top()->functionMods.last().argument_mods.last().modified_type = - attributes->takeAt(modifiedTypeIndex).value().toString(); - return true; -} - -bool TypeSystemParser::parseCustomConversion(const QXmlStreamReader &, - const 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."); - return false; - } - - QString sourceFile; - QString snippetLabel; - TypeSystem::Language lang = TypeSystem::NativeCode; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == classAttribute()) { - const QStringRef languageAttribute = attributes->takeAt(i).value(); - lang = languageFromAttribute(languageAttribute); - if (lang != TypeSystem::TargetLangCode && lang != TypeSystem::NativeCode) { - m_error = QStringLiteral("unsupported class attribute: '%1'").arg(languageAttribute); - return false; - } - } else if (name == QLatin1String("file")) { - sourceFile = attributes->takeAt(i).value().toString(); - } else if (name == snippetAttribute()) { - snippetLabel = attributes->takeAt(i).value().toString(); - } - } - - if (topElement.type == StackElement::ModifyArgument) { - CodeSnip snip; - snip.language = lang; - m_contextStack.top()->functionMods.last().argument_mods.last().conversion_rules.append(snip); - return true; - } - - if (topElement.entry->hasConversionRule() || topElement.entry->hasCustomConversion()) { - m_error = QLatin1String("Types can have only one conversion rule"); - return false; - } - - // The old conversion rule tag that uses a file containing the conversion - // will be kept temporarily for compatibility reasons. - if (!sourceFile.isEmpty()) { - if (m_generate != TypeEntry::GenerateForSubclass - && m_generate != TypeEntry::GenerateNothing) { - - const char* conversionFlag = NATIVE_CONVERSION_RULE_FLAG; - if (lang == TypeSystem::TargetLangCode) - conversionFlag = TARGET_CONVERSION_RULE_FLAG; - - QFile conversionSource(sourceFile); - if (conversionSource.open(QIODevice::ReadOnly | QIODevice::Text)) { - const QString conversionRule = - extractSnippet(QString::fromUtf8(conversionSource.readAll()), snippetLabel); - topElement.entry->setConversionRule(QLatin1String(conversionFlag) + conversionRule); - } else { - qCWarning(lcShiboken).noquote().nospace() - << "File containing conversion code for " - << topElement.entry->name() << " type does not exist or is not readable: " - << sourceFile; - } - } - } - - auto *customConversion = new CustomConversion(m_current->entry); - customConversionsForReview.append(customConversion); - return true; -} - -bool TypeSystemParser::parseNativeToTarget(const QXmlStreamReader &, - const 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."); - return false; - } - CodeSnip snip; - if (!readFileSnippet(attributes, &snip)) - return false; - m_contextStack.top()->codeSnips.append(snip); - return true; -} - -bool TypeSystemParser::parseAddConversion(const QXmlStreamReader &, - const 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."); - return false; - } - QString sourceTypeName; - QString typeCheck; - CodeSnip snip; - if (!readFileSnippet(attributes, &snip)) - return false; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == QLatin1String("type")) - sourceTypeName = attributes->takeAt(i).value().toString(); - else if (name == QLatin1String("check")) - typeCheck = attributes->takeAt(i).value().toString(); - } - if (sourceTypeName.isEmpty()) { - m_error = QLatin1String("Target to Native conversions must specify the input type with the 'type' attribute."); - return false; - } - m_current->entry->customConversion()->addTargetToNativeConversion(sourceTypeName, typeCheck); - m_contextStack.top()->codeSnips.append(snip); - return true; -} - -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); - return ok; -} - -static bool parseArgumentIndex(const QString &index, int *result, QString *errorMessage) -{ - if (index == QLatin1String("return")) { - *result = 0; - return true; - } - if (index == QLatin1String("this")) { - *result = -1; - return true; - } - return parseIndex(index, result, errorMessage); -} - -bool TypeSystemParser::parseModifyArgument(const QXmlStreamReader &, - 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); - return false; - } - - QString index; - QString replaceValue; - bool resetAfterUse = false; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == indexAttribute()) { - index = attributes->takeAt(i).value().toString(); - } else if (name == QLatin1String("replace-value")) { - replaceValue = attributes->takeAt(i).value().toString(); - } else if (name == invalidateAfterUseAttribute()) { - resetAfterUse = convertBoolean(attributes->takeAt(i).value(), - invalidateAfterUseAttribute(), false); - } - } - - if (index.isEmpty()) { - m_error = msgMissingAttribute(indexAttribute()); - return false; - } - - int idx; - if (!parseArgumentIndex(index, &idx, &m_error)) - return false; - - if (!replaceValue.isEmpty() && idx) { - m_error = QLatin1String("replace-value is only supported for return values (index=0)."); - return false; - } - - ArgumentModification argumentModification = ArgumentModification(idx); - argumentModification.replace_value = replaceValue; - argumentModification.resetAfterUse = resetAfterUse; - m_contextStack.top()->functionMods.last().argument_mods.append(argumentModification); - return true; -} - -bool TypeSystemParser::parseNoNullPointer(const QXmlStreamReader &reader, - const StackElement &topElement, QXmlStreamAttributes *attributes) -{ - if (topElement.type != StackElement::ModifyArgument) { - m_error = QLatin1String("no-null-pointer requires argument modification as parent"); - return false; - } - - ArgumentModification &lastArgMod = m_contextStack.top()->functionMods.last().argument_mods.last(); - lastArgMod.noNullPointers = true; - - const int defaultValueIndex = - indexOfAttribute(*attributes, u"default-value"); - if (defaultValueIndex != -1) { - const QXmlStreamAttribute attribute = attributes->takeAt(defaultValueIndex); - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, attribute))); - } - return true; -} - -bool TypeSystemParser::parseDefineOwnership(const QXmlStreamReader &, - const StackElement &topElement, - QXmlStreamAttributes *attributes) -{ - if (topElement.type != StackElement::ModifyArgument) { - m_error = QLatin1String("define-ownership requires argument modification as parent"); - return false; - } - - TypeSystem::Language lang = TypeSystem::TargetLangCode; - QString ownership; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == classAttribute()) { - const QStringRef className = attributes->takeAt(i).value(); - lang = languageFromAttribute(className); - if (lang != TypeSystem::TargetLangCode && lang != TypeSystem::NativeCode) { - m_error = QStringLiteral("unsupported class attribute: '%1'").arg(className); - return false; - } - } else if (name == ownershipAttribute()) { - ownership = attributes->takeAt(i).value().toString(); - } - } - const TypeSystem::Ownership owner = ownershipFromFromAttribute(ownership); - if (owner == TypeSystem::InvalidOwnership) { - m_error = QStringLiteral("unsupported owner attribute: '%1'").arg(ownership); - return false; - } - m_contextStack.top()->functionMods.last().argument_mods.last().ownerships[lang] = owner; - return true; -} - -bool TypeSystemParser::parseArgumentMap(const QXmlStreamReader &, - const StackElement &topElement, - QXmlStreamAttributes *attributes) -{ - if (!(topElement.type & StackElement::CodeSnipMask)) { - m_error = QLatin1String("Argument maps requires code injection as parent"); - return false; - } - - int pos = 1; - QString metaName; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == indexAttribute()) { - if (!parseIndex(attributes->takeAt(i).value().toString(), &pos, &m_error)) - return false; - if (pos <= 0) { - m_error = QStringLiteral("Argument position %1 must be a positive number").arg(pos); - return false; - } - } else if (name == QLatin1String("meta-name")) { - metaName = attributes->takeAt(i).value().toString(); - } - } - - if (metaName.isEmpty()) - qCWarning(lcShiboken) << "Empty meta name in argument map"; - - if (topElement.type == StackElement::InjectCodeInFunction) { - m_contextStack.top()->functionMods.last().snips.last().argumentMap[pos] = metaName; - } else { - qCWarning(lcShiboken) << "Argument maps are only useful for injection of code " - "into functions."; - } - return true; -} - -bool TypeSystemParser::parseRemoval(const QXmlStreamReader &, - const StackElement &topElement, - QXmlStreamAttributes *attributes) -{ - if (topElement.type != StackElement::ModifyFunction) { - m_error = QLatin1String("Function modification parent required"); - return false; - } - - TypeSystem::Language lang = TypeSystem::All; - const int classIndex = indexOfAttribute(*attributes, classAttribute()); - if (classIndex != -1) { - const QStringRef value = attributes->takeAt(classIndex).value(); - lang = languageFromAttribute(value); - if (lang == TypeSystem::TargetLangCode) // "target" means TargetLangAndNativeCode here - lang = TypeSystem::TargetLangAndNativeCode; - if (lang != TypeSystem::TargetLangAndNativeCode && lang != TypeSystem::All) { - m_error = QStringLiteral("unsupported class attribute: '%1'").arg(value); - return false; - } - } - m_contextStack.top()->functionMods.last().removal = lang; - return true; -} - -bool TypeSystemParser::parseRename(const QXmlStreamReader &reader, - StackElement::ElementType type, - const StackElement &topElement, - QXmlStreamAttributes *attributes) -{ - if (topElement.type != StackElement::ModifyField - && topElement.type != StackElement::ModifyFunction - && topElement.type != StackElement::ModifyArgument) { - m_error = QLatin1String("Function, field or argument modification parent required"); - return false; - } - - Modification *mod = nullptr; - if (topElement.type == StackElement::ModifyFunction) - mod = &m_contextStack.top()->functionMods.last(); - else if (topElement.type == StackElement::ModifyField) - mod = &m_contextStack.top()->fieldMods.last(); - - Modification::Modifiers modifierFlag = Modification::Rename; - if (type == StackElement::Rename) { - const int toIndex = indexOfAttribute(*attributes, toAttribute()); - if (toIndex == -1) { - m_error = msgMissingAttribute(toAttribute()); - return false; - } - const QString renamed_to = attributes->takeAt(toIndex).value().toString(); - if (topElement.type == StackElement::ModifyFunction) - mod->setRenamedTo(renamed_to); - else if (topElement.type == StackElement::ModifyField) - mod->setRenamedTo(renamed_to); - else - m_contextStack.top()->functionMods.last().argument_mods.last().renamed_to = renamed_to; - } else { - const int modifierIndex = indexOfAttribute(*attributes, modifierAttribute()); - if (modifierIndex == -1) { - m_error = msgMissingAttribute(modifierAttribute()); - return false; - } - const QStringRef modifier = attributes->takeAt(modifierIndex).value(); - modifierFlag = modifierFromAttribute(modifier); - if (modifierFlag == Modification::InvalidModifier) { - m_error = QStringLiteral("Unknown access modifier: '%1'").arg(modifier); - return false; - } - if (modifierFlag == Modification::Friendly) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeValueWarning(reader, modifierAttribute(), modifier))); - } - } - - if (mod) - mod->modifiers |= modifierFlag; - return true; -} - -bool TypeSystemParser::parseModifyField(const QXmlStreamReader &reader, - QXmlStreamAttributes *attributes) -{ - FieldModification fm; - fm.modifiers = FieldModification::Readable | FieldModification::Writable; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == nameAttribute()) { - fm.name = attributes->takeAt(i).value().toString(); - } else if (name == removeAttribute()) { - if (!convertRemovalAttribute(attributes->takeAt(i).value(), fm, m_error)) - return false; - } else if (name == readAttribute()) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - if (!convertBoolean(attributes->takeAt(i).value(), readAttribute(), true)) - fm.modifiers &= ~FieldModification::Readable; - } else if (name == writeAttribute()) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - if (!convertBoolean(attributes->takeAt(i).value(), writeAttribute(), true)) - fm.modifiers &= ~FieldModification::Writable; - } - } - if (fm.name.isEmpty()) { - m_error = msgMissingAttribute(nameAttribute()); - return false; - } - m_contextStack.top()->fieldMods << fm; - return true; -} - -bool TypeSystemParser::parseAddFunction(const QXmlStreamReader &, - const StackElement &topElement, - QXmlStreamAttributes *attributes) -{ - if (!(topElement.type & (StackElement::ComplexTypeEntryMask | StackElement::Root))) { - m_error = QString::fromLatin1("Add function requires a complex type or a root tag as parent" - ", was=%1").arg(topElement.type, 0, 16); - return false; - } - QString originalSignature; - QString returnType = QLatin1String("void"); - bool staticFunction = false; - QString access; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == QLatin1String("signature")) { - originalSignature = attributes->takeAt(i).value().toString(); - } else if (name == QLatin1String("return-type")) { - returnType = attributes->takeAt(i).value().toString(); - } else if (name == staticAttribute()) { - staticFunction = convertBoolean(attributes->takeAt(i).value(), - staticAttribute(), false); - } else if (name == accessAttribute()) { - access = attributes->takeAt(i).value().toString(); - } - } - - QString signature = TypeDatabase::normalizedSignature(originalSignature); - if (signature.isEmpty()) { - m_error = QLatin1String("No signature for the added function"); - return false; - } - - QString errorString = checkSignatureError(signature, QLatin1String("add-function")); - if (!errorString.isEmpty()) { - m_error = errorString; - return false; - } - - AddedFunctionPtr func(new AddedFunction(signature, returnType)); - func->setStatic(staticFunction); - if (!signature.contains(QLatin1Char('('))) - signature += QLatin1String("()"); - m_currentSignature = signature; - - if (!access.isEmpty()) { - const AddedFunction::Access a = addedFunctionAccessFromAttribute(access); - if (a == AddedFunction::InvalidAccess) { - m_error = QString::fromLatin1("Bad access type '%1'").arg(access); - return false; - } - func->setAccess(a); - } - - m_contextStack.top()->addedFunctions << func; - m_contextStack.top()->addedFunctionModificationIndex = - m_contextStack.top()->functionMods.size(); - - FunctionModification mod; - if (!mod.setSignature(m_currentSignature, &m_error)) - return false; - mod.setOriginalSignature(originalSignature); - m_contextStack.top()->functionMods << mod; - return true; -} - -bool TypeSystemParser::parseModifyFunction(const QXmlStreamReader &reader, - const StackElement &topElement, - QXmlStreamAttributes *attributes) -{ - 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; - } - - QString originalSignature; - QString access; - QString removal; - QString rename; - QString association; - bool deprecated = false; - bool isThread = false; - TypeSystem::ExceptionHandling exceptionHandling = TypeSystem::ExceptionHandling::Unspecified; - TypeSystem::AllowThread allowThread = TypeSystem::AllowThread::Unspecified; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef 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 == QLatin1String("associated-to")) { - association = attributes->takeAt(i).value().toString(); - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - } else if (name == removeAttribute()) { - removal = attributes->takeAt(i).value().toString(); - } else if (name == deprecatedAttribute()) { - deprecated = convertBoolean(attributes->takeAt(i).value(), - deprecatedAttribute(), false); - } else if (name == threadAttribute()) { - isThread = convertBoolean(attributes->takeAt(i).value(), - threadAttribute(), false); - } else if (name == allowThreadAttribute()) { - const QXmlStreamAttribute attribute = attributes->takeAt(i); - allowThread = allowThreadFromAttribute(attribute.value()); - if (allowThread == TypeSystem::AllowThread::Unspecified) { - m_error = msgInvalidAttributeValue(attribute); - return false; - } - } else if (name == exceptionHandlingAttribute()) { - const auto attribute = attributes->takeAt(i); - exceptionHandling = exceptionHandlingFromAttribute(attribute.value()); - if (exceptionHandling == TypeSystem::ExceptionHandling::Unspecified) { - qCWarning(lcShiboken, "%s", - qPrintable(msgInvalidAttributeValue(attribute))); - } - } else if (name == virtualSlotAttribute()) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeWarning(reader, name))); - } - } - - const QString signature = TypeDatabase::normalizedSignature(originalSignature); - if (signature.isEmpty()) { - m_error = QLatin1String("No signature for modified function"); - return false; - } - - QString errorString = checkSignatureError(signature, QLatin1String("modify-function")); - if (!errorString.isEmpty()) { - m_error = errorString; - return false; - } - - FunctionModification mod; - if (!mod.setSignature(signature, &m_error)) - return false; - mod.setOriginalSignature(originalSignature); - mod.setExceptionHandling(exceptionHandling); - m_currentSignature = signature; - - if (!access.isEmpty()) { - const Modification::Modifiers m = modifierFromAttribute(access); - if ((m & (Modification::AccessModifierMask | Modification::FinalMask)) == 0) { - m_error = QString::fromLatin1("Bad access type '%1'").arg(access); - return false; - } - if (m == Modification::Final || m == Modification::NonFinal) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeValueWarning(reader, - accessAttribute(), access))); - } - mod.modifiers |= m; - } - - if (deprecated) - mod.modifiers |= Modification::Deprecated; - - if (!removal.isEmpty() && !convertRemovalAttribute(removal, mod, m_error)) - return false; - - if (!rename.isEmpty()) { - mod.renamedToName = rename; - mod.modifiers |= Modification::Rename; - } - - if (!association.isEmpty()) - mod.association = association; - - mod.setIsThread(isThread); - if (allowThread != TypeSystem::AllowThread::Unspecified) - mod.setAllowThread(allowThread); - - m_contextStack.top()->functionMods << mod; - return true; -} - -bool TypeSystemParser::parseReplaceDefaultExpression(const QXmlStreamReader &, - const StackElement &topElement, - QXmlStreamAttributes *attributes) -{ - if (!(topElement.type & StackElement::ModifyArgument)) { - m_error = QLatin1String("Replace default expression only allowed as child of argument modification"); - return false; - } - const int 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."); - return false; - } - - m_contextStack.top()->functionMods.last().argument_mods.last().replacedDefaultExpression = - attributes->takeAt(withIndex).value().toString(); - return true; -} - -CustomFunction * - TypeSystemParser::parseCustomMetaConstructor(const QXmlStreamReader &, - 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 QStringRef 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 QXmlStreamReader &reader, - const StackElement &topElement, - QXmlStreamAttributes *attributes) -{ - if (topElement.type != StackElement::ModifyArgument) { - m_error = QLatin1String("reference-count must be child of modify-argument"); - return false; - } - - ReferenceCount rc; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == actionAttribute()) { - const QXmlStreamAttribute attribute = attributes->takeAt(i); - rc.action = referenceCountFromAttribute(attribute.value()); - switch (rc.action) { - case ReferenceCount::Invalid: - m_error = QLatin1String("unrecognized value '") + attribute.value() - + QLatin1String("' for action attribute."); - return false; - case ReferenceCount::AddAll: - case ReferenceCount::Ignore: - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedAttributeValueWarning(reader, attribute))); - break; - default: - break; - } - } else if (name == QLatin1String("variable-name")) { - rc.varName = attributes->takeAt(i).value().toString(); - } - } - - m_contextStack.top()->functionMods.last().argument_mods.last().referenceCounts.append(rc); - return true; -} - -bool TypeSystemParser::parseParentOwner(const QXmlStreamReader &, - const StackElement &topElement, - QXmlStreamAttributes *attributes) -{ - if (topElement.type != StackElement::ModifyArgument) { - m_error = QLatin1String("parent-policy must be child of modify-argument"); - return false; - } - ArgumentOwner ao; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == indexAttribute()) { - const QString index = attributes->takeAt(i).value().toString(); - if (!parseArgumentIndex(index, &ao.index, &m_error)) - return false; - } else if (name == actionAttribute()) { - const QStringRef action = attributes->takeAt(i).value(); - ao.action = argumentOwnerActionFromAttribute(action); - if (ao.action == ArgumentOwner::Invalid) { - m_error = QLatin1String("Invalid parent actionr '") + action + QLatin1String("'."); - return false; - } - } - } - m_contextStack.top()->functionMods.last().argument_mods.last().owner = ao; - return true; -} - -bool TypeSystemParser::readFileSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip) -{ - QString fileName; - QString snippetLabel; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef 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 (fileName.isEmpty()) - return true; - const QString resolved = m_database->modifiedTypesystemFilepath(fileName, m_currentPath); - if (!QFile::exists(resolved)) { - m_error = QLatin1String("File for inject code not exist: ") - + QDir::toNativeSeparators(fileName); - return false; - } - QFile codeFile(resolved); - if (!codeFile.open(QIODevice::Text | QIODevice::ReadOnly)) { - m_error = msgCannotOpenForReading(codeFile); - return false; - } - QString source = fileName; - if (!snippetLabel.isEmpty()) - source += QLatin1String(" (") + snippetLabel + QLatin1Char(')'); - QString content; - QTextStream str(&content); - str << "// ========================================================================\n" - "// START of custom code block [file: " - << source << "]\n" - << extractSnippet(QString::fromUtf8(codeFile.readAll()), snippetLabel) - << "// END of custom code block [file: " << source - << "]\n// ========================================================================\n"; - snip->addCode(content); - return true; -} - -bool TypeSystemParser::parseInjectCode(const QXmlStreamReader &, - 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"); - return false; - } - - TypeSystem::CodeSnipPosition position = TypeSystem::CodeSnipPositionBeginning; - TypeSystem::Language lang = TypeSystem::TargetLangCode; - CodeSnip snip; - if (!readFileSnippet(attributes, &snip)) - return false; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == classAttribute()) { - const QStringRef className = attributes->takeAt(i).value(); - lang = languageFromAttribute(className); - if (lang == TypeSystem::NoLanguage) { - m_error = QStringLiteral("Invalid class specifier: '%1'").arg(className); - return false; - } - } else if (name == positionAttribute()) { - const QStringRef value = attributes->takeAt(i).value(); - position = codeSnipPositionFromAttribute(value); - if (position == TypeSystem::CodeSnipPositionInvalid) { - m_error = QStringLiteral("Invalid position: '%1'").arg(value); - return false; - } - } - } - - snip.position = position; - snip.language = lang; - - if (topElement.type == StackElement::ModifyFunction - || topElement.type == StackElement::AddFunction) { - FunctionModification &mod = m_contextStack.top()->functionMods.last(); - mod.snips << snip; - if (!snip.code().isEmpty()) - mod.modifiers |= 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; - } - return true; -} - -bool TypeSystemParser::parseInclude(const QXmlStreamReader &, - const StackElement &topElement, - TypeEntry *entry, QXmlStreamAttributes *attributes) -{ - QString fileName; - QString location; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == fileNameAttribute()) - fileName = attributes->takeAt(i).value().toString(); - else if (name == locationAttribute()) - location = attributes->takeAt(i).value().toString(); - } - const Include::IncludeType loc = locationFromAttribute(location); - if (loc == Include::InvalidInclude) { - m_error = QStringLiteral("Location not recognized: '%1'").arg(location); - return false; - } - - Include inc(loc, fileName); - if (topElement.type - & (StackElement::ComplexTypeEntryMask | StackElement::PrimitiveTypeEntry)) { - entry->setInclude(inc); - } else if (topElement.type == StackElement::ExtraIncludes) { - entry->addExtraInclude(inc); - } else { - m_error = QLatin1String("Only supported parent tags are primitive-type, complex types or extra-includes"); - return false; - } - return true; -} - -bool TypeSystemParser::parseSystemInclude(const QXmlStreamReader &, - QXmlStreamAttributes *attributes) -{ - const int index = indexOfAttribute(*attributes, fileNameAttribute()); - if (index == -1) { - m_error = msgMissingAttribute(fileNameAttribute()); - return false; - } - TypeDatabase::instance()->addSystemInclude(attributes->takeAt(index).value().toString()); - return true; -} - -TemplateInstance * - TypeSystemParser::parseTemplateInstanceEnum(const QXmlStreamReader &, - const 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."); - return nullptr; - } - const int nameIndex = indexOfAttribute(*attributes, nameAttribute()); - if (nameIndex == -1) { - m_error = msgMissingAttribute(nameAttribute()); - return nullptr; - } - return new TemplateInstance(attributes->takeAt(nameIndex).value().toString()); -} - -bool TypeSystemParser::parseReplace(const QXmlStreamReader &, - const StackElement &topElement, - StackElement *element, QXmlStreamAttributes *attributes) -{ - if (topElement.type != StackElement::TemplateInstanceEnum) { - m_error = QLatin1String("Can only insert replace rules into insert-template."); - return false; - } - QString from; - QString to; - for (int i = attributes->size() - 1; i >= 0; --i) { - const QStringRef name = attributes->at(i).qualifiedName(); - if (name == QLatin1String("from")) - from = attributes->takeAt(i).value().toString(); - else if (name == toAttribute()) - to = attributes->takeAt(i).value().toString(); - } - element->parent->value.templateInstance->addReplaceRule(from, to); - return true; -} - -static bool parseVersion(const QString &versionSpec, const QString &package, - QVersionNumber *result, QString *errorMessage) -{ - *result = QVersionNumber::fromString(versionSpec); - if (result->isNull()) { - *errorMessage = msgInvalidVersion(versionSpec, package); - return false; - } - return true; -} - -bool TypeSystemParser::startElement(const QXmlStreamReader &reader) -{ - if (m_ignoreDepth) { - ++m_ignoreDepth; - return true; - } - - const QStringRef tagName = reader.name(); - QXmlStreamAttributes attributes = reader.attributes(); - - VersionRange versionRange; - for (int i = attributes.size() - 1; i >= 0; --i) { - const QStringRef name = attributes.at(i).qualifiedName(); - if (name == sinceAttribute()) { - if (!parseVersion(attributes.takeAt(i).value().toString(), - m_defaultPackage, &versionRange.since, &m_error)) { - return false; - } - } else if (name == untilAttribute()) { - if (!parseVersion(attributes.takeAt(i).value().toString(), - m_defaultPackage, &versionRange.until, &m_error)) { - return false; - } - } - } - - if (!m_defaultPackage.isEmpty() && !versionRange.isNull()) { - TypeDatabase* td = TypeDatabase::instance(); - if (!td->checkApiVersion(m_defaultPackage, versionRange)) { - ++m_ignoreDepth; - return true; - } - } - - if (tagName.compare(QLatin1String("import-file"), Qt::CaseInsensitive) == 0) - return importFileElement(attributes); - - const StackElement::ElementType elementType = elementFromTag(tagName); - if (elementType == StackElement::None) { - m_error = QStringLiteral("Unknown tag name: '%1'").arg(tagName); - return false; - } - - if (m_currentDroppedEntry) { - ++m_currentDroppedEntryDepth; - return true; - } - - auto *element = new StackElement(m_current); - element->type = elementType; - - if (element->type == StackElement::Root && m_generate == TypeEntry::GenerateAll) - customConversionsForReview.clear(); - - if (element->type == StackElement::CustomMetaConstructor - || element->type == StackElement::CustomMetaDestructor) { - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedElementWarning(reader, tagName))); - } - - switch (element->type) { - case StackElement::Root: - case StackElement::NamespaceTypeEntry: - case StackElement::InterfaceTypeEntry: - case StackElement::ObjectTypeEntry: - case StackElement::ValueTypeEntry: - case StackElement::PrimitiveTypeEntry: - case StackElement::TypedefTypeEntry: - m_contextStack.push(new StackElementContext()); - break; - default: - break; - } - - if (element->type & StackElement::TypeEntryMask) { - QString name; - if (element->type != StackElement::FunctionTypeEntry) { - const int 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()); - 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::"))) { - 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, identifier)) { - m_currentDroppedEntry = element; - m_currentDroppedEntryDepth = 1; - if (ReportHandler::isDebug(ReportHandler::SparseDebug)) { - qCInfo(lcShiboken, "Type system entry '%s' was intentionally dropped from generation.", - qPrintable(identifier)); - } - 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 - && !parseRenameFunction(reader, &name, &attributes)) { - return false; - } - - // 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 (tmp && !tmp->isNamespace()) - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("Duplicate type entry: '%1'").arg(name); - } - - if (element->type == StackElement::EnumTypeEntry) { - const int 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"); - return false; - } - } - - if (name.isEmpty()) { - m_error = QLatin1String("no 'name' attribute specified"); - return false; - } - - switch (element->type) { - case StackElement::CustomTypeEntry: - if (!checkRootElement()) - return false; - element->entry = new TypeEntry(name, TypeEntry::CustomType, versionRange.since, m_current->entry); - break; - case StackElement::PrimitiveTypeEntry: - element->entry = parsePrimitiveTypeEntry(reader, name, versionRange.since, &attributes); - if (Q_UNLIKELY(!element->entry)) - return false; - break; - case StackElement::ContainerTypeEntry: - if (ContainerTypeEntry *ce = parseContainerTypeEntry(reader, name, versionRange.since, &attributes)) { - applyComplexTypeAttributes(reader, ce, &attributes); - element->entry = ce; - } else { - return false; - } - break; - - case StackElement::SmartPointerTypeEntry: - if (SmartPointerTypeEntry *se = parseSmartPointerEntry(reader, name, versionRange.since, &attributes)) { - applyComplexTypeAttributes(reader, se, &attributes); - element->entry = se; - } else { - 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; - break; - - case StackElement::ValueTypeEntry: - if (ValueTypeEntry *ve = parseValueTypeEntry(reader, name, versionRange.since, &attributes)) { - applyComplexTypeAttributes(reader, ve, &attributes); - element->entry = ve; - } else { - return false; - } - break; - case StackElement::NamespaceTypeEntry: - if (auto entry = parseNamespaceTypeEntry(reader, name, versionRange.since, &attributes)) - element->entry = entry; - else - return false; - break; - case StackElement::ObjectTypeEntry: - 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); - break; - case StackElement::FunctionTypeEntry: - element->entry = parseFunctionTypeEntry(reader, name, versionRange.since, &attributes); - if (Q_UNLIKELY(!element->entry)) - return false; - break; - case StackElement::TypedefTypeEntry: - if (TypedefEntry *te = parseTypedefEntry(reader, name, versionRange.since, &attributes)) { - applyComplexTypeAttributes(reader, te, &attributes); - element->entry = te; - } else { - return false; - } - break; - default: - Q_ASSERT(false); - } - - if (element->entry) { - if (!m_database->addType(element->entry, &m_error)) - return false; - } else { - qCWarning(lcShiboken).noquote().nospace() - << QStringLiteral("Type: %1 was rejected by typesystem").arg(name); - } - - } else if (element->type == StackElement::InjectDocumentation) { - if (!parseInjectDocumentation(reader, &attributes)) - return false; - } else if (element->type == StackElement::ModifyDocumentation) { - if (!parseModifyDocumentation(reader, &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); - return false; - } - - StackElement topElement = !m_current ? StackElement(nullptr) : *m_current; - element->entry = topElement.entry; - - switch (element->type) { - case StackElement::Root: - element->entry = parseRootElement(reader, versionRange.since, &attributes); - element->type = StackElement::Root; - break; - case StackElement::LoadTypesystem: - if (!loadTypesystem(reader, &attributes)) - return false; - break; - case StackElement::RejectEnumValue: - if (!parseRejectEnumValue(reader, &attributes)) - return false; - break; - case StackElement::ReplaceType: - if (!parseReplaceArgumentType(reader, topElement, &attributes)) - return false; - break; - case StackElement::ConversionRule: - if (!TypeSystemParser::parseCustomConversion(reader, topElement, &attributes)) - return false; - break; - case StackElement::NativeToTarget: - if (!parseNativeToTarget(reader, topElement, &attributes)) - 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."); - 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); - } - break; - case StackElement::AddConversion: - if (!parseAddConversion(reader, topElement, &attributes)) - return false; - break; - case StackElement::ModifyArgument: - if (!parseModifyArgument(reader, topElement, &attributes)) - return false; - break; - case StackElement::NoNullPointers: - if (!parseNoNullPointer(reader, topElement, &attributes)) - return false; - break; - case StackElement::DefineOwnership: - if (!parseDefineOwnership(reader, topElement, &attributes)) - return false; - break; - case StackElement::SuppressedWarning: { - const int 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)) - return false; - } - } - break; - case StackElement::ArgumentMap: - qCWarning(lcShiboken, "%s", - qPrintable(msgUnimplementedElementWarning(reader, tagName))); - if (!parseArgumentMap(reader, topElement, &attributes)) - return false; - break; - case StackElement::Removal: - if (!parseRemoval(reader, topElement, &attributes)) - return false; - break; - case StackElement::Rename: - case StackElement::Access: - if (!parseRename(reader, element->type, topElement, &attributes)) - return false; - break; - case StackElement::RemoveArgument: - if (topElement.type != StackElement::ModifyArgument) { - m_error = QLatin1String("Removing argument requires argument modification as parent"); - return false; - } - - m_contextStack.top()->functionMods.last().argument_mods.last().removed = true; - break; - - case StackElement::ModifyField: - if (!parseModifyField(reader, &attributes)) - return false; - break; - case StackElement::AddFunction: - if (!parseAddFunction(reader, topElement, &attributes)) - return false; - break; - case StackElement::ModifyFunction: - if (!parseModifyFunction(reader, topElement, &attributes)) - return false; - break; - case StackElement::ReplaceDefaultExpression: - if (!parseReplaceDefaultExpression(reader, topElement, &attributes)) - return false; - break; - case StackElement::RemoveDefaultExpression: - m_contextStack.top()->functionMods.last().argument_mods.last().removedDefaultExpression = true; - break; - case StackElement::CustomMetaConstructor: - case StackElement::CustomMetaDestructor: - element->value.customFunction = - parseCustomMetaConstructor(reader, element->type, topElement, &attributes); - break; - case StackElement::ReferenceCount: - if (!parseReferenceCount(reader, topElement, &attributes)) - return false; - break; - case StackElement::ParentOwner: - if (!parseParentOwner(reader, topElement, &attributes)) - return false; - break; - case StackElement::Array: - if (topElement.type != StackElement::ModifyArgument) { - m_error = QLatin1String("array must be child of modify-argument"); - return false; - } - m_contextStack.top()->functionMods.last().argument_mods.last().array = true; - break; - case StackElement::InjectCode: - if (!parseInjectCode(reader, topElement, element, &attributes)) - return false; - break; - case StackElement::Include: - if (!parseInclude(reader, topElement, element->entry, &attributes)) - return false; - break; - case StackElement::Rejection: - if (!addRejection(m_database, &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()); - if (nameIndex == -1) { - m_error = msgMissingAttribute(nameAttribute()); - return false; - } - element->value.templateEntry = - new TemplateEntry(attributes.takeAt(nameIndex).value().toString()); - } - break; - case StackElement::TemplateInstanceEnum: - element->value.templateInstance = - parseTemplateInstanceEnum(reader, topElement, &attributes); - if (!element->value.templateInstance) - return false; - break; - case StackElement::Replace: - if (!parseReplace(reader, topElement, element, &attributes)) - return false; - break; - default: - break; // nada - } - } - - if (!attributes.isEmpty()) { - const QString message = msgUnusedAttributes(tagName, attributes); - qCWarning(lcShiboken, "%s", qPrintable(msgReaderWarning(reader, message))); - } - - m_current = element; - return true; -} diff --git a/sources/shiboken2/ApiExtractor/typesystemparser.h b/sources/shiboken2/ApiExtractor/typesystemparser.h deleted file mode 100644 index 66d61f4a1..000000000 --- a/sources/shiboken2/ApiExtractor/typesystemparser.h +++ /dev/null @@ -1,281 +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 <QtCore/QStack> -#include <QtCore/QHash> -#include <QtCore/QScopedPointer> - -QT_FORWARD_DECLARE_CLASS(QXmlStreamAttributes) -QT_FORWARD_DECLARE_CLASS(QXmlStreamReader) - -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, - ArgumentMap = 0x0800, - SuppressedWarning = 0x0900, - Rejection = 0x0a00, - LoadTypesystem = 0x0b00, - RejectEnumValue = 0x0c00, - Template = 0x0d00, - TemplateInstanceEnum = 0x0e00, - Replace = 0x0f00, - AddFunction = 0x1000, - NativeToTarget = 0x1100, - TargetToNative = 0x1200, - AddConversion = 0x1300, - SystemInclude = 0x1400, - SimpleMask = 0x3f00, - - // Code snip tags (0x1000, 0x2000, ... , 0xf000) - InjectCode = 0x4000, - InjectCodeInFunction = 0x8000, - CodeSnipMask = 0xc000, - - // Function modifier tags (0x010000, 0x020000, ... , 0xf00000) - Access = 0x010000, - Removal = 0x020000, - Rename = 0x040000, - 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(QXmlStreamReader &reader); - - QString errorString() const { return m_error; } - -private: - bool parseXml(QXmlStreamReader &reader); - bool setupSmartPointerInstantiations(); - bool startElement(const QXmlStreamReader &reader); - SmartPointerTypeEntry *parseSmartPointerEntry(const QXmlStreamReader &, - const QString &name, - const QVersionNumber &since, - QXmlStreamAttributes *attributes); - bool endElement(const QStringRef& localName); - template <class String> // QString/QStringRef - bool characters(const String &ch); - - bool importFileElement(const QXmlStreamAttributes &atts); - - const TypeEntry *currentParentTypeEntry() const; - bool checkRootElement(); - void applyCommonAttributes(const QXmlStreamReader &reader, TypeEntry *type, - QXmlStreamAttributes *attributes) const; - PrimitiveTypeEntry * - parsePrimitiveTypeEntry(const QXmlStreamReader &, const QString &name, - const QVersionNumber &since, QXmlStreamAttributes *); - ContainerTypeEntry * - parseContainerTypeEntry(const QXmlStreamReader &, const QString &name, - const QVersionNumber &since, QXmlStreamAttributes *); - EnumTypeEntry * - parseEnumTypeEntry(const QXmlStreamReader &, const QString &name, - const QVersionNumber &since, QXmlStreamAttributes *); - FlagsTypeEntry * - parseFlagsEntry(const QXmlStreamReader &, EnumTypeEntry *enumEntry, - QString flagName, const QVersionNumber &since, - QXmlStreamAttributes *); - - NamespaceTypeEntry * - parseNamespaceTypeEntry(const QXmlStreamReader &, - const QString &name, const QVersionNumber &since, - QXmlStreamAttributes *attributes); - - ValueTypeEntry * - parseValueTypeEntry(const QXmlStreamReader &, const QString &name, - const QVersionNumber &since, QXmlStreamAttributes *); - FunctionTypeEntry * - parseFunctionTypeEntry(const QXmlStreamReader &, const QString &name, - const QVersionNumber &since, QXmlStreamAttributes *); - TypedefEntry * - parseTypedefEntry(const QXmlStreamReader &, const QString &name, - const QVersionNumber &since, QXmlStreamAttributes *); - void applyComplexTypeAttributes(const QXmlStreamReader &, ComplexTypeEntry *ctype, - QXmlStreamAttributes *) const; - bool parseRenameFunction(const QXmlStreamReader &, QString *name, - QXmlStreamAttributes *); - bool parseInjectDocumentation(const QXmlStreamReader &, QXmlStreamAttributes *); - bool parseModifyDocumentation(const QXmlStreamReader &, QXmlStreamAttributes *); - TypeSystemTypeEntry * - parseRootElement(const QXmlStreamReader &, const QVersionNumber &since, - QXmlStreamAttributes *); - bool loadTypesystem(const QXmlStreamReader &, QXmlStreamAttributes *); - bool parseRejectEnumValue(const QXmlStreamReader &, QXmlStreamAttributes *); - bool parseReplaceArgumentType(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *); - bool parseCustomConversion(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *); - bool parseAddConversion(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *); - bool parseNativeToTarget(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *attributes); - bool parseModifyArgument(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *attributes); - bool parseNoNullPointer(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *attributes); - bool parseDefineOwnership(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *); - bool parseArgumentMap(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *); - bool parseRemoval(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *); - bool parseRename(const QXmlStreamReader &, StackElement::ElementType type, - const StackElement &topElement, QXmlStreamAttributes *); - bool parseModifyField(const QXmlStreamReader &, QXmlStreamAttributes *); - bool parseAddFunction(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *); - bool parseModifyFunction(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *); - bool parseReplaceDefaultExpression(const QXmlStreamReader &, - const StackElement &topElement, QXmlStreamAttributes *); - CustomFunction * - parseCustomMetaConstructor(const QXmlStreamReader &, - StackElement::ElementType type, - const StackElement &topElement, QXmlStreamAttributes *); - bool parseReferenceCount(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *); - bool parseParentOwner(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *); - bool readFileSnippet(QXmlStreamAttributes *attributes, CodeSnip *snip); - bool parseInjectCode(const QXmlStreamReader &, const StackElement &topElement, - StackElement* element, QXmlStreamAttributes *); - bool parseInclude(const QXmlStreamReader &, const StackElement &topElement, - TypeEntry *entry, QXmlStreamAttributes *); - bool parseSystemInclude(const QXmlStreamReader &, QXmlStreamAttributes *); - TemplateInstance - *parseTemplateInstanceEnum(const QXmlStreamReader &, const StackElement &topElement, - QXmlStreamAttributes *); - bool parseReplace(const QXmlStreamReader &, 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/shiboken2/ApiExtractor/xmlutils.cpp b/sources/shiboken2/ApiExtractor/xmlutils.cpp deleted file mode 100644 index a179412a7..000000000 --- a/sources/shiboken2/ApiExtractor/xmlutils.cpp +++ /dev/null @@ -1,68 +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$ -** -****************************************************************************/ - -#include "xmlutils.h" - -#include "xmlutils_qt.h" -#include "xmlutils_libxslt.h" - -XQuery::XQuery() = default; - -XQuery::~XQuery() = default; - -QString XQuery::evaluate(QString xPathExpression, QString *errorMessage) -{ - // XQuery can't have invalid XML characters - xPathExpression.replace(QLatin1Char('&'), QLatin1String("&")); - xPathExpression.replace(QLatin1Char('<'), QLatin1String("<")); - return doEvaluate(xPathExpression, errorMessage); -} - -QSharedPointer<XQuery> XQuery::create(const QString &focus, QString *errorMessage) -{ -#if defined(HAVE_LIBXSLT) - return libXml_createXQuery(focus, errorMessage); -#elif defined(HAVE_QTXMLPATTERNS) - return qt_createXQuery(focus, errorMessage); -#else - *errorMessage = QLatin1String(__FUNCTION__) + QLatin1String(" is not implemented."); - return QSharedPointer<XQuery>(); -#endif -} - -QString xsl_transform(const QString &xml, const QString &xsl, QString *errorMessage) -{ -#if defined(HAVE_LIBXSLT) - return libXslt_transform(xml, xsl, errorMessage); -#elif defined(HAVE_QTXMLPATTERNS) - return qt_xsl_transform(xml, xsl, errorMessage); -#else - *errorMessage = QLatin1String(__FUNCTION__) + QLatin1String(" is not implemented."); - return xml; -#endif -} diff --git a/sources/shiboken2/ApiExtractor/xmlutils.h b/sources/shiboken2/ApiExtractor/xmlutils.h deleted file mode 100644 index 879b7757a..000000000 --- a/sources/shiboken2/ApiExtractor/xmlutils.h +++ /dev/null @@ -1,53 +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 XMLUTILS_H -#define XMLUTILS_H - -#include <QtCore/QSharedPointer> -#include <QtCore/QString> - -class XQuery -{ -public: - Q_DISABLE_COPY(XQuery); - - virtual ~XQuery(); - - QString evaluate(QString xPathExpression, QString *errorMessage); - - static QSharedPointer<XQuery> create(const QString &focus, QString *errorMessage); - -protected: - XQuery(); - - virtual QString doEvaluate(const QString &xPathExpression, QString *errorMessage) = 0; -}; - -QString xsl_transform(const QString &xml, const QString &xsl, QString *errorMessage); - -#endif // XMLUTILS_H diff --git a/sources/shiboken2/ApiExtractor/xmlutils_libxslt.cpp b/sources/shiboken2/ApiExtractor/xmlutils_libxslt.cpp deleted file mode 100644 index e1e185130..000000000 --- a/sources/shiboken2/ApiExtractor/xmlutils_libxslt.cpp +++ /dev/null @@ -1,231 +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$ -** -****************************************************************************/ - -#include "xmlutils_libxslt.h" -#include "xmlutils.h" - -#include <QtCore/QByteArray> -#include <QtCore/QCoreApplication> -#include <QtCore/QDir> -#include <QtCore/QFile> -#include <QtCore/QString> - -#include <libxslt/xsltutils.h> -#include <libxslt/transform.h> - -#include <libxml/xmlsave.h> -#include <libxml/xpath.h> - -#include <cstdlib> -#include <memory> - -static void cleanup() -{ - xsltCleanupGlobals(); - xmlCleanupParser(); -} - -static void ensureInitialized() -{ - static bool initialized = false; - if (!initialized) { - initialized = true; - xmlInitParser(); - xsltInit(); - qAddPostRoutine(cleanup); - } -} - -namespace { - -// RAI Helpers for cleaning up libxml2/libxslt data - -struct XmlDocDeleter // for std::unique_ptr<xmlDoc> -{ - void operator()(xmlDocPtr xmlDoc) { xmlFreeDoc(xmlDoc); } -}; - -struct XmlXPathObjectDeleter -{ - void operator()(xmlXPathObjectPtr xPathObject) { xmlXPathFreeObject(xPathObject); } -}; - -struct XmlStyleSheetDeleter // for std::unique_ptr<xsltStylesheet> -{ - void operator()(xsltStylesheetPtr xslt) { xsltFreeStylesheet(xslt); } -}; - -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>; -using XmlXPathContextUniquePtr = std::unique_ptr<xmlXPathContext, XmlXPathContextDeleter>; - -// Helpers for formatting nodes obtained from XPATH queries - -static int qbXmlOutputWriteCallback(void *context, const char *buffer, int len) -{ - static_cast<QByteArray *>(context)->append(buffer, len); - return len; -} - -static int qbXmlOutputCloseCallback(void * /* context */) { return 0; } - -static QByteArray formatNode(xmlNodePtr node, QString *errorMessage) -{ - QByteArray result; - xmlSaveCtxtPtr saveContext = - xmlSaveToIO(qbXmlOutputWriteCallback, qbXmlOutputCloseCallback, - &result, "UTF-8", 0); - if (!saveContext) { - *errorMessage = QLatin1String("xmlSaveToIO() failed."); - return result; - } - const long saveResult = xmlSaveTree(saveContext, node); - xmlSaveClose(saveContext); - if (saveResult < 0) - *errorMessage = QLatin1String("xmlSaveTree() failed."); - return result; -} - -// XPath expressions -class LibXmlXQuery : public XQuery -{ -public: - explicit LibXmlXQuery(XmlDocUniquePtr &doc, XmlXPathContextUniquePtr &xpathContext) : - m_doc(std::move(doc)), m_xpathContext(std::move(xpathContext)) - { - ensureInitialized(); - } - -protected: - QString doEvaluate(const QString &xPathExpression, QString *errorMessage) override; - -private: - XmlDocUniquePtr m_doc; - XmlXPathContextUniquePtr m_xpathContext; -}; - -QString LibXmlXQuery::doEvaluate(const QString &xPathExpression, QString *errorMessage) -{ - const QByteArray xPathExpressionB = xPathExpression.toUtf8(); - auto xPathExpressionX = reinterpret_cast<const xmlChar *>(xPathExpressionB.constData()); - - XmlPathObjectUniquePtr xPathObject(xmlXPathEvalExpression(xPathExpressionX, m_xpathContext.get())); - if (!xPathObject) { - *errorMessage = QLatin1String("xmlXPathEvalExpression() failed for \"") + xPathExpression - + QLatin1Char('"'); - return QString(); - } - QString result; - if (xmlNodeSetPtr nodeSet = xPathObject->nodesetval) { - for (int n = 0, count = nodeSet->nodeNr; n < count; ++n) { - auto node = nodeSet->nodeTab[n]; - if (node->type == XML_ELEMENT_NODE) { - result += QString::fromLocal8Bit(formatNode(node, errorMessage)); - if (!errorMessage->isEmpty()) - return QString(); - } - } - } - return result; -} - -QSharedPointer<XQuery> libXml_createXQuery(const QString &focus, QString *errorMessage) -{ - XmlDocUniquePtr doc(xmlParseFile(QFile::encodeName(focus).constData())); - if (!doc) { - *errorMessage = QLatin1String("libxml2: Cannot set focus to ") + QDir::toNativeSeparators(focus); - return {}; - } - XmlXPathContextUniquePtr xpathContext(xmlXPathNewContext(doc.get())); - if (!xpathContext) { - *errorMessage = QLatin1String("libxml2: xmlXPathNewContext() failed"); - return {}; - } - return QSharedPointer<XQuery>(new LibXmlXQuery(doc, xpathContext)); -} - -// XSLT transformation - -static const char xsltPrefix[] = R"(<?xml version="1.0" encoding="UTF-8" ?> - <xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> -)"; - -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>")); - } - const QByteArray xmlData = xml.toUtf8(); - XmlDocUniquePtr xmlDoc(xmlParseMemory(xmlData.constData(), xmlData.size())); - if (!xmlDoc) { - *errorMessage = QLatin1String("xmlParseMemory() failed for XML."); - return xml; - } - - // Read XSL data as a XML file - const QByteArray xslData = xsl.toUtf8(); - // xsltFreeStylesheet will delete this pointer - xmlDocPtr xslDoc = xmlParseMemory(xslData.constData(), xslData.size()); - if (!xslDoc) { - *errorMessage = QLatin1String("xmlParseMemory() failed for XSL \"") - + xsl + QLatin1String("\"."); - return xml; - }; - - // Parse XSL data - XmlStyleSheetUniquePtr xslt(xsltParseStylesheetDoc(xslDoc)); - if (!xslt) { - *errorMessage = QLatin1String("xsltParseStylesheetDoc() failed."); - return xml; - } - - // Apply XSL - XmlDocUniquePtr xslResult(xsltApplyStylesheet(xslt.get(), xmlDoc.get(), nullptr)); - xmlChar *buffer = nullptr; - int bufferSize; - QString result; - if (xsltSaveResultToString(&buffer, &bufferSize, xslResult.get(), xslt.get()) == 0) { - result = QString::fromUtf8(reinterpret_cast<char*>(buffer), bufferSize); - std::free(buffer); - } else { - *errorMessage = QLatin1String("xsltSaveResultToString() failed."); - result = xml; - } - return result.trimmed(); -} diff --git a/sources/shiboken2/ApiExtractor/xmlutils_libxslt.h b/sources/shiboken2/ApiExtractor/xmlutils_libxslt.h deleted file mode 100644 index c32b3901d..000000000 --- a/sources/shiboken2/ApiExtractor/xmlutils_libxslt.h +++ /dev/null @@ -1,40 +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 XMLUTILS_LIBXSLT_H -#define XMLUTILS_LIBXSLT_H - -#include <QtCore/QString> -#include <QtCore/QSharedPointer> - -class XQuery; - -QSharedPointer<XQuery> libXml_createXQuery(const QString &focus, QString *errorMessage); - -QString libXslt_transform(const QString &xml, QString xsl, QString *errorMessage); - -#endif // XMLUTILS_LIBXSLT_H diff --git a/sources/shiboken2/ApiExtractor/xmlutils_qt.cpp b/sources/shiboken2/ApiExtractor/xmlutils_qt.cpp deleted file mode 100644 index f703bc5f9..000000000 --- a/sources/shiboken2/ApiExtractor/xmlutils_qt.cpp +++ /dev/null @@ -1,102 +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$ -** -****************************************************************************/ - -#include "xmlutils.h" -#include "xmlutils_qt.h" - -#include <QtXmlPatterns/QXmlQuery> - -#include <QtCore/QDir> -#include <QtCore/QUrl> - -class QtXQuery : public XQuery -{ -public: - QtXQuery() = default; - - bool setFocus(const QString &fileName) - { return m_xquery.setFocus(QUrl::fromLocalFile(fileName)); } - -protected: - QString doEvaluate(const QString &xPathExpression, QString *errorMessage) override; - -private: - QXmlQuery m_xquery; -}; - -QString QtXQuery::doEvaluate(const QString &xPathExpression, QString *errorMessage) -{ - m_xquery.setQuery(xPathExpression); - if (!m_xquery.isValid()) { - *errorMessage = QLatin1String("QXmlQuery: Bad query: \"") + xPathExpression - + QLatin1Char('"'); - return QString(); - } - - QString result; - m_xquery.evaluateTo(&result); - return result; -} - -QSharedPointer<XQuery> qt_createXQuery(const QString &focus, QString *errorMessage) -{ - QSharedPointer<QtXQuery> result(new QtXQuery); - if (!result->setFocus(focus)) { - *errorMessage = QLatin1String("QXmlQuery: Cannot set focus to ") + QDir::toNativeSeparators(focus); - result.reset(); - } - return std::move(result); -} - -// XSLT transformation - -static const char xsltPrefix[] = R"(<?xml version="1.0" encoding="UTF-8"?> - <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> -)"; - -QString qt_xsl_transform(const QString &xml, QString xsl, QString *errorMessage) -{ - QXmlQuery query(QXmlQuery::XSLT20); - if (!xsl.startsWith(QLatin1String("<?xml"))) { - xsl.prepend(QLatin1String(xsltPrefix)); - xsl.append(QLatin1String("</xsl:stylesheet>")); - } - query.setFocus(xml); - query.setQuery(xsl); - if (!query.isValid()) { - *errorMessage = QLatin1String("QXmlQuery: Invalid query \"") + xsl - + QLatin1String("\"."); - return xml; - } - QString result; - if (!query.evaluateTo(&result)) { - *errorMessage = QLatin1String("QXmlQuery: evaluate() failed."); - return xml; - } - return result.trimmed(); -} diff --git a/sources/shiboken2/ApiExtractor/xmlutils_qt.h b/sources/shiboken2/ApiExtractor/xmlutils_qt.h deleted file mode 100644 index a9c9adfa2..000000000 --- a/sources/shiboken2/ApiExtractor/xmlutils_qt.h +++ /dev/null @@ -1,40 +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 XMLUTILS_QT_H -#define XMLUTILS_QT_H - -#include <QtCore/QString> -#include <QtCore/QSharedPointer> - -class XQuery; - -QSharedPointer<XQuery> qt_createXQuery(const QString &focus, QString *errorMessage); - -QString qt_xsl_transform(const QString &xml, QString xsl, QString *errorMessage); - -#endif // XMLUTILS_QT_H |