summaryrefslogtreecommitdiffstats
path: root/languages/cpp/simpletypecatalog.cpp
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit114a878c64ce6f8223cfd22d76a20eb16d177e5e (patch)
treeacaf47eb0fa12142d3896416a69e74cbf5a72242 /languages/cpp/simpletypecatalog.cpp
downloadtdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.tar.gz
tdevelop-114a878c64ce6f8223cfd22d76a20eb16d177e5e.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdevelop@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'languages/cpp/simpletypecatalog.cpp')
-rw-r--r--languages/cpp/simpletypecatalog.cpp375
1 files changed, 375 insertions, 0 deletions
diff --git a/languages/cpp/simpletypecatalog.cpp b/languages/cpp/simpletypecatalog.cpp
new file mode 100644
index 00000000..2b02cd9e
--- /dev/null
+++ b/languages/cpp/simpletypecatalog.cpp
@@ -0,0 +1,375 @@
+/***************************************************************************
+ copyright : (C) 2006 by David Nolden
+ email : david.nolden.kdevelop@art-master.de
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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 "simpletypecatalog.h"
+#include "simpletypefunction.h"
+#include "safetycounter.h"
+
+extern SafetyCounter safetyCounter;
+extern CppCodeCompletion* cppCompletionInstance;
+
+//SimpleTypeCatalog implementation
+
+TypePointer SimpleTypeCatalog::clone() {
+ return new SimpleTypeCachedCatalog( this );
+}
+
+QString SimpleTypeCatalog::specialization() const {
+ return m_tag.getSpecializationDeclaration();
+}
+
+void SimpleTypeCatalog::addAliasesTo( SimpleTypeNamespace* ns ) {
+ if ( m_tag.kind() != Tag::Kind_Namespace ) return;
+ QValueList<Catalog::QueryArgument> args;
+
+///Insert all namespace-imports
+ args << Catalog::QueryArgument( "scope", specializedScope() );
+ args << Catalog::QueryArgument( "kind", Tag::Kind_UsingDirective );
+
+ QValueList<Tag> tags( cppCompletionInstance->m_repository->query( args ) );
+
+ for ( QValueList<Tag>::iterator it = tags.begin(); it != tags.end(); ++it ) {
+ TypeDesc d( (*it).name() );
+ d.setIncludeFiles( HashedString((*it).fileName()) ); ///@todo implement the include-file-logic
+ ns->addAliasMap( TypeDesc(), d, HashedString((*it).fileName()), true, false, bigContainer() );
+ }
+///Insert all namespace-aliases
+ args.clear();
+ args << Catalog::QueryArgument( "scope", specializedScope() );
+ args << Catalog::QueryArgument( "kind", Tag::Kind_NamespaceAlias );
+
+ tags = cppCompletionInstance->m_repository->query( args );
+
+ for ( QValueList<Tag>::iterator it = tags.begin(); it != tags.end(); ++it ) {
+ QVariant v = (*it).attribute( "alias" );
+ if ( v.type() == QVariant::String ) {
+ TypeDesc d( v.asString() );
+ d.setIncludeFiles( HashedString((*it).fileName()) );
+ ns->addAliasMap( (*it).name(), d, HashedString((*it).fileName()), true, false, bigContainer() );
+ } else
+ kdDebug( 9007 ) << "namespace-alias has no alias-text" << endl;
+ }
+}
+
+QValueList<TypePointer> SimpleTypeCatalog::getMemberClasses( const TypeDesc& name ) {
+ QValueList<TypePointer> ret;
+
+ QValueList<Catalog::QueryArgument> args;
+
+ args << Catalog::QueryArgument( "scope", specializedScope() );
+ args << Catalog::QueryArgument( "name", name.name() );
+
+ QValueList<Tag> tags( cppCompletionInstance->m_repository->query( args ) );
+
+ for ( QValueList<Tag>::iterator it = tags.begin(); it != tags.end(); ++it ) {
+ if ( (*it).kind() == Tag::Kind_Class ) {
+ ///It would be better to return all matched class-names from within findMember and use them from there so all this will be cached too.
+ CatalogBuildInfo b( *it, name, TypePointer( this ) );
+ TypePointer t = b.buildCached();
+ if ( t ) ret << t;
+ }
+ }
+
+ return ret;
+}
+
+SimpleTypeImpl::MemberInfo SimpleTypeCatalog::findMember( TypeDesc name, SimpleTypeImpl::MemberInfo::MemberType type ) {
+ MemberInfo ret;
+ ret.name = name.name();
+ ret.memberType = MemberInfo::NotFound;
+ if ( !name ) return ret;
+
+ if ( ( type & MemberInfo::Template) ) {
+ LocateResult s = findTemplateParam( name.name() );
+ if ( s ) {
+ ret.memberType = MemberInfo::Template;
+ ret.type = s;
+ ret.decl.name = name.name();
+ ret.decl.file = m_tag.fileName();
+ m_tag.getStartPosition( &ret.decl.startLine, &ret.decl.startCol );
+ m_tag.getEndPosition( &ret.decl.endLine, &ret.decl.endCol );
+ }
+ }
+
+ QValueList<Catalog::QueryArgument> args;
+
+ args << Catalog::QueryArgument( "scope", specializedScope() );
+ args << Catalog::QueryArgument( "name", name.name() );
+
+ QValueList<Tag> tags( cppCompletionInstance->m_repository->query( args ) );
+
+ if ( tags.isEmpty() ) return ret;
+
+///skip all using-directives
+ QValueList<Tag>::iterator it = tags.begin();
+ while ( ( (*it).kind() == Tag::Kind_UsingDirective || (*it).kind() == Tag::Kind_NamespaceAlias ) && it != tags.end() )
+ ++it;
+
+ if ( it == tags.end() ) return ret;
+
+ Tag tag = *it;
+
+ if ( tag.kind() == Tag::Kind_Variable && (type & MemberInfo::Variable) ) {
+ ret.memberType = MemberInfo::Variable;
+ ret.type = tagType( tag );
+ ret.decl.name = tag.name();
+ ret.decl.comment = tag.comment();
+ tag.getStartPosition( &ret.decl.startLine, &ret.decl.startCol );
+ tag.getEndPosition( &ret.decl.endLine, &ret.decl.endCol );
+ ret.decl.file = tag.fileName();
+ }
+ if ( tag.kind() == Tag::Kind_Enumerator && (type & MemberInfo::Variable) ) {
+ ret.memberType = MemberInfo::Variable;
+ if ( !tag.hasAttribute( "enum" ) ) {
+ ret.type = TypeDesc( "const int" );
+ } else {
+ ret.type = tag.attribute( "enum" ).asString();
+ if ( ret.type->name().isEmpty() )
+ ret.type = TypeDesc( "const int" );
+ }
+ ret.decl.name = tag.name();
+ ret.decl.comment = tag.comment();
+ tag.getStartPosition( &ret.decl.startLine, &ret.decl.startCol );
+ tag.getEndPosition( &ret.decl.endLine, &ret.decl.endCol );
+ ret.decl.file = tag.fileName();
+ } else if ( tag.kind() == Tag::Kind_Class && ( type & MemberInfo::NestedType ) ) {
+ //if( tag.hasSpecializationDeclaration() ) {
+ //Choose another tag(the main class, not a specialization).
+ bool hasSpecializationDeclaration = tag.hasSpecializationDeclaration();
+ bool isIncluded = name.includeFiles()[tag.fileName()];
+ if ( hasSpecializationDeclaration || !isIncluded ) {
+ for ( QValueList<Tag>::const_iterator it = tags.begin(); it != tags.end(); ++it ) {
+ if ( (*it).kind() == Tag::Kind_Class && !(*it).hasSpecializationDeclaration() ) {
+ if ( name.includeFiles()[(*it).fileName()] ) {
+ tag = *it;
+ isIncluded = true;
+ hasSpecializationDeclaration = false;
+ } else if ( hasSpecializationDeclaration ) {
+ tag = *it;
+ hasSpecializationDeclaration = false;
+ isIncluded = false;
+ }
+
+ if ( isIncluded && !hasSpecializationDeclaration ) break;
+ }
+ }
+ }
+ //only accept non-specialized classes
+ if ( !tag.hasSpecializationDeclaration() ) {
+ ret.setBuildInfo( new CatalogBuildInfo( tag, name, TypePointer( this ) ) );
+ ret.memberType = MemberInfo::NestedType;
+ ret.type = name;
+ }
+ } else if ( tag.kind() == Tag::Kind_Typedef && ( type & MemberInfo::Typedef ) ) {
+ ret.memberType = MemberInfo::Typedef;
+ ret.type = tagType( tag );
+ ret.decl.name = tag.name();
+ ret.decl.comment = tag.comment();
+ tag.getStartPosition( &ret.decl.startLine, &ret.decl.startCol );
+ tag.getEndPosition( &ret.decl.endLine, &ret.decl.endCol );
+ ret.decl.file = tag.fileName();
+ } else if ( tag.kind() == Tag::Kind_Enum && ( type & MemberInfo::Typedef ) ) {
+ ret.memberType = MemberInfo::Typedef;
+ ret.type = TypeDesc( "const int" );
+ ret.decl.name = tag.name();
+ ret.decl.comment = tag.comment();
+ tag.getStartPosition( &ret.decl.startLine, &ret.decl.startCol );
+ tag.getEndPosition( &ret.decl.endLine, &ret.decl.endCol );
+ ret.decl.file = tag.fileName();
+ } else if ( (tag.kind() == Tag::Kind_FunctionDeclaration || tag.kind() == Tag::Kind_Function) && ( type & MemberInfo::Function ) ) {
+ ret.memberType = MemberInfo::Function;
+ ret.type = tagType( tag );
+ ret.type->increaseFunctionDepth();
+ ret.setBuildInfo( new SimpleTypeCatalogFunction::CatalogFunctionBuildInfo( tags, name, TypePointer( this ) ) );
+ } else if ( tag.kind() == Tag::Kind_Namespace && ( type & MemberInfo::Namespace ) ) {
+ ret.setBuildInfo( new CatalogBuildInfo( tag , name, TypePointer( this ) ) );
+ ret.memberType = MemberInfo::Namespace;
+ ret.type = name;
+ }
+
+///Check if it is a template-name
+
+//if( !ret.type) ret.memberType = MemberInfo::NotFound; //constructor..
+
+ if( ret.memberType == MemberInfo::Function || ret.memberType == MemberInfo::Variable || ret.memberType == MemberInfo::Template || ret.memberType == MemberInfo::Typedef || ret.memberType == MemberInfo::NestedType ) {
+ //For redirected types it is necessary to add the include-files of the context they were searched in.
+ //That is not quite correct, but it makes sure that at least the same namespace-aliases will be activated while the search for the type.
+
+ ret.type->addIncludeFiles( name.includeFiles() );
+ }
+
+ chooseSpecialization( ret );
+ return ret;
+}
+
+Tag SimpleTypeCatalog::findSubTag( const QString& name ) {
+ if ( name.isEmpty() ) return Tag();
+
+ QValueList<Catalog::QueryArgument> args;
+ QTime t;
+
+ t.start();
+ args << Catalog::QueryArgument( "scope", specializedScope() );
+ args << Catalog::QueryArgument( "name", name );
+
+ QValueList<Tag> tags( cppCompletionInstance->m_repository->query( args ) );
+ if ( ! tags.isEmpty() ) {
+ //ifVerbose( dbg() << "findTag: \"" << str() << "\": tag \"" << name << "\" found " << endl );
+ return tags.front();
+ } else {
+ //ifVerbose( dbg() << "findTag: \"" << str() << "\": tag \"" << name << "\" not found " << endl );
+ return Tag();
+ }
+}
+
+QValueList<Tag> SimpleTypeCatalog::getBaseClassList( ) {
+ if ( scope().isEmpty() )
+ return QValueList<Tag>();
+ return cppCompletionInstance->m_repository->getBaseClassList( scope().join("::") + specialization() );
+}
+
+void SimpleTypeCatalog::initFromTag() {
+ QStringList l = m_tag.scope();
+ l << m_tag.name();
+ setScope( l );
+}
+
+void SimpleTypeCatalog::init() {
+ if ( !scope().isEmpty() ) {
+ QStringList l = scope();
+ QStringList cp = l;
+ cp.pop_back();
+ setScope( cp );
+ m_tag = findSubTag( l.back() );
+ setScope( l );
+ //initFromTag( ); ///must not be done, because it may initialize to wrong namespaces etc.
+ }
+}
+
+DeclarationInfo SimpleTypeCatalog::getDeclarationInfo() {
+ DeclarationInfo ret;
+
+ ret.name = fullTypeResolved();
+ if ( m_tag ) {
+ ret.file = m_tag.fileName();
+ m_tag.getStartPosition( &ret.startLine, &ret.startCol );
+ m_tag.getEndPosition( &ret.endLine, &ret.endCol );
+ ret.comment = m_tag.comment();
+ }
+
+ return ret;
+}
+
+QStringList SimpleTypeCatalog::getBaseStrings() {
+ Debug d( "#getbases#" );
+ if ( !d || !safetyCounter ) {
+ //ifVerbose( dbg() << "\"" << str() << "\": recursion to deep while getting bases" << endl );
+ return QStringList();
+ }
+
+ QStringList ret;
+ QMap<QString, bool> bases;
+// try with parentsc
+ QTime t;
+ t.restart();
+ QValueList<Tag> parents( getBaseClassList() );
+
+ QValueList<Tag>::Iterator it = parents.begin();
+ while ( it != parents.end() ) {
+ Tag & tag = *it;
+ ++it;
+
+ CppBaseClass<Tag> info( tag );
+
+ bases[ info.baseClass() ] = true;
+ }
+ return bases.keys();
+}
+
+SimpleTypeImpl::TemplateParamInfo SimpleTypeCatalog::getTemplateParamInfo() {
+ TemplateParamInfo ret;
+
+ if ( m_tag ) {
+ if ( m_tag.hasAttribute( "tpl" ) ) {
+ QStringList l = m_tag.attribute( "tpl" ).asStringList();
+
+ TypeDesc::TemplateParams templateParams = m_desc.templateParams();
+ uint pi = 0;
+ QStringList::const_iterator it = l.begin();
+ while ( it != l.end() ) {
+ TemplateParamInfo::TemplateParam curr;
+ curr.name = *it;
+ curr.number = pi;
+ ++pi;
+ ++it;
+ if ( it != l.end() ) {
+ curr.def = *it;
+ ++it;
+ }
+ if ( pi < templateParams.count() )
+ curr.value = *templateParams[pi];
+ ret.addParam( curr );
+ };
+ }
+ }
+
+ return ret;
+}
+
+const LocateResult SimpleTypeCatalog::findTemplateParam( const QString& name ) {
+ if ( m_tag ) {
+ if ( m_tag.hasAttribute( "tpl" ) ) {
+ QStringList l = m_tag.attribute( "tpl" ).asStringList();
+ ///we need the index, so count the items through
+ uint pi = 0;
+
+ QStringList::const_iterator it = l.begin();
+ while ( it != l.end() && *it != name ) {
+ ++pi;
+ ++it;
+ if ( it != l.end() ) ++it;
+ };
+
+ TypeDesc::TemplateParams templateParams = m_desc.templateParams();
+
+ if ( it != l.end() && pi < templateParams.count() ) {
+ return *templateParams[pi];
+ } else {
+ if ( it != l.end() && *it == name && !(*it).isEmpty()) {
+ ++it;
+ if ( it != l.end() && !(*it).isEmpty() ) {
+ ifVerbose( dbg() << "using default-template-type " << *it << " for " << name << endl );
+ return TypeDesc( *it ); ///return default-parameter
+ }
+ }
+ }
+ }
+ }
+ return LocateResult();
+}
+
+//SimpleTypeCatalog::CatalogBuildInfo implementation
+TypePointer SimpleTypeCatalog::CatalogBuildInfo::build() {
+ if ( !m_tag )
+ return TypePointer();
+ else {
+ TypePointer tp = new SimpleTypeCachedCatalog( m_tag );
+ tp->parseParams( m_desc );
+ if ( m_parent ) tp->setParent( m_parent->bigContainer() );
+ return tp;
+ }
+
+}
+
+// kate: indent-mode csands; tab-width 4;
+