File indexing completed on 2024-05-12 04:37:56
0001 /* 0002 SPDX-FileCopyrightText: 2002-2005 Roberto Raggi <roberto@kdevelop.org> 0003 SPDX-FileCopyrightText: 2006 Adam Treat <treat@kde.org> 0004 SPDX-FileCopyrightText: 2006 Hamish Rodda <rodda@kde.org> 0005 SPDX-FileCopyrightText: 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de> 0006 0007 SPDX-License-Identifier: LGPL-2.0-only 0008 */ 0009 0010 #include "classfunctiondeclaration.h" 0011 #include "ducontext.h" 0012 #include "types/functiontype.h" 0013 #include "duchainregister.h" 0014 #include <debug.h> 0015 0016 namespace KDevelop { 0017 static Identifier& conversionIdentifier() 0018 { 0019 static Identifier conversionIdentifierObject(QStringLiteral("operator{...cast...}")); 0020 return conversionIdentifierObject; 0021 } 0022 0023 REGISTER_DUCHAIN_ITEM(ClassFunctionDeclaration); 0024 0025 ClassFunctionDeclaration::ClassFunctionDeclaration(const ClassFunctionDeclaration& rhs) 0026 : ClassFunctionDeclarationBase(*new ClassFunctionDeclarationData(*rhs.d_func())) 0027 { 0028 } 0029 0030 void ClassFunctionDeclaration::setAbstractType(AbstractType::Ptr type) 0031 { 0032 ///TODO: write testcase for typealias case which used to trigger this warning: 0033 /// typedef bool (*EventFilter)(void *message, long *result); 0034 /// in e.g. qcoreapplication.h:172 0035 if (type && !dynamic_cast<FunctionType*>(type.data()) && type->whichType() != AbstractType::TypeAlias) { 0036 qCWarning(LANGUAGE) << "WARNING: Non-function type assigned to function declaration. Type is: " 0037 << type->toString() << "whichType:" << type->whichType() 0038 << "Declaration is:" << toString() 0039 << topContext()->url().str() << range().castToSimpleRange(); 0040 } 0041 ClassMemberDeclaration::setAbstractType(type); 0042 } 0043 0044 DEFINE_LIST_MEMBER_HASH(ClassFunctionDeclarationData, m_defaultParameters, IndexedString) 0045 0046 ClassFunctionDeclaration::ClassFunctionDeclaration(ClassFunctionDeclarationData& data) : ClassFunctionDeclarationBase( 0047 data) 0048 { 0049 } 0050 0051 ClassFunctionDeclaration::ClassFunctionDeclaration(const RangeInRevision& range, DUContext* context) 0052 : ClassFunctionDeclarationBase(*new ClassFunctionDeclarationData, range) 0053 { 0054 d_func_dynamic()->setClassId(this); 0055 if (context) 0056 setContext(context); 0057 } 0058 0059 ClassFunctionDeclaration::ClassFunctionDeclaration(ClassFunctionDeclarationData& data, const RangeInRevision& range, 0060 DUContext* context) 0061 : ClassFunctionDeclarationBase(data, range) 0062 { 0063 if (context) 0064 setContext(context); 0065 } 0066 0067 Declaration* ClassFunctionDeclaration::clonePrivate() const 0068 { 0069 return new ClassFunctionDeclaration(*this); 0070 } 0071 0072 ClassFunctionDeclaration::~ClassFunctionDeclaration() 0073 { 0074 } 0075 0076 bool ClassFunctionDeclaration::isFunctionDeclaration() const 0077 { 0078 return true; 0079 } 0080 0081 QString ClassFunctionDeclaration::toString() const 0082 { 0083 if (!abstractType()) 0084 return ClassMemberDeclaration::toString(); 0085 0086 TypePtr<FunctionType> function = type<FunctionType>(); 0087 if (function) { 0088 return QStringLiteral("%1 %2 %3").arg(function->partToString(FunctionType::SignatureReturn), 0089 identifier().toString(), 0090 function->partToString(FunctionType::SignatureArguments)); 0091 } else { 0092 QString type = abstractType() ? abstractType()->toString() : QStringLiteral("<notype>"); 0093 qCDebug(LANGUAGE) << "A function has a bad type attached:" << type; 0094 return i18n("invalid member-function %1 type %2", identifier().toString(), type); 0095 } 0096 } 0097 0098 /*bool ClassFunctionDeclaration::isSimilar(KDevelop::CodeItem *other, bool strict ) const 0099 { 0100 if (!CppClassMemberType::isSimilar(other,strict)) 0101 return false; 0102 0103 FunctionModelItem func = dynamic_cast<ClassFunctionDeclaration*>(other); 0104 0105 if (isConstant() != func->isConstant()) 0106 return false; 0107 0108 if (arguments().count() != func->arguments().count()) 0109 return false; 0110 0111 for (int i=0; i<arguments().count(); ++i) 0112 { 0113 ArgumentModelItem arg1 = arguments().at(i); 0114 ArgumentModelItem arg2 = arguments().at(i); 0115 0116 if (arg1->type() != arg2->type()) 0117 return false; 0118 } 0119 0120 return true; 0121 }*/ 0122 0123 uint setFlag(bool enable, uint flag, uint flags) 0124 { 0125 if (enable) 0126 return flags | flag; 0127 else 0128 return flags & (~flag); 0129 } 0130 0131 bool ClassFunctionDeclaration::isAbstract() const 0132 { 0133 return d_func()->m_functionFlags & AbstractFunctionFlag; 0134 } 0135 0136 void ClassFunctionDeclaration::setIsAbstract(bool abstract) 0137 { 0138 d_func_dynamic()->m_functionFlags = ( ClassFunctionFlags )setFlag(abstract, AbstractFunctionFlag, 0139 d_func()->m_functionFlags); 0140 } 0141 0142 bool ClassFunctionDeclaration::isFinal() const 0143 { 0144 return d_func()->m_functionFlags & FinalFunctionFlag; 0145 } 0146 0147 void ClassFunctionDeclaration::setIsFinal(bool final) 0148 { 0149 d_func_dynamic()->m_functionFlags = ( ClassFunctionFlags )setFlag(final, FinalFunctionFlag, 0150 d_func()->m_functionFlags); 0151 } 0152 0153 bool ClassFunctionDeclaration::isSignal() const 0154 { 0155 return d_func()->m_functionFlags & FunctionSignalFlag; 0156 } 0157 0158 void ClassFunctionDeclaration::setIsSignal(bool isSignal) 0159 { 0160 d_func_dynamic()->m_functionFlags = ( ClassFunctionFlags )setFlag(isSignal, FunctionSignalFlag, 0161 d_func()->m_functionFlags); 0162 } 0163 0164 bool ClassFunctionDeclaration::isSlot() const 0165 { 0166 return d_func()->m_functionFlags & FunctionSlotFlag; 0167 } 0168 0169 void ClassFunctionDeclaration::setIsSlot(bool isSlot) 0170 { 0171 d_func_dynamic()->m_functionFlags = ( ClassFunctionFlags )setFlag(isSlot, FunctionSlotFlag, 0172 d_func()->m_functionFlags); 0173 } 0174 0175 bool ClassFunctionDeclaration::isConversionFunction() const 0176 { 0177 return identifier() == conversionIdentifier(); 0178 } 0179 0180 bool ClassFunctionDeclaration::isConstructor() const 0181 { 0182 DUContext* ctx = context(); 0183 if (ctx && ctx->type() == DUContext::Class && ctx->localScopeIdentifier().top().nameEquals(identifier())) 0184 return true; 0185 return false; 0186 } 0187 0188 bool ClassFunctionDeclaration::isDestructor() const 0189 { 0190 DUContext* ctx = context(); 0191 QString id = identifier().toString(); 0192 return ctx && ctx->type() == DUContext::Class && id.startsWith(QLatin1Char('~')) && 0193 id.midRef(1) == ctx->localScopeIdentifier().top().toString(); 0194 } 0195 0196 uint ClassFunctionDeclaration::additionalIdentity() const 0197 { 0198 if (abstractType()) 0199 return abstractType()->hash(); 0200 else 0201 return 0; 0202 } 0203 0204 const IndexedString* ClassFunctionDeclaration::defaultParameters() const 0205 { 0206 return d_func()->m_defaultParameters(); 0207 } 0208 0209 unsigned int ClassFunctionDeclaration::defaultParametersSize() const 0210 { 0211 return d_func()->m_defaultParametersSize(); 0212 } 0213 0214 void ClassFunctionDeclaration::addDefaultParameter(const IndexedString& str) 0215 { 0216 d_func_dynamic()->m_defaultParametersList().append(str); 0217 } 0218 0219 void ClassFunctionDeclaration::clearDefaultParameters() 0220 { 0221 d_func_dynamic()->m_defaultParametersList().clear(); 0222 } 0223 }