summaryrefslogtreecommitdiffstats
path: root/languages/cpp/codeinformationrepository.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'languages/cpp/codeinformationrepository.cpp')
-rw-r--r--languages/cpp/codeinformationrepository.cpp339
1 files changed, 339 insertions, 0 deletions
diff --git a/languages/cpp/codeinformationrepository.cpp b/languages/cpp/codeinformationrepository.cpp
new file mode 100644
index 00000000..5bb22a68
--- /dev/null
+++ b/languages/cpp/codeinformationrepository.cpp
@@ -0,0 +1,339 @@
+/***************************************************************************
+* 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 QValueList<KTextEditor::CompletionEntry>
+my_unique( const QValueList<KTextEditor::CompletionEntry>& entryList )
+{
+
+ QValueList< KTextEditor::CompletionEntry > l;
+ QMap<QString, bool> map;
+ QValueList< KTextEditor::CompletionEntry >::ConstIterator it = entryList.begin();
+ while ( it != entryList.end() )
+ {
+ KTextEditor::CompletionEntry e = *it++;
+ QString 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()
+{}
+
+QValueList<Tag> CodeInformationRepository::query( const QValueList<Catalog :: QueryArgument> & args )
+{
+// kdDebug( 9007 ) << "CodeInformationRepository::query()" << endl;
+
+ QValueList<Tag> tags;
+
+ QValueList<Catalog*> catalogs = m_rep->registeredCatalogs();
+ QValueList<Catalog*>::Iterator it = catalogs.begin();
+ while ( it != catalogs.end() )
+ {
+ Catalog * catalog = *it;
+ ++it;
+
+ if ( !catalog->enabled() )
+ continue;
+
+ tags += catalog->query( args );
+ }
+
+ return tags;
+}
+
+QValueList<Tag> CodeInformationRepository::getTagsInFile( const QString & fileName )
+{
+ kdDebug( 9007 ) << "CodeInformationRepository::getTagsInFile()" << endl;
+
+ QValueList<Catalog::QueryArgument> args;
+ args << Catalog::QueryArgument( "fileName", fileName );
+
+ QValueList<Catalog*> catalogs = m_rep->registeredCatalogs();
+ QValueList<Catalog*>::Iterator it = catalogs.begin();
+ while ( it != catalogs.end() )
+ {
+ Catalog * catalog = *it;
+ ++it;
+
+ QValueList<Tag> tags = catalog->query( args );
+
+ if ( tags.size() )
+ return tags;
+ }
+
+ return QValueList<Tag>();
+}
+
+QValueList<Tag> CodeInformationRepository::getTagsInScope( const QStringList & scope, bool // isInstance
+ )
+{
+ kdDebug( 9007 ) << "CodeInformationRepository::getTagsInScope()" << endl;
+
+ QValueList<Tag> tags;
+ QValueList<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;
+}
+
+QValueList<KTextEditor::CompletionEntry> CodeInformationRepository::getEntriesInScope( const QStringList & 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 ) );
+}
+
+
+QValueList<Tag> CodeInformationRepository::getBaseClassList( const QString& className )
+{
+// kdDebug( 9007 ) << "CodeInformationRepository::getBaseClassList()" << endl;
+
+ if ( className.isEmpty() )
+ return QValueList<Tag>();
+
+ QValueList<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 );
+}
+
+QValueList<Tag> CodeInformationRepository::getClassOrNamespaceList( const QStringList & scope )
+{
+ kdDebug( 9007 ) << "CodeInformationRepository::getClassOrNamespaceList()" << endl;
+
+ QValueList<Tag> tags;
+ QValueList<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;
+}
+
+QValueList<Tag> CodeInformationRepository::getTagsInScope( const QString & name, const QStringList & scope )
+{
+ QValueList<Tag> tags;
+ QValueList<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 );
+ QStringList arguments = tagInfo.arguments();
+ QStringList 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 += "( ";
+
+ QString 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 )
+ {
+ QString argName = argumentNames[ i ];
+ if ( !argName.isEmpty() )
+ signature += QString::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 = QString::null;
+ }
+ else if ( completionMode != CppCodeCompletion::NormalCompletion )
+ {
+ entry.text += entry.postfix;
+ entry.postfix = QString::null;
+ }
+
+ QString 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;
+}
+
+QValueList<KTextEditor :: CompletionEntry> CodeInformationRepository::toEntryList( const QValueList<Tag> & tags, CppCodeCompletion::CompletionMode completionMode )
+{
+ QValueList<KTextEditor :: CompletionEntry> entryList;
+ QMap<QString, bool> ns;
+
+ QValueList<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;
+}
+
+