source: trunk/tools/qdoc3/qscodemarker.cpp@ 356

Last change on this file since 356 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 11.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the tools applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*
43 qscodemarker.cpp
44*/
45
46#include "node.h"
47#include "qscodemarker.h"
48
49QT_BEGIN_NAMESPACE
50
51QsCodeMarker::QsCodeMarker()
52{
53}
54
55QsCodeMarker::~QsCodeMarker()
56{
57}
58
59bool QsCodeMarker::recognizeCode( const QString& /* code */ )
60{
61 return true;
62}
63
64bool QsCodeMarker::recognizeExtension( const QString& ext )
65{
66 return ext == "js" || ext == "qs";
67}
68
69bool QsCodeMarker::recognizeLanguage( const QString& lang )
70{
71 return lang == "JavaScript" || lang == "Qt Script";
72}
73
74QString QsCodeMarker::plainName( const Node *node )
75{
76 QString name = node->name();
77 if ( node->type() == Node::Function )
78 name += "()";
79 return name;
80}
81
82QString QsCodeMarker::plainFullName( const Node *node, const Node * /* relative */ )
83{
84 QString fullName;
85 for ( ;; ) {
86 fullName.prepend( plainName(node) );
87 if ( node->parent()->name().isEmpty() )
88 break;
89 node = node->parent();
90 fullName.prepend(".");
91 }
92 return fullName;
93}
94
95QString QsCodeMarker::markedUpCode( const QString& code,
96 const Node * /* relative */,
97 const QString& /* dirPath */ )
98{
99 return protect( code );
100}
101
102QString QsCodeMarker::markedUpSynopsis( const Node *node,
103 const Node * /* relative */,
104 SynopsisStyle style )
105{
106 QString synopsis;
107 QStringList extras;
108 QString name;
109
110 name = taggedNode( node );
111 if ( style != Detailed )
112 name = linkTag( node, name );
113 name = "<@name>" + name + "</@name>";
114
115 if ( style == Detailed && !node->parent()->name().isEmpty() &&
116 node->type() != Node::Enum )
117 name.prepend( taggedNode(node->parent()) + "." );
118
119 switch ( node->type() ) {
120 case Node::Class:
121 synopsis = "class " + name;
122 break;
123 case Node::Function:
124 {
125 const FunctionNode *func = (const FunctionNode *) node;
126
127 synopsis = name;
128
129 if ( style == SeparateList ) {
130 synopsis += "()";
131 } else {
132 synopsis += " (";
133 if ( !func->parameters().isEmpty() ) {
134 synopsis += " ";
135 int numOptional = 0;
136 QList<Parameter>::ConstIterator p = func->parameters().begin();
137 while ( p != func->parameters().end() ) {
138 if ( !(*p).defaultValue().isEmpty() ) {
139 if ( p == func->parameters().begin() ) {
140 synopsis += "[ ";
141 } else {
142 synopsis += " [ , ";
143 }
144 numOptional++;
145 } else {
146 if ( p != func->parameters().begin() )
147 synopsis += ", ";
148 }
149 if ( !(*p).name().isEmpty() )
150 synopsis += "<@param>" + protect( (*p).name() ) +
151 "</@param> : ";
152 synopsis += protect( (*p).leftType() );
153 ++p;
154 }
155 for ( int i = 0; i < numOptional; i++ )
156 synopsis += " ]";
157 synopsis += " ";
158 }
159 synopsis += ")";
160 }
161
162 if ( style != SeparateList && !func->returnType().isEmpty() )
163 synopsis += " : " + protect( func->returnType() );
164
165 if ( style == Detailed && func->metaness() == FunctionNode::Signal )
166 extras << "[signal]";
167 }
168 break;
169 case Node::Property:
170 {
171 const PropertyNode *property = (const PropertyNode *) node;
172
173 synopsis = name;
174 if ( style != SeparateList )
175 synopsis += " : " + property->dataType();
176 if ( style == Detailed && property->setters().isEmpty() )
177 extras << "[read only]";
178 }
179 break;
180 case Node::Enum:
181 {
182 /*
183 The letters A to F and X (upper- and lower-case) can
184 appear in a hexadecimal constant (e.g. 0x3F).
185 */
186 QRegExp letterRegExp( "[G-WYZg-wyz_]" );
187 const EnumNode *enume = (const EnumNode *) node;
188
189 synopsis = name;
190 if ( style == Summary && !enume->items().isEmpty() ) {
191 synopsis += " : ";
192 QString comma;
193 QList<EnumItem>::ConstIterator it = enume->items().begin();
194 while ( it != enume->items().end() ) {
195 if ( enume->itemAccess((*it).name()) == Node::Public ) {
196 synopsis += comma;
197 synopsis += (*it).name();
198 if ( (*it).value().indexOf(letterRegExp) != -1 )
199 synopsis += " = " + (*it).value();
200 comma = ", ";
201 }
202 ++it;
203 }
204 }
205 }
206 break;
207 case Node::Namespace:
208 case Node::Typedef:
209 default:
210 synopsis = name;
211 }
212
213 if ( style == Summary ) {
214 if ( node->status() == Node::Preliminary ) {
215 extras << "(preliminary)";
216 } else if ( node->status() == Node::Deprecated ) {
217 extras << "(deprecated)";
218 } else if ( node->status() == Node::Obsolete ) {
219 extras << "(obsolete)";
220 }
221 }
222
223 QString extra;
224 if ( !extras.isEmpty() )
225 extra = "<@extra>" + extras.join(" ") + "</@extra>";
226 return synopsis + extra;
227}
228
229QString QsCodeMarker::markedUpName( const Node *node )
230{
231 QString name = linkTag( node, taggedNode(node) );
232 if ( node->type() == Node::Function )
233 name += "()";
234 return name;
235}
236
237QString QsCodeMarker::markedUpFullName( const Node *node,
238 const Node * /* relative */ )
239{
240 QString fullName;
241 for ( ;; ) {
242 fullName.prepend( markedUpName(node) );
243 if ( node->parent()->name().isEmpty() )
244 break;
245 node = node->parent();
246 fullName.prepend( "<@op>.</@op>" );
247 }
248 return fullName;
249}
250
251QString QsCodeMarker::markedUpEnumValue(const QString & /* enumValue */,
252 const Node * /* relative */)
253{
254 return QString();
255}
256
257QString QsCodeMarker::markedUpIncludes( const QStringList& /* includes */ )
258{
259 return QString();
260}
261
262QString QsCodeMarker::functionBeginRegExp( const QString& funcName )
263{
264 return "^function[ \t].*\\b" + QRegExp::escape( funcName );
265}
266
267QString QsCodeMarker::functionEndRegExp( const QString& /* funcName */ )
268{
269 return "^}";
270}
271
272QList<Section> QsCodeMarker::sections( const InnerNode *inner, SynopsisStyle style, Status status )
273{
274 QList<Section> sections;
275
276 if (inner->type() != Node::Class)
277 return sections;
278
279 const ClassNode *classe = static_cast<const ClassNode *>(inner);
280
281 if ( style == Summary ) {
282 FastSection enums(classe, "Enums", "enum", "enums");
283 FastSection functions(classe, "Functions", "function", "functions");
284 FastSection readOnlyProperties(classe, "Read-Only Properties", "property", "properties");
285 FastSection signalz(classe, "Signals", "signal", "signals");
286 FastSection writableProperties(classe, "Writable Properties", "property", "properties");
287
288 QStack<const ClassNode *> stack;
289 stack.push( classe );
290
291 while ( !stack.isEmpty() ) {
292 const ClassNode *ancestorClass = stack.pop();
293
294 NodeList::ConstIterator c = ancestorClass->childNodes().begin();
295 while ( c != ancestorClass->childNodes().end() ) {
296 if ( (*c)->access() == Node::Public ) {
297 if ( (*c)->type() == Node::Enum ) {
298 insert( enums, *c, style, status );
299 } else if ( (*c)->type() == Node::Function ) {
300 const FunctionNode *func = (const FunctionNode *) *c;
301 if ( func->metaness() == FunctionNode::Signal ) {
302 insert( signalz, *c, style, status );
303 } else {
304 insert( functions, *c, style, status );
305 }
306 } else if ( (*c)->type() == Node::Property ) {
307 const PropertyNode *property =
308 (const PropertyNode *) *c;
309 if ( property->setters().isEmpty() ) {
310 insert( readOnlyProperties, *c, style, status );
311 } else {
312 insert( writableProperties, *c, style, status );
313 }
314 }
315 }
316 ++c;
317 }
318
319 QList<RelatedClass>::ConstIterator r = ancestorClass->baseClasses().begin();
320 while ( r != ancestorClass->baseClasses().end() ) {
321 stack.prepend( (*r).node );
322 ++r;
323 }
324 }
325 append( sections, enums );
326 append( sections, writableProperties );
327 append( sections, readOnlyProperties );
328 append( sections, functions );
329 append( sections, signalz );
330 } else if ( style == Detailed ) {
331 FastSection enums( classe, "Enum Documentation" );
332 FastSection functionsAndSignals( classe, "Function and Signal Documentation" );
333 FastSection properties( classe, "Property Documentation" );
334
335 NodeList::ConstIterator c = classe->childNodes().begin();
336 while ( c != classe->childNodes().end() ) {
337 if ( (*c)->access() == Node::Public ) {
338 if ( (*c)->type() == Node::Enum ) {
339 insert( enums, *c, style, status );
340 } else if ( (*c)->type() == Node::Function ) {
341 insert( functionsAndSignals, *c, style, status );
342 } else if ( (*c)->type() == Node::Property ) {
343 insert( properties, *c, style, status );
344 }
345 }
346 ++c;
347 }
348 append( sections, enums );
349 append( sections, properties );
350 append( sections, functionsAndSignals );
351 } else { // ( style == SeparateList )
352 FastSection all( classe );
353
354 QStack<const ClassNode *> stack;
355 stack.push( classe );
356
357 while ( !stack.isEmpty() ) {
358 const ClassNode *ancestorClass = stack.pop();
359
360 NodeList::ConstIterator c = ancestorClass->childNodes().begin();
361 while ( c != ancestorClass->childNodes().end() ) {
362 if ( (*c)->access() == Node::Public )
363 insert( all, *c, style, status );
364 ++c;
365 }
366
367 QList<RelatedClass>::ConstIterator r = ancestorClass->baseClasses().begin();
368 while ( r != ancestorClass->baseClasses().end() ) {
369 stack.prepend( (*r).node );
370 ++r;
371 }
372 }
373 append( sections, all );
374 }
375 return sections;
376}
377
378const Node *QsCodeMarker::resolveTarget( const QString& /* target */,
379 const Tree * /* tree */,
380 const Node * /* relative */ )
381{
382 return 0;
383}
384
385QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.