tools/qdoc3/qscodemarker.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/qdoc3/qscodemarker.cpp	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,385 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+  qscodemarker.cpp
+*/
+
+#include "node.h"
+#include "qscodemarker.h"
+
+QT_BEGIN_NAMESPACE
+
+QsCodeMarker::QsCodeMarker()
+{
+}
+
+QsCodeMarker::~QsCodeMarker()
+{
+}
+
+bool QsCodeMarker::recognizeCode( const QString& /* code */ )
+{
+    return true;
+}
+
+bool QsCodeMarker::recognizeExtension( const QString& ext )
+{
+    return ext == "js" || ext == "qs";
+}
+
+bool QsCodeMarker::recognizeLanguage( const QString& lang )
+{
+    return lang == "JavaScript" || lang == "Qt Script";
+}
+
+QString QsCodeMarker::plainName( const Node *node )
+{
+    QString name = node->name();
+    if ( node->type() == Node::Function )
+	name += "()";
+    return name;
+}
+
+QString QsCodeMarker::plainFullName( const Node *node, const Node * /* relative */ )
+{
+    QString fullName;
+    for ( ;; ) {
+	fullName.prepend( plainName(node) );
+	if ( node->parent()->name().isEmpty() )
+	    break;
+	node = node->parent();
+	fullName.prepend(".");
+    }
+    return fullName;
+}
+
+QString QsCodeMarker::markedUpCode( const QString& code,
+				    const Node * /* relative */,
+				    const QString& /* dirPath */ )
+{
+    return protect( code );
+}
+
+QString QsCodeMarker::markedUpSynopsis( const Node *node,
+					const Node * /* relative */,
+					SynopsisStyle style )
+{
+    QString synopsis;
+    QStringList extras;
+    QString name;
+
+    name = taggedNode( node );
+    if ( style != Detailed )
+        name = linkTag( node, name );
+    name = "<@name>" + name + "</@name>";
+
+    if ( style == Detailed && !node->parent()->name().isEmpty() &&
+	 node->type() != Node::Enum )
+	name.prepend( taggedNode(node->parent()) + "." );
+
+    switch ( node->type() ) {
+    case Node::Class:
+        synopsis = "class " + name;
+        break;
+    case Node::Function:
+	{
+            const FunctionNode *func = (const FunctionNode *) node;
+
+	    synopsis = name;
+
+	    if ( style == SeparateList ) {
+		synopsis += "()";
+	    } else {
+		synopsis += " (";
+        	if ( !func->parameters().isEmpty() ) {
+        	    synopsis += " ";
+		    int numOptional = 0;
+        	    QList<Parameter>::ConstIterator p = func->parameters().begin();
+        	    while ( p != func->parameters().end() ) {
+			if ( !(*p).defaultValue().isEmpty() ) {
+			    if ( p == func->parameters().begin() ) {
+				synopsis += "[ ";
+			    } else {
+				synopsis += " [ , ";
+			    }
+			    numOptional++;
+			} else {
+                	    if ( p != func->parameters().begin() )
+                		synopsis += ", ";
+			}
+			if ( !(*p).name().isEmpty() )
+			    synopsis += "<@param>" + protect( (*p).name() ) +
+					"</@param> : ";
+			synopsis += protect( (*p).leftType() );
+                	++p;
+        	    }
+		    for ( int i = 0; i < numOptional; i++ )
+			synopsis += " ]";
+        	    synopsis += " ";
+        	}
+		synopsis += ")";
+	    }
+
+	    if ( style != SeparateList && !func->returnType().isEmpty() )
+		synopsis += " : " + protect( func->returnType() );
+
+            if ( style == Detailed && func->metaness() == FunctionNode::Signal )
+		extras << "[signal]";
+	}
+        break;
+    case Node::Property:
+	{
+            const PropertyNode *property = (const PropertyNode *) node;
+
+	    synopsis = name;
+	    if ( style != SeparateList )
+		synopsis += " : " + property->dataType();
+	    if ( style == Detailed && property->setters().isEmpty() )
+		extras << "[read only]";
+	}
+        break;
+    case Node::Enum:
+	{
+	    /*
+	      The letters A to F and X (upper- and lower-case) can
+	      appear in a hexadecimal constant (e.g. 0x3F).
+	    */
+	    QRegExp letterRegExp( "[G-WYZg-wyz_]" );
+	    const EnumNode *enume = (const EnumNode *) node;
+
+	    synopsis = name;
+	    if ( style == Summary && !enume->items().isEmpty() ) {
+		synopsis += " : ";
+		QString comma;
+		QList<EnumItem>::ConstIterator it = enume->items().begin();
+		while ( it != enume->items().end() ) {
+		    if ( enume->itemAccess((*it).name()) == Node::Public ) {
+			synopsis += comma;
+			synopsis += (*it).name();
+			if ( (*it).value().indexOf(letterRegExp) != -1 )
+			    synopsis += " = " + (*it).value();
+			comma = ", ";
+		    }
+		    ++it;
+		}
+	    }
+	}
+	break;
+    case Node::Namespace:
+    case Node::Typedef:
+    default:
+        synopsis = name;
+    }
+
+    if ( style == Summary ) {
+        if ( node->status() == Node::Preliminary ) {
+            extras << "(preliminary)";
+        } else if ( node->status() == Node::Deprecated ) {
+            extras << "(deprecated)";
+        } else if ( node->status() == Node::Obsolete ) {
+            extras << "(obsolete)";
+        }
+    }
+
+    QString extra;
+    if ( !extras.isEmpty() )
+        extra = "<@extra>" + extras.join(" ") + "</@extra>";
+    return synopsis + extra;
+}
+
+QString QsCodeMarker::markedUpName( const Node *node )
+{
+    QString name = linkTag( node, taggedNode(node) );
+    if ( node->type() == Node::Function )
+	name += "()";
+    return name;
+}
+
+QString QsCodeMarker::markedUpFullName( const Node *node,
+					const Node * /* relative */ )
+{
+    QString fullName;
+    for ( ;; ) {
+	fullName.prepend( markedUpName(node) );
+	if ( node->parent()->name().isEmpty() )
+	    break;
+	node = node->parent();
+	fullName.prepend( "<@op>.</@op>" );
+    }
+    return fullName;
+}
+
+QString QsCodeMarker::markedUpEnumValue(const QString & /* enumValue */,
+                                        const Node * /* relative */)
+{
+    return QString();
+}
+
+QString QsCodeMarker::markedUpIncludes( const QStringList& /* includes */ )
+{
+    return QString();
+}
+
+QString QsCodeMarker::functionBeginRegExp( const QString& funcName )
+{
+    return "^function[ \t].*\\b" + QRegExp::escape( funcName );
+}
+
+QString QsCodeMarker::functionEndRegExp( const QString& /* funcName */ )
+{
+    return "^}";
+}
+
+QList<Section> QsCodeMarker::sections( const InnerNode *inner, SynopsisStyle style, Status status )
+{
+    QList<Section> sections;
+
+    if (inner->type() != Node::Class)
+        return sections;
+
+    const ClassNode *classe = static_cast<const ClassNode *>(inner);
+
+    if ( style == Summary ) {
+	FastSection enums(classe, "Enums", "enum", "enums");
+	FastSection functions(classe, "Functions", "function", "functions");
+	FastSection readOnlyProperties(classe, "Read-Only Properties", "property", "properties");
+	FastSection signalz(classe, "Signals", "signal", "signals");
+	FastSection writableProperties(classe, "Writable Properties", "property", "properties");
+
+	QStack<const ClassNode *> stack;
+	stack.push( classe );
+
+	while ( !stack.isEmpty() ) {
+	    const ClassNode *ancestorClass = stack.pop();
+
+	    NodeList::ConstIterator c = ancestorClass->childNodes().begin();
+	    while ( c != ancestorClass->childNodes().end() ) {
+		if ( (*c)->access() == Node::Public ) {
+		    if ( (*c)->type() == Node::Enum ) {
+			insert( enums, *c, style, status );
+		    } else if ( (*c)->type() == Node::Function ) {
+			const FunctionNode *func = (const FunctionNode *) *c;
+			if ( func->metaness() == FunctionNode::Signal ) {
+			    insert( signalz, *c, style, status );
+			} else {
+			    insert( functions, *c, style, status );
+			}
+		    } else if ( (*c)->type() == Node::Property ) {
+			const PropertyNode *property =
+				(const PropertyNode *) *c;
+			if ( property->setters().isEmpty() ) {
+			    insert( readOnlyProperties, *c, style, status );
+			} else {
+			    insert( writableProperties, *c, style, status );
+			}
+		    }
+		}
+		++c;
+	    }
+
+	    QList<RelatedClass>::ConstIterator r = ancestorClass->baseClasses().begin();
+	    while ( r != ancestorClass->baseClasses().end() ) {
+		stack.prepend( (*r).node );
+		++r;
+	    }
+	}
+	append( sections, enums );
+	append( sections, writableProperties );
+	append( sections, readOnlyProperties );
+	append( sections, functions );
+	append( sections, signalz );
+    } else if ( style == Detailed ) {
+	FastSection enums( classe, "Enum Documentation" );
+	FastSection functionsAndSignals( classe, "Function and Signal Documentation" );
+	FastSection properties( classe, "Property Documentation" );
+
+	NodeList::ConstIterator c = classe->childNodes().begin();
+	while ( c != classe->childNodes().end() ) {
+	    if ( (*c)->access() == Node::Public ) {
+		if ( (*c)->type() == Node::Enum ) {
+		    insert( enums, *c, style, status );
+		} else if ( (*c)->type() == Node::Function ) {
+		    insert( functionsAndSignals, *c, style, status );
+		} else if ( (*c)->type() == Node::Property ) {
+		    insert( properties, *c, style, status );
+		}
+	    }
+	    ++c;
+	}
+	append( sections, enums );
+	append( sections, properties );
+	append( sections, functionsAndSignals );
+    } else { // ( style == SeparateList )
+	FastSection all( classe );
+
+	QStack<const ClassNode *> stack;
+	stack.push( classe );
+
+	while ( !stack.isEmpty() ) {
+	    const ClassNode *ancestorClass = stack.pop();
+
+	    NodeList::ConstIterator c = ancestorClass->childNodes().begin();
+	    while ( c != ancestorClass->childNodes().end() ) {
+		if ( (*c)->access() == Node::Public )
+		    insert( all, *c, style, status );
+		++c;
+	    }
+
+	    QList<RelatedClass>::ConstIterator r = ancestorClass->baseClasses().begin();
+	    while ( r != ancestorClass->baseClasses().end() ) {
+		stack.prepend( (*r).node );
+		++r;
+	    }
+	}
+	append( sections, all );
+    }
+    return sections;
+}
+
+const Node *QsCodeMarker::resolveTarget( const QString& /* target */,
+                                         const Tree * /* tree */,
+					 const Node * /* relative */ )
+{
+    return 0;
+}
+
+QT_END_NAMESPACE