22
23
24
25
28
29
30
31
32TagFileWriter::TagFileWriter() : m_qdb(QDocDatabase::qdocDB()) { }
35
36
37
41 for (
const auto *node : nonFunctionList) {
42 if (!node->url().isNull() || node->isPrivate())
46 switch (node->nodeType()) {
47 case NodeType::Namespace:
51 case NodeType::Struct:
53 case NodeType::QmlType:
59 const auto *aggregate =
static_cast<
const Aggregate *>(node);
61 QString access =
"public";
62 if (node->isProtected())
65 QString objName = node->name();
68 if (objName.isEmpty() && node != m_qdb->primaryTreeRoot())
72 writer.writeStartElement(
"compound");
73 writer.writeAttribute(
"kind", kind);
75 if (node->isClassNode()) {
76 writer.writeTextElement(
"name", node->fullDocumentName());
77 writer.writeTextElement(
"filename", m_generator->fullDocumentLocation(node));
80 const auto *classNode =
static_cast<
const ClassNode *>(node);
81 const QList<RelatedClass> &bases = classNode->baseClasses();
82 for (
const auto &related : bases) {
83 ClassNode *n = related.m_node;
85 writer.writeTextElement(
"base", n->name());
89 generateTagFileMembers(writer, aggregate);
90 writer.writeEndElement();
93 generateTagFileCompounds(writer, aggregate);
95 writer.writeTextElement(
"name", node->fullDocumentName());
96 writer.writeTextElement(
"filename", m_generator->fullDocumentLocation(node));
99 generateTagFileMembers(writer, aggregate);
100 writer.writeEndElement();
103 generateTagFileCompounds(writer, aggregate);
109
110
111
116 for (
const auto *node : childNodes) {
117 if (!node->url().isNull())
122 switch (node->nodeType()) {
124 case NodeType::QmlEnum:
126 kind =
"enumeration";
128 case NodeType::TypeAlias:
129 case NodeType::Typedef:
133 case NodeType::Property:
137 case NodeType::Function:
141 case NodeType::Namespace:
142 nodeName =
"namespace";
144 case NodeType::Class:
145 case NodeType::Struct:
146 case NodeType::Union:
149 case NodeType::Variable:
155 switch (node->access()) {
159 case Access::Protected:
160 access =
"protected";
162 case Access::Private:
167 QString objName = node->name();
170 if (objName.isEmpty() && node != m_qdb->primaryTreeRoot())
174 writer.writeStartElement(nodeName);
176 writer.writeAttribute(
"kind", kind);
178 switch (node->nodeType()) {
179 case NodeType::Class:
180 case NodeType::Struct:
181 case NodeType::Union:
182 writer.writeCharacters(node->fullDocumentName());
183 writer.writeEndElement();
185 case NodeType::Namespace:
186 writer.writeCharacters(node->fullDocumentName());
187 writer.writeEndElement();
189 case NodeType::Function: {
191
192
193
195 const auto *functionNode =
static_cast<
const FunctionNode *>(node);
196 writer.writeAttribute(
"protection", access);
197 writer.writeAttribute(
"virtualness", functionNode->virtualness());
198 writer.writeAttribute(
"static", functionNode->isStatic() ?
"yes" :
"no");
200 if (functionNode->isNonvirtual())
201 writer.writeTextElement(
"type", functionNode->returnType());
203 writer.writeTextElement(
"type",
"virtual " + functionNode->returnType());
205 writer.writeTextElement(
"name", objName);
206 const QStringList pieces =
207 m_generator->fullDocumentLocation(node).split(QLatin1Char(
'#'));
208 writer.writeTextElement(
"anchorfile", pieces[0]);
209 writer.writeTextElement(
"anchor", pieces[1]);
210 QString signature = functionNode->signature(Node::SignatureReturnType);
211 signature = signature.mid(signature.indexOf(QChar(
'('))).trimmed();
212 if (functionNode->isConst())
213 signature +=
" const";
214 if (functionNode->isFinal())
215 signature +=
" final";
216 if (functionNode->isOverride())
217 signature +=
" override";
218 if (functionNode->isPureVirtual())
220 writer.writeTextElement(
"arglist", signature);
222 writer.writeEndElement();
224 case NodeType::Property: {
225 const auto *propertyNode =
static_cast<
const PropertyNode *>(node);
226 writer.writeAttribute(
"type", propertyNode->dataType());
227 writer.writeTextElement(
"name", objName);
228 const QStringList pieces =
229 m_generator->fullDocumentLocation(node).split(QLatin1Char(
'#'));
230 writer.writeTextElement(
"anchorfile", pieces[0]);
231 writer.writeTextElement(
"anchor", pieces[1]);
232 writer.writeTextElement(
"arglist", QString());
234 writer.writeEndElement();
236 case NodeType::QmlEnum:
237 case NodeType::Enum: {
238 const auto *enumNode =
static_cast<
const EnumNode *>(node);
239 writer.writeTextElement(
"name", objName);
240 const QStringList pieces =
241 m_generator->fullDocumentLocation(node).split(QLatin1Char(
'#'));
242 writer.writeTextElement(
"anchorfile", pieces[0]);
243 writer.writeTextElement(
"anchor", pieces[1]);
244 writer.writeEndElement();
246 for (
const auto &item : enumNode->items()) {
247 writer.writeStartElement(
"member");
248 writer.writeAttribute(
"kind",
"enumvalue");
249 writer.writeTextElement(
"name", item.name());
250 writer.writeTextElement(
"anchorfile", pieces[0]);
251 writer.writeTextElement(
"anchor", pieces[1]);
252 writer.writeTextElement(
"arglist", QString());
253 writer.writeEndElement();
256 case NodeType::TypeAlias:
257 case NodeType::Typedef: {
258 const auto *typedefNode =
static_cast<
const TypedefNode *>(node);
259 if (typedefNode->associatedEnum())
260 writer.writeAttribute(
"type", typedefNode->associatedEnum()->fullDocumentName());
262 writer.writeAttribute(
"type", QString());
263 writer.writeTextElement(
"name", objName);
264 const QStringList pieces =
265 m_generator->fullDocumentLocation(node).split(QLatin1Char(
'#'));
266 writer.writeTextElement(
"anchorfile", pieces[0]);
267 writer.writeTextElement(
"anchor", pieces[1]);
268 writer.writeTextElement(
"arglist", QString());
270 writer.writeEndElement();
273 case NodeType::Variable:
281
282
285 QFile file(fileName);
286 QFileInfo fileInfo(fileName);
290 if (fileInfo.fileName() == fileName || !fileInfo.dir().exists())
291 file.setFileName(m_generator->outputDir() + QLatin1Char(
'/') + fileInfo.fileName());
293 if (!file.open(QFile::WriteOnly | QFile::Text)) {
294 Location().warning(QString(
"Failed to open %1 for writing.").arg(file.fileName()));
299 QXmlStreamWriter writer(&file);
300 writer.setAutoFormatting(
true);
301 writer.writeStartDocument();
302 writer.writeStartElement(
"tagfile");
303 generateTagFileCompounds(writer, m_qdb->primaryTreeRoot());
304 writer.writeEndElement();
305 writer.writeEndDocument();
const NodeList & nonfunctionList()
Returns a const reference to the list of child nodes of this aggregate that are not function nodes.
const NodeList & childNodes() const
Returns a const reference to the child list.
The Location class provides a way to mark a location in a file.
Location()
Constructs an empty location.
This class handles the generation of the QDoc tag files.
The Node class is the base class for all the nodes in QDoc's parse tree.
static bool nodeNameLessThan(const Node *first, const Node *second)
Returns true if the node n1 is less than node n2.