summaryrefslogtreecommitdiff
path: root/src/qdoc/qmlcodeparser.h
Commit message (Collapse)AuthorAgeFilesLines
* QDoc: Move QDoc source files under a further "qdoc" directoryLuca Di Sera2023-04-121-38/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc development under the "qttools" repository is currently performed under the "src/qdoc" directory, which contains all source files and directories relevant to QDoc as direct children. Due to a slow restructuring of how QDoc works, what its dependencies are and certain possible architectural changes, the infrastructure that is expected to be required for the development of QDoc might increase. Some of that infrastructure, which might require some custom effort, is expected to be developed as "independent" "library-like" sub-projects, which QDoc depends on. Albeit developed "independently", such infrastructure would be developed specifically for QDoc and thus should live "adjacent" to it. To allow such a structure a new "qdoc" directory was added under the "src/qdoc" directory. All source files and directory that were previously children of the "src/qdoc" directory were moved under the new "qdoc" directory. This preserves the space for QDoc-related elements and the relative project structure while allowing some space for "adjacent" projects that are intended for QDoc specifically. To support the change, a new "CMakeLists.txt" file was introduced under "src/qdoc", which dispatches to the "CMakeLists.txt" file in the new "src/qdoc/qdoc" directory. QDoc is only built when certain dependencies are found. This is supported through the use of Qt features at the CMake level. The "CMakeLists.txt" file in "src", thus dispatched to the "src/qdoc" directory only when the required features were found. As "independent", "library-like", entities might not have the same requirements as QDoc, the "CMakeLists.txt" file in "src" was modified to always dispatch to the "src/qdoc" directory while the features-check was moved to the new "CMakeLists.txt" files in "src/qdoc", so as to allow non-QDoc but QDoc-specific project to have an independent configuration for building. Certain test projects in "test/auto/qdoc/" depends on QDoc-specific source-files to generate their CMake targets. Those dependencies were generally specified as relative paths. The additional level in the directory structure invalidated the paths and, hence, the relevant "CMakeLists.txt" files for those projects were modified to correctly refer to the new directory structure. Change-Id: I50c7106614428753544eaba5091e1e44d48fd31d Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Remove `QmlCodeParser::m_engine`Luca Di Sera2023-03-271-3/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As part of producing a documentation set, QDoc parses a series of user-defined input source files in various languages to extract the user-provided documentation and certain source-code level elements. For QML source files, the `QmlCodeParser` class is used, taking care of reading the QML code and build an internal representation for some of its elements. `QmlCodeParser` uses the `QQmlJs` parsing api to do so. As part of using the `QQmlJs` parsing api, `QmlCodeParser` has to build a `QQmlJs::Engine`, `QQmlJs::Lexer` and `QQmlJsEngine::Parser`. Currently, `QmlCodeParser` stores the engine element as an instance member, `m_engine`. Supposedly, this is intended as a way to avoid building the element more than once. Building a `QQmlJs::Engine` more than once does not provide any meaningful overhead, moreover not in the code path where it is used. Furthermore, `m_engine` is used only a few times, in `QmlCodeParser::parseSourceFile`, the entry point for parsing a QML source file. Hence, to reduce the scope of `m_engine` and avoid requiring an out-of-scope initialization for it, `m_engine` is now removed in favor of a local instance in `QmlCodeParser::parseSourceFile`. Change-Id: I73f23ec06c1fa3ba3fe50ff4dffc9ff9229c114d Reviewed-by: Topi Reiniö <topi.reinio@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Remove `QmlCodeParser::m_parser`Luca Di Sera2023-03-271-4/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As part of producing a documentation set, QDoc parses a series of user-defined input source files in various languages to extract the user-provided documentation and certain source-code level elements. For QML source files, the `QmlCodeParser` class is used, taking care of reading the QML code and build an internal representation for some of its elements. `QmlCodeParser` uses the `QQmlJs` parsing api to do so. As part of using the `QQmlJs` parsing api, `QmlCodeParser` has to build a `QQmlJs::Engine`, `QQmlJs::Lexer` and `QQmlJsEngine::Parser`. Currently, `QmlCodeParser` stores the engine and parser elements as instance members. For example, for the `QQmlJs::Parser` instance, a member variable `m_parser` is used as storage. Supposedly, this is intended as a way to avoid building the three elements more than once. Building a `QQmlJs::Parser` more than once does not provide any meaningful overhead, moreover not in the code path where it is used. Furthermore, `m_parser` is used only a few times, in `QmlCodeParser::parseSourceFile`, the entry point for parsing a QML source file. Hence, to reduce the scope of `m_parser` and avoid requiring an out-of-scope initialization for it, `m_parser` is now removed in favor of a local instance in `QmlCodeParser::parseSourceFile`. The initialization and deletion of `m_parser` in `QmlCodeParser::initializeParser` and `QmlCodeParser::terminateParser` was removed as a consequence of the removal of the member. As `QmlCodeParser::initializeParser` and `QmlCodeParser::terminateParser` were only taking care of `m_parser`, their implementation is now removed as dead code. As `initializeParser` and `terminateParser`are required to be implemented, by `CodeParser`, `QmlCodeParser` base class, due to their pure virtual nature, an empty implementation was added to "qmlcodeparser.h". Similarly, the constructor for `QmlCodeParser` was only taking care of initializing `m_parser` and is now removed in favor of a defaulted implementation. Change-Id: Id07e6d9cf8083c83482232606fb9a2611dcce420 Reviewed-by: Topi Reiniö <topi.reinio@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Remove `QmlCodeParser::m_lexer`Luca Di Sera2023-03-271-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As part of producing a documentation set, QDoc parses a series of user-defined input source files in various languages to extract the user-provided documentation and certain source-code level elements. For QML source files, the `QmlCodeParser` class is used, taking care of reading the QML code and build an internal representation for some of its elements. `QmlCodeParser` uses the `QQmlJs` parsing api to do so. As part of using the `QQmlJs` parsing api, `QmlCodeParser` has to build a `QQmlJs::Engine`, `QQmlJs::Lexer` and `QQmlJsEngine::Parser`. Currently, `QmlCodeParser` stores all those elements as instance members. For example, for the `QQmlJs::Lexer` instance, a member variable `m_lexer` is used as storage. Supposedly, this is intended as a way to avoid building the three elements more than once. Building a `QQmlJs::Lexer` more than once does not provide any meaningful overhead, moreover not in the code path where it is used. Furthermore, `m_lexer` is used only once, in `QmlCodeParser::parseSourceFile`, the entry point for parsing a QML source file. Hence, to reduce the scope of `m_lexer` and avoid requiring an out-of-scope initialization for it, `m_lexer` is now removed in favor of an local instance in `QmlCodeParser::parseSourceFile`. The initialization and deletion of `m_lexer` in `QmlCodeParser::initializeParser` and `QmlCodeParser::terminateParser` was removed as a consequence of the removal of the member. Some comments that mentioned the initialization or deletion of the lexer were modified to represent the modified code. Change-Id: I32d38e7883273ab83745eb1f34d183fd5ecca19a Reviewed-by: Topi Reiniö <topi.reinio@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Remove `CppCodeParser` from the `CodeParser` hierarchyLuca Di Sera2023-03-221-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc extracts the user-provided documentation from which its output is generated from a variety of input source file based on a project configuration. Those input source file can be of a variety of formats, as long as QDoc currently supports them. When parsing those files, QDoc extracts format specific information, such as information about the available elements in a C++ translation unit, and all the QDoc language comment-block that form the actual documentation. The format specific elements that are extracted are lowered into an internal representation, the `Node` hierarchy, that QDoc later uses to perform sanity checks on the user-provided documentation or to automatically generate certain documentation. The QDoc comment-blocks are generally processed in place, and they, too, are converted into an internal representation, partly filling a `Node` data partly filling a `Doc` instance, and used during later stages to generate the final output. It performs this process through the `CodeParser` hierarchy. The base `CodeParser` class provides an interface to parse certain source file based on their extension. Child classes of `CodeParser` implements the actual parsing based on the format that they support. `CppCodeParser`, a direct child of `CodeParser`, implements the semantic for topic and meta commands in a comment block. That is, it gives meaning to commands such as `\fn` and `\example`. `ClangCodeParser`, a direct child of `CppCodeParser` and indirect child of `CodeParser`, implements the logic to extract information from C++ source code. `PureDocParser`, a direct child of `CppCodeParser` and an indirect child of `CodeParser`, implements the logic to extract QDoc comment-blocks from a ".qdoc" file. Finally, `QmlCodeParser`, a direct child of `CodeParser`, implements the logic to extract information from QML source files. Both `ClangCodeParser` and `PureDocParser`, but not `QmlCodeParser`, depends on `CppCodeParser`. That is, as they process the found QDoc comment-block in-place during their parsing, they use `CppCodeParser` to perform this processing. Indeed, `CppCodeParser` is never itself instanciated, and is only intended to provide the shared logic for `ClangCodeParser` and `PureDocParser`. At the same, since `CppCodeParser` purpose is not to actually parse any source file, it doesn't respect, meaningfully, the interface for `CodeParser`, mostly providing stub implementation for its pure virtual methods to satisfy the compiler. Due to recent, purposefully made, changes, `CppCodeParser` does not depend, mostly, on any internal-only state of `CodeParser`, while `ClangCodeParser` and `PureDocParser` do not depend on any internal-only state of `CppCodeParser`, instead depending only on access to some of its methods. Hence, `CppCodeParser`, which does not respect the `CodeParser` interface meaningfully, can be removed from the hierarchy, simplifying it and reducing the implicit state and interface of the other members, additionally moving the codebase forward in the intention of removing the `CodeParser` interface and some of the shared-mutable state that QDoc depends on. Thus, `CppCodeParser` does not inherit anymore from `CodeParser`. As a consequence, `ClangCodeParser` and `PureDocParser` now inherit directly from `CodeParser`, flattening the hierarchy depth to one. Certain pure virtual methods that were provided directly or indirectly by `CppCodeParser` are now implemented directly in `ClangCodeParser` and `PureDocParser` to satisfy the `CodeParser` interface. In particular, `ClangCodeParser` now implements an empty `terminateParser`, as before the `terminateParser` implementation only referred back to `CppCodeParser::terminateParser`. Similarly, `ClangCodeParser::initializeParser` does not refer back to `CppCodeParser::initializeParser` anymore. `PureDocParser` now implements empty `initializeParser` and `language` methods, as, while required by the `CodeParser` inheritance, are completely meaningless in the scope of the class. The methods that `CppCodeParser` inherited from `CodeParser` are thus removed. That is, `CppCodeParser::initializeParser`, `CppCodeParser::terminateParser`, `CppCodeParser::language` and `CppCodeParser::sourceFileNameFilter` are directly deleted. `CodeParser` objects are built once and registered into a static list owned by `CodeParser`. Their lifetime is then managed by the `initialize`/`terminate` methods of `CodeParser`, manually. As `CppCodeParser` does not respect this manual management anymore, the processing performed in `initializeParser` was moved to its constructor and the processing performed in `terminateParser` was moved to its destructor. In doing so a declaration for the destructor was added to "cppcodeparser.h" and an implementation of it was added to "cppcodeparser.cpp", replacing the `terminateParser` implementation. Similarly, the defaulted constructor for `CppCodeParser` was removed in favor of a custom one and its implementation replaces the implementation for `initializeParser`. The implementation for `CppCodeParser` made use of the `m_qdb`, a pointer to the `QDocDatabase` singleton, which keeps a certain amount of state that is necessary during parsing, instance-member provided by the `CodeParser` class. Due to the changes in the inheritance hierarchy, those usages were modified to obtain an instance of the database directly in their scope. In particular, `CppCodeParser::parseOtherFuncArg`, `CppCodeParser::parseMacroArg`, `CppCodeParser::processTopicArgs`, `CppCodeParser::processQmlProperties`, `CppCodeParser::processMetaCommand` and `CppCodeParser::processTopicCommand` were modified as such. `CppCodeParser` made use of certain static methods of `CodeParser`. Usages of those methods were modified to directly refer to the `CodeParser` namespace as they are not implicitly available in the relevant scopes anymore. In particular, `CppCodeParser::processTopicArgs`, which referenced `CodeParser::parserForLanguage` and `processTopicCommands`/`processMetaCommand`, which referenced `CodeParser::isWorthWarningAbout`, were modified as such. Both `ClangCodeParser` and `PureDocParser` made use of `CppCodeParser` methods in the call chain for the virtual `parseSourceFile` method, the entry point to the parsing of a source file. All the usages are required to process the extracted QDoc comment-blocks in-place. Due to the hierarchy changes, both objects do not have access to the required methods anymore. As this dependency cannot be directly removed at this point, `CodeParser::parseSourceFile` interface was modified to require a `CppCodeParser` instance, to allow for the required in-place processing. Thus, `ClangCodeParser::parseSourceFile`, `PureDocParser::parseSourceFile` and `QmlCodeParser::parseSourceFile` had their signature update to respect the new interface. `QmlCodeParser` does not make use of `CppCodeParser` provided methods and thus had no implementation change for `parseSourceFile`. `ClangCodeParser` makes direct usages of certain `CppCodeParser` methods in `parseSourceFile` and was thus modified to access them through the passed in `CppCodeParser` instance. `PureDocParser` makes use of `CppCodeParser` methods in `processQDocComments`, the actual processing logic for the parser, as called by `parseSourceFile`. Hence, `PureDocParser::processQDocComments` was modified to receive an instance of `CppCodeParser`. The instance is passed directly by `parseSourceFile` and each call to `CppCodeParser` method was modified to use the passed in instance. Certain methods for `CppCodeParser` that are accessed by either `ClangCodeParser` or `PureDocParser` were protected. To allow the access to continue now that the classes aren't related those methods are now public under `CppCodeParser`'s interface. In particular, `CppCodeParser::hasTooManyTopics`, `CppCodeParser::processTopicArgs`, `CppCodeParser::processMetaCommand` and the two overloads of `CppCodeParser::processMetaCommands` were modified as such. Due to `parseSourceFile` now requiring a `CppCodeParser` instance, its only usage, in `processQDconFile`, was modified to obtain such an instance. The instance is built in-place, once per call, in the smallest scope that respects those requirements near the call to `parseSourceFile`. Precedently, the manual lifetime management derived by `CodeParser` would scope a `CppCodeParser` implicit instance, as provided by `ClangCodeParser` and `PureDocParser`, as the whole of `processQDocConf`. As the only usages of `CppCodeParser` is through direct calls to `parseSourceFile`, the new scope, while smaller, still ensures that the object is long-lived enough for its usages. All state that `CppCodeParser` depends upon, as the `CodeParsers` is either instance based or `processQDocConf` scoped and thus no semantic changes should derive from the instancing scope. The change, while invasive, is not expected to change any of the output documentation for QDoc, preserving the same semantic as before. Change-Id: Iae448be6c6975649044aa08ed334c73faa38bddf Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Remove `QmlCodeParser::topicCommands`Luca Di Sera2023-03-191-3/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As part of extracting user-provided documentation, QDoc has to parse a variety of source files in a variety of languages. `CodeParser` is the base class of objects that take care of performing this parsing process in QDoc. When extracting the documentation in one of the `CodeParser`s QDoc generally tries to parse the extracted documentation in-place. The documentation has a series of available commands that might depend on the currently used parser. To support this process various `CodeParser` child classes provides a way to access the available commands. In particular, `QmlCodeParser`, the class that processes QML files, provides `topicCommands`, a method to retrieve the available topic commands for documentation extracted by QML files. `topicCommands` initializes a static member, `topicCommands_` and then returns it, avoiding initialization if the method is called more than once. While this process can be better expressed by the simple use of a `static` there are two probable reason for why it wasn't done in this way. Supposedly, when this code was written, there was no suitable way to initialize a `QSet<QString>`, the type of `topicCommands_`, in-place, as similar patterns can be found in other legacy parts of QDoc that are confirmed to have had this issue due to their age. Additionally, the expansion of the `COMMAND_*` macros, which form the content for `topicCommands_`, were, until recently, dependent on certain data being available in another part of the system, so that expanding them in a static context that would be processed before this data was available would incur into a series of errors. This dependency was removed in a recent patch, so that the issue is no more. Hence, the `topicCommands()` method is removed, along with `topicCommands_`, in favor of a static, `topic_commands`, that is initialized in-place, to simplify the related code. `topicCommands()` only uses were in `QmlCodeParser::parseSourceFile`, the entry point for the extraction of documentation from a specific QML file. Thus, `topic_commands` is now scoped as a static in `parseSourceFile`, the smaller scope where it is required. All usages of `topicCommands()` were modified to refer to `topic_commands`, keeping an equivalent semantic. Change-Id: Ic97166a9a563f4e8d5ac840999231d92045a6f0d Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Always depend on QmlPrivatePaul Wicking2023-03-041-9/+3
| | | | | | | | | | | | | | | | | | | | | | Make Qml a hard dependency for QDoc. - There are no known usecases for running QDoc without qml support. - We're not testing QDoc without qml support, as it's not officially supported. - There are known issues with parsing certain file types when qml support is missing. - Dropping feature checks makes the code easier to reason about and thus maintain. - Clean up some of the configure and CMake configuration that's affected by the change. [ChangeLog][QDoc] QDoc now requires the library QmlPrivate. Make sure the qtdeclarative module is available. Fixes: QTBUG-111673 Change-Id: I3a8aa20ace3c379c3896b9f59aa4e8113cd9a873 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* Use SPDX license identifiersLucie Gérard2022-05-191-27/+2
| | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Task-number: QTBUG-67283 Change-Id: I5335388c0472b0ee554234fc7eca60769e504660 Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
* QDoc: Code cleanupPaul Wicking2021-05-191-3/+3
| | | | | | | | | | | | | * Unify members; use s_ or m_ prefix instead of _ suffix. * Remove unnecessary member that duplicates content in base class. * Add [[nodiscard]] annotations where applicable. * Add overloads to virtual methods that have been extended with parameters with default values. * Make single argument ctors explicit. * Remove semi-colon from namespace declaration. Change-Id: Ie1ff39079722b81ba6754f945a898dc9b335bbae Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Code cleanupPaul Wicking2021-05-031-6/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Use multiple arguments for QStrings instead of calling .arg() multiple times. * Define trivial constructor/destructor '= default' instead of adding empty implementations. * Remove unreachable code. * Prefer ranged-based for loops. * Initialize with auto from static_cast<>() and new. * Simplify expressions. * Prefer "QList::empty()" over "QList::size() > 0". * Remove unused method. * Return qsizetype instead of int to avoid narrowing conversion. * Remove unused include. * Remove unreachable return statement. * Prefer raw string literals over escaped regexes. * Initialize struct members. * Make variables used as const refs const refs. * Use std::move instead of passing const ref in ctor. * Drop redundant 'virtual' from methods marked 'override'. * Make local copies that arent ever modified const refs to avoid copying. * Turn for-loop into std::any_of. * Made single-argument constructor explicit. * Don't shadow variable names from outer scope if not necessary. * Remove const at top level that does not improve const correctness. * Update copyright notice for affected classes. Task-number: QTBUG-71176 Change-Id: Ia41e5b947b72f594b60d189b6b0ff68587c3afb9 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Drop half-baked translation effortPaul Wicking2020-06-041-2/+0
| | | | | | | | | | | | | | The current implementation suffers from lack of maintenance. This causes a poor user experience that adds little value, or is even detrimental to perceived value. Work to improve the situation would have to be done at the expense of something else. This patch removes the Q_DECLARE_TR_FUNCTIONS macros from QDoc, and replaces calls to tr() with QStringLiteral(). Fixes: QTBUG-84568 Change-Id: I2df71c27246ca5de816608c887cf359db8f85900 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Make Config a singletonTopi Reinio2020-01-131-2/+1
| | | | | | | | | | | | There is no need to pass a pointer to Config throughout the API; the only instance of it is created in main() so we can turn it into a singleton. Having access to Config without API changes makes implementation of configurable features easier. Change-Id: Ida47e067865082dfe036a7a97f7f1ffc736db346 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* clang-format QDocPaul Wicking2019-12-171-3/+3
| | | | | | | | | | | | | | | | This patch is the result of formatting all of QDoc's source with clang-format. The clang-format style is from the qt5 super repo's _clang-format definition. The purpose is unify the style across the code, to avoid spending too much time on style related issues in reviews and cleanup patches. Future changes to QDoc can benefit from using git-clang-format in combination with the git commit hook provided in qtrepotools.git as mentioned in this email to the dev list: https://lists.qt-project.org/pipermail/development/2019-October/037682.html Change-Id: I8af6a051c8334b5f35862a4dcd3becce8ac500c2 Reviewed-by: Martin Smith <martin.smith@qt.io>
* QDoc: Remove empty destructors and add missing override keywordPaul Wicking2019-08-121-1/+1
| | | | | | | | | | | This change removes reduntant destructors. It also adds the 'override' keyword to overridden destructors to remove warnings from clang-tidy in Creator. The patch also replaces two instances of 0 as nullptr constant. Change-Id: I576c248b7d4637249d167d7bfb8885af4f7811ff Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QDoc: Clean up whitespacePaul Wicking2019-08-081-3/+3
| | | | | | | | | | | Ensure that QDoc conforms to Qt style, whitespace edition. For the most part, the change involves moving the pointer operators. Also remove whitespace following an opening parenthesis, or immediately preceding a closing one. In some cases, adjust the following line accordingly in methods that span multiple lines. Change-Id: I56ae125a2acf09c669c0a73dc814d05f13575f39 Reviewed-by: Martin Smith <martin.smith@qt.io>
* QDoc: Ensure all includes are uniform and according to stylePaul Wicking2019-08-031-2/+3
| | | | | | | | | | | | | | | | | | | Housekeeping. Includes are organized after recommended best practice and organized in the following order: - include self (i.e. include own header) - include local files - include Qt, e.g. <QtCore/qstring.h> - include Qt private - include externals, e.g. stdio.h in alphabetic order within each block, aside from accommodating #if-ery, in which includes follow the block they belong to. Also, updated copyright notice to year of latest edit in each file. Change-Id: I1e6b215f172fd5373d57016f7678b88b9e73231e Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* qdoc: Major clean-up of FunctionNode and parameter processingv5.13.0-alpha1Martin Smith2019-02-061-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This update was motivated by the need to correct two known issues in qdoc. First, linking to overloaded functions failed in some cases because the overloads were not numbered consistently, causing links to go to the wrong overload or to nowhere at all. Second, the mechanism for handling the \relates command didn't support using it to relate a function to more than one class. For example, there are many global qHash() functions spread around QtBase. Each is meant to compute a hash index for an object of some class type, so the object can be inserted into a QHash map for that class type. It is then desired to relate qHash(type Xxx, int seed) to both QHash<type> and class Xxx, so that the documentation for that qHash() function appears as a related non-member function of both QHash<type> and class Xxx. The example above also illustrates the overload numbering problem, because all these qHash() functions are overloads of the name qHash. To make matters worse, they are not all in the same module. Most of them are in QtCore, but a few are in QtNetwork, and this distribution problem will become worse over time as more qHash() functions are added. Prior to this update, qdoc was unable to relate a function to something in a different module, or it didn't always work. While designing a fix for these issues, it became clear that the processing of the FunctionNode and the function parameters would have to be rewritten. That's what this update does. These are the main points: 1. A new subclass of Node is added to act as a proxy for a class in another module. This ProxyNode acts as a place holder for the functions (and possibly other elements) that are related to a class in another module. This is used for the qHash() functions in QtNetwork that are related to QHash in QtCore. qdoc generates an html file named qtnetwork/qhash-proxy.html that contains the documentation for these functions. But these functions are listed as related non-members on the QHash class reference page in the qtcore output directory. They are listed there in the summary, but they link to the qhash-proxy.html page in qtnetwork. 2. A new, Parameters class is added to qdoc (parameters.h and parameters.cpp), and the class Parameter is moved there from node.h. class Parameters replaces the old QVector<Parameter> wherever it was used. This encapsulates all the parameter processing and matching in the Parameters class and simplifies the code at all the places where QVector<Parameter> had been used. 3. The assignment of overload numbers is now done in the normalizeOverloads() function, which is called after all the headers and sources have been processed but before the generate phase begins. This assignment is a simple renumbering now because all the overloads of a function are linked to each other via a nextOverload_ link in the FunctionNode. The first function named qHash() is inserted into the Aggregate node's function map, but subsequent qHash() FunctionNodes are not entered into the function map but are linked to the first qHash() via its nextOverload_ link. 4. The \relates command can now be used multiple times in a single qdoc comment. There remains some work to be done here because this currently only works for global entities, but there are several cases where \relates has been used in the qdoc comment of a member of a class. This will be fixed soon, I believe. When qdoc sees the first \relates Xxx command, for example for qHash(Yyy, seed), that qHash() is a child of the global namespace. qdoc allows it to remain as a child of the global namespace but it tells class Xxx to "adopt" that child (see Node::adoptChild()). This function makes this instance of qHash() be a child of class Xxx (in this case QHash<type>), so that the parent of this qHash() becomes Xxx. After this "adoption," qHash() is a child of both the global namespace and class Xxx, but qHash() only knows it is a child of Xxx, i.e. its parent pointer is Xxx. If this is the first qHash() to become a child of Xxx, it is inserted into the function map of Xxx, but its nextOverload_ link is not changed. This is because all the global qHash() functions have already been linked into the nextOverload_ linked list, and this list must not be changed. Hence, when qdoc searches for qHash(something) to make a link to it, it will find it as a child of the global namespace, but it will correctly link to it using its actual parent pointer. When qdoc sees the second \relates Yyy for this qHash() function, qdoc sees that this FunctionNode has already been made a related non-member of Xxx, so it can't let Yyy "adopt" it. Instead, it tells Yyy to clone this qHash(), which creates a shallow copy of it but resets its nextOverload_ pointer to nullptr. I believe this clone of qHash() won't be found in a search for a function named qHash(), because the global one (the adopted one) will be found first. Or, if it is found, a link to the clone will be generated, but that's ok because the documentation is identical. Note that the existence of qHash in two child lists is taken into account at destruction time. The only place where a Node is destroyed is in the destructor of Tree, which destroys the Node tree from the root down to the leaves. Each aggregate node is responsible for deleting each of its child nodes, but it only deletes a child node if it is the parent of that child node. All of the above revealed that some of the findFunctionNode() functions were either no longer needed or weren't being called in the first place, so they were deleted. This change is now ready for testing. Change-Id: I6da3e2e9e71d39a29d90e073ed614309a49e3d4c Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* Merge remote-tracking branch 'origin/wip/qdoc-clang' into devLiang Qi2017-11-131-1/+0
|\ | | | | | | | | | | | | | | | | Conflicts: src/qdoc/cppcodeparser.h src/qdoc/location.cpp src/qdoc/qmlcodeparser.h Change-Id: I2e579ca5d83cd1c4b42acc9a07066d800cbc02cb
| * Use clang as a parser in qdocOlivier Goffart2017-08-101-1/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The file qt_find_clang.prf is inspired by qtcreator's clang_installation.pri. The code from the while loop in ClangVisitor::parseProperty contains code moved from CppCodeParser::matchProperty. The code in the for loop of ClangCodeParser::parseSourceFile (from the "Doc parses the comment"), is mostly moved from CppCodeParser::matchDocsAndStuff. In CppCodeParser, most of the code is removed since clang is used for parsing. We just need to leave enough to parse the declaration in the comments which still use the old parser (\fn, ...) Known issues: - When the parameter name is a comment, it is lost. (e.g. QObject::eventFilter(QObject * /* watched */, QEvent * /* event */) - I can't compute default parameters when they are expanded from a macro. (e.g. QObject::tr) - Instances of #ifndef Q_QDOC need to be reviewed Change-Id: I92d4ca4fc52810d9d3de433147a9953eea3a1802 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* | Replace Q_DECL_OVERRIDE with overrideKevin Funk2017-09-221-6/+6
|/ | | | | Change-Id: I1b8b338a6bc2f3c87af62c20ff1428096b309628 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Updated license headers and license testsAntti Kokko2016-06-101-17/+12
| | | | | | | | | | | | | From Qt 5.7 -> tools & applications are licensed under GPL v3 with some exceptions, see http://blog.qt.io/blog/2016/01/13/new-agreement-with-the-kde-free-qt-foundation/ Updated license headers to use new GPL-EXCEPT header instead of LGPL21 one (in those files which will be under GPL 3 with exceptions) License header tests also updated to match current headers. Change-Id: Ia6bdacaa3c5bbc9d31334e1a0cabfe502a484dc4 Reviewed-by: Jani Heikkinen <jani.heikkinen@qt.io>
* qdoc: Let qdoc run without QtDeclarativeMartin Smith2016-03-091-0/+6
| | | | | | | | | | | | | | | When qdoc is built without QtDeclarative present, define QT_NO_DECLARATIVE. Then qdoc will not compile the QML and JS parsers from QtDeclarative, and if it encounters a request in the documentation to parse a QML or JS snippet or file, it prints an error message indicating that it can't parse QML or JS because QtDeclarative is not installed. Change-Id: I7e7948118244b7ffa563126520def083d75e3bb6 Task-number: QTBUG-51409 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> Reviewed-by: Topi Reiniö <topi.reinio@theqtcompany.com>
* move qdoc back to qttoolsOswald Buddenhagen2015-10-231-0/+84
we can do that now, as the bootstrap lib is now a properly exported module, and qmldevtools is now bootstrapped as well. this removes the abomination of a copy of the qml parser in qtbase. unfortunately qtbase/2422251ee5025a067b14b989153764ab36e43f10 is reverted, as qtdeclarative is still missing the respective change. this introduces no regression in discoverability or usability, as a full doc build already needed qttools - for qhelpgenerator. Change-Id: Ic9c4c9732ddf5998637b9e42e27939ba50b31479 Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@theqtcompany.com> Reviewed-by: Martin Smith <martin.smith@digia.com> Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com> Reviewed-by: Topi Reiniö <topi.reinio@digia.com>