summaryrefslogtreecommitdiffstats
path: root/languages/cpp/simpletypefunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'languages/cpp/simpletypefunction.cpp')
-rw-r--r--languages/cpp/simpletypefunction.cpp726
1 files changed, 726 insertions, 0 deletions
diff --git a/languages/cpp/simpletypefunction.cpp b/languages/cpp/simpletypefunction.cpp
new file mode 100644
index 00000000..898228bb
--- /dev/null
+++ b/languages/cpp/simpletypefunction.cpp
@@ -0,0 +1,726 @@
+/***************************************************************************
+ 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 "simpletypefunction.h"
+#include "safetycounter.h"
+#include "simpletypenamespace.h"
+
+extern SafetyCounter safetyCounter;
+extern CppCodeCompletion* cppCompletionInstance;
+
+HashedStringSet getIncludeFiles( const ItemDom& item ) {
+ if ( item ) {
+ FileDom f = item->file();
+ if ( f ) {
+ ParseResultPointer p = f->parseResult();
+ if ( p ) {
+ ParsedFilePointer pp = dynamic_cast<ParsedFile*>( p.data() );
+ if ( pp ) {
+ return pp->includeFiles();
+ }
+ }
+ }
+ }
+
+ return HashedStringSet();
+}
+
+
+
+//SimpleTypeFunctionInterface implementation
+
+QString SimpleTypeFunctionInterface::signature() {
+ QString sig = "( ";
+ SimpleTypeImpl* asType = dynamic_cast<SimpleTypeImpl*>( this );
+
+ QStringList argDefaults = getArgumentDefaults();
+ QStringList argNames = getArgumentNames();
+ QValueList<TypeDesc> argTypes = getArgumentTypes();
+ QValueList<LocateResult> argRealTypes;
+
+ if ( asType ) {
+ for ( QValueList<TypeDesc>::iterator it = argTypes.begin(); it != argTypes.end(); ++it ) {
+ argRealTypes << asType->locateDecType( *it );
+ }
+ }
+
+ QStringList::iterator def = argDefaults.begin();
+ QStringList::iterator name = argNames.begin();
+ QValueList<LocateResult>::iterator realType = argRealTypes.begin();
+
+ while ( realType != argRealTypes.end() ) {
+ if ( sig != "( " )
+ sig += ", ";
+
+ sig += ( *realType )->fullNameChain();
+ ++realType;
+
+ if ( name != argNames.end() ) {
+ if ( !( *name ).isEmpty() ) sig += " " + *name;
+ ++name;
+ }
+
+ if ( def != argDefaults.end() && !( *def ).isEmpty() ) {
+ sig += " = " + *def;
+ ++def;
+ }
+ }
+
+ sig += " )";
+ return sig;
+}
+
+bool SimpleTypeFunctionInterface::containsUndefinedTemplateParam( TypeDesc& desc, SimpleTypeImpl::TemplateParamInfo& paramInfo ) {
+ TypeDesc::TemplateParams& pm = desc.templateParams();
+ SimpleTypeImpl::TemplateParamInfo::TemplateParam t;
+
+ if ( pm.isEmpty() && paramInfo.getParam( t, desc.name() ) )
+ if ( !t.value ) return true;
+
+ if ( desc.next() )
+ if ( containsUndefinedTemplateParam( *desc.next(), paramInfo ) )
+ return true;
+
+ for ( TypeDesc::TemplateParams::iterator it = pm.begin(); it != pm.end(); ++it ) {
+ if ( containsUndefinedTemplateParam( **it, paramInfo ) ) return true;
+ }
+
+ return false;
+}
+
+void SimpleTypeFunctionInterface::resolveImplicitTypes( TypeDesc& argType, TypeDesc& gottenArgType, SimpleTypeImpl::TemplateParamInfo& paramInfo ) {
+ if ( argType.templateParams().isEmpty() ) { ///Template-types may not be templates.
+ SimpleTypeImpl::TemplateParamInfo::TemplateParam p;
+ if ( paramInfo.getParam( p, argType.name() ) && !p.value ) {
+ ifVerbose( dbg() << "choosing \"" << gottenArgType.fullNameChain() << "\" as implicit template-parameter for \"" << argType.name() << "\"" << endl );
+ p.value = gottenArgType;
+ p.value.makePrivate();
+ for ( int d = 0; d < argType.totalPointerDepth(); d++ )
+ p.value.setTotalPointerDepth( p.value.totalPointerDepth() - 1 );
+
+ paramInfo.addParam( p );
+ }
+ } else {
+ if ( argType.name() == gottenArgType.name() )
+ resolveImplicitTypes( argType.templateParams(), gottenArgType.templateParams(), paramInfo );
+ }
+}
+
+void SimpleTypeFunctionInterface::resolveImplicitTypes( TypeDesc::TemplateParams& argTypes, TypeDesc::TemplateParams& gottenArgTypes, SimpleTypeImpl::TemplateParamInfo& paramInfo ) {
+ TypeDesc::TemplateParams::iterator it = argTypes.begin();
+ TypeDesc::TemplateParams::iterator it2 = gottenArgTypes.begin();
+
+ while ( it != argTypes.end() && it2 != gottenArgTypes.end() ) {
+ resolveImplicitTypes( **it, **it2, paramInfo );
+ ++it;
+ ++it2;
+ }
+}
+
+void SimpleTypeFunctionInterface::resolveImplicitTypes( QValueList<TypeDesc>& argTypes, QValueList<TypeDesc>& gottenArgTypes, SimpleTypeImpl::TemplateParamInfo& paramInfo ) {
+ QValueList<TypeDesc>::iterator it = argTypes.begin();
+ QValueList<TypeDesc>::iterator it2 = gottenArgTypes.begin();
+
+ while ( it != argTypes.end() && it2 != gottenArgTypes.end() ) {
+ resolveImplicitTypes( *it, *it2, paramInfo );
+ ++it;
+ ++it2;
+ }
+}
+
+void SimpleTypeFunctionInterface::appendNextFunction( SimpleType func ) {
+ Debug d( "#fapp#" );
+ if ( !func || !d ) return;
+ if (( SimpleTypeImpl* ) func.get() == ( SimpleTypeImpl* ) this ) return;
+ if ( m_nextFunction && m_nextFunction->asFunction() ) {
+ m_nextFunction->asFunction()->appendNextFunction( func );
+ } else {
+ m_nextFunction = func;
+ }
+}
+
+//SimpleTypeCodeModel implementation
+
+void SimpleTypeCodeModel::addAliasesTo( SimpleTypeNamespace* ns ) {
+ const NamespaceModel* m = dynamic_cast<const NamespaceModel*>( m_item.data() );
+ if ( m ) {
+ const NamespaceModel::NamespaceAliasModelList& namespaceAliases = m->namespaceAliases();
+ const NamespaceModel::NamespaceImportModelList& namespaceImports = m->namespaceImports();
+ for ( NamespaceModel::NamespaceAliasModelList::const_iterator it = namespaceAliases.begin(); it != namespaceAliases.end(); ++it ) {
+ HashedStringSet searchFiles;
+ FileDom d = m->codeModel()->fileByName( it->fileName().str() );
+ ParsedFilePointer p = dynamic_cast<ParsedFile*>( d->parseResult().data() );
+ if ( p ) {
+ searchFiles = p->includeFiles();
+ } else {
+ searchFiles = HashedStringSet( HashedString( it->fileName() ) );
+ }
+ TypeDesc ds( it->aliasName() );
+ ds.setIncludeFiles( searchFiles );
+ ns->addAliasMap( it->name(), ds, HashedString( it->fileName() ), true, false, bigContainer() );
+ }
+ for ( NamespaceModel::NamespaceImportModelList::const_iterator it = namespaceImports.begin(); it != namespaceImports.end(); ++it ) {
+ HashedStringSet searchFiles;
+ FileDom d = m->codeModel()->fileByName( it->fileName().str() );
+ ParsedFilePointer p = dynamic_cast<ParsedFile*>( d->parseResult().data() );
+ if ( p ) {
+ searchFiles = p->includeFiles();
+ } else {
+ searchFiles = HashedStringSet( HashedString( it->fileName() ) );
+ }
+ TypeDesc ds( it->name() );
+ ds.setIncludeFiles( searchFiles );
+ ns->addAliasMap( TypeDesc(), ds, HashedString( it->fileName() ), true, false, bigContainer() );
+ }
+ }
+}
+
+SimpleTypeCodeModel::SimpleTypeCodeModel( ItemDom& item ) : m_item( item ) {
+ CodeModelItem* i = & ( *item );
+ FunctionModel* m = dynamic_cast<FunctionModel*>( i );
+ ClassModel* c = dynamic_cast<ClassModel*>( i );
+ if ( m ) {
+ QStringList l = m->scope();
+ l << m->name();
+ setScope( l );
+ return;
+ }
+ if ( c ) {
+ QStringList l = c->scope();
+ l << c->name();
+ setScope( l );
+ return;
+ }
+ ifVerbose( dbg() << "code-model-item has an unsupported type: " << i->name() << endl );
+}
+
+ItemDom SimpleTypeCodeModel::locateModelContainer( class CodeModel* m, TypeDesc t, ClassDom cnt ) {
+ if ( !cnt ) {
+ if ( m->globalNamespace() ) {
+ cnt = model_cast<ClassDom> ( m->globalNamespace() );
+ } else {
+ return ItemDom();
+ }
+ }
+ if ( t ) {
+ if ( cnt->hasClass( t.name() ) ) {
+ ClassList l = cnt->classByName( t.name() );
+ if ( !l.isEmpty() ) {
+ if ( t.next() )
+ return locateModelContainer( m, *t.next(), l.front() );
+ else
+ return model_cast<ItemDom> ( l.front() );
+ }
+ }
+ NamespaceModel* ns = dynamic_cast<NamespaceModel*>( & ( *cnt ) );
+ if ( ns ) {
+ NamespaceDom n = ns->namespaceByName( t.name() );
+ if ( t.next() )
+ return locateModelContainer( m, *t.next(), model_cast<ClassDom> ( n ) );
+ else
+ return model_cast<ItemDom> ( n );
+ }
+ }
+
+ return ItemDom();
+}
+
+///Until header-parsing is implemented, this tries to find the class that is most related to this item
+/*ClassDom SimpleTypeCodeModel::pickMostRelated( ClassList lst, QString fn ) {
+ if( lst.isEmpty() ) return ClassDom();
+
+ ClassDom best = lst.front();
+ uint bestMatch = 0;
+ //kdDebug() << "searching most related to " << fn << endl;
+
+ for( ClassList::iterator it = lst.begin(); it != lst.end(); ++it ) {
+ if( !(*it)->getSpecializationDeclaration().isEmpty() ) continue; ///Don't consider specialized classes
+ //kdDebug() << "comparing " << (*it)->fileName() << endl;
+ QString str = (*it)->fileName();
+ uint len = str.length();
+ if( fn.length() < len ) len = fn.length();
+
+ uint matchLen = 0;
+ for( uint a = 0; a < len; a++ ) {
+ if( str[a] == fn[a] )
+ matchLen++;
+ else
+ break;
+ }
+
+ if( matchLen > bestMatch ) {
+ //kdDebug() << "picking " << str << endl;
+ bestMatch = matchLen;
+ best = *it;
+ }
+ }
+
+ //kdDebug() << "picked " << best->fileName() << endl;
+ if( !best->getSpecializationDeclaration().isEmpty() ) best = 0; ///only accept non-specialized classes
+ return best;
+}*/
+
+/*QValueList<TypePointer> SimpleTypeCodeModel::findSpecializations( const QString& name ) {
+ ClassModel* klass = dynamic_cast<ClassModel*> ( & (*m_item) );
+ if( !klass ) {
+ ifVerbose( dbg() << "\"" << str() << "\": search for member " << name.name() << " unsuccessful because the own type is invalid" << endl );
+ return QValueList<TypePointer>();
+ }
+
+ ClassList l = klass->classByName( name.name() );
+
+ if( !l.isEmpty() ) {
+ ClassDom i = pickMostRelated( l, globalCurrentFile );
+ if( i ) {
+ ret.setBuildInfo( new CodeModelBuildInfo( model_cast<ItemDom>( i ), name, TypePointer( this ) ) );
+
+ ret.memberType = MemberInfo::NestedType;
+ ret.type = name;
+ }
+ }
+
+ return QValueList<TypePointer>();
+}*/
+
+
+QValueList<TypePointer> SimpleTypeCodeModel::getMemberClasses( const TypeDesc& name ) {
+ QValueList<TypePointer> ret;
+
+ if ( !m_item ) return ret;
+
+ ClassModel* klass = dynamic_cast<ClassModel*>( & ( *m_item ) );
+ if ( !klass ) {
+ ifVerbose( dbg() << "\"" << str() << "\": search for member " << name.name() << " unsuccessful because the own type is invalid" << endl );
+ return ret;
+ }
+
+ ClassList l = klass->classByName( name.name() );
+
+ if ( !l.isEmpty() ) {
+ for ( ClassList::iterator it = l.begin(); it != l.end(); ++it ) {
+ CodeModelBuildInfo b( model_cast<ItemDom> ( *it ), name, TypePointer( this ) );
+ TypePointer r = b.build();
+ if ( r )
+ ret << r;
+ }
+ }
+ return ret;
+}
+
+template<class Item>
+Item pickMostRelated( const HashedStringSet& includeFiles, const QValueList<Item>& list ) {
+ if ( list.isEmpty() ) return Item();
+
+ for ( typename QValueList<Item>::const_iterator it = list.begin(); it != list.end(); ++it ) {
+ if ( includeFiles[( *it )->fileName()] )
+ return *it;
+ }
+ return list.front();
+}
+
+template<>
+ClassDom pickMostRelated( const HashedStringSet& includeFiles, const QValueList<ClassDom>& list ) {
+ if ( list.isEmpty() ) return ClassDom(); ///@todo the current file must be preferred
+
+ for ( QValueList<ClassDom>::const_iterator it = list.begin(); it != list.end(); ++it ) {
+ if ( !( *it )->getSpecializationDeclaration().isEmpty() ) continue; ///Don't consider specialized classes
+ if ( includeFiles[( *it )->fileName()] )
+ return *it;
+ }
+
+
+ if ( !list.front()->getSpecializationDeclaration().isEmpty() ) return ClassDom(); ///Don't consider specialized classes
+ return list.front();
+}
+
+SimpleTypeImpl::MemberInfo SimpleTypeCodeModel::findMember( TypeDesc name , MemberInfo::MemberType type ) {
+ MemberInfo ret;
+ ret.name = name.name();
+ ret.memberType = MemberInfo::NotFound;
+ if ( !name || !m_item ) return ret;
+
+ ClassModel* klass = dynamic_cast<ClassModel*>( & ( *m_item ) );
+ if ( !klass ) {
+ ifVerbose( dbg() << "\"" << str() << "\": search for member " << name.name() << " unsuccessful because the own type is invalid" << endl );
+ return ret;
+ }
+ NamespaceModel* ns = dynamic_cast<NamespaceModel*>( klass );
+
+ if ( klass->hasVariable( name.name() ) && ( type & MemberInfo::Variable ) ) {
+ ret.memberType = MemberInfo::Variable;
+ VariableDom d = klass->variableByName( name.name() );
+ if ( d ) {
+ ret.type = d->type();
+ ret.type->setIncludeFiles( HashedString( d->fileName() ) );
+ ret.decl.name = d->name();
+ ret.decl.file = d->fileName();
+ ret.decl.comment = d->comment();
+ d->getStartPosition( &ret.decl.startLine, &ret.decl.startCol );
+ d->getEndPosition( &ret.decl.endLine, &ret.decl.endCol );
+ }
+ } else if ( klass->hasTypeAlias( name.name() ) && ( type & MemberInfo::Typedef ) ) {
+ ret.memberType = MemberInfo::Typedef;
+ TypeAliasList li = klass->typeAliasByName( name.name() );
+ TypeAliasDom a = pickMostRelated( name.includeFiles(), li );
+
+ if ( a ) {
+ ret.type = a->type();
+ ret.type->setIncludeFiles( getIncludeFiles( a.data() ) );
+ ret.decl.name = a->name();
+ ret.decl.file = a->fileName();
+ ret.decl.comment = a->comment();
+ a->getStartPosition( &ret.decl.startLine, &ret.decl.startCol );
+ a->getEndPosition( &ret.decl.endLine, &ret.decl.endCol );
+ }
+ } else if ( klass->hasEnum( name.name() ) && ( type & MemberInfo::Typedef ) ) {
+ ret.memberType = MemberInfo::Typedef;
+ EnumDom e = klass->enumByName( name.name() );
+ ret.type = TypeDesc( "const int" );
+ ret.type->setIncludeFiles( HashedString( e->fileName() ) );
+ ret.decl.name = e->name();
+ ret.decl.file = e->fileName();
+ ret.decl.comment = e->comment();
+ e->getStartPosition( &ret.decl.startLine, &ret.decl.startCol );
+ e->getEndPosition( &ret.decl.endLine, &ret.decl.endCol );
+ } else if ( klass->hasClass( name.name() ) && ( type & MemberInfo::NestedType ) ) {
+ ClassList l = klass->classByName( name.name() );
+
+ if ( !l.isEmpty() ) {
+ ClassDom i = pickMostRelated( name.includeFiles(), l );
+ if ( i ) {
+ ret.setBuildInfo( new CodeModelBuildInfo( model_cast<ItemDom> ( i ), name, TypePointer( this ) ) );
+
+ ret.memberType = MemberInfo::NestedType;
+ ret.type = name;
+ ret.type->setIncludeFiles( HashedString( i->fileName() ) );
+ }
+ }
+ } else if ( klass->hasFunction( name.name() ) && ( type & MemberInfo::Function ) ) {
+ ret.memberType = MemberInfo::Function;
+ FunctionList l = klass->functionByName( name.name() );
+ if ( !l.isEmpty() && l.front() ) {
+ ret.setBuildInfo( new SimpleTypeCodeModelFunction::CodeModelFunctionBuildInfo( l, name , TypePointer( this ) ) );
+ ret.type = l.front()->resultType();
+ ret.type->setIncludeFiles( HashedString( l.front()->fileName() ) );
+ ret.type->increaseFunctionDepth();
+ }
+ } else if ( ns && ns->hasNamespace( name.name() ) && ( type & MemberInfo::Namespace ) ) {
+ NamespaceDom n = ns->namespaceByName( name.name() );
+ ret.setBuildInfo( new CodeModelBuildInfo( model_cast<ItemDom> ( n ), name, TypePointer( this ) ) );
+ ret.memberType = MemberInfo::Namespace;
+ ret.type = name;
+ //ret.type->setIncludeFiles( d->fileName() );
+ } else if ( klass->hasFunctionDefinition( name.name() ) && ( type & MemberInfo::Function ) ) {
+ FunctionDefinitionList l = klass->functionDefinitionByName( name.name() );
+ for ( FunctionDefinitionList::iterator it = l.begin(); it != l.end(); ++it ) {
+ if ( !( *it )->scope().isEmpty() && ( *it )->scope() != scope() ) continue; ///Only use definitions with empty scope or that are within this class
+ ret.setBuildInfo( new SimpleTypeCodeModelFunction::CodeModelFunctionBuildInfo( l, name, TypePointer( this ) ) );
+ ret.type = l.front()->resultType();
+ ret.type->setIncludeFiles( HashedString(( *it )->fileName() ) );
+ ret.type->increaseFunctionDepth();
+ ret.memberType = MemberInfo::Function;
+ break;
+ }
+ }
+
+ if ( ret.memberType == MemberInfo::NotFound ) {
+ if ( type & MemberInfo::Template ) {
+ LocateResult s = findTemplateParam( name.name() );
+ if ( s ) {
+ ret.memberType = MemberInfo::Template;
+ ret.type = s;
+ if ( m_item )
+ ret.type->setIncludeFiles( getIncludeFiles( m_item.data() ) );
+ ret.decl.name = name.name();
+ if ( m_item ) {
+ ret.decl.file = m_item->fileName();
+ m_item->getStartPosition( &ret.decl.startLine, &ret.decl.startCol );
+ m_item->getEndPosition( &ret.decl.endLine, &ret.decl.endCol );
+ }
+ }
+ }
+ }
+
+ 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,
+ //Which is necessary because the alias is parented by exactly this class.
+
+ ret.type->addIncludeFiles( name.includeFiles() );
+ }
+
+ chooseSpecialization( ret );
+
+ return ret;
+}
+
+bool SimpleTypeCodeModel::findItem() {
+ QString key = str();
+ m_item = locateModelContainer( cppCompletionInstance->m_pSupport->codeModel(), str() );
+ return ( bool ) m_item;
+}
+
+void SimpleTypeCodeModel::init() {
+ if ( scope().isEmpty() ) {
+ m_item = cppCompletionInstance->m_pSupport->codeModel() ->globalNamespace();
+ } else {
+ findItem();
+ }
+}
+
+DeclarationInfo SimpleTypeCodeModel::getDeclarationInfo() {
+ DeclarationInfo ret;
+ ItemDom i = item();
+ ret.name = fullTypeResolved();
+ if ( i ) {
+ ret.file = i->fileName();
+ i->getStartPosition( &ret.startLine, &ret.startCol );
+ i->getEndPosition( &ret.endLine, &ret.endCol );
+ ret.comment = i->comment();
+ }
+ return ret;
+}
+
+QString SimpleTypeCodeModel::specialization() const {
+ const ClassModel* klass = dynamic_cast<const ClassModel*>( m_item.data() );
+ if ( !klass ) return QString::null;
+ return klass->getSpecializationDeclaration();
+}
+
+SimpleTypeImpl::TemplateParamInfo SimpleTypeCodeModel::getTemplateParamInfo() {
+ TemplateParamInfo ret;
+
+ if ( m_item ) {
+ TemplateModelItem* ti = dynamic_cast<TemplateModelItem*>( & ( *m_item ) );
+ TypeDesc::TemplateParams& templateParams = m_desc.templateParams();
+
+ TemplateModelItem::ParamMap m = ti->getTemplateParams();
+ for ( uint a = 0; a < m.size(); a++ ) {
+ TemplateParamInfo::TemplateParam t;
+ t.number = a;
+ t.name = m[a].first;
+ t.def = m[a].second;
+ if ( templateParams.count() > a )
+ t.value = *templateParams[a];
+ ret.addParam( t );
+ }
+ }
+
+ return ret;
+}
+
+const LocateResult SimpleTypeCodeModel::findTemplateParam( const QString& name ) {
+ if ( m_item ) {
+ TemplateModelItem* ti = dynamic_cast<TemplateModelItem*>( & ( *m_item ) );
+ TypeDesc::TemplateParams& templateParams = m_desc.templateParams();
+ int pi = ti->findTemplateParam( name );
+ if ( pi != -1 && ( int ) templateParams.count() > pi ) {
+ return *templateParams[pi];
+ } else {
+ if ( pi != -1 && !ti->getParam( pi ).second.isEmpty() ) {
+ QString def = ti->getParam( pi ).second;
+ ifVerbose( dbg() << "\"" << str() << "\": using default-template-parameter \"" << def << "\" for " << name << endl );
+ return TypeDesc( def );
+ } else if ( pi != -1 ) {
+ ifVerbose( dbg() << "\"" << str() << "\": template-type \"" << name << "\" has no pameter! " << endl );
+ }
+ }
+ }
+ return LocateResult();
+}
+
+QStringList SimpleTypeCodeModel::getBaseStrings() {
+ Debug d( "#getbases#" );
+ if ( !d || !safetyCounter ) {
+ //ifVerbose( dbg() << "\"" << str() << "\": recursion to deep while getting bases" << endl );
+ return QStringList();
+ }
+
+ QStringList ret;
+
+ ClassModel* klass;
+
+ if ( !m_item || ( klass = dynamic_cast<ClassModel*>( & ( *m_item ) ) ) == 0 ) return ret;
+
+ QStringList parents = klass->baseClassList();
+ for ( QStringList::Iterator it = parents.begin(); it != parents.end(); ++it ) {
+ ret << *it;
+ }
+
+ return ret;
+}
+
+TypePointer SimpleTypeCodeModel::CodeModelBuildInfo::build() {
+ TypePointer tp = new SimpleTypeCachedCodeModel( m_item );
+ tp->parseParams( m_desc );
+ if ( m_parent ) tp->setParent( m_parent->bigContainer() );
+ return tp;
+}
+
+//SimpleTypeCodeModelFunction implementation
+TypeDesc SimpleTypeCodeModelFunction::getReturnType() {
+ if ( item() ) {
+ IncludeFiles files;
+ if( parent() )
+ files = parent()->getFindIncludeFiles();
+ if ( FunctionModel* m = dynamic_cast<FunctionModel*>( & ( *item() ) ) ) {
+ TypeDesc d = m->resultType();
+ d.setIncludeFiles( files );
+ return d;
+ }
+ }
+
+ return TypeDesc();
+}
+
+bool SimpleTypeCodeModelFunction::isConst() {
+ if ( asFunctionModel() )
+ return asFunctionModel()->isConstant();
+
+ return false;
+}
+
+
+QValueList<TypeDesc> SimpleTypeCodeModelFunction::getArgumentTypes() {
+ QValueList<TypeDesc> ret;
+
+ if ( item() ) {
+ IncludeFiles files;
+ if( parent() )
+ files = parent()->getFindIncludeFiles();
+ if ( FunctionModel* m = dynamic_cast<FunctionModel*>( & ( *item() ) ) ) {
+ ArgumentList l = m->argumentList();
+ for ( ArgumentList::iterator it = l.begin(); it != l.end(); ++it ) {
+ ret << TypeDesc(( *it )->type() );
+ ret.back().setIncludeFiles( files );
+ }
+ }
+ }
+
+ return ret;
+}
+
+QStringList SimpleTypeCodeModelFunction::getArgumentNames() {
+ QStringList ret;
+
+ if ( item() ) {
+ if ( FunctionModel* m = dynamic_cast<FunctionModel*>( & ( *item() ) ) ) {
+ ArgumentList l = m->argumentList();
+ for ( ArgumentList::iterator it = l.begin(); it != l.end(); ++it )
+ ret << ( *it )->name();
+ }
+ }
+
+ return ret;
+}
+
+QStringList SimpleTypeCodeModelFunction::getArgumentDefaults() {
+ QStringList ret;
+
+ if ( item() ) {
+ if ( FunctionModel* m = dynamic_cast<FunctionModel*>( & ( *item() ) ) ) {
+ ArgumentList l = m->argumentList();
+ for ( ArgumentList::iterator it = l.begin(); it != l.end(); ++it )
+ ret << ( *it )->defaultValue();
+ }
+ }
+
+ return ret;
+}
+
+
+//SimpleTypeCodeModelFunction::CodeModelFunctionBuildInfo implementation
+
+SimpleTypeCodeModelFunction::CodeModelFunctionBuildInfo::CodeModelFunctionBuildInfo( FunctionDefinitionList items, TypeDesc& desc, TypePointer parent ) : m_desc( desc ), m_parent( parent ) {
+
+ for ( FunctionDefinitionList::iterator it = items.begin(); it != items.end(); ++it ) {
+ m_items << model_cast<FunctionDom> ( *it );
+ }
+}
+
+TypePointer SimpleTypeCodeModelFunction::CodeModelFunctionBuildInfo::build() {
+ QValueList<TypePointer> ret;
+ TypePointer last;
+ for ( FunctionList::iterator it = m_items.begin(); it != m_items.end(); ++it ) {
+ TypePointer tp = new SimpleTypeCodeModelFunction( model_cast<ItemDom> ( *it ) );
+ tp->takeTemplateParams( m_desc );
+ tp->descForEdit().increaseFunctionDepth();
+ tp->setParent( m_parent->bigContainer() );
+ if ( last && last->asFunction() ) last->asFunction()->appendNextFunction( SimpleType( tp ) );
+ last = tp;
+ ret << tp;
+ }
+
+ if ( ret.isEmpty() ) {
+ ifVerbose( dbg() << "error" << endl );
+ return TypePointer();
+ } else
+ return ret.front();
+}
+
+//SimpleTypeCatalogFunction implementation
+TypeDesc SimpleTypeCatalogFunction::getReturnType() {
+ if ( tag() ) {
+ return tagType( tag() );
+ }
+
+ return TypeDesc();
+}
+
+bool SimpleTypeCatalogFunction::isConst() {
+ Tag t = tag();
+ CppFunction<Tag> tagInfo( t );
+ return tagInfo.isConst();
+}
+
+QStringList SimpleTypeCatalogFunction::getArgumentNames() {
+ QStringList ret;
+ Tag t = tag();
+ CppFunction<Tag> tagInfo( t );
+ return tagInfo.argumentNames();
+}
+
+QValueList<TypeDesc> SimpleTypeCatalogFunction::getArgumentTypes() {
+ QValueList<TypeDesc> ret;
+ Tag t = tag();
+ CppFunction<Tag> tagInfo( t );
+ QStringList arguments = tagInfo.arguments();
+ for ( QStringList::iterator it = arguments.begin(); it != arguments.end(); ++it )
+ ret << TypeDesc( *it );
+ return ret;
+}
+
+//SimpleTypeCatalogFunction::CatalogFunctionBuildInfo implementation
+
+TypePointer SimpleTypeCatalogFunction::CatalogFunctionBuildInfo::build() {
+ QValueList<TypePointer> ret;
+ TypePointer last;
+ for ( QValueList<Tag>::iterator it = m_tags.begin(); it != m_tags.end(); ++it ) {
+ TypePointer tp = new SimpleTypeCatalogFunction( *it );
+ tp->takeTemplateParams( m_desc );
+ tp->descForEdit().increaseFunctionDepth();
+ if ( m_parent ) tp->setParent( m_parent->bigContainer() );
+ if ( last && last->asFunction() ) last->asFunction()->appendNextFunction( SimpleType( tp ) );
+ last = tp;
+ ret << tp;
+ }
+
+ if ( ret.isEmpty() ) {
+ ifVerbose( dbg() << "error" << endl );
+ return TypePointer();
+ }
+ return ret.front();
+}
+
+// kate: indent-mode csands; tab-width 4;