1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#pragma once
5
6#include "clangcodeparser.h"
7#include "puredocparser.h"
8
9#include <variant>
10
11#include <QString>
12#include <QFileInfo>
13
14struct CppSourceFile {};
15struct CppHeaderSourceFile {};
16struct QDocSourceFile {};
17struct JsSourceFile {};
18struct UnknownSourceFile {};
19
20using SourceFileTag = std::variant<CppSourceFile, CppHeaderSourceFile, QDocSourceFile, JsSourceFile, UnknownSourceFile>;
21using TaggedSourceFile = std::pair<QString, SourceFileTag>;
22
23inline TaggedSourceFile tag_source_file(const QString& path) {
24 static QStringList cpp_file_extensions{
25 "c++", "cc", "cpp", "cxx", "mm"
26 };
27 static QStringList cpp_header_extensions{ "h", "h++", "hpp", "hxx" };
28 static QStringList qdoc_file_extensions{ "qdoc" };
29 static QStringList javascript_file_extensions{ "js" };
30
31 QString extension{QFileInfo(path).suffix()};
32
33 const bool inHeaders = Config::instance().get(CONFIG_DOCUMENTATIONINHEADERS).asBool();
34
35 if (inHeaders && cpp_header_extensions.contains(str: extension)) {
36 return TaggedSourceFile{ path, CppHeaderSourceFile{} };
37 } else if (cpp_file_extensions.contains(str: extension)) {
38 return TaggedSourceFile{ path, CppSourceFile{} };
39 } else if (qdoc_file_extensions.contains(str: extension))
40 return TaggedSourceFile{ path, QDocSourceFile{} };
41 else if (javascript_file_extensions.contains(str: extension)) return TaggedSourceFile{path, JsSourceFile{}};
42
43 return TaggedSourceFile{path, UnknownSourceFile{}};
44}
45
46class SourceFileParser {
47public:
48 struct ParseResult {
49 std::vector<UntiedDocumentation> untied;
50 std::vector<TiedDocumentation> tied;
51 };
52
53public:
54 SourceFileParser(ClangCodeParser& clang_parser, PureDocParser& pure_parser)
55 : cpp_file_parser(clang_parser),
56 pure_file_parser(pure_parser)
57 {}
58
59 ParseResult operator()(const TaggedSourceFile& source) {
60 if (std::holds_alternative<CppSourceFile>(v: source.second))
61 return (*this)(source.first, std::get<CppSourceFile>(v: source.second));
62 else if (std::holds_alternative<CppHeaderSourceFile>(v: source.second))
63 return (*this)(source.first, std::get<CppHeaderSourceFile>(v: source.second));
64 else if (std::holds_alternative<QDocSourceFile>(v: source.second))
65 return (*this)(source.first, std::get<QDocSourceFile>(v: source.second));
66 else if (std::holds_alternative<JsSourceFile>(v: source.second))
67 return (*this)(source.first, std::get<JsSourceFile>(v: source.second));
68 else if (std::holds_alternative<UnknownSourceFile>(v: source.second))
69 return {.untied: {}, .tied: {}};
70
71 Q_UNREACHABLE();
72 }
73
74private:
75 ParseResult operator()(const QString& path, CppSourceFile) {
76 auto [untied, tied] = cpp_file_parser.parse_cpp_file(filePath: path);
77
78 return {.untied: untied, .tied: tied};
79 }
80 ParseResult operator()(const QString& path, CppHeaderSourceFile) {
81 return (*this)(path, CppSourceFile{});
82 }
83
84 ParseResult operator()(const QString& path, QDocSourceFile) {
85 return {.untied: pure_file_parser.parse_qdoc_file(filePath: path), .tied: {}};
86 }
87
88 ParseResult operator()(const QString& path, JsSourceFile) {
89 return {.untied: pure_file_parser.parse_qdoc_file(filePath: path), .tied: {}};
90 }
91
92private:
93 ClangCodeParser& cpp_file_parser;
94 PureDocParser& pure_file_parser;
95};
96

source code of qttools/src/qdoc/qdoc/src/qdoc/sourcefileparser.h