diff options
Diffstat (limited to 'src/qdoc/qdoc/src/qdoc/boundaries/filesystem')
6 files changed, 401 insertions, 0 deletions
diff --git a/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/directorypath.cpp b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/directorypath.cpp new file mode 100644 index 000000000..799582139 --- /dev/null +++ b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/directorypath.cpp @@ -0,0 +1,126 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "directorypath.h" + +/*! + * \class DirectoryPath + * + * \brief Represents a path to a directory that was known to exist on the + * filesystem. + * + * An instance of this type guarantees that, at the time of creation + * of the instance, the contained path represented an existing, + * readable, executable directory. + * + * The type is intended to be used whenever a user-provided path to a + * directory is encountered the first time, validating that it can be + * used later on for the duration of a QDoc execution and + * canonicalizing the original path. + * + * Such a usage example could be during the configuration process, + * when encountering the paths that defines where QDoc should search + * for images or other files. + * + * Similarly, it is intended to be used at the API boundaries, + * internally, to relieve the called element of the requirement to + * check the validity of a path when a directory is required and to + * ensure that a single format of the path is encountered. + * + * Do note that the guarantees provided by this type do not + * necessarily hold after the time of creation of an instance. + * Indeed, the underlying filesystem may have changed. + * + * It is possible to renew the contract by obtaining a new instance: + * + * \code + * DirectoryPath old... + * + * ... + * + * auto current{DirectoryPath:refine(old.value())}; + * \endcode + * + * QDoc itself will not generally perform destructive operations on + * its input files during an execution and, as such, it is never + * required to renew a contract. Ensuring that the underlying input + * files are indeed immutable is out-of-scope for QDoc and it is + * allowed to consider a case where the contract was invalidated as + * undefined behavior. + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {wrapped_type_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {has_equality_operator_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {has_less_than_operator_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {has_strictly_less_than_operator_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {has_greater_than_operator_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {has_strictly_greater_than_operator_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {refine_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {value_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {copy_constructor_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {copy_assignment_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {move_constructor_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {move_assignment_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {conversion_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_equal_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_unequal_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_less_than_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_less_than_or_equal_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_greater_than_documentation} {DirectoryPath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_greater_than_or_equal_documentation} {DirectoryPath} + */ diff --git a/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/directorypath.h b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/directorypath.h new file mode 100644 index 000000000..7ec1dd415 --- /dev/null +++ b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/directorypath.h @@ -0,0 +1,17 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "../refined_typedef.h" + +#include <optional> + +#include <QtCore/qstring.h> +#include <QtCore/qfileinfo.h> + +QDOC_REFINED_TYPEDEF(QString, DirectoryPath) { + QFileInfo info{value}; + + return (info.isDir() && info.isReadable() && info.isExecutable()) ? std::optional(DirectoryPath{info.canonicalFilePath()}) : std::nullopt; +} diff --git a/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/filepath.cpp b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/filepath.cpp new file mode 100644 index 000000000..d8964b6a6 --- /dev/null +++ b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/filepath.cpp @@ -0,0 +1,125 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "filepath.h" + +/*! + * \class FilePath + * + * \brief Represents a path to a file that was known to exist on the + * filesystem. + * + * An instance of this type guarantees that, at the time of creation + * of the instance, the contained path represented an existing, + * readable file. + * + * The type is intended to be used whenever a user-provided path to a + * file is encountered the first time, validating that it can be + * used later on for the duration of a QDoc execution and + * canonicalizing the original path. + * + * Such a usage example could be when resolving a file whose path is + * provided by the user. + * + * Similarly, it is intended to be used at the API boundaries, + * internally, to relieve the called element of the requirement to + * check the validity of a path when a file is required and to + * ensure that a single format of the path is encountered. + * + * Do note that the guarantees provided by this type do not + * necessarily hold after the time of creation of an instance. + * Indeed, the underlying filesystem may have changed. + * + * It is possible to renew the contract by obtaining a new instance: + * + * \code + * FilePath old... + * + * ... + * + * auto current{FilePath::refine(old.value())}; + * \endcode + * + * QDoc itself will not generally perform destructive operations on + * its input files during an execution and, as such, it is never + * required to renew a contract. Ensuring that the underlying input + * files are indeed immutable is out-of-scope for QDoc and it is + * allowed to consider a case where the contract was invalidated as + * undefined behavior. + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {wrapped_type_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {has_equality_operator_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {has_less_than_operator_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {has_strictly_less_than_operator_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {has_greater_than_operator_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {has_strictly_greater_than_operator_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {refine_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {value_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {copy_constructor_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {copy_assignment_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {move_constructor_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {move_assignment_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {conversion_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_equal_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_unequal_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_less_than_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_less_than_or_equal_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_greater_than_documentation} {FilePath} + */ + +/*! + * \include boundaries/refined_typedef_members.qdocinc {operator_greater_than_or_equal_documentation} {FilePath} + */ diff --git a/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/filepath.h b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/filepath.h new file mode 100644 index 000000000..e8a9b2d35 --- /dev/null +++ b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/filepath.h @@ -0,0 +1,17 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "qdoc/boundaries/refined_typedef.h" + +#include <optional> + +#include <QtCore/qstring.h> +#include <QtCore/qfileinfo.h> + +QDOC_REFINED_TYPEDEF(QString, FilePath) { + QFileInfo info{value}; + + return (info.isFile() && info.isReadable()) ? std::optional(FilePath{info.canonicalFilePath()}) : std::nullopt; +} diff --git a/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/resolvedfile.cpp b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/resolvedfile.cpp new file mode 100644 index 000000000..4d5eca512 --- /dev/null +++ b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/resolvedfile.cpp @@ -0,0 +1,96 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "resolvedfile.h" + +/*! + * \class ResolvedFile + * + * \brief Represents a file that is reachable by QDoc based on its + * current configuration. + * + * Instances of this type are, generally, intended to be generated by + * any process that needs to query the filesystem for the presence of + * some files based on a user-inputted path to ensure their + * availability. + * + * Such an example might be when QDoc is searching for a file whose + * path is provided by the user, such as the one in a snippet command, + * that should represent a file that is reachable with the current + * configuration. + * + * On the other side, logic that requires access to files that are + * known to be user-provided, such as the quoting of snippets, can use + * this type at the API boundary to signal that the file should be + * accessible so that they avoid the need to search for the file + * themselves. + * + * Do note that, semantically, this type doesn't actually guarantee + * anything about its origin and only guarantees whatever its members + * guarantee. + * + * The reasoning behind this lack of enforcement is to allow for an + * easier testing. + * As many parts of QDoc might require the presence of an instance of + * this type, we want to be able to construct those instances without + * the need to pass trough whichever valid generator for them. + * + * Nonetheless, inside QDoc, any boundary that requires an instance of + * this type can consider it guaranteed that the instance was + * generated trough some appropriate logic, and consider it a bug if + * such is not the case. + * + * An instance of this type provides two pieces of information. + * + * The path to the file that is considered resolved, accessible trough + * the get_path() method and the string that was used to resolve the + * file in the first place, accessible trough the get_query() method. + * + * The first should be used by consumer who needs to interact with the + * file itself, such as reading from it or copying it. + * + * The second is provided for context and can be used when consumers + * need to know what the user-inputted path was in the first place, + * for example when presenting debug information. + * + * It is not semantically guaranteed that this two pieces of + * information are actually related. Any such instance for which this + * is true should be considered malformed. Inside QDoc, tough, + * consumer of this type can consider it guaranteed that no malformed + * instance will be passed to them, and consider it a bug if it + * happens otherwise. + */ + +/*! + * \fn ResolvedFile::ResolvedFile(QString query, FilePath filepath) + * + * Constructs an instance of this type from \a query and \a filepath. + * + * \a query should represent the user-inputted path that was used to + * resolve the file that this instance represents. + * + * \a filepath should represent the file that is found querying the + * filesystem trough \a query using an appropriate logic for resolving + * files. + * + * An instance that is built from \a query and \a filepath is + * guaranteed to return a value that is equivalent to \a query when + * get_query() is called and a value that is equivalent to \a + * filepath.value() when get_path() is called. + */ + +/*! + * \fn const QString& ResolvedFile::get_query() const + * + * Returns a string representing the user-inputted path that was used + * to resolve the file. + */ + +/*! + * \fn const QString& ResolvedFile::get_path() const + * + * Returns a string representing the canonicalized path to the file + * that was resolved. + * + * Access to this file is to be considered guranteed to be available. + */ diff --git a/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/resolvedfile.h b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/resolvedfile.h new file mode 100644 index 000000000..e21120ab1 --- /dev/null +++ b/src/qdoc/qdoc/src/qdoc/boundaries/filesystem/resolvedfile.h @@ -0,0 +1,20 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "qdoc/boundaries/filesystem/filepath.h" + +#include <QString> + +struct ResolvedFile { +public: + ResolvedFile(QString query, FilePath filepath) : query{query}, filepath{filepath} {} + + [[nodiscard]] const QString& get_query() const { return query; } + [[nodiscard]] const QString& get_path() const { return filepath.value(); } + +private: + QString query; + FilePath filepath; +}; |