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.
340 lines
9.4 KiB
340 lines
9.4 KiB
/***************************************************************************
|
|
* Copyright (C) 2003 by Roberto Raggi *
|
|
* roberto@kdevelop.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 "codeinformationrepository.h"
|
|
#include "cpp_tags.h"
|
|
|
|
#include <kdevcoderepository.h>
|
|
#include <kdebug.h>
|
|
|
|
/// @todo move in utils.cpp
|
|
static TQValueList<KTextEditor::CompletionEntry>
|
|
my_unique( const TQValueList<KTextEditor::CompletionEntry>& entryList )
|
|
{
|
|
|
|
TQValueList< KTextEditor::CompletionEntry > l;
|
|
TQMap<TQString, bool> map;
|
|
TQValueList< KTextEditor::CompletionEntry >::ConstIterator it = entryList.begin();
|
|
while ( it != entryList.end() )
|
|
{
|
|
KTextEditor::CompletionEntry e = *it++;
|
|
TQString key = e.type + " " +
|
|
e.text + " " +
|
|
e.prefix + " " +
|
|
e.postfix + " ";
|
|
if ( map.find( key ) == map.end() )
|
|
{
|
|
map[ key ] = TRUE;
|
|
l << e;
|
|
}
|
|
}
|
|
return l;
|
|
}
|
|
|
|
CodeInformationRepository::CodeInformationRepository( KDevCodeRepository* rep )
|
|
: m_rep( rep )
|
|
{}
|
|
|
|
CodeInformationRepository::~CodeInformationRepository()
|
|
{}
|
|
|
|
TQValueList<Tag> CodeInformationRepository::query( const TQValueList<Catalog :: QueryArgument> & args )
|
|
{
|
|
// kdDebug( 9007 ) << "CodeInformationRepository::query()" << endl;
|
|
|
|
TQValueList<Tag> tags;
|
|
|
|
TQValueList<Catalog*> catalogs = m_rep->registeredCatalogs();
|
|
TQValueList<Catalog*>::Iterator it = catalogs.begin();
|
|
while ( it != catalogs.end() )
|
|
{
|
|
Catalog * catalog = *it;
|
|
++it;
|
|
|
|
if ( !catalog->enabled() )
|
|
continue;
|
|
|
|
tags += catalog->query( args );
|
|
}
|
|
|
|
return tags;
|
|
}
|
|
|
|
TQValueList<Tag> CodeInformationRepository::getTagsInFile( const TQString & fileName )
|
|
{
|
|
kdDebug( 9007 ) << "CodeInformationRepository::getTagsInFile()" << endl;
|
|
|
|
TQValueList<Catalog::QueryArgument> args;
|
|
args << Catalog::QueryArgument( "fileName", fileName );
|
|
|
|
TQValueList<Catalog*> catalogs = m_rep->registeredCatalogs();
|
|
TQValueList<Catalog*>::Iterator it = catalogs.begin();
|
|
while ( it != catalogs.end() )
|
|
{
|
|
Catalog * catalog = *it;
|
|
++it;
|
|
|
|
TQValueList<Tag> tags = catalog->query( args );
|
|
|
|
if ( tags.size() )
|
|
return tags;
|
|
}
|
|
|
|
return TQValueList<Tag>();
|
|
}
|
|
|
|
TQValueList<Tag> CodeInformationRepository::getTagsInScope( const TQStringList & scope, bool // isInstance
|
|
)
|
|
{
|
|
kdDebug( 9007 ) << "CodeInformationRepository::getTagsInScope()" << endl;
|
|
|
|
TQValueList<Tag> tags;
|
|
TQValueList<Catalog::QueryArgument> args;
|
|
|
|
#if 0
|
|
|
|
args.clear();
|
|
args << Catalog::QueryArgument( "kind", Tag::Kind_Namespace )
|
|
<< Catalog::QueryArgument( "scope", scope );
|
|
tags += query( args );
|
|
|
|
args.clear();
|
|
args << Catalog::QueryArgument( "kind", Tag::Kind_Class )
|
|
<< Catalog::QueryArgument( "scope", scope );
|
|
tags += query( args );
|
|
#endif
|
|
|
|
args.clear();
|
|
args << Catalog::QueryArgument( "kind", Tag::Kind_FunctionDeclaration )
|
|
<< Catalog::QueryArgument( "scope", scope );
|
|
tags += query( args );
|
|
|
|
args.clear();
|
|
args << Catalog::QueryArgument( "kind", Tag::Kind_Variable )
|
|
<< Catalog::QueryArgument( "scope", scope );
|
|
tags += query( args );
|
|
|
|
if ( true /*!isInstance*/ )
|
|
{
|
|
args.clear();
|
|
args << Catalog::QueryArgument( "kind", Tag::Kind_Enumerator )
|
|
<< Catalog::QueryArgument( "scope", scope );
|
|
tags += query( args );
|
|
}
|
|
|
|
return tags;
|
|
}
|
|
|
|
TQValueList<KTextEditor::CompletionEntry> CodeInformationRepository::getEntriesInScope( const TQStringList & scope, bool isInstance, bool recompute )
|
|
{
|
|
kdDebug( 9007 ) << "CodeInformationRepository::getEntriesInScope()" << endl;
|
|
|
|
if ( !recompute && !scope.size() && m_globalEntries.size() )
|
|
return m_globalEntries;
|
|
else if ( scope.size() == 0 )
|
|
{
|
|
m_globalEntries = my_unique( toEntryList( getTagsInScope( scope, isInstance ) ) );
|
|
return m_globalEntries;
|
|
}
|
|
|
|
return toEntryList( getTagsInScope( scope, isInstance ) );
|
|
}
|
|
|
|
|
|
TQValueList<Tag> CodeInformationRepository::getBaseClassList( const TQString& className )
|
|
{
|
|
// kdDebug( 9007 ) << "CodeInformationRepository::getBaseClassList()" << endl;
|
|
|
|
if ( className.isEmpty() )
|
|
return TQValueList<Tag>();
|
|
|
|
TQValueList<Catalog::QueryArgument> args;
|
|
args << Catalog::QueryArgument( "kind", Tag::Kind_Base_class );
|
|
/* if( className.length() >= 2 )
|
|
args << Catalog::QueryArgument( "prefix", className.left(2) );*/
|
|
args << Catalog::QueryArgument( "name", className );
|
|
return query( args );
|
|
}
|
|
|
|
TQValueList<Tag> CodeInformationRepository::getClassOrNamespaceList( const TQStringList & scope )
|
|
{
|
|
kdDebug( 9007 ) << "CodeInformationRepository::getClassOrNamespaceList()" << endl;
|
|
|
|
TQValueList<Tag> tags;
|
|
TQValueList<Catalog::QueryArgument> args;
|
|
|
|
args << Catalog::QueryArgument( "kind", Tag::Kind_Namespace )
|
|
<< Catalog::QueryArgument( "scope", scope );
|
|
tags += query( args );
|
|
|
|
args.clear();
|
|
args << Catalog::QueryArgument( "kind", Tag::Kind_Class )
|
|
<< Catalog::QueryArgument( "scope", scope );
|
|
tags += query( args );
|
|
|
|
return tags;
|
|
}
|
|
|
|
TQValueList<Tag> CodeInformationRepository::getTagsInScope( const TQString & name, const TQStringList & scope )
|
|
{
|
|
TQValueList<Tag> tags;
|
|
TQValueList<Catalog::QueryArgument> args;
|
|
|
|
args.clear();
|
|
args << Catalog::QueryArgument( "scope", scope );
|
|
/* if( name.length() >= 2 )
|
|
args << Catalog::QueryArgument( "prefix", name.left(2) ); */
|
|
args << Catalog::QueryArgument( "name", name );
|
|
|
|
tags += query( args );
|
|
|
|
return tags;
|
|
}
|
|
|
|
KTextEditor::CompletionEntry CodeInformationRepository::toEntry( Tag & tag, CppCodeCompletion::CompletionMode completionMode, TypeProcessor* proc )
|
|
{
|
|
KTextEditor::CompletionEntry entry;
|
|
|
|
if ( tag.name().isEmpty() )
|
|
return entry;
|
|
|
|
switch ( tag.kind() )
|
|
{
|
|
case Tag::Kind_Typedef:
|
|
entry.prefix = "typedef";
|
|
entry.text = tag.name();
|
|
break;
|
|
|
|
case Tag::Kind_Class:
|
|
entry.prefix = "class";
|
|
entry.text = tag.name();
|
|
break;
|
|
|
|
case Tag::Kind_Struct:
|
|
entry.prefix = "struct";
|
|
entry.text = tag.name();
|
|
break;
|
|
|
|
case Tag::Kind_Namespace:
|
|
entry.prefix = "namespace";
|
|
entry.text = tag.name();
|
|
break;
|
|
|
|
case Tag::Kind_FunctionDeclaration:
|
|
//case Tag::Kind_Function:
|
|
{
|
|
|
|
CppFunction<Tag> tagInfo( tag );
|
|
TQStringList arguments = tagInfo.arguments();
|
|
TQStringList argumentNames = tagInfo.argumentNames();
|
|
|
|
if ( completionMode == CppCodeCompletion::VirtualDeclCompletion )
|
|
{
|
|
//Ideally the type info would be a entry.prefix, but we need them to be
|
|
//inserted upon completion so they have to be part of entry.text
|
|
entry.text = tagInfo.type();
|
|
entry.text += " ";
|
|
entry.text += tag.name();
|
|
}
|
|
else
|
|
entry.text = tag.name();
|
|
|
|
if ( !arguments.size() )
|
|
entry.text += "(";
|
|
else
|
|
entry.text += "( ";
|
|
|
|
TQString signature;
|
|
for ( uint i = 0; i < arguments.size(); ++i )
|
|
{
|
|
if( !proc )
|
|
signature += arguments[ i ];
|
|
else
|
|
signature += proc->processType( arguments[ i ] );
|
|
|
|
if ( completionMode == CppCodeCompletion::NormalCompletion ||
|
|
completionMode == CppCodeCompletion::VirtualDeclCompletion )
|
|
{
|
|
TQString argName = argumentNames[ i ];
|
|
if ( !argName.isEmpty() )
|
|
signature += TQString::fromLatin1( " " ) + argName;
|
|
|
|
}
|
|
|
|
if ( i != ( arguments.size() - 1 ) )
|
|
{
|
|
signature += ", ";
|
|
}
|
|
}
|
|
|
|
if ( signature.isEmpty() )
|
|
entry.text += ")";
|
|
else
|
|
entry.postfix = signature + " )";
|
|
|
|
if ( tagInfo.isConst() )
|
|
entry.postfix += " const";
|
|
|
|
if ( completionMode == CppCodeCompletion::VirtualDeclCompletion )
|
|
{
|
|
entry.text += entry.postfix + ";";
|
|
entry.postfix = TQString::null;
|
|
}
|
|
else if ( completionMode != CppCodeCompletion::NormalCompletion )
|
|
{
|
|
entry.text += entry.postfix;
|
|
entry.postfix = TQString::null;
|
|
}
|
|
|
|
TQString comment = tag.attribute( "description" ).toString();
|
|
if ( !comment.isNull() )
|
|
entry.comment = comment;
|
|
//else
|
|
//entry.comment = "no documentation available!";
|
|
}
|
|
|
|
break;
|
|
|
|
case Tag::Kind_Enumerator:
|
|
case Tag::Kind_Variable:
|
|
entry.text = tag.name();
|
|
break;
|
|
|
|
default:
|
|
;
|
|
}
|
|
|
|
entry.comment = tag.comment();
|
|
|
|
return entry;
|
|
}
|
|
|
|
TQValueList<KTextEditor :: CompletionEntry> CodeInformationRepository::toEntryList( const TQValueList<Tag> & tags, CppCodeCompletion::CompletionMode completionMode )
|
|
{
|
|
TQValueList<KTextEditor :: CompletionEntry> entryList;
|
|
TQMap<TQString, bool> ns;
|
|
|
|
TQValueList<Tag>::ConstIterator it = tags.begin();
|
|
while ( it != tags.end() )
|
|
{
|
|
Tag tag = *it;
|
|
++it;
|
|
|
|
KTextEditor::CompletionEntry entry = toEntry( tag, completionMode );
|
|
if ( !entry.text.isEmpty() )
|
|
entryList << entry;
|
|
}
|
|
|
|
return entryList;
|
|
}
|
|
|
|
|