Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
document.cpp
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "document.h"
5
6#include <QJsonArray>
7#include <optional>
8
9QT_BEGIN_NAMESPACE
10
11using namespace Qt::Literals::StringLiterals;
12
13namespace IR {
14
15/*!
16 \struct IR::Document
17 \brief Intermediate representation for a documentation topic.
18
19 Document contains all information needed to render a single documentation
20 page using templates. All links are pre-resolved, sections are pre-organized,
21 and file paths are pre-computed. The template engine receives only this IR
22 and performs no lookups or resolution itself.
23
24 The struct includes classification metadata (nodeType, genus, status, access)
25 that allows templates to conditionally render content based on the type and
26 visibility of the documented entity.
27*/
28
29// Classification fields use a two-part structure:
30// - "id": Stable kebab-case identifier for template conditionals (e.g., "qml-type")
31// - "label": Human-readable display name (e.g., "QML type")
32//
33// This separation allows templates to use stable ids for logic while displaying
34// user-friendly labels. Changing labels won't break template conditionals.
35
36// Helper to create a classification JSON object with id and label
37static QJsonObject classificationObject(const QString &id, const QString &label)
38{
39 QJsonObject obj;
40 obj["id"_L1] = id;
41 obj["label"_L1] = label;
42 return obj;
43}
44
45// Returns {id, label} pair for NodeType. Returns nullopt for NoType (unclassified).
47{
48 switch (t) {
49 case NodeType::NoType: return std::nullopt;
50 case NodeType::Namespace: return classificationObject("namespace"_L1, "Namespace"_L1);
51 case NodeType::Class: return classificationObject("class"_L1, "Class"_L1);
52 case NodeType::Struct: return classificationObject("struct"_L1, "Struct"_L1);
53 case NodeType::Union: return classificationObject("union"_L1, "Union"_L1);
54 case NodeType::HeaderFile: return classificationObject("header-file"_L1, "Header file"_L1);
55 case NodeType::Page: return classificationObject("page"_L1, "Page"_L1);
56 case NodeType::Enum: return classificationObject("enum"_L1, "Enum"_L1);
57 case NodeType::Example: return classificationObject("example"_L1, "Example"_L1);
58 case NodeType::ExternalPage: return classificationObject("external-page"_L1, "External page"_L1);
59 case NodeType::TypeAlias: return classificationObject("type-alias"_L1, "Type alias"_L1);
60 case NodeType::Typedef: return classificationObject("typedef"_L1, "Typedef"_L1);
61 case NodeType::Function: return classificationObject("function"_L1, "Function"_L1);
62 case NodeType::Property: return classificationObject("property"_L1, "Property"_L1);
63 case NodeType::Proxy: return classificationObject("proxy"_L1, "Proxy"_L1);
64 case NodeType::Variable: return classificationObject("variable"_L1, "Variable"_L1);
65 case NodeType::Group: return classificationObject("group"_L1, "Group"_L1);
66 case NodeType::Module: return classificationObject("module"_L1, "Module"_L1);
67 case NodeType::QmlType: return classificationObject("qml-type"_L1, "QML type"_L1);
68 case NodeType::QmlValueType: return classificationObject("qml-value-type"_L1, "QML value type"_L1);
69 case NodeType::QmlModule: return classificationObject("qml-module"_L1, "QML module"_L1);
70 case NodeType::QmlProperty: return classificationObject("qml-property"_L1, "QML property"_L1);
71 case NodeType::QmlEnum: return classificationObject("qml-enum"_L1, "QML enum"_L1);
72 case NodeType::SharedComment: return classificationObject("shared-comment"_L1, "Shared comment"_L1);
73 case NodeType::Collection: return classificationObject("collection"_L1, "Collection"_L1);
74 }
75 Q_UNREACHABLE();
76}
77
78// Returns {id, label} pair for Genus. Returns nullopt for DontCare (unclassified).
80{
81 switch (g) {
82 case Genus::DontCare: return std::nullopt;
83 case Genus::CPP: return classificationObject("cpp"_L1, "C++"_L1);
84 case Genus::QML: return classificationObject("qml"_L1, "QML"_L1);
85 case Genus::DOC: return classificationObject("doc"_L1, "Documentation"_L1);
86 case Genus::API: return classificationObject("api"_L1, "API"_L1);
87 }
88 Q_UNREACHABLE();
89}
90
91// Returns {id, label} pair for Status.
93{
94 switch (s) {
95 case Status::Deprecated: return classificationObject("deprecated"_L1, "Deprecated"_L1);
96 case Status::Preliminary: return classificationObject("preliminary"_L1, "Preliminary"_L1);
97 case Status::Active: return classificationObject("active"_L1, "Active"_L1);
98 case Status::Internal: return classificationObject("internal"_L1, "Internal"_L1);
99 case Status::DontDocument: return classificationObject("ignored"_L1, "Ignored"_L1);
100 }
101 Q_UNREACHABLE();
102}
103
104// Returns {id, label} pair for Access.
106{
107 switch (a) {
108 case Access::Public: return classificationObject("public"_L1, "Public"_L1);
109 case Access::Protected: return classificationObject("protected"_L1, "Protected"_L1);
110 case Access::Private: return classificationObject("private"_L1, "Private"_L1);
111 }
112 Q_UNREACHABLE();
113}
114
115/*!
116 Converts the Document to a QJsonObject for template rendering.
117
118 The JSON structure follows a convention where field names use camelCase
119 and match template variable names. Classification fields (nodeType, genus,
120 status, access) use a two-part structure with "id" (stable kebab-case
121 identifier for conditionals) and "label" (human-readable display name).
122
123 The \c contentJson field is nested under a 'content' key to provide better
124 structure and namespace separation in templates.
125
126 Returns a QJsonObject containing all IR data in a format suitable for
127 passing to the Inja template engine via InjaBridge.
128*/
130{
131 QJsonObject json;
132
133 // Classification (as {id, label} objects for template convenience)
134 // nodeType and genus are omitted when unclassified (NoType/DontCare),
135 // allowing templates to use `if defined` checks.
136 if (const auto t = nodeTypeToJson(nodeType))
137 json["nodeType"_L1] = *t;
138 if (const auto g = genusToJson(genus))
139 json["genus"_L1] = *g;
140 json["status"_L1] = statusToJson(status);
141 json["access"_L1] = accessToJson(access);
142
143 // Identity
144 json["title"_L1] = title;
145 json["fullTitle"_L1] = fullTitle;
146 json["url"_L1] = url;
147 if (!since.isEmpty())
148 json["since"_L1] = since;
149 if (!deprecatedSince.isEmpty())
150 json["deprecatedSince"_L1] = deprecatedSince;
151 json["brief"_L1] = brief;
152
153 Q_ASSERT(!contentJson.contains("blocks"_L1));
154 QJsonObject content = contentJson;
155
156 QJsonArray blocks;
157 for (const auto &block : body)
158 blocks.append(block.toJson());
159 content["blocks"_L1] = blocks;
160
161 json["content"_L1] = content;
162
163 return json;
164}
165
166} // namespace IR
167
168QT_END_NAMESPACE
Access
Definition access.h:11
Status
Specifies the status of the QQmlIncubator.
NodeType
Definition genustypes.h:150
Definition builder.cpp:14
static std::optional< QJsonObject > nodeTypeToJson(NodeType t)
Definition document.cpp:46
static QJsonObject accessToJson(Access a)
Definition document.cpp:105
static QJsonObject classificationObject(const QString &id, const QString &label)
Definition document.cpp:37
static std::optional< QJsonObject > genusToJson(Genus g)
Definition document.cpp:79
static QJsonObject statusToJson(Status s)
Definition document.cpp:92
Intermediate representation for a documentation topic.
Definition document.h:22
QJsonObject toJson() const
Converts the Document to a QJsonObject for template rendering.
Definition document.cpp:129