summaryrefslogtreecommitdiff
path: root/src/qdoc/cppcodeparser.cpp
Commit message (Collapse)AuthorAgeFilesLines
* QDoc: Move QDoc source files under a further "qdoc" directoryLuca Di Sera2023-04-121-977/+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>
* Revert "qdoc: Add support for 'category' argument in \generatelist command"Topi Reinio2023-04-111-5/+2
| | | | | | | | | | | | | | | This reverts commit df735050ecd01687f17df8f161c706541319ad05. While the commit works, it introduces unnecessary complexity to the processing of the \meta command. The same functionality can be achieved with the help of a documentation macro. The commit did contain a bug-fix for the \generatelist command, which is re-introduced as a separate change. Pick-to: 6.5 Change-Id: Ie8578baa35cfee210fc52428c610307f51103d22 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* qdoc: Add support for 'category' argument in \generatelist commandTopi Reinio2023-03-271-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Examples in the Qt codebase are now tagged with specific categories, using the '\meta category {Category}' command. To easily generate lists of members in each category, add support for a 'category' argument in the \generatelist command. Internally, utilize the mechanism already provided by \ingroup command, by adding the node to an internal group prefixed by 'category', when processing the '\meta category' command. \generatelist already supported listing members of a group as a simple unordered list of titles/links. Fix the generated links as they were broken, always referring to the current document. In DocBook generator, reuse generateAnnotatedList() as it already has support for outputting simple itemized/unordered lists. Create a new private enum GeneratedListType to select the list 'subtype' and clean up the API. Add simple test case and documentation of the new argument. Pick-to: 6.5 Fixes: QTBUG-111891 Fixes: QTBUG-111575 Change-Id: Icd5647a09b9ae8cb0ac243fa49d3d99263d397cb Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Nicholas Bennett <nicholas.bennett@qt.io>
* Rename local variable in CppCodeParserPaul Wicking2023-03-231-32/+32
| | | | | | | | | | | Following a recent change that changed the scope of QDocDatabase access in CppCodeParser to method local, the class no longer has a member called `m_qdb`. To avoid confusion, drop the `m_` prefix from local use, so that readers won't mistake local variables for a class member. Change-Id: I2f1d38707911c2ee4e8be45a43cb5b861e59ecae Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Remove `CppCodeParser` from the `CodeParser` hierarchyLuca Di Sera2023-03-221-23/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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: Move `CodeParser::checkModuleInclusion` to "cppcodeparser.cpp"Luca Di Sera2023-03-191-0/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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. For certain documentable elements, QDoc expects that an "\inmodule" commands is provided, as it requires it to understand where to position them when generating the output documentation. To ensure that this constraint is satisfied, CppCodeParser`, the `CodeParser` subclass that takes care of providing the semantic for QDoc block-comments, calls at a certain point `CodeParser::checkModuleInclusion`, a method that makes sure that the internal representation of the comment-block and the documented element have a valid "\inmodule" information for the later stages. `checkModuleInclusion` is only called by `CppCodeParser` and does not require any instance-state that would not otherwise be available. Hence, `checkModuleInclusion` is removed from `CodeParser` in favor of being a static in "cppcodeparser.cpp", just above its actual usage. An access to `m_qdb`, an instance-member for `CodeParser` that reference the `QDocDatabase` singleton was modified to directly obtain a `QDocDatabase` instance, as the member is not available outside `CodeParser`s. Change-Id: I0a8abc53d3c4fbd3e6687254a0034a3e12a6e018 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Remove `CppCodeParser::metaCommands`Luca Di Sera2023-03-191-25/+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 some of the `CodeParser` child classes provides series of methods to retrieve the required commands for each parser. `CppCodeParser`, the parser that provides the semantic for QDoc's comment-blocks, for example, provides `metaCommands`, to list the available "meta commands" in a comment-block. `metaCommands` returns a static member, `metaComamnds_`. This static member is initialized during the construction of an `CppCodeParser` instance, and the initialization is made so that it doesn't run more than once, albeit this is done in a non-thread-safe way. The initialization is based on `CppCodeParser::common_meta_commands`, as a base, plus some other commands that are not in `common_meta_commands`. Generally, this process could be better expressed by the use of a static with in-place initialization. There are two probable reasons why this has not been the way it was written in the past. Supposedly, when this code was written, there was no suitable way to initialize a `QSet<QString>`, the type of `metaCommands_`, 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 `metaCommands_`, 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 `metaCommands()` method is removed, along with `metaCommands_`, in favor of a public static, `meta_commands`, that is initialized in-place, to simplify the related code. All usages of `meta_commands` were modified to refer to `CppCodeParser::meta_commands`, keeping an equivalent semantic, as a consequence of the change. As the initialization of `metaCommands_` was the only thing that was being done in the constructor for `CppCodeParser`, the constructor was removed in favor of a default one. Change-Id: I6e54b95a50d07a394d727c0af8c409599a088d4c Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Remove `CppCodeParser::topicCommands`Luca Di Sera2023-03-191-23/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 some of the `CodeParser` child classes provides series of methods to retrieve the required commands for each parser. `CppCodeParser`, the parser that provides the semantic for QDoc's comment-blocks, for example, provides `topicCommands`, to list the available "topic commands" in a commnet-block. `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 public static, `topic_commands`, that is initialized in-place, to simplify the related code. All usages of `topicCommands` were modified to refer to `CppCodeParser::topic_commands`, keeping an equivalent semantic, as a consequence of the change. Change-Id: I9de2332bf557254e7ffd33290e6af678c2b121aa Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Remove `CodeParser::commonMetaCommands`Luca Di Sera2023-03-191-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 `CodeParser` provides as part of its interface a series of methods to retrieve the required commands for each parser. One of those methods, `commonMetaCommands`, provides the commands that are common to all parser. `commonMetaCommands` initializes a static member, `commonMetaCommands_` 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 `commonMetaCommands_`, 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 `commonMetaCommands_`, 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 `commonMetaCommands()` method is removed, along with `commonMetaCommands_`, in favor of a public static, `common_meta_commands`, that is initialized in-place, to simplify the related code. `common_meta_commands` is initialized inline under `CodeParser` in "codeparser.h". Its initialization depends on the `COMMAND_*` macros being available. Previously, those macros were defined under `Codeparser` in "codeparser.h" so that they would not be available at the point of initialization. Hence, all definition of the `COMMAND_*` macros were moved higher up in "codeparser.h", to ensure that they would be available when required by `common_meta_commands`. All usages of `commonMetaCommands()` were modified to refer to `CodeParser::common_meta_commands`, keeping an equivalent semantic. Change-Id: If4987e5c1b53e80585e7556e62701690d98954c3 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Remove `CppCodeParser::ExtraFuncData`Luca Di Sera2023-03-161-1/+0
| | | | | | | | | | | | | | | | | | | | `CppCodeParser`, the class that generally takes care of providing the semantics of topics and meta commands for QDoc, exposed an inner class `ExtraFuncData`, that bundled together some of the data that QDoc might use when processing certain elements of the documentation. `ExtraFuncData` was instantiated once and never used. Supposedly, it was the either the result of a never finished refactoring or was suppressed away during a refactoring, without the complete code being cleaned of it. Nonetheless, it is now removed as dead code. Its single unused instantiation in `CppCodeParser::processTopicCommand` was removed as a consequence of the removal of the class. Change-Id: I7212cd0538421bb3c5e60517f53afb2eb4bd90bf Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Remove unnecessary Config access functionsTopi Reinio2023-03-141-5/+7
| | | | | | | | | | | | | | | | | | Config class now provides Config::get(), returning a ConfigVar reference which can be further converted to string, list, set, int, or bool. Use get() throughout the codebase and remove the old access functions. In addition, make Config::get() return a const reference, and prevent an unnecessary contains() check by using an iterator. Do some drive-by cleaning of related code. Change-Id: I2ff2203824cd4ae80c4615080948565219ad20b2 Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Don't call CodeParser::terminateParser from CppCodeParserPaul Wicking2023-03-101-3/+1
| | | | | | | | | Drop the call to CodeParser::terminateParser() from CppCodeParser::terminateParser, as the former does _nothing_. Task-number: QTBUG-111686 Change-Id: I900aede323e4249be339227fc0f70d1511d998a2 Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Replace members in CppCodeParser with local staticsPaul Wicking2023-03-101-31/+26
| | | | | | | | | | | * Replace the members m_nodeTypeMap and m_nodeTypeTestFuncMap in CppCodeParser with statics local to the implementation. * Initialize the new variables directly instead of in CppCodeParser::initializeParser. Task-number: QTBUG-111686 Change-Id: I6ea8985b061efb40c2e2dbac4a7f28c82c219ad6 Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Remove CodeParser::initializeParser()Paul Wicking2023-03-101-2/+0
| | | | | | | | | | | | | Due to recent changes, CodeParser::initializeParser() is a noop. * Derived classes implement overrides, so make it pure virtual in CodeParser. * Drop the call from the initializeParser methods of CppCodeParser and QmlCodeParser. Task-number: QTBUG-111686 Change-Id: Ia018132d9401b9189e3a0d6346606488fd163edd Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Remove CodeParser::s_showInternal member and associated getterPaul Wicking2023-03-101-3/+3
| | | | | | | | | | | | Get rid of the static CodeParser::s_showInternal member, because there's no reason for the CodeParser to have a static member that tracks whether the config is set to showInternal, when the config already carries that information around. Most of the derived CodeParsers already keep a reference to the config anyway. Get rid of it, as it is unnecessary. Task-number: QTBUG-111686 Change-Id: If658282b1c198e48dd236dc6b9eac280e2a5890e Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: refactor and document CppCodeParser::hasTooManyTopicsPaul Wicking2023-03-101-21/+30
| | | | | | | | | | | | | | | | | | | | | * Inverse a conditional check and make the condition more expressive. This allows an early return, as well as dedenting the remaining code in the method, and the removal of a later Q_ASSERT that could be surprising for readers that don't keep in mind that QString::lastIndexOf may return -1. * Use std::all_of instead of a for loop on a negative condition, to make the code more expressive about the intention. Remove an internal bool that was used to indicate whether the error condition was met or not as it is superfluous after this change. * Rename a variable internal to the method for accuracy. * Add internal documentation for the method. * Remove adding of punctuation in the warning message in favor of reusing convenience methods provided by Utilies. Build the warning message using std::accumulate. * Be const correct, because it's nice. Change-Id: I418362a9464575e1aeae2c93bd20e9a114ace3bc Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Move `CodeParser::parseHeaderFile` to `ClangCodeParser`Luca Di Sera2023-03-101-8/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc parses a series of source file in different languages and formats to find the user-provided documentation. The base parsing interface for elements that perform this process is given by the `CodeParser` class, with the concrete implementation of the process for different languages/formats give by its child classes. `CodeParser`, as part of its interface, provides certain methods that are only meaningful when processing specific programming languages source. For example, it exposes `CodeParser::parseHeaderFile` whose purpose it to provide an entry point for parsing C++ header files. The method is only meaningfully implemented and used in the `ClangCodeParser` child class, the class that actually implements the processing of C++ source files. Hence, the method is now removed from `CodeParser`'s interface and directly exposed as part of the interface of `ClangCodeParser`, to reduce the surface of the method and to reduce the dependencies between `ClangCodeParser` and the `CodeParser` interface, which is generally expected to be removed in the future. `CodeParser` are, currently and temporarily, mostly initialized statically and then retrieved through certain methods of the `CodeParser` interface. `CodeParser::parserForHeaderFile` is one such method that would retrieve a `CodeParser` or child class instance that is able to parse an header file. Due to the removal of `parseHeaderFile` from `CodeParser` interface and the fact that only one specific parser is able, and should be able, to parse header files, `CodeParser::parserForHeaderFile` was removed. Its only usage in "main.cpp", where it was called to retrieve the already available `ClangCodeParser`, was modified to make use of `ClangCodeParser` directly. An auxiliary method, `CodeParser::headerFileNameFilter`, previously used only by `CodeParser::parserForHeaderFile`, which provided a list of extensions to identify what files could be accepted by a certain parser as header files, is now removed as dead code. A non-meaningful reimplementation of the `headerFileNameFilter` method in `CppCodeParser`, a child class of `CodeParser`, was removed as of consequence. Similarly, the same method implementation in `ClangCodeParser` was removed. The filtering functionality that the method indirectly provided when used by `CodeParser::parserForHeaderFile`, which is to be retained for backward compatibility reasons, was moved to `processQdocconfFile` in "main.cpp", where the header files that should be parsed are gathered. Instead of using the `headerFileNameFilter` method, the data that was provided by it is now exposed as a static member of `ClangCodeParser` and accessed directly when filtering is necessary. Change-Id: Iff9a204627675aa7b34232c114945afceb8313ff Reviewed-by: Topi Reiniö <topi.reinio@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* qdoc: Unify handling of QML types and QML value typesTopi Reinio2022-12-121-12/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QML value types, formerly known as basic types, are nowadays provided by multiple modules and contain also properties and methods. QDoc's support for value types was rather basic (pun intended): No import/since statements nor sections for properties etc. was generated, the reference page had essentially a flat structure similar to a generic \page. As QML and QML value types are closely related, eliminate the dedicated Node subclass for value types (QmlValueTypeNode), handle both with QmlTypeNode class, differentiating them only with NodeType enumeration. Make Node::isQmlType() return true for both to provide similar behavior for all QML types, with a few exceptions: * Do not warn if \qmlvaluetype command is missing \inqmlmodule info as many of the original value types do not document it * Do not generate 'all members' file for value types as they're not expected to inherit other types. * Do not include the QML module name qualifier into the filenames generated for value types. This is done in order to keep the existing behavior for value types and to avoid creating redirects for online documentation. Related to the last point, remove code from Generator::fullDocumentLocation() that was never executed as it was a duplicate from Generator::fileBase(). Unifying the types under a single Node subclass allows for removal of multiple functions and code paths related to value types. They have some constraints compared to proper QML types, but QDoc does not currently enforce them. [ChangeLog][QDoc][QDoc now properly outputs documentation for QML value types with properties and methods.] Pick-to: 6.4 Fixes: QTBUG-109132 Change-Id: I418660b0a6e0461c82fd5cb67e4f955a0d9a712c Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* Port from container::count() and length() to size() - V4Marc Mutz2022-10-101-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a semantic patch using ClangTidyTransformator as in qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to handle typedefs and accesses through pointers, too: const std::string o = "object"; auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); }; auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) { auto exprOfDeclaredType = [&](auto decl) { return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o); }; return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes)))); }; auto renameMethod = [&] (ArrayRef<StringRef> classes, StringRef from, StringRef to) { return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)), callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))), changeTo(cat(access(o, cat(to)), "()")), cat("use '", to, "' instead of '", from, "'")); }; renameMethod(<classes>, "count", "size"); renameMethod(<classes>, "length", "size"); a.k.a qt-port-to-std-compatible-api V4 with config Scope: 'Container'. Change-Id: I58e1b41b91c34d2e860dbb5847b3752edbfc6fc9 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Port from qAsConst() to std::as_const()Marc Mutz2022-10-061-1/+1
| | | | | | | | | | | | | | | We've been requiring C++17 since Qt 6.0, and our qAsConst use finally starts to bother us (QTBUG-99313), so time to port away from it now. Since qAsConst has exactly the same semantics as std::as_const (down to rvalue treatment, constexpr'ness and noexcept'ness), there's really nothing more to it than a global search-and-replace. Task-number: QTBUG-99313 Change-Id: I234704ba429750ddee958a82f6c941d041da0653 Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Port from container::count() and length() to size()Marc Mutz2022-10-061-3/+3
| | | | | | | | | | | | | | | | | | | | | | This is a semantic patch using ClangTidyTransformator as in qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8: auto QtContainerClass = anyOf( expr(hasType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))))).bind(o), expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)); makeRule(cxxMemberCallExpr(on(QtContainerClass), callee(cxxMethodDecl(hasAnyName({"count", "length"), parameterCountIs(0))))), changeTo(cat(access(o, cat("size"), "()"))), cat("use 'size()' instead of 'count()/length()'")) a.k.a qt-port-to-std-compatible-api with config Scope: 'Container', with the extended set of container classes recognized. Change-Id: I95f6410e57a6a92b1cf91bbedfbe3d517cab6b44 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Kai Koehne <kai.koehne@qt.io> Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
* QDoc: Remove deprecated usage of _qs literal operatorLuca Di Sera2022-09-131-1/+3
| | | | | | | | | | | | | The usage was recently added but, Qt 6.8 onward, deprecates the usage of "_qs" in favor of the "_s" literal operator in the "Qt::Literals::StringLiterals" namespace. A "using" for the namespaces was added to gain access to the non-deprecated literal operators and the usage of "_qs" was converted to "_s". Change-Id: I43ad074ee7fdd1d50ab218cc74b57d983edca8da Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Remove Node::PageTypeLuca Di Sera2022-09-081-20/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc uses a series of internal structure, based on an inheritance tree with base `Node`, to represent elements that are documentable and their properties. For documentable elements that generate a documentation page in the output, such as a documented C++ class, a subtree of the hierarchy, starting at `PageNode`, is used. A `PageNode`, and more generally a `Node`, can have a "Page Type", representing the type of element that the output documentation should represent. This is implemented in terms of an enumeration and an internal memeber of that enumeration. Supposedly, originally there was almost no hierarchy of types for `PageNode`s, and the enumeration was used as a form of tagged union to discern the the type of page that the `PageNode` would produce to determine the valid operations on it and the required computations that should have been performed during a generation. At some point in QDoc lifetime, some of the types implied by `PageType` were promoted to actual types under a `PageNode` hierarchy, for example `ExampleNode`, such that the use of `PageType` was reduced. Today, `PageType` is used only when parsing a "\page" command, which generates a `PageNode`. The "\page" command, which declares that a comment-block should generate a standalone documentation page in the output that doesn't document any specific or code-level element, takes an argument representing the name of the generated file and, optionally, a second argument. The optional second argument is a bare string that, if of a specific form, is used to define the type of the generated `PageNode` that represents the page. For example, a second argument of form "api" would mark the `PageNode` with as being of type `PageType::ApiPage`. Generally, this information is not used at all during the rest of a QDoc execution, as none of the remaining `PageType` nodes that don't have an actual type require special handling. There is, albeit, one exception to this. When the second argument of a "\page" command is "attribution", the `PageNode` has type `PageType::AttributionPage`. This type is meaningful as it is later used to collect "Attribution Pages" for a certain module so that QDoc can generate a list of them in Qt's documentation. "Attribution pages" are a special type of page that are used in Qt's documentation to "attribute" usages of third-party libraries, so as to comply with their licensing. Those pages are only expected to be generated by "qattributionscanner", which takes care of parsing json-defined attribution metadata for third-party libraries to generate the required attribution page. Thus, while `PageType` is generally not required, this specific behavior has to be supported. Hence, we remove `PageType`, replacing it with an equivalent behavior that only handles attributions. The `PageType` enum in `Node` is now removed. `Node::pageType`, the getter for the current `PageType` of `PageNode`, the two `Node::setPageType` overloads, the setter for the `PageType` of a `PageNode` and `Node::getPageType`, a converter from `Node::NodeType` to `Node::PageType`, were removed as they have no meaning anymore. The member `m_pageType` of `Node`, that contained the current "Page Type" of a `Node` instance, was removed as it lost its use. The constructor for `Node` is now modified to not set a `PageType`. The constructor for `PageNode` that took a `PageType` to set was removed, as it lost its use. As a consequence, the code that handles the "\page" command in `CppCodeParser::processTopicCommand`, was removed call the constructor for `PageNode` that does not require a `PageType`. Furthermore, the same code was modified to not process the second argument of a "\page" command anymore. The parsing and retrieval of the second argument is tied to the current model used by `DocParser`, which is general for topic commands, and cannot be easily removed, such that it will still be valid to pass a second argument albeit it will be completely ignored. The documentation in QDoc's manual that explains the usage of "\page"'s second argument was removed as a consequence. The code in `QDocIndexFiles` that writes and reads a `PageNode` was modified to ignore the type, where possible, while keeping a similar structure for the produced format. To preserve the "Attribution Pages" behavior, a new member, `is_attribution`, was introduced in `PageNode`, acting as a flag, defaulting to false, that is set when a `PageNode` is an "Attribution Page". A setter that turns on the flag, `markAttribution`, and a getter that reads the flag, `isAttribution`, were added to `PageNode`. Albeit in a more contained scope than the previous `Node` scope, the new members are too broadly scoped compared to their actual usages. For example, a `ClassNode` is allowed to be an "Attribution Page" albeit we don't expect that to make sense. Due to the low granularity of QDoc's internal representation, fixing this would either require a bigger refactoring or the introduction of new idioms, both of which are not an amount of work that is intended to be undertaken as of this patch. The code in `Aggregate::findAllAttribution`, that is used to build the list of "Attribution Pages" in a module, was modified to use the new methods to discern whether a child node is an "Attribution Page". A new command, "\attribution", was added to allow a user to mark a "\page" as an attribution. The command is not intended to take any arguments and will simply mark the documented page as being an "Attribution Page". No user-facing documentation for the command is provided as the command is intended only to support the internal "qattributionscanner" behavior in Qt's documentation and should not be used manually or in other places at the current time. The necessary code to handle the command was added to `CppCodeParser`, turning on the relevant flag when the command is found and producing a warning if the command is not in a "\page" comment-block. Due to the limited granularity of QDoc's datatypes, the command will incorrectly pass for non "\page", non `Aggregate` comment-block, such as "\example", where it could produce seemingly incorrect documentation. This is something that should be addressed separately in a general look at QDoc's internal structures. The code in `QDocIndexFiles::readIndexSection` that reads back a `PageNode` was modified to call `PageNode::markAttribution` when reading back a `PageNode` that is an attribution. The generator of QDoc's "Attribution Pages" for "qattributionscanner" was modified to output an "\attribution" command on the line following the "\page" command produced for an "Attribution Page" instead of generating an "attribution" argument for the "\page" command itself, to be compliant with the new interface. Change-Id: I41405fd4db884d98463a43bff8815c4504dc00ea Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Remove unfinished support for documenting javascriptLuca Di Sera2022-09-071-62/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The codebase for QDoc has support for commands related to documenting pure javascript codebases. Generally, given a certain QML specific command, a javascript equivalent is provided. For example, "\jstype" or "\jsmodule". Codewise, the support is bolted on by reusing the exact same code that is used for QML types. The internal structures used to represent QML elements, like `QmlPropertyNode`, were reused for javascript elements, with the sole difference of changing the metaness value, for elements where the metaness is meaningful, and the internal type tag of the node. Code that branched specifically with QML types was modified to branch for javascript types too, with mostly no other difference in the branched code itself. The support for javascript was never finalized, albeit it is supposed to work, lacking, for example, representation in the documentation. As a consequence of this it is not currently used, tested or necessary. Hence, the code supporting the documentation of javascript elements is now removed as dead code. Anything referring to javascript specific elements were removed, from the commands definitions to the categorization functions. "Node::changeType" and "FunctionNode::changeMetaness", that switched the type and metaness, respectively, of an existing node with a new one, albeit implemented in a more general fashion, are now removed as dead code, since they were used specifically to "convert" Qml nodes to "javascript nodes". References to javascript were removed in the documentation for QDoc. Do note that not all javascript related features were removed from the codebase. In particular, the "js" and "endjs" commands, to mark a codeblock as being javascript code, and their supporting code such as `JsCodeMarker`, were currently retained as, albeit no documentation exists, are currently used a couple of time in the current Qt's codebase. The remaining javascript specific code is expected to be addressed and removed in a future commit, unless the current usages are specific enough that they cannot be replaced with qml specific commands. Task-number: QTBUG-106275 Change-Id: I6a199ce97b26d6a3a645c0022e599a8654989a85 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Move `Node::setNoAutoList` to `PageNode`Luca Di Sera2022-09-051-1/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc generates automatic lists of elements for some of its pages that represents a collection of certain elements. In particular, it does so for pages generated through the "\module", "\qmlmodule", "\group" and "\example" topics. The user can avoid this behavior by using the "\noautolist" command anywhere in a comment-block that has one of those topics, inhibiting the generation of the automated list, generally to replace it with a manually chosen list by the author. Internally, QDoc uses a simple boolean flag that is turned on by the presence of a "\noautolist" command in a comment block. This flag is available to any `PageNode`, the internal representation for documentation elements that generate a page in the output, and subclasses instances, under the `m_noAutoList` member, together with a getter method `noAutoList` and a setter method `setNoAutoList`. Contrary to the getter method, the setter method `setNoAutoList` is not a direct member of `PageNode`, and is instead overridden from the virtual method `setNoAutoList` under `Node`, the base class for internal representation of documentation elements in QDoc. `Node::setNoAutoList` has no meaningful implementation or usage of `setNoAutoList`. Indeed, only `PageNode`s would be able to give a meaning to "not generating an automatic list in the produced output page" as they are the only element producing a page in the output in the first place. To limit the scope of the method to where it has meaning, remove the virtual call overhead and generally provide a cleaner interface, `Node::setNoAutoList` was removed and the implementation in `PageNode` was made a direct implementation. The documentation for `Node::setNoAutoList` in `node.cpp` was further removed as a consequence of the change. To support the change, the code in `CppCodeParser` that handles the "\noautolist" command, setting the boolean flag through a call to `setNoAutoList`, was modified to check that the command is applicable and cast to appropriate node type to access the required method if such is the case. When the command is not applicable, a new warning will now be emitted admonishing the user of the unnecessary use of the command. Do note that, with the current codebase, the "\noautolist" command is not meaningful for all page nodes and is indeed only meaningful for `CollectionNode`s (module, qmlmodule, group) and `ExampleNode`s. While this restriction was taken into account with regards to the generation of the new warning, this puts the current getter and setter method at too broad a scope, as they could incorrectly be used for other page nodes, such as aggregates. Currently, `ExampleNode`s and `CollectionNode`s do not share a more restricted inherited type than `PageNode`, and the concession for the broader scope was thus made with this limitation in mind and with regards for the current structure of the codebase. Nonetheless, it could be in the future considered to revise the current location and implementation of the methods to restrict such a scope. Change-Id: I88945d022fc3a041786a51496bbd53a7edeaa8bc Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Introduce \modulestate commandTopi Reinio2022-07-151-0/+9
| | | | | | | | | | | | | | | | | | | | | | | | This command can be used in \module or \qmlmodule topic to describe a module state other than \preliminary or \deprecated. A typical use case is to mark modules in tech. preview: /*! \module QFoo \modulestate Techical Preview ... */ This information is displayed on the module page itself, as well as on the navigation bar of the module's member reference pages. Introduce a new function, QDocDatabase::getModuleNode() that retrieves the associated module node for any other Node instance. Use this in HtmlGenerator::generateNavigation() and also in Tree::resolveSince() to avoid code duplication. Fixes: QTBUG-104591 Change-Id: Ifd85e769f6df6f06ed9938da4f9981b22a56e19e Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* QDoc: Assume that aggregates have a single meaningful include fileLuca Di Sera2022-07-081-6/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | QDoc's `Aggregates`, which are used to internally represent "containing" elements, such as cpp classes, have a concept of "include files". "include files" represent the name of a file or similar construct from which the aggregate can be obtained the sources. For example, the name an header file declaring a cpp class. Aggregates, up to now, exposed an interface that allowed to set multiple "include file" for each aggregate. Furthermore, QDoc allows the user to manually specify include files through the use of the "\inheaderfile" command. Those include files were later used by QDoc to show information about the aggregate, In particular, the generator would show an "include requisite" to help a user understand where to import the aggregate from. The multiplicity of the include files had effects on later parts of the code that either set or read them. For example, the generators whose code required handling the multiplicity to show the required information on multiple lines. In practice, this never took effect as, at least in Qt's codebase, no aggregate has more than 1 include file. While it is not unthinkable of wanting to have more than one include file, we consider improbable for it to happen. In general, include file will mostly be used for classes, which we expect to be able to be meaningfully included from a specific file only. As such, the interface for `Aggregates` is now modified to expose a single include file per aggregate. The previous methods were removed and a singular version of them was introduced. The internal state of `Aggregate` was modified to take this into account storing a single optional include file instead of a vector of them. A singular include file was set during the construction of `HeaderNode`. The constructor is now modified to use the new interface. Include files are then generally set only during the code parsing phase. In particular, each file-name coming from an "\inheaderfile" command was appended to the vector of include files. Furthermore, each aggregate either inherited the include files of one of its parent or generated one from the aggregate's name when no sensible parent was available, unless a previous "\inheaderfile" command for the aggregate was encountered. The code is now changed to take into account the lack of multiplicity. The semantic is mostly preserved from the previous version and, in the case of the Qt's codebase, is preserved entirely due to no aggregate with more than one include file ever being produced. Some slight semantic breakages are, albeit, included with this change. Previously, if the user provided more than one "\inheaderfile" command, the arguments from all of them would be preserved and saved in the relevant aggregate. With the current change, each "\inheaderfile" after the first will overwrite the preceding value, such that only the last encountered command will be taken, effectively, into account. This breakage would currently be opaque for the user. It is later advised to better expose this behavior through changes to `DocParser`, albeit those changes are not expected to be performed right away as a more thorough inspection of `DocParser` must be made in general. Furthermore, the previous version would set include files that could be the empty string, specifically as they came from an "\inheaderfile" command. The new version ignore empty include files, such that it is ensured that, if an include file was ever provided, that include file is not an empty string. This breakage improves on the previous version, where later user of the include files had to perform possibly costly filtering operations to avoid empty strings, who are expected to have no meaning as an include file. To better support this change and partially help in exposing this semantic, the new interface for the include file exposes an std::optional and informally guarantees, but does not enforce, that if a value is ever set it is not the empty string. The changes to the code were made so as to ensure that this will be the case as for the current codebase. A more thorough enforcement was avoided as it would require deeper changes that are currently unfeasible. User of the include file, namely the generators, were modified to take into account the lack of multiplicity. The generators previously depended on `CodeMarker::markedUpIncludes` to flatten the vector of include files into a representable string. `CodeMarker::markedUpIncludes` is now supplanted with `CodeMarker::markedUpInclude`, its singular version, to take into account the lack of multiplicity. The semantics of the method is preserved and is expected to be equivalent to a call to `CodeMarker::markedUpIncludes` for vectors of include files with a single element, with the exclusion of a trailing newline. Small clean up changes were made to `HtmlGenerator::addIncludeFilesToMap`, which is the main consumer of include file for the HTML format. The method was renamed to its singular version. Some now unnecessary operations, such as the filtering of include files that were the empty string, are now removed. The `text` parameter of the method, previously a `Text*`, is now modified to a reference. The `Text` that is passed to the method is always created in its immediate scope and is never a nullptr, allowing us to remove and unnecessary check. Indeed, calling the method with a nullptr would generally be a no-op, such that there would be no meaning to it in the first place (and there was no flow-requirement for it to be a no-op). A slight change to the laying out of the table in `HtmlGenerator::generateTheTable` was included to better divide the lines of the table. The regression files for `tst_generatedOutput` were regenerated to take into account the additional newlines in the tables. Change-Id: Idebca8a74444328cd21c83be9e3f3b1706907f84 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: Add warning for the location of duplicate-documented QML propertyTopi Reinio2022-04-071-3/+5
| | | | | | | | | | | | | | QDoc warned if a QML property was documented multiple times, but did not output the location of the previously seen doc entry. Display the previously seen comment location in warning details, and adjust similar warnings to the same format as they were previously emitting two warnings for a single problem. Pick-to: 6.3 Fixes: QTBUG-102332 Change-Id: Ib5d05a378bb8120d5d5cfe34681c5d90ed71ddcf Reviewed-by: Luca Di Sera <luca.disera@qt.io>
* Rename QML basic types to value typesUlf Hermann2022-01-181-4/+5
| | | | | | | | | | | | | | Internally they've been called value types for a long time and they are not really basic. [ChangeLog][qdoc] QML value types are now marked with the \qmlvaluetype directive, rather than \qmlbasictype. \qmlbasictype still works but is deprecated. So far, all value types are hardcoded into the QML engine, making the directive irrelevant for user projects. This will change. Change-Id: I915ea0388e1de4c18911f7e81ba29559ebf33cb7 Reviewed-by: Kai Koehne <kai.koehne@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* qdoc: Don't warn about \instantiates classes if -no-link-errors is setTopi Reinio2021-12-031-4/+11
| | | | | | | | | | | | | The C++ class that a QML type \instantiates can be located in another module. As -no-link-errors is set when testing documentation builds of individual module without loading the .index files of any dependencies, skip these warnings. Clarify the potential causes of the warning in the documentation. Fixes: QTBUG-98517 Change-Id: I3014541544269f81587fbfd2b13b6dcacf96731c Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* qdoc: Improve function tagging for grouped \fn commandsTopi Reinio2021-08-231-7/+8
| | | | | | | | | | | | | | | | | | | QDoc provides a mechanism for tagging specific function declarations in a header with //! [tag] comments, allowing these tags to be referenced in an \fn command. This feature did not work for shared comment nodes containing multiple \fn commands, however. To make this work, we need to associate the 'bracketed args' (where the id tag is) with the command itself - previously it was stored in the Doc instance, but that doesn't work when there are multiple topic commands sharing a doc. To do so, repurpose the ArgLocPair structure to store the bracketed arg instead of a Location, as we never used this particular Location for anything, anyway. Pick-to: 6.2 Fixes: QTBUG-95948 Change-Id: Ic899d4252d705f84ba56ea201a55f3e5db068f00 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Code cleanupPaul Wicking2021-05-191-37/+37
| | | | | | | | | | | | | * 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>
* Doc: Improve \deprecated commandPaul Wicking2021-05-101-4/+8
| | | | | | | | | | | | | | | | | | | | | | This change allows users to specify an optional parameter to the \deprecated command to record which version something was deprecated. It also allows for free text descriptions. These descriptions become the first paragraph of the resulting documentation. Usage: \deprecated \deprecated [6.2] \deprecated [6.2] Use QFoo() instead. \deprecated Use QFoo() instead. [ChangeLog][qdoc] QDoc now lets you record the version something is deprecated and suggest replacements with the \deprecated command. Task-number: QTBUG-58249 Change-Id: I27081627132b2f8ea3dd7d48ded8e37213366074 Reviewed-by: Topi Reiniö <topi.reinio@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* qdoc: Remove Node::Obsolete statusTopi Reinio2021-05-101-2/+2
| | | | | | | | | | | | | | | | | QDoc had two commands for the same purpose, \obsolete and \deprecated. As 'deprecated' describes the status better, as in, something that is subject to being removed from the public API, document only the latter. Keep \obsolete for now for backward compatibility. .index file recognize the "obsolete" attribute still for backward compatibility, converting to "deprecated". [ChangeLog][qdoc] Replaced \obsolete command in favor of \deprecated as it's a more accurate description of the intended status. Task-number: QTBUG-58249 Change-Id: I3d311ebf7b4a3e8a23fa85e4efcf60965cf12a13 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Code cleanupPaul Wicking2021-05-031-16/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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>
* Revert "QDoc: Add \deprecatedsince command"Paul Wicking2021-04-301-8/+2
| | | | | | | | | | | | This reverts commit 1637d91efd8fb389bc09bdaa960f5d9d4f9e0164. Reason for revert: User feedback shows this implementation isn't good enough. Further discussion led to the discovery of a better approach. Task-number: QTBUG-58249 Change-Id: I48e0500ac95745b1ce10a29e77c6fa515b9e048f Reviewed-by: Kai Koehne <kai.koehne@qt.io>
* QDoc: Add \deprecatedsince commandPaul Wicking2021-04-281-2/+8
| | | | | | | | | | | | | As deprecated methods may stick around over a couple of versions, add a command that lets us record which version something was deprecated in. [ChangeLog][qdoc] QDoc now lets you record the version something is deprecated in with the new \deprecatedsince command. Fixes: QTBUG-58249 Change-Id: I69de350502580f446008f717462bbc1c4c251564 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Re-implement \default commandTopi Reinio2021-03-171-0/+10
| | | | | | | | | | | | | | Marking a QML property as a default property is now done with \qmldefault command; repurpose the \default command to set a default value for a property. The default value is visible in the detailed property documentation as an extra 'default: <value>' attribute. The value is taken as-is from the argument passed to the command. Fixes: QTBUG-81525 Change-Id: I7a4395e6e96046facfc3d75cc62a3bd01d04935b Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* qdoc: Allow overriding documentation from abstract QML base typesTopi Reinio2021-01-211-1/+1
| | | | | | | | | | | | | | | | | | QDoc replicates property/function documentation from abstract QML base types to the reference of the inheriting type. Attempting to override a member documentation for the inheriting type resulted in duplication: both the base and inheriting docs were rendered. As the decision on what's shown on the type reference is deferred to constructing the sections, implement this logic there. Modify FunctionNode::compare() so that we can compare methods from different parents, allowing us to override a specific overload of a method. Pick-to: 6.0 Fixes: QTBUG-89913 Change-Id: I3fb56c747e72b5a6ff387667e035a959e8f1c479 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Allow type aliases as a parameter to \class commandTopi Reinio2020-11-091-0/+14
| | | | | | | | | | | | | | | | In Qt 6, some types that used to be classes are now type aliases or specializations of a templated class; for example, QPair is now an alias to std::pair. While the \typedef command supports aliases, it's not always clear where the reference of such type should live, as a \typedef cannot generate a page of its own and needs to be related to some other aggregate (class, header, or namespace). Therefore, allow aliases to generate a type page using the \class command. Fixes: QTBUG-88012 Change-Id: Ice67d58eb036299c0fd04f6ed48a846bfed8ed1d Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Manage logging category in utilities.h/cppTor Arne Vestbø2020-09-241-1/+0
| | | | | Change-Id: I39ec66fbe95edc42a3dac51e8bc718ee42cc4a2a Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Drop ditaref remainsPaul Wicking2020-09-111-5/+5
| | | | | | | | | | | | Most of the dita code is removed, get rid of the last few bits and the header that is no longer used. [ChangeLog][qdoc] The obsolete \ditamap has been removed. Task-number: QTBUG-71176 Fixes: QTBUG-86560 Change-Id: I7c65cc8a74d4caeabdc98d6852026f54a3c32dda Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Introduce \required command and handle REQUIRED for QML propertiesTopi Reinio2020-07-151-0/+5
| | | | | | | | | | | | | | | | | | | Q_PROPERTY macro now supports the REQUIRED keyword. This is relevant for QML types, where the type cannot be instatiated without declaring all required properties. Make QDoc parse the REQUIRED keyword, set associated QML property as required, and introduce a new command, \required, to do this explicitly in the docs. Likewise in QML visitor, check for the 'required' keyword for properties. [ChangeLog][qdoc] Support marking QML properties as required in the generated documentation. Fixes: QTBUG-85597 Change-Id: Ib8a25c5ebc1183812aec6e672b557c8fb1196741 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* QDoc: Remove remnant of deprecated commandPaul Wicking2020-06-151-3/+0
| | | | | | Task-number: QTBUG-71176 Change-Id: Ic381a5642bd353ee34dc4f9749f0ce8cbafc1498 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Use QList instead of QVectorJarek Kobus2020-06-091-2/+2
| | | | | | | | Task-number: QTBUG-84469 Change-Id: I88b99ba7f5648d9da7878b7f7723f48cd86be2ac Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* qdoc: Extend synopsis for detailed reference sectionsTopi Reinio2020-06-081-4/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Include \since information for detailed synopsis generation, and allow duplication of qdoc comments for C++/QML nodes on the condition that the extra comments contain no body text, only meta-commands. The use case is to have full status information in the signature/section title, and allow additional meta-commands for items that share a documentation comment. /*! \fn void A:foo() \fn void A:foo(int i) Shared documentation for overloads. */ /*! \fn void A:foo(int i) \since 2.0 */ Extract the code for 'extra' synopsis into a new helper function and use for both HTML and DocBook generators. Fixes: QTBUG-55739 Fixes: QTBUG-82902 Change-Id: I6e797d3ce7bc7b02102bb949515f88e7a0fbe929 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Extract ExternalPageNode from NodePaul Wicking2020-06-041-0/+1
| | | | | | Task-number: QTBUG-84578 Change-Id: I5581a7e5f3f1b10850688a1395943fb50c43160b Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Extract ExampleNode from NodePaul Wicking2020-06-041-0/+1
| | | | | | Task-number: QTBUG-84578 Change-Id: Ieae12d5a75c89470165759fb92c79897d9ad910c Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* QDoc: Extract CollectionNode from NodePaul Wicking2020-06-041-0/+1
| | | | | | Task-number: QTBUG-84578 Change-Id: Icf8db259a269d0e31f4686097addcfdde1e77f14 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>