language/duchain
functiontype.cpp
00001 /* This file is part of KDevelop 00002 Copyright 2006 Roberto Raggi <roberto@kdevelop.org> 00003 Copyright 2006-2008 Hamish Rodda <rodda@kde.org> 00004 Copyright 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License version 2 as published by the Free Software Foundation. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "functiontype.h" 00022 00023 #include "../indexedstring.h" 00024 #include "../repositories/typerepository.h" 00025 #include "typesystemdata.h" 00026 #include "typeregister.h" 00027 #include "typesystem.h" 00028 00029 namespace KDevelop 00030 { 00031 00032 REGISTER_TYPE(FunctionType); 00033 00034 DEFINE_LIST_MEMBER_HASH(FunctionTypeData, m_arguments, IndexedType) 00035 00036 FunctionType::FunctionType(const FunctionType& rhs) : AbstractType(copyData<FunctionType>(*rhs.d_func())) { 00037 } 00038 00039 FunctionType::FunctionType(FunctionTypeData& data) : AbstractType(data) { 00040 } 00041 00042 AbstractType* FunctionType::clone() const { 00043 return new FunctionType(*this); 00044 } 00045 00046 bool FunctionType::equals(const AbstractType* _rhs) const 00047 { 00048 if( this == _rhs ) 00049 return true; 00050 00051 if (!AbstractType::equals(_rhs)) 00052 return false; 00053 00054 Q_ASSERT(fastCast<const FunctionType*>(_rhs)); 00055 00056 const FunctionType* rhs = static_cast<const FunctionType*>(_rhs); 00057 00058 TYPE_D(FunctionType); 00059 if( d->m_argumentsSize() != rhs->d_func()->m_argumentsSize() ) 00060 return false; 00061 00062 if( (bool)rhs->d_func()->m_returnType != (bool)d->m_returnType ) 00063 return false; 00064 00065 if( d->m_returnType != rhs->d_func()->m_returnType ) 00066 return false; 00067 00068 for(unsigned int a = 0; a < d->m_argumentsSize(); ++a) 00069 if(d->m_arguments()[a] != rhs->d_func()->m_arguments()[a]) 00070 return false; 00071 00072 return true; 00073 } 00074 00075 FunctionType::FunctionType() 00076 : AbstractType(createData<FunctionType>()) 00077 { 00078 } 00079 00080 FunctionType::~FunctionType() 00081 { 00082 } 00083 00084 00085 void FunctionType::addArgument(AbstractType::Ptr argument) 00086 { 00087 d_func_dynamic()->m_argumentsList().append(argument->indexed()); 00088 } 00089 00090 void FunctionType::removeArgument(AbstractType::Ptr argument) 00091 { 00092 TYPE_D_DYNAMIC(FunctionType); 00093 00094 IndexedType i = argument->indexed(); 00095 uint shift = 0; 00096 for(unsigned int a = 0; a < d->m_argumentsSize(); ++a) { 00097 if(d->m_arguments()[a] == i) { 00098 ++shift; 00099 }else if(shift) { 00100 d->m_argumentsList()[a-shift] = d->m_argumentsList()[a]; 00101 } 00102 } 00103 d->m_argumentsList().resize(d->m_argumentsSize()-shift); 00104 } 00105 00106 void FunctionType::setReturnType(AbstractType::Ptr returnType) 00107 { 00108 d_func_dynamic()->m_returnType = returnType->indexed(); 00109 } 00110 00111 AbstractType::Ptr FunctionType::returnType () const 00112 { 00113 return d_func()->m_returnType.abstractType(); 00114 } 00115 00116 QList<AbstractType::Ptr> FunctionType::arguments () const 00117 { 00119 QList<AbstractType::Ptr> ret; 00120 FOREACH_FUNCTION(IndexedType arg, d_func()->m_arguments) 00121 ret << arg.abstractType(); 00122 return ret; 00123 } 00124 00125 const IndexedType* FunctionType::indexedArguments() const 00126 { 00127 return d_func()->m_arguments(); 00128 } 00129 00130 uint FunctionType::indexedArgumentsSize() const 00131 { 00132 return d_func()->m_argumentsSize(); 00133 } 00134 00135 void FunctionType::accept0 (TypeVisitor *v) const 00136 { 00137 TYPE_D(FunctionType); 00138 if (v->visit (this)) 00139 { 00140 acceptType (d->m_returnType.abstractType(), v); 00141 00142 for (unsigned int i = 0; i < d->m_argumentsSize (); ++i) 00143 acceptType (d->m_arguments()[i].abstractType(), v); 00144 } 00145 00146 v->endVisit (this); 00147 } 00148 00149 void FunctionType::exchangeTypes( TypeExchanger* exchanger ) 00150 { 00151 TYPE_D_DYNAMIC(FunctionType); 00152 for (uint i = 0; i < d->m_argumentsSize (); ++i) 00153 d->m_argumentsList()[i] = exchanger->exchange( d->m_arguments()[i].abstractType() )->indexed(); 00154 d->m_returnType = exchanger->exchange(d->m_returnType.abstractType())->indexed(); 00155 } 00156 00157 QString FunctionType::partToString( SignaturePart sigPart ) const { 00158 QString args; 00159 TYPE_D(FunctionType); 00160 if( sigPart == SignatureArguments || sigPart == SignatureWhole ) 00161 { 00162 args += '('; 00163 bool first = true; 00164 FOREACH_FUNCTION(const IndexedType& type, d->m_arguments) { 00165 if (first) 00166 first = false; 00167 else 00168 args.append(", "); 00169 args.append(type ? type.abstractType()->toString() : QString("<notype>")); 00170 } 00171 args += ')'; 00172 } 00173 00174 if( sigPart == SignatureArguments ) 00175 return args; 00176 else if( sigPart == SignatureWhole ) 00177 return QString("function %1 %2").arg(returnType() ? returnType()->toString() : QString("<notype>")).arg(args); 00178 else if( sigPart == SignatureReturn ) 00179 return returnType() ? returnType()->toString() : QString(); 00180 00181 return QString("ERROR"); 00182 } 00183 00184 QString FunctionType::toString() const 00185 { 00186 return partToString(SignatureWhole) + AbstractType::toString(true); 00187 } 00188 00189 AbstractType::WhichType FunctionType::whichType() const 00190 { 00191 return TypeFunction; 00192 } 00193 00194 uint FunctionType::hash() const 00195 { 00196 uint hash_value = AbstractType::hash(); 00197 hash_value += d_func()->m_returnType.hash() * 859321; 00198 00199 FOREACH_FUNCTION(IndexedType t, d_func()->m_arguments) { 00200 hash_value = (hash_value << 5) - hash_value + t.hash(); 00201 } 00202 00203 return hash_value; 00204 } 00205 00206 } 00207 00208 // kate: space-indent on; indent-width 2; tab-width 4; replace-tabs on; auto-insert-doxygen on
KDE 4.4 API Reference