language/duchain
classdeclaration.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "classdeclaration.h"
00021 #include <language/duchain/identifier.h>
00022 #include <language/duchain/declaration.h>
00023 #include <language/duchain/appendedlist.h>
00024 #include <language/duchain/duchainregister.h>
00025
00026
00027 namespace KDevelop {
00028
00029 DEFINE_LIST_MEMBER_HASH(ClassDeclarationData, baseClasses, BaseClassInstance)
00030
00031
00032 ClassDeclaration::ClassDeclaration(const KDevelop::SimpleRange& range, DUContext* context)
00033 : ClassMemberDeclaration(*new ClassDeclarationData, range)
00034 {
00035 d_func_dynamic()->setClassId(this);
00036 setContext(context);
00037 }
00038
00039 ClassDeclaration::ClassDeclaration( ClassDeclarationData& data, const KDevelop::SimpleRange& range, DUContext* context )
00040 : ClassMemberDeclaration( data, range )
00041 {
00042 setContext(context);
00043 }
00044
00045 ClassDeclaration::ClassDeclaration(ClassDeclarationData& data)
00046 : ClassMemberDeclaration(data)
00047 {
00048 }
00049
00050 REGISTER_DUCHAIN_ITEM(ClassDeclaration);
00051
00052 void ClassDeclaration::clearBaseClasses() {
00053 d_func_dynamic()->baseClassesList().clear();
00054 }
00055
00056 uint ClassDeclaration::baseClassesSize() const {
00057 return d_func()->baseClassesSize();
00058 }
00059
00060 const BaseClassInstance* ClassDeclaration::baseClasses() const {
00061 return d_func()->baseClasses();
00062 }
00063
00064 void ClassDeclaration::addBaseClass(BaseClassInstance klass) {
00065 d_func_dynamic()->baseClassesList().append(klass);
00066 }
00067
00068 void ClassDeclaration::replaceBaseClass(uint n, BaseClassInstance klass) {
00069 Q_ASSERT(n <= d_func()->baseClassesSize());
00070 d_func_dynamic()->baseClassesList()[n] = klass;
00071 }
00072
00073 ClassDeclaration::~ClassDeclaration()
00074 {
00075 }
00076
00077 ClassDeclaration::ClassDeclaration(const ClassDeclaration& rhs) : ClassMemberDeclaration(*new ClassDeclarationData(*rhs.d_func())) {
00078 d_func_dynamic()->setClassId(this);
00079 }
00080
00081 Declaration* ClassDeclaration::clonePrivate() const {
00082 return new ClassDeclaration(*this);
00083 }
00084
00085 bool ClassDeclaration::isPublicBaseClass( ClassDeclaration* base, const KDevelop::TopDUContext* topContext, int* baseConversionLevels ) const {
00086 if( baseConversionLevels )
00087 *baseConversionLevels = 0;
00088
00089 if( indexedType() == base->indexedType() )
00090 return true;
00091
00092 FOREACH_FUNCTION(const BaseClassInstance& b, baseClasses)
00093 {
00094 if( baseConversionLevels )
00095 ++ (*baseConversionLevels);
00096
00097 if( b.access != KDevelop::Declaration::Private ) {
00098 int nextBaseConversion = 0;
00099 if( StructureType::Ptr c = b.baseClass.type<StructureType>() ) {
00100 ClassDeclaration* decl = dynamic_cast<ClassDeclaration*>(c->declaration(topContext));
00101 if( decl && decl->isPublicBaseClass( base, topContext, &nextBaseConversion ) ) {
00102 if ( baseConversionLevels )
00103 *baseConversionLevels += nextBaseConversion;
00104 return true;
00105 }
00106 }
00107 }
00108 if( baseConversionLevels )
00109 -- (*baseConversionLevels);
00110 }
00111 return false;
00112 }
00113
00114 QString ClassDeclaration::toString() const {
00115 QString ret;
00116 switch ( classModifier() ) {
00117 case ClassDeclarationData::None:
00118
00119 break;
00120 case ClassDeclarationData::Abstract:
00121 ret += "abstract ";
00122 break;
00123 case ClassDeclarationData::Final:
00124 ret += "final ";
00125 break;
00126 }
00127 switch ( classType() ) {
00128 case ClassDeclarationData::Class:
00129 ret += "class ";
00130 break;
00131 case ClassDeclarationData::Interface:
00132 ret += "interface ";
00133 break;
00134 case ClassDeclarationData::Union:
00135 ret += "union ";
00136 break;
00137 case ClassDeclarationData::Struct:
00138 ret += "struct ";
00139 break;
00140 }
00141 return ret + identifier().toString();
00142 }
00143
00144 ClassDeclarationData::ClassType ClassDeclaration::classType() const {
00145 return d_func()->m_classType;
00146 }
00147
00148 void ClassDeclaration::setClassType(ClassDeclarationData::ClassType type) {
00149 d_func_dynamic()->m_classType = type;
00150 }
00151
00152 ClassDeclarationData::ClassModifier ClassDeclaration::classModifier() const {
00153 return d_func()->m_classModifier;
00154 }
00155
00156 void ClassDeclaration::setClassModifier(ClassDeclarationData::ClassModifier modifier) {
00157 d_func_dynamic()->m_classModifier = modifier;
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 }