language/duchain
classfunctiondeclaration.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "classfunctiondeclaration.h"
00023
00024 #include "ducontext.h"
00025 #include "types/functiontype.h"
00026 #include "duchainregister.h"
00027
00028 namespace KDevelop
00029 {
00030 Identifier conversionIdentifier("operator{...cast...}");
00031
00032 REGISTER_DUCHAIN_ITEM(ClassFunctionDeclaration);
00033
00034 ClassFunctionDeclaration::ClassFunctionDeclaration(const ClassFunctionDeclaration& rhs)
00035 : ClassFunctionDeclarationBase(*new ClassFunctionDeclarationData( *rhs.d_func() )) {
00036 setSmartRange(rhs.smartRange(), DocumentRangeObject::DontOwn);
00037 }
00038
00039 void ClassFunctionDeclaration::setAbstractType(AbstractType::Ptr type) {
00040 if(!( !type || dynamic_cast<FunctionType*>(type.unsafeData()) )) {
00041 kWarning(9505) << "WARNING: Non-function type assigned to function declaration";
00042 }
00043 ClassMemberDeclaration::setAbstractType(type);
00044 }
00045
00046 DEFINE_LIST_MEMBER_HASH(ClassFunctionDeclarationData, m_defaultParameters, IndexedString)
00047
00048 ClassFunctionDeclaration::ClassFunctionDeclaration(ClassFunctionDeclarationData& data) : ClassFunctionDeclarationBase(data)
00049 {
00050 }
00051
00052 ClassFunctionDeclaration::ClassFunctionDeclaration(const SimpleRange& range, DUContext* context)
00053 : ClassFunctionDeclarationBase(*new ClassFunctionDeclarationData, range)
00054 {
00055 d_func_dynamic()->setClassId(this);
00056 if( context )
00057 setContext( context );
00058 }
00059
00060 ClassFunctionDeclaration::ClassFunctionDeclaration(ClassFunctionDeclarationData& data, const SimpleRange& range, DUContext* context)
00061 : ClassFunctionDeclarationBase(data, range)
00062 {
00063 if( context )
00064 setContext( context );
00065 }
00066
00067 Declaration* ClassFunctionDeclaration::clonePrivate() const {
00068 return new ClassFunctionDeclaration(*this);
00069 }
00070
00071 ClassFunctionDeclaration::~ClassFunctionDeclaration()
00072 {
00073 }
00074
00075 bool ClassFunctionDeclaration::isFunctionDeclaration() const
00076 {
00077 return true;
00078 }
00079
00080 QString ClassFunctionDeclaration::toString() const {
00081 if( !abstractType() )
00082 return ClassMemberDeclaration::toString();
00083
00084 TypePtr<FunctionType> function = type<FunctionType>();
00085 if(function) {
00086 return QString("%1 %2 %3").arg(function->partToString( FunctionType::SignatureReturn )).arg(identifier().toString()).arg(function->partToString( FunctionType::SignatureArguments ));
00087 } else {
00088 QString type = abstractType() ? abstractType()->toString() : QString("<notype>");
00089 kDebug(9505) << "A function has a bad type attached:" << type;
00090 return QString("invalid member-function %1 type %2").arg(identifier().toString()).arg(type);
00091 }
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 uint setFlag(bool enable, uint flag, uint flags) {
00121 if(enable)
00122 return flags | flag;
00123 else
00124 return flags & (~flag);
00125 }
00126
00127 bool ClassFunctionDeclaration::isAbstract() const
00128 {
00129 return d_func()->m_functionFlags & AbstractFunctionFlag;
00130 }
00131
00132 void ClassFunctionDeclaration::setIsAbstract(bool abstract)
00133 {
00134 d_func_dynamic()->m_functionFlags = (ClassFunctionFlags)setFlag(abstract, AbstractFunctionFlag, d_func()->m_functionFlags);
00135 }
00136
00137 bool ClassFunctionDeclaration::isFinal() const
00138 {
00139 return d_func()->m_functionFlags & FinalFunctionFlag;
00140 }
00141
00142 void ClassFunctionDeclaration::setIsFinal(bool final)
00143 {
00144 d_func_dynamic()->m_functionFlags = (ClassFunctionFlags)setFlag(final, FinalFunctionFlag, d_func()->m_functionFlags);
00145 }
00146
00147 bool ClassFunctionDeclaration::isSignal() const
00148 {
00149 return d_func()->m_functionFlags & FunctionSignalFlag;
00150 }
00151
00152 void ClassFunctionDeclaration::setIsSignal(bool isSignal) {
00153 d_func_dynamic()->m_functionFlags = (ClassFunctionFlags)setFlag(isSignal, FunctionSignalFlag, d_func()->m_functionFlags);
00154 }
00155
00156 bool ClassFunctionDeclaration::isSlot() const
00157 {
00158 return d_func()->m_functionFlags & FunctionSlotFlag;
00159 }
00160
00161 void ClassFunctionDeclaration::setIsSlot(bool isSlot) {
00162 d_func_dynamic()->m_functionFlags = (ClassFunctionFlags)setFlag(isSlot, FunctionSlotFlag, d_func()->m_functionFlags);
00163 }
00164
00165 bool ClassFunctionDeclaration::isConversionFunction() const {
00166 return identifier() == conversionIdentifier;
00167 }
00168
00169 bool ClassFunctionDeclaration::isConstructor() const
00170 {
00171 DUContext* ctx = context();
00172 if (ctx && ctx->type() == DUContext::Class && ctx->localScopeIdentifier().top().nameEquals(identifier()))
00173 return true;
00174 return false;
00175 }
00176
00177 bool ClassFunctionDeclaration::isDestructor() const
00178 {
00179 DUContext* ctx = context();
00180 QString id = identifier().toString();
00181 return ctx && ctx->type() == DUContext::Class && id.startsWith('~') && id.mid(1) == ctx->localScopeIdentifier().top().toString();
00182 }
00183
00184 uint ClassFunctionDeclaration::additionalIdentity() const
00185 {
00186 if(abstractType())
00187 return abstractType()->hash();
00188 else
00189 return 0;
00190 }
00191
00192 const IndexedString* ClassFunctionDeclaration::defaultParameters() const
00193 {
00194 return d_func()->m_defaultParameters();
00195 }
00196
00197 unsigned int ClassFunctionDeclaration::defaultParametersSize() const
00198 {
00199 return d_func()->m_defaultParametersSize();
00200 }
00201
00202 void ClassFunctionDeclaration::addDefaultParameter(const IndexedString& str)
00203 {
00204 d_func_dynamic()->m_defaultParametersList().append(str);
00205 }
00206
00207 void ClassFunctionDeclaration::clearDefaultParameters()
00208 {
00209 d_func_dynamic()->m_defaultParametersList().clear();
00210 }
00211
00212 }
00213