language/duchain
abstracttypebuilder.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef ABSTRACTTYPEBUILDER_H
00020 #define ABSTRACTTYPEBUILDER_H
00021
00022 #include "../types/structuretype.h"
00023 #include "../declaration.h"
00024 #include "../duchain.h"
00025 #include "../duchainlock.h"
00026
00027 namespace KDevelop {
00028
00041 template<typename T, typename NameT, typename LangugageSpecificTypeBuilderBase>
00042 class AbstractTypeBuilder : public LangugageSpecificTypeBuilderBase
00043 {
00044 public:
00052 const QList< KDevelop::AbstractType::Ptr >& topTypes() const
00053 {
00054 return m_topTypes;
00055 }
00056
00057 protected:
00064 virtual DUContext* searchContext() const
00065 {
00066 return LangugageSpecificTypeBuilderBase::currentContext();
00067 }
00068
00075 virtual void classTypeOpened(KDevelop::AbstractType::Ptr) {}
00076
00081 virtual void supportBuild(T* node, DUContext* context = 0)
00082 {
00083 m_topTypes.clear();
00084
00085 LangugageSpecificTypeBuilderBase::supportBuild(node, context);
00086
00087 Q_ASSERT(m_typeStack.isEmpty());
00088 }
00089
00094 KDevelop::AbstractType::Ptr lastType() const
00095 {
00096 return m_lastType;
00097 }
00098
00104 void setLastType(KDevelop::AbstractType::Ptr ptr)
00105 {
00106 m_lastType = ptr;
00107 }
00108
00110 void clearLastType()
00111 {
00112 m_lastType = 0;
00113 }
00114
00119 void injectType(const KDevelop::AbstractType::Ptr& type)
00120 {
00121 openType(type);
00122 closeType();
00123 }
00124
00129 template <class T2>
00130 void injectType(const TypePtr<T2>& type)
00131 { injectType(KDevelop::AbstractType::Ptr::staticCast(type)); }
00132
00136 template <class T2>
00137 void openType(TypePtr<T2> type)
00138 { openAbstractType(KDevelop::AbstractType::Ptr::staticCast(type)); }
00139
00143 void openAbstractType(KDevelop::AbstractType::Ptr type)
00144 {
00145 m_typeStack.append(type);
00146 }
00147
00151 void closeType()
00152 {
00153 m_lastType = currentAbstractType();
00154
00155 bool replaced = m_lastType != currentAbstractType();
00156
00157
00158 m_typeStack.pop();
00159
00160 if (!hasCurrentType() && !replaced)
00161 m_topTypes.append(m_lastType);
00162 }
00163
00165 inline bool hasCurrentType() { return !m_typeStack.isEmpty(); }
00166
00174 inline KDevelop::AbstractType::Ptr currentAbstractType() { return m_typeStack.top(); }
00175
00183 template <class T2>
00184 TypePtr<T2> currentType() { return TypePtr<T2>::dynamicCast(m_typeStack.top()); }
00185
00194 bool openTypeFromName(NameT* name, bool needClass)
00195 {
00196 return openTypeFromName(identifierForNode(name), name, needClass);
00197 }
00198
00208 bool openTypeFromName(QualifiedIdentifier id, T* typeNode, bool needClass)
00209 {
00210 bool openedType = false;
00211
00212 bool delay = false;
00213
00214 if(!delay) {
00215 SimpleCursor pos(editorFindRange(typeNode, typeNode).start());
00216 DUChainReadLocker lock(DUChain::lock());
00217
00218 QList<Declaration*> dec = searchContext()->findDeclarations(id, pos);
00219
00220 if ( dec.isEmpty() )
00221 delay = true;
00222
00223 if(!delay) {
00224 foreach( Declaration* decl, dec ) {
00225
00226 if( needClass && !decl->abstractType().cast(static_cast<StructureType *>(0)) )
00227 continue;
00228
00229 if (decl->abstractType() ) {
00231
00232
00233 openedType = true;
00234 openType(decl->abstractType());
00235 break;
00236 }
00237 }
00238 }
00239
00240 if(!openedType)
00241 delay = true;
00242 }
00244
00245
00246
00247
00248
00249
00250
00251
00252 return openedType;
00253 }
00254
00255 private:
00256 QStack<KDevelop::AbstractType::Ptr> m_typeStack;
00257
00258 KDevelop::AbstractType::Ptr m_lastType;
00259
00260 QList<KDevelop::AbstractType::Ptr> m_topTypes;
00261 };
00262
00263 }
00264
00265 #endif // ABSTRACTTYPEBUILDER_H
00266