1 /****************************************************************************
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the tools applications of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "javadocgenerator.h"
46 enum JavaSignatureSyntax
{
52 static QString
javaSignature(const FunctionNode
*func
, JavaSignatureSyntax syntax
,
53 int maxParams
= 65535)
55 maxParams
= qMin(maxParams
, func
->parameters().count());
59 if (syntax
== GeneratedJdocFile
) {
60 if (func
->access() == Node::Public
) {
62 } else if (func
->access() == Node::Protected
) {
63 result
+= "protected ";
68 if (func
->metaness() == FunctionNode::Native
)
74 // ### func->metaness() == FunctionNode::Abstract
79 if (!func
->returnType().isEmpty()) {
80 result
+= func
->returnType();
85 if (syntax
== SlotSignature
) {
86 result
+= "void mySlot";
88 result
+= func
->name();
91 for (int i
= 0; i
< maxParams
; ++i
) {
94 result
+= func
->parameters().at(i
).leftType();
95 if (syntax
!= JavadocRef
) {
97 result
+= func
->parameters().at(i
).name();
105 static QString
packageName(const Node
*node
)
107 while (node
&& node
->type() != Node::Class
&& node
->type() != Node::Fake
)
108 node
= node
->parent();
111 return node
->moduleName();
114 JavadocGenerator::JavadocGenerator()
115 : oldDevice(0), currentDepth(0)
119 JavadocGenerator::~JavadocGenerator()
123 void JavadocGenerator::initializeGenerator(const Config
&config
)
125 HtmlGenerator::initializeGenerator(config
);
127 formattingLeftMap().insert(ATOM_FORMATTING_PARAMETER
,
128 formattingLeftMap().value(ATOM_FORMATTING_TELETYPE
));
129 formattingRightMap().insert(ATOM_FORMATTING_PARAMETER
,
130 formattingRightMap().value(ATOM_FORMATTING_TELETYPE
));
133 void JavadocGenerator::terminateGenerator()
135 HtmlGenerator::terminateGenerator();
138 QString
JavadocGenerator::format()
143 void JavadocGenerator::generateTree(const Tree
*tree
, CodeMarker
*marker
)
145 HtmlGenerator::generateTree(tree
, marker
);
148 QString
JavadocGenerator::fileExtension(const Node
*node
)
150 if (node
->type() == Node::Fake
) {
157 QString
JavadocGenerator::typeString(const Node
*node
)
159 if (node
->type() == Node::Function
) {
160 const FunctionNode
*func
= static_cast<const FunctionNode
*>(node
);
161 return func
->metaness() == FunctionNode::Signal
? "signal" : "method";
163 return HtmlGenerator::typeString(node
);
167 QString
JavadocGenerator::imageFileName(const Node
*relative
, const QString
& fileBase
)
169 QString result
= HtmlGenerator::imageFileName(relative
, fileBase
);
170 if (!result
.isEmpty()) {
171 QString package
= packageName(relative
);
172 int numSubPackages
= package
.count('.') - 2;
173 while (numSubPackages
> 0) {
174 result
.prepend("%2E%2E/"); // javadoc 1.5.0_06 chokes on '../'
181 static int textDepth
= 0;
183 void JavadocGenerator::startText(const Node
*relative
, CodeMarker
*marker
)
185 if (textDepth
++ == 0 && relative
->type() != Node::Fake
) {
186 Q_ASSERT(!oldDevice
);
187 oldDevice
= out().device();
189 out().setString(&buffer
);
191 HtmlGenerator::startText(relative
, marker
);
194 void JavadocGenerator::endText(const Node
*relative
, CodeMarker
*marker
)
196 HtmlGenerator::endText(relative
, marker
);
197 if (--textDepth
== 0 && relative
->type() != Node::Fake
) {
199 out().setDevice(oldDevice
);
203 Need to escape XML metacharacters in .jdoc files.
205 buffer
.replace("*/", "*<!-- noop -->/");
206 buffer
.replace("&", "&");
207 buffer
.replace("\"", """);
208 buffer
.replace("<", "<");
209 buffer
.replace(">", ">");
215 int JavadocGenerator::generateAtom(const Atom
*atom
, const Node
*relative
, CodeMarker
*marker
)
217 return HtmlGenerator::generateAtom(atom
, relative
, marker
);
220 void JavadocGenerator::generateClassLikeNode(const InnerNode
*inner
, CodeMarker
*marker
)
223 out() << "<class name=\"" << protect(inner
->name()) << "\"";
224 generateDoc(inner
, marker
);
228 foreach (Node
*node
, inner
->childNodes()) {
229 if (node
->isInnerNode()) {
230 generateClassLikeNode(static_cast<InnerNode
*>(node
), marker
);
232 if (node
->type() == Node::Enum
) {
233 EnumNode
*enume
= static_cast<EnumNode
*>(node
);
236 out() << "<enum name=\"" << protect(node
->name()) << "\"";
237 generateDoc(node
, marker
);
241 const QList
<EnumItem
> &items
= enume
->items();
242 for (int i
= 0; i
< items
.count(); ++i
) {
243 const EnumItem
&item
= items
.at(i
);
245 out() << "<enum-value name=\"" << protect(item
.name()) << "\"";
246 generateEnumItemDoc(item
.text(), enume
, marker
);
251 out() << "</enum>\n";
252 } else if (node
->type() == Node::Function
) {
253 FunctionNode
*func
= static_cast<FunctionNode
*>(node
);
255 out() << (func
->metaness() == FunctionNode::Signal
? "<signal" : "<method")
257 << protect(javaSignature(func
, GeneratedJdocFile
))
259 generateDoc(node
, marker
);
267 out() << "</class>\n";
270 void JavadocGenerator::generateFakeNode(const FakeNode
*fake
, CodeMarker
*marker
)
272 HtmlGenerator::generateFakeNode(fake
, marker
);
275 bool JavadocGenerator::generateText(const Text
& text
, const Node
*relative
, CodeMarker
*marker
)
277 HtmlGenerator::generateText(text
, relative
, marker
);
281 void JavadocGenerator::generateBody(const Node
*node
, CodeMarker
*marker
)
283 generateText(node
->doc().body(), node
, marker
);
286 void JavadocGenerator::generateAlsoList( const Node
*node
, CodeMarker
*marker
)
288 QList
<Text
> alsoList
= node
->doc().alsoList();
289 supplementAlsoList(node
, alsoList
);
291 if (node
->type() == Node::Fake
292 || (node
->type() == Node::Function
293 && static_cast<const FunctionNode
*>(node
)->metaness() == FunctionNode::Signal
)) {
296 if (!alsoList
.isEmpty()) {
297 text
<< Atom(Atom::ListLeft
, ATOM_LIST_TAG
)
298 << Atom(Atom::ListTagLeft
, ATOM_LIST_TAG
)
299 << Atom(Atom::FormattingLeft
, ATOM_FORMATTING_BOLD
)
301 << Atom(Atom::FormattingRight
, ATOM_FORMATTING_BOLD
)
302 << Atom(Atom::ListTagRight
, ATOM_LIST_TAG
)
303 << Atom(Atom::ListItemLeft
, ATOM_LIST_TAG
);
305 for (int i
= 0; i
< alsoList
.count(); ++i
) {
308 text
<< alsoList
.at(i
);
310 text
<< Atom(Atom::ListItemRight
, ATOM_LIST_TAG
)
311 << Atom(Atom::ListRight
, ATOM_LIST_TAG
);
314 generateText(text
, node
, marker
);
316 foreach (const Text
&text
, alsoList
) {
318 generateText(text
, node
, marker
);
323 QString
JavadocGenerator::refForNode( const Node
*node
)
325 if (node
->type() == Node::Function
)
326 return javaSignature(static_cast<const FunctionNode
*>(node
), JavadocRef
);
328 return HtmlGenerator::refForNode(node
);
331 QString
JavadocGenerator::linkForNode( const Node
*node
, const Node
*relative
)
333 // ### EVIL, relative should never be null
337 if (packageName(node
).isEmpty()) {
343 if (node
->type() == Node::Fake
) {
344 result
= node
->name();
346 if (!node
->isInnerNode()) {
347 result
= linkForNode(node
->parent(), relative
) + "#" + refForNode(node
);
349 result
= node
->name() + ".html";
353 QStringList nodePackage
= packageName(node
).split(".");
354 QStringList relativePackage
= packageName(relative
).split(".");
355 if (nodePackage
== QStringList(QString()) || relativePackage
== QStringList(QString())) {
356 qWarning("I'm in trouble [%s][%s]", qPrintable(node
->name()), qPrintable(relative
->name()));
360 int i
= nodePackage
.count() - 1;
361 while (nodePackage
.value(i
) != relativePackage
.value(i
)) {
362 result
.prepend(nodePackage
.at(i
) + "/");
367 while (i
< relativePackage
.count()) {
368 result
.prepend("%2E%2E/"); // javadoc 1.5.0_06 chokes on '../'
375 QString
JavadocGenerator::refForAtom(Atom
*atom
, const Node
*node
)
377 return HtmlGenerator::refForAtom(atom
, node
);
381 Neutralize dumb functions called from HtmlGenerator.
383 void JavadocGenerator::generateDcf(const QString
& /* fileBase */, const QString
& /* startPage */,
384 const QString
& /* title */, DcfSection
& /* dcfRoot */)
388 void JavadocGenerator::generateIndex(const QString
& /* fileBase */, const QString
& /* url */,
389 const QString
& /* title */)
393 void JavadocGenerator::generateIndent()
395 for (int i
= 0; i
< currentDepth
; ++i
)
399 void JavadocGenerator::generateDoc(const Node
*node
, CodeMarker
*marker
)
401 const Text
&text
= node
->doc().body();
402 if (!text
.isEmpty()) {
403 out() << " doc=\"/**\n";
404 Generator::generateStatus(node
, marker
);
405 generateText(text
, node
, marker
);
406 if (node
&& node
->type() == Node::Function
) {
407 const FunctionNode
*func
= static_cast<const FunctionNode
*>(node
);
408 if (func
->metaness() == FunctionNode::Signal
) {
409 QStringList slotSignatures
;
410 for (int i
= func
->parameters().count(); i
>= 0; --i
)
411 slotSignatures
+= javaSignature(func
, SlotSignature
, i
);
415 text
<< Atom(Atom::ListLeft
, ATOM_LIST_TAG
)
416 << Atom(Atom::ListTagLeft
, ATOM_LIST_TAG
)
417 << Atom(Atom::FormattingLeft
, ATOM_FORMATTING_BOLD
);
419 if (slotSignatures
.count() == 1) {
420 text
<< "Compatible Slot Signature:";
422 text
<< "Compatible Slot Signatures:";
425 text
<< Atom(Atom::FormattingRight
, ATOM_FORMATTING_BOLD
)
426 << Atom(Atom::ListTagRight
, ATOM_LIST_TAG
);
428 for (int i
= 0; i
< slotSignatures
.count(); ++i
) {
429 text
<< Atom(Atom::ListItemLeft
, ATOM_LIST_TAG
)
430 << Atom(Atom::C
, marker
->markedUpCode(slotSignatures
.at(i
), 0, ""))
431 << Atom(Atom::ListItemRight
, ATOM_LIST_TAG
);
433 text
<< Atom(Atom::ListRight
, ATOM_LIST_TAG
);
434 generateText(text
, node
, marker
);
438 generateAlsoList(node
, marker
);
443 void JavadocGenerator::generateEnumItemDoc(const Text
&text
, const Node
*node
, CodeMarker
*marker
)
445 out() << " doc=\"/**\n";
446 if (text
.isEmpty()) {
447 out() << "Internal.";
449 generateText(text
, node
, marker
);