You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
885 lines
22 KiB
885 lines
22 KiB
/***************************************************************************
|
|
* Copyright (C) 2003 by Roberto Raggi *
|
|
* roberto@tdevelop.org *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "tag_creator.h"
|
|
#include "catalog.h"
|
|
#include "ast_utils.h"
|
|
#include "cpp_tags.h"
|
|
#include "doxydoc.h"
|
|
#include "driver.h"
|
|
|
|
#include <kdebug.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqregexp.h>
|
|
|
|
DoxyDoc* TagCreator::m_documentation = new DoxyDoc( TQStringList() );
|
|
|
|
TagCreator::TagCreator( const TQString& fileName, Catalog* c )
|
|
: m_catalog( c ), m_fileName( fileName ), m_anon( 0 )
|
|
{
|
|
}
|
|
|
|
TagCreator::~TagCreator()
|
|
{
|
|
}
|
|
|
|
void TagCreator::destroyDocumentation()
|
|
{
|
|
delete m_documentation;
|
|
}
|
|
|
|
void TagCreator::setDocumentationDirectories( const TQStringList& str )
|
|
{
|
|
if ( m_documentation )
|
|
delete m_documentation;
|
|
m_documentation = new DoxyDoc( str );
|
|
}
|
|
|
|
void TagCreator::parseDeclaration( DeclarationAST* ast )
|
|
{
|
|
if( ast->nodeType() == NodeType_AccessDeclaration ||
|
|
m_currentAccess.isEmpty() ||
|
|
m_currentAccess.contains("private") || ///In order to correctly evaluate templates, the private members are necessary too
|
|
m_currentAccess.contains("public") ||
|
|
m_currentAccess.contains("protected") ||
|
|
m_currentAccess.contains("signals") )
|
|
{
|
|
TreeParser::parseDeclaration( ast );
|
|
}
|
|
}
|
|
|
|
void TagCreator::parseTranslationUnit( const ParsedFile& ast )
|
|
{
|
|
m_currentScope.clear();
|
|
m_currentAccess = TQString();
|
|
m_inSlots = false;
|
|
m_inSignals = false;
|
|
m_anon = 0;
|
|
m_imports.clear();
|
|
m_inClass = false;
|
|
|
|
m_imports << TQStringList();
|
|
|
|
Tag tag;
|
|
tag.setKind( Tag::Kind_TranslationUnit );
|
|
tag.setFileName( m_fileName );
|
|
tag.setName( m_fileName );
|
|
|
|
TQByteArray data;
|
|
TQDataStream stream(data, IO_WriteOnly );
|
|
ast.write( stream );
|
|
tag.setAttribute( "cppparsedfile", data );
|
|
tag.setAttribute( "includedFrom", ast.includedFrom() );
|
|
tag.setAttribute( "skippedLines", TQString("%1").arg( ast.skippedLines()) );
|
|
tag.setAttribute( "macroValueHash", TQString("%1").arg( ast.usedMacros().valueHash()) );
|
|
tag.setAttribute( "macroIdHash", TQString("%1").arg( ast.usedMacros().idHash() ) );
|
|
|
|
tag.setScope( m_currentScope );
|
|
if( !ast->comment().isEmpty() )
|
|
tag.setComment( ast->comment() );
|
|
|
|
m_catalog->addItem( tag );
|
|
|
|
TreeParser::parseTranslationUnit( ast );
|
|
m_imports.pop_back();
|
|
}
|
|
|
|
void TagCreator::parseNamespaceAlias( NamespaceAliasAST* ast ) {
|
|
TQString nsName;
|
|
TQString aliasName;
|
|
|
|
if( !ast->namespaceName() || ast->namespaceName()->text().isEmpty() )
|
|
{
|
|
// anonymous namespace
|
|
}
|
|
else
|
|
nsName = ast->namespaceName()->text();
|
|
|
|
if( ast->aliasName() )
|
|
aliasName = ast->aliasName()->text();
|
|
|
|
Tag tag;
|
|
tag.setKind( Tag::Kind_Namespace );
|
|
tag.setFileName( m_fileName );
|
|
tag.setName( nsName ); ///nsName is the new name of the namespace
|
|
tag.setAttribute( "alias", aliasName ); ///aliasName is the name of the real namespace
|
|
tag.setScope( m_currentScope );
|
|
if( !ast->comment().isEmpty() )
|
|
tag.setComment( ast->comment() );
|
|
|
|
int line, col;
|
|
ast->getStartPosition( &line, &col );
|
|
tag.setStartPosition( line, col );
|
|
|
|
ast->getEndPosition( &line, &col );
|
|
tag.setEndPosition( line, col );
|
|
|
|
m_catalog->addItem( tag );
|
|
|
|
TreeParser::parseNamespaceAlias( ast );
|
|
}
|
|
|
|
void TagCreator::parseNamespace( NamespaceAST* ast )
|
|
{
|
|
TQString nsName;
|
|
if( !ast->namespaceName() || ast->namespaceName()->text().isEmpty() )
|
|
{
|
|
// anonymous namespace
|
|
}
|
|
else
|
|
nsName = ast->namespaceName()->text();
|
|
|
|
Tag tag;
|
|
tag.setKind( Tag::Kind_Namespace );
|
|
tag.setFileName( m_fileName );
|
|
tag.setName( nsName );
|
|
tag.setScope( m_currentScope );
|
|
if( !ast->comment().isEmpty() )
|
|
tag.setComment( ast->comment() );
|
|
|
|
int line, col;
|
|
ast->getStartPosition( &line, &col );
|
|
tag.setStartPosition( line, col );
|
|
|
|
ast->getEndPosition( &line, &col );
|
|
tag.setEndPosition( line, col );
|
|
|
|
m_catalog->addItem( tag );
|
|
|
|
m_currentScope.push_back( nsName );
|
|
TreeParser::parseNamespace( ast );
|
|
m_currentScope.pop_back();
|
|
}
|
|
|
|
void TagCreator::parseElaboratedTypeSpecifier( ElaboratedTypeSpecifierAST* ast )
|
|
{
|
|
TreeParser::parseElaboratedTypeSpecifier( ast );
|
|
}
|
|
|
|
void TagCreator::parseUsingDirective( UsingDirectiveAST* ast )
|
|
{
|
|
TQString name;
|
|
if( ast->name() )
|
|
name = ast->name()->text();
|
|
|
|
if( !name.isNull() ){
|
|
Tag tag;
|
|
tag.setKind( Tag::Kind_UsingDirective );
|
|
tag.setFileName( m_fileName );
|
|
tag.setName( name );
|
|
tag.setScope( m_currentScope );
|
|
|
|
int line, col;
|
|
ast->getStartPosition( &line, &col );
|
|
tag.setStartPosition( line, col );
|
|
|
|
ast->getEndPosition( &line, &col );
|
|
tag.setEndPosition( line, col );
|
|
|
|
m_catalog->addItem( tag );
|
|
}
|
|
|
|
m_imports.back().push_back( name );
|
|
}
|
|
|
|
void TagCreator::parseTypedef( TypedefAST* ast )
|
|
{
|
|
TypeSpecifierAST* typeSpec = ast->typeSpec();
|
|
InitDeclaratorListAST* declarators = ast->initDeclaratorList();
|
|
|
|
if( typeSpec && declarators ){
|
|
TQString typeId;
|
|
|
|
if( typeSpec->name() )
|
|
typeId = typeSpec->name()->text();
|
|
|
|
TQPtrList<InitDeclaratorAST> l( declarators->initDeclaratorList() );
|
|
TQPtrListIterator<InitDeclaratorAST> it( l );
|
|
|
|
InitDeclaratorAST* initDecl = 0;
|
|
while( 0 != (initDecl = it.current()) )
|
|
{
|
|
|
|
TQString type, id;
|
|
if( initDecl->declarator() )
|
|
{
|
|
type = typeOfDeclaration( typeSpec, initDecl->declarator() );
|
|
|
|
DeclaratorAST* d = initDecl->declarator();
|
|
while( d->subDeclarator() )
|
|
d = d->subDeclarator();
|
|
|
|
if( d->declaratorId() )
|
|
id = d->declaratorId()->text();
|
|
}
|
|
|
|
Tag tag;
|
|
if( !ast->comment().isEmpty() )
|
|
tag.setComment( ast->comment() );
|
|
|
|
tag.setKind( Tag::Kind_Typedef );
|
|
tag.setFileName( m_fileName );
|
|
tag.setName( id );
|
|
tag.setScope( m_currentScope );
|
|
tag.setAttribute( "t", type );
|
|
|
|
int line, col;
|
|
initDecl->getStartPosition( &line, &col );
|
|
tag.setStartPosition( line, col );
|
|
|
|
initDecl->getEndPosition( &line, &col );
|
|
tag.setEndPosition( line, col );
|
|
|
|
m_catalog->addItem( tag );
|
|
|
|
++it;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
void TagCreator::parseTemplateDeclaration( TemplateDeclarationAST* ast )
|
|
{
|
|
m_currentTemplateDeclarator.push( ast );
|
|
if ( ast->declaration() )
|
|
parseDeclaration( ast->declaration() );
|
|
|
|
|
|
|
|
TreeParser::parseTemplateDeclaration( ast );
|
|
|
|
m_currentTemplateDeclarator.pop();
|
|
}
|
|
|
|
|
|
void TagCreator::parseSimpleDeclaration( SimpleDeclarationAST* ast )
|
|
{
|
|
CommentPusher push( *this, ast->comment() );
|
|
|
|
TypeSpecifierAST* typeSpec = ast->typeSpec();
|
|
InitDeclaratorListAST* declarators = ast->initDeclaratorList();
|
|
|
|
if( typeSpec )
|
|
parseTypeSpecifier( typeSpec );
|
|
|
|
if( declarators )
|
|
{
|
|
TQPtrList<InitDeclaratorAST> l = declarators->initDeclaratorList();
|
|
|
|
TQPtrListIterator<InitDeclaratorAST> it( l );
|
|
while( it.current() )
|
|
{
|
|
parseMyDeclaration( ast->functionSpecifier(), ast->storageSpecifier(), typeSpec, it.current() );
|
|
++it;
|
|
}
|
|
}
|
|
}
|
|
|
|
void TagCreator::parseFunctionDefinition( FunctionDefinitionAST* ast )
|
|
{
|
|
TypeSpecifierAST * typeSpec = ast->typeSpec();
|
|
GroupAST* funSpec = ast->functionSpecifier();
|
|
GroupAST* storageSpec = ast->storageSpecifier();
|
|
|
|
if ( !ast->initDeclarator() )
|
|
return ;
|
|
|
|
DeclaratorAST* d = ast->initDeclarator() ->declarator();
|
|
|
|
if ( !d->declaratorId() )
|
|
return ;
|
|
|
|
bool isFriend = false;
|
|
bool isVirtual = false;
|
|
bool isStatic = false;
|
|
bool isInline = false;
|
|
|
|
if ( funSpec )
|
|
{
|
|
TQPtrList<AST> l = funSpec->nodeList();
|
|
TQPtrListIterator<AST> it( l );
|
|
while ( it.current() )
|
|
{
|
|
TQString text = it.current() ->text();
|
|
if ( text == "virtual" )
|
|
isVirtual = true;
|
|
else if ( text == "inline" )
|
|
isInline = true;
|
|
++it;
|
|
}
|
|
}
|
|
|
|
if ( storageSpec )
|
|
{
|
|
TQPtrList<AST> l = storageSpec->nodeList();
|
|
TQPtrListIterator<AST> it( l );
|
|
while ( it.current() )
|
|
{
|
|
TQString text = it.current() ->text();
|
|
if ( text == "friend" )
|
|
isFriend = true;
|
|
else if ( text == "static" )
|
|
isStatic = true;
|
|
++it;
|
|
}
|
|
}
|
|
|
|
|
|
TQString id = d->declaratorId() ->unqualifiedName() ->text().stripWhiteSpace();
|
|
TQString scopeStr = scopeOfDeclarator( d );
|
|
|
|
Tag tag;
|
|
if( !comment() )
|
|
tag.setComment( ast->comment() );
|
|
|
|
CppFunction<Tag> tagBuilder( tag );
|
|
tag.setKind( Tag::Kind_Function );
|
|
|
|
tag.setFileName( m_fileName );
|
|
tag.setName( id );
|
|
tag.setScope( TQStringList::split( ".", scopeStr ) );
|
|
if( !ast->comment().isEmpty() )
|
|
tag.setComment( ast->comment() );
|
|
|
|
int line, col;
|
|
ast->getStartPosition( &line, &col );
|
|
tag.setStartPosition( line, col );
|
|
|
|
ast->getEndPosition( &line, &col );
|
|
tag.setEndPosition( line, col );
|
|
|
|
tagBuilder.setType( typeOfDeclaration( typeSpec, d ) );
|
|
|
|
parseFunctionArguments( tag, d );
|
|
checkTemplateDeclarator( tag );
|
|
|
|
TQString arguments = tag.attribute( "a" ).toStringList().join( "," );
|
|
tag.setAttribute( "description", m_documentation->functionDescription( scopeStr.replace( TQRegExp( "." ), ":" ), id, typeOfDeclaration( typeSpec, d ), arguments ) );
|
|
|
|
tagBuilder.setAccess( TagUtils::stringToAccess( m_currentAccess ) );
|
|
|
|
tagBuilder.setFriend( isFriend );
|
|
tagBuilder.setVirtual( isVirtual );
|
|
tagBuilder.setStatic( isStatic );
|
|
tagBuilder.setInline( isInline );
|
|
tagBuilder.setPure( false );
|
|
tagBuilder.setConst( d->constant() != 0 );
|
|
tagBuilder.setSignal( m_inSignals );
|
|
tagBuilder.setSlot( m_inSlots );
|
|
|
|
m_catalog->addItem( tag );
|
|
|
|
if ( !m_currentAccess.isEmpty() )
|
|
{
|
|
tag.setKind( Tag::Kind_FunctionDeclaration );
|
|
m_catalog->addItem( tag );
|
|
}
|
|
}
|
|
|
|
void TagCreator::parseLinkageBody( LinkageBodyAST* ast )
|
|
{
|
|
TQPtrList<DeclarationAST> l = ast->declarationList();
|
|
TQPtrListIterator<DeclarationAST> it( l );
|
|
while ( it.current() )
|
|
{
|
|
parseDeclaration( it.current() );
|
|
++it;
|
|
}
|
|
}
|
|
|
|
void TagCreator::checkTemplateDeclarator( Tag& tag ) {
|
|
if( !m_currentTemplateDeclarator.empty() && m_currentTemplateDeclarator.top() != 0) {
|
|
TemplateDeclarationAST* a = m_currentTemplateDeclarator.top();
|
|
|
|
m_currentTemplateDeclarator.pop();
|
|
m_currentTemplateDeclarator.push(0);
|
|
|
|
///the template-declarator belongs to exactly this declaration
|
|
takeTemplateParams( tag, a );
|
|
}
|
|
}
|
|
|
|
|
|
void TagCreator::takeTemplateParams( Tag& target, TemplateDeclarationAST* ast) {
|
|
TemplateParameterListAST* pl = ast->templateParameterList();
|
|
if( pl ) {
|
|
TQPtrList<TemplateParameterAST> list = pl->templateParameterList();
|
|
|
|
TemplateParameterAST* curr = list.first();
|
|
while( curr != 0 ) {
|
|
TQString a, b;
|
|
if( curr->typeParameter() ) {
|
|
if( curr->typeParameter()->name() )
|
|
a = curr->typeParameter()->name()->text();
|
|
if( curr->typeParameter()->typeId() )
|
|
b = curr->typeParameter()->typeId()->text();
|
|
}
|
|
|
|
target.addTemplateParam( a, b );
|
|
curr = list.next();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void TagCreator::parseClassSpecifier( ClassSpecifierAST* ast )
|
|
{
|
|
int startLine, startColumn;
|
|
int endLine, endColumn;
|
|
ast->getStartPosition( &startLine, &startColumn );
|
|
ast->getEndPosition( &endLine, &endColumn );
|
|
|
|
TQString oldAccess = m_currentAccess;
|
|
bool oldInSlots = m_inSlots;
|
|
bool oldInSignals = m_inSignals;
|
|
|
|
TQString kind = ast->classKey() ->text();
|
|
if ( kind == "class" )
|
|
m_currentAccess = "private";
|
|
else
|
|
m_currentAccess = "public";
|
|
m_inSlots = false;
|
|
m_inSignals = false;
|
|
|
|
TQString className;
|
|
if ( !ast->name() )
|
|
{
|
|
//TQFileInfo fileInfo( m_fileName );
|
|
//TQString shortFileName = fileInfo.baseName();
|
|
//className.sprintf( "(%s_%d)", shortFileName.local8Bit(), m_anon++ );
|
|
}
|
|
else
|
|
{
|
|
className = ast->name() ->text();
|
|
}
|
|
|
|
Tag tag;
|
|
if( !ast->comment().isEmpty() )
|
|
tag.setComment( ast->comment() );
|
|
|
|
tag.setKind( Tag::Kind_Class );
|
|
|
|
tag.setFileName( m_fileName );
|
|
|
|
int i = className.find( '<' );
|
|
TQString specialization;
|
|
|
|
if( i != -1 ) {
|
|
specialization = className.mid( i );
|
|
tag.setSpecializationDeclaration( specialization );
|
|
className = className.left( i );
|
|
}
|
|
|
|
tag.setName( className );
|
|
tag.setScope( m_currentScope );
|
|
|
|
int line, col;
|
|
ast->getStartPosition( &line, &col );
|
|
tag.setStartPosition( line, col );
|
|
|
|
ast->getEndPosition( &line, &col );
|
|
tag.setEndPosition( line, col );
|
|
|
|
checkTemplateDeclarator( tag );
|
|
|
|
m_catalog->addItem( tag );
|
|
|
|
if ( ast->baseClause() )
|
|
parseBaseClause( tag.path()+specialization, ast->baseClause() );
|
|
|
|
m_currentScope.push_back( className + specialization );
|
|
int oldInClass = m_inClass;
|
|
m_inClass = true;
|
|
TreeParser::parseClassSpecifier( ast );
|
|
m_currentScope.pop_back();
|
|
m_inClass = oldInClass;
|
|
|
|
m_currentAccess = oldAccess;
|
|
m_inSlots = oldInSlots;
|
|
m_inSignals = oldInSignals;
|
|
}
|
|
|
|
void TagCreator::parseEnumSpecifier( EnumSpecifierAST* ast )
|
|
{
|
|
Tag tag;
|
|
if( !ast->comment().isEmpty() )
|
|
tag.setComment( ast->comment() );
|
|
|
|
tag.setKind( Tag::Kind_Enum );
|
|
|
|
tag.setFileName( m_fileName );
|
|
if ( ast->name() )
|
|
tag.setName( ast->name() ->text() );
|
|
tag.setScope( m_currentScope );
|
|
|
|
int line, col;
|
|
ast->getStartPosition( &line, &col );
|
|
tag.setStartPosition( line, col );
|
|
|
|
ast->getEndPosition( &line, &col );
|
|
tag.setEndPosition( line, col );
|
|
|
|
m_catalog->addItem( tag );
|
|
|
|
TQPtrList<EnumeratorAST> l = ast->enumeratorList();
|
|
TQPtrListIterator<EnumeratorAST> it( l );
|
|
while ( it.current() )
|
|
{
|
|
TQString name = it.current() ->id() ->text();
|
|
|
|
Tag tag;
|
|
tag.setKind( Tag::Kind_Enumerator );
|
|
tag.setComment( it.current()->comment() );
|
|
|
|
tag.setFileName( m_fileName );
|
|
tag.setName( name );
|
|
tag.setScope( m_currentScope );
|
|
|
|
if( ast->name() ) {
|
|
tag.setAttribute( "enum", ast->name()->text() );
|
|
} else {
|
|
tag.setAttribute( "enum", "const int" );
|
|
}
|
|
|
|
int line, col;
|
|
it.current() ->getStartPosition( &line, &col );
|
|
tag.setStartPosition( line, col );
|
|
|
|
it.current() ->getEndPosition( &line, &col );
|
|
tag.setEndPosition( line, col );
|
|
|
|
m_catalog->addItem( tag );
|
|
|
|
++it;
|
|
}
|
|
|
|
TreeParser::parseEnumSpecifier( ast );
|
|
}
|
|
|
|
void TagCreator::parseMyDeclaration( GroupAST* funSpec, GroupAST* storageSpec, TypeSpecifierAST* typeSpec, InitDeclaratorAST* decl )
|
|
{
|
|
DeclaratorAST * d = decl->declarator();
|
|
|
|
if ( !d )
|
|
return ;
|
|
|
|
if ( !d->subDeclarator() && d->parameterDeclarationClause() )
|
|
return parseFunctionDeclaration( funSpec, storageSpec, typeSpec, decl );
|
|
|
|
DeclaratorAST* t = d;
|
|
while ( t && t->subDeclarator() )
|
|
t = t->subDeclarator();
|
|
|
|
TQString id;
|
|
if ( t && t->declaratorId() && t->declaratorId() ->unqualifiedName() )
|
|
id = t->declaratorId() ->unqualifiedName() ->text();
|
|
|
|
TQString scopeStr = scopeOfDeclarator( d );
|
|
|
|
TQString type = typeOfDeclaration( typeSpec, d );
|
|
|
|
|
|
bool isFriend = false;
|
|
//bool isVirtual = false;
|
|
bool isStatic = false;
|
|
//bool isInline = false;
|
|
//bool isInitialized = decl->initializer() != 0;
|
|
|
|
if ( storageSpec )
|
|
{
|
|
TQPtrList<AST> l = storageSpec->nodeList();
|
|
TQPtrListIterator<AST> it( l );
|
|
while ( it.current() )
|
|
{
|
|
TQString text = it.current() ->text();
|
|
if ( text == "friend" )
|
|
isFriend = true;
|
|
else if ( text == "static" )
|
|
isStatic = true;
|
|
++it;
|
|
}
|
|
}
|
|
|
|
Tag tag;
|
|
CppVariable<Tag> tagBuilder( tag );
|
|
|
|
tag.setKind( Tag::Kind_Variable );
|
|
tag.setFileName( m_fileName );
|
|
tag.setName( id );
|
|
tag.setScope( TQStringList::split( ".", scopeStr ) );
|
|
if( !comment().isEmpty() )
|
|
tag.setComment( comment() );
|
|
|
|
int line, col;
|
|
decl->getStartPosition( &line, &col );
|
|
tag.setStartPosition( line, col );
|
|
|
|
decl->getEndPosition( &line, &col );
|
|
tag.setEndPosition( line, col );
|
|
|
|
tagBuilder.setType( type );
|
|
tagBuilder.setFriend( isFriend );
|
|
tagBuilder.setStatic( isStatic );
|
|
tagBuilder.setAccess( TagUtils::stringToAccess( m_currentAccess ) );
|
|
|
|
m_catalog->addItem( tag );
|
|
}
|
|
|
|
void TagCreator::parseAccessDeclaration( AccessDeclarationAST * access )
|
|
{
|
|
TQPtrList<AST> l = access->accessList();
|
|
|
|
m_currentAccess = l.at( 0 )->text();
|
|
if( m_currentAccess == "signals" )
|
|
m_currentAccess = "protected";
|
|
|
|
m_inSlots = l.count() > 1 ? l.at( 1 )->text() == "slots" : false;
|
|
m_inSignals = l.count() >= 1 ? l.at( 0 )->text() == "signals" : false;
|
|
}
|
|
|
|
void TagCreator::parseFunctionDeclaration( GroupAST* funSpec, GroupAST* storageSpec,
|
|
TypeSpecifierAST * typeSpec, InitDeclaratorAST * decl )
|
|
{
|
|
bool isFriend = false;
|
|
bool isVirtual = false;
|
|
bool isStatic = false;
|
|
bool isInline = false;
|
|
bool isPure = decl->initializer() != 0;
|
|
|
|
if ( funSpec )
|
|
{
|
|
TQPtrList<AST> l = funSpec->nodeList();
|
|
TQPtrListIterator<AST> it( l );
|
|
while ( it.current() )
|
|
{
|
|
TQString text = it.current() ->text();
|
|
if ( text == "virtual" )
|
|
isVirtual = true;
|
|
else if ( text == "inline" )
|
|
isInline = true;
|
|
++it;
|
|
}
|
|
}
|
|
|
|
if ( storageSpec )
|
|
{
|
|
TQPtrList<AST> l = storageSpec->nodeList();
|
|
TQPtrListIterator<AST> it( l );
|
|
while ( it.current() )
|
|
{
|
|
TQString text = it.current() ->text();
|
|
if ( text == "friend" )
|
|
isFriend = true;
|
|
else if ( text == "static" )
|
|
isStatic = true;
|
|
++it;
|
|
}
|
|
}
|
|
|
|
int startLine, startColumn;
|
|
int endLine, endColumn;
|
|
decl->getStartPosition( &startLine, &startColumn );
|
|
decl->getEndPosition( &endLine, &endColumn );
|
|
|
|
DeclaratorAST* d = decl->declarator();
|
|
TQString id = d->declaratorId() ->unqualifiedName() ->text();
|
|
|
|
TQString type = typeOfDeclaration( typeSpec, d );
|
|
|
|
Tag tag;
|
|
CppFunction<Tag> tagBuilder( tag );
|
|
|
|
if( !comment().isEmpty() )
|
|
tag.setComment( comment() );
|
|
tag.setKind( Tag::Kind_FunctionDeclaration );
|
|
tag.setFileName( m_fileName );
|
|
tag.setName( id );
|
|
tag.setScope( m_currentScope );
|
|
|
|
int line, col;
|
|
decl->getStartPosition( &line, &col );
|
|
tag.setStartPosition( line, col );
|
|
|
|
decl->getEndPosition( &line, &col );
|
|
tag.setEndPosition( line, col );
|
|
|
|
tagBuilder.setType( type );
|
|
tagBuilder.setFriend( isFriend );
|
|
tagBuilder.setVirtual( isVirtual );
|
|
tagBuilder.setStatic( isStatic );
|
|
tagBuilder.setInline( isInline );
|
|
tagBuilder.setPure( isPure );
|
|
tagBuilder.setConst( d->constant() != 0 );
|
|
tagBuilder.setSignal( m_inSignals );
|
|
tagBuilder.setSlot( m_inSlots );
|
|
|
|
parseFunctionArguments( tag, d );
|
|
checkTemplateDeclarator( tag );
|
|
|
|
TQString arguments = tag.attribute( "a" ).toStringList().join( "," );
|
|
TQString scopeStr = m_currentScope.join( "::" );
|
|
tag.setAttribute( "description", m_documentation->functionDescription( scopeStr, id, type, arguments ) );
|
|
|
|
m_catalog->addItem( tag );
|
|
}
|
|
|
|
void TagCreator::parseFunctionArguments( Tag& tag, DeclaratorAST* declarator )
|
|
{
|
|
ParameterDeclarationClauseAST* clause = declarator->parameterDeclarationClause();
|
|
|
|
TQStringList types;
|
|
TQStringList args;
|
|
if( clause && clause->parameterDeclarationList() ){
|
|
ParameterDeclarationListAST* params = clause->parameterDeclarationList();
|
|
TQPtrList<ParameterDeclarationAST> l( params->parameterList() );
|
|
TQPtrListIterator<ParameterDeclarationAST> it( l );
|
|
|
|
while( it.current() ){
|
|
ParameterDeclarationAST* param = it.current();
|
|
++it;
|
|
|
|
TQString name;
|
|
if( param->declarator() ){
|
|
name = declaratorToString(param->declarator(), TQString(), true );
|
|
}
|
|
|
|
TQString type = typeOfDeclaration( param->typeSpec(), param->declarator() );
|
|
|
|
types << type;
|
|
args << name;
|
|
}
|
|
|
|
if( clause->ellipsis() ){
|
|
types << "...";
|
|
args << "";
|
|
}
|
|
|
|
}
|
|
|
|
CppFunction<Tag> tagBuilder( tag );
|
|
|
|
tagBuilder.setArguments( types );
|
|
tagBuilder.setArgumentNames( args );
|
|
}
|
|
|
|
TQString TagCreator::typeOfDeclaration( TypeSpecifierAST* typeSpec, DeclaratorAST* declarator )
|
|
{
|
|
if( !typeSpec || !declarator )
|
|
return TQString();
|
|
|
|
TQString text;
|
|
|
|
text += typeSpec->text();
|
|
text = text.simplifyWhiteSpace();
|
|
|
|
TQPtrList<AST> ptrOpList = declarator->ptrOpList();
|
|
for( TQPtrListIterator<AST> it(ptrOpList); it.current(); ++it )
|
|
text += it.current()->text();
|
|
|
|
for( int a = 0; a < declarator->arrayDimensionList().count(); a++ )
|
|
text += "*";
|
|
|
|
return text;
|
|
}
|
|
|
|
void TagCreator::parseBaseClause( const TQString& className, BaseClauseAST * baseClause )
|
|
{
|
|
TQPtrList<BaseSpecifierAST> l = baseClause->baseSpecifierList();
|
|
TQPtrListIterator<BaseSpecifierAST> it( l );
|
|
while ( it.current() )
|
|
{
|
|
BaseSpecifierAST * baseSpecifier = it.current();
|
|
|
|
TQString access;
|
|
if ( baseSpecifier->access() )
|
|
access = baseSpecifier->access() ->text();
|
|
bool isVirtual = baseSpecifier->isVirtual() != 0;
|
|
|
|
if( baseSpecifier->name() == 0 ) return; ///Workaround for some bug elsewhere
|
|
|
|
TQString baseName;
|
|
if ( baseSpecifier->name() )
|
|
baseName = baseSpecifier->name() ->text();
|
|
|
|
Tag tag;
|
|
CppBaseClass<Tag> tagBuilder( tag );
|
|
|
|
tag.setKind( Tag::Kind_Base_class );
|
|
tag.setFileName( m_fileName );
|
|
tag.setName( className );
|
|
tag.setScope( m_currentScope );
|
|
|
|
tagBuilder.setBaseClass( baseName );
|
|
tagBuilder.setVirtual( isVirtual );
|
|
tagBuilder.setAccess( TagUtils::stringToAccess( access ) );
|
|
|
|
int line, col;
|
|
baseClause->getStartPosition( &line, &col );
|
|
tag.setStartPosition( line, col );
|
|
|
|
baseClause->getEndPosition( &line, &col );
|
|
tag.setEndPosition( line, col );
|
|
|
|
m_catalog->addItem( tag );
|
|
|
|
++it;
|
|
}
|
|
}
|
|
|
|
TQString TagCreator::scopeOfDeclarator( DeclaratorAST* d )
|
|
{
|
|
TQStringList scope = m_currentScope;
|
|
if ( d && d->declaratorId() && d->declaratorId() ->classOrNamespaceNameList().count() )
|
|
{
|
|
if ( d->declaratorId() ->isGlobal() )
|
|
scope.clear();
|
|
TQPtrList<ClassOrNamespaceNameAST> l = d->declaratorId() ->classOrNamespaceNameList();
|
|
TQPtrListIterator<ClassOrNamespaceNameAST> it( l );
|
|
while ( it.current() )
|
|
{
|
|
if ( it.current() ->name() )
|
|
scope << it.current() ->name() ->text();
|
|
|
|
++it;
|
|
}
|
|
}
|
|
|
|
return scope.join( "." );
|
|
}
|
|
|
|
int TagUtils::stringToAccess( const TQString & access )
|
|
{
|
|
TQStringList l = TQStringList()
|
|
<< "public" << "protected" << "private"
|
|
<< "public slots" << "protected slots" << "private slots"
|
|
<< "signals";
|
|
|
|
int idx = l.findIndex( access );
|
|
return idx == -1 ? 0 : idx+1;
|
|
}
|
|
|
|
TQString TagUtils::accessToString( int id )
|
|
{
|
|
if( id == 0 ) return "unknown";
|
|
|
|
TQStringList l = TQStringList()
|
|
<< "public" << "protected" << "private"
|
|
<< "public slots" << "protected slots" << "private slots"
|
|
<< "signals";
|
|
|
|
if( l.at(id-1) != l.end() )
|
|
return l[ id-1 ];
|
|
|
|
return TQString();
|
|
}
|
|
|
|
//kate: indent-mode csands; tab-width 4; space-indent off;
|