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.
725 lines
25 KiB
725 lines
25 KiB
/***************************************************************************
|
|
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
|
|
|
|
TQString SimpleTypeFunctionInterface::signature() {
|
|
TQString sig = "( ";
|
|
SimpleTypeImpl* asType = dynamic_cast<SimpleTypeImpl*>( this );
|
|
|
|
TQStringList argDefaults = getArgumentDefaults();
|
|
TQStringList argNames = getArgumentNames();
|
|
TQValueList<TypeDesc> argTypes = getArgumentTypes();
|
|
TQValueList<LocateResult> argRealTypes;
|
|
|
|
if ( asType ) {
|
|
for ( TQValueList<TypeDesc>::iterator it = argTypes.begin(); it != argTypes.end(); ++it ) {
|
|
argRealTypes << asType->locateDecType( *it );
|
|
}
|
|
}
|
|
|
|
TQStringList::iterator def = argDefaults.begin();
|
|
TQStringList::iterator name = argNames.begin();
|
|
TQValueList<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( TQValueList<TypeDesc>& argTypes, TQValueList<TypeDesc>& gottenArgTypes, SimpleTypeImpl::TemplateParamInfo& paramInfo ) {
|
|
TQValueList<TypeDesc>::iterator it = argTypes.begin();
|
|
TQValueList<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 ) {
|
|
TQStringList l = m->scope();
|
|
l << m->name();
|
|
setScope( l );
|
|
return;
|
|
}
|
|
if ( c ) {
|
|
TQStringList 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, TQString 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;
|
|
TQString 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;
|
|
}*/
|
|
|
|
/*TQValueList<TypePointer> SimpleTypeCodeModel::findSpecializations( const TQString& 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 TQValueList<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 TQValueList<TypePointer>();
|
|
}*/
|
|
|
|
|
|
TQValueList<TypePointer> SimpleTypeCodeModel::getMemberClasses( const TypeDesc& name ) {
|
|
TQValueList<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 TQValueList<Item>& list ) {
|
|
if ( list.isEmpty() ) return Item();
|
|
|
|
for ( typename TQValueList<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 TQValueList<ClassDom>& list ) {
|
|
if ( list.isEmpty() ) return ClassDom(); ///@todo the current file must be preferred
|
|
|
|
for ( TQValueList<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() {
|
|
TQString 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;
|
|
}
|
|
|
|
TQString SimpleTypeCodeModel::specialization() const {
|
|
const ClassModel* klass = dynamic_cast<const ClassModel*>( m_item.data() );
|
|
if ( !klass ) return TQString();
|
|
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 TQString& 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() ) {
|
|
TQString 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();
|
|
}
|
|
|
|
TQStringList SimpleTypeCodeModel::getBaseStrings() {
|
|
Debug d( "#getbases#" );
|
|
if ( !d || !safetyCounter ) {
|
|
//ifVerbose( dbg() << "\"" << str() << "\": recursion to deep while getting bases" << endl );
|
|
return TQStringList();
|
|
}
|
|
|
|
TQStringList ret;
|
|
|
|
ClassModel* klass;
|
|
|
|
if ( !m_item || ( klass = dynamic_cast<ClassModel*>( & ( *m_item ) ) ) == 0 ) return ret;
|
|
|
|
TQStringList parents = klass->baseClassList();
|
|
for ( TQStringList::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;
|
|
}
|
|
|
|
|
|
TQValueList<TypeDesc> SimpleTypeCodeModelFunction::getArgumentTypes() {
|
|
TQValueList<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;
|
|
}
|
|
|
|
TQStringList SimpleTypeCodeModelFunction::getArgumentNames() {
|
|
TQStringList 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;
|
|
}
|
|
|
|
TQStringList SimpleTypeCodeModelFunction::getArgumentDefaults() {
|
|
TQStringList 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() {
|
|
TQValueList<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();
|
|
}
|
|
|
|
TQStringList SimpleTypeCatalogFunction::getArgumentNames() {
|
|
TQStringList ret;
|
|
Tag t = tag();
|
|
CppFunction<Tag> tagInfo( t );
|
|
return tagInfo.argumentNames();
|
|
}
|
|
|
|
TQValueList<TypeDesc> SimpleTypeCatalogFunction::getArgumentTypes() {
|
|
TQValueList<TypeDesc> ret;
|
|
Tag t = tag();
|
|
CppFunction<Tag> tagInfo( t );
|
|
TQStringList arguments = tagInfo.arguments();
|
|
for ( TQStringList::iterator it = arguments.begin(); it != arguments.end(); ++it )
|
|
ret << TypeDesc( *it );
|
|
return ret;
|
|
}
|
|
|
|
//SimpleTypeCatalogFunction::CatalogFunctionBuildInfo implementation
|
|
|
|
TypePointer SimpleTypeCatalogFunction::CatalogFunctionBuildInfo::build() {
|
|
TQValueList<TypePointer> ret;
|
|
TypePointer last;
|
|
for ( TQValueList<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();
|
|
}
|