#ifndef CppTagModel_H
#define CppTagModel_H
#include "smart_ptr.h"
#include "stl_ext.h"
#include <string>
#include <list>
#include <map>
#include <iostream>
#include <Model/FullQualifiedName.h>
#include <Model/HierarchyLoader.h>
typedef enum {ePublic = 0x01, eProtected = 0x02, ePrivate = 0x04} AccessQualifier;
typedef enum {eDefault, eVirtual, eAbstract } ImplementationQualifier;
typedef enum { eNamespace = 0x0001,
eClass = 0x0002,
eStruct = 0x0004,
eUnion = 0x0008,
eEnum = 0x0010,
eTypedef = 0x0020,
eEnumMember = 0x0040,
eField = 0x0080,
eVariable = 0x0100,
eMethod = 0x0200,
eFunction = 0x0400,
} CppTagType;
class CppTagVisitor;
template<class VisitorPolicy> class InheritableX;
struct ClassVisitorPolicy;
struct StructVisitorPolicy;
struct UnionVisitorPolicy;
class Namespace;
typedef InheritableX<ClassVisitorPolicy> Class;
typedef InheritableX<StructVisitorPolicy> Struct;
typedef InheritableX<UnionVisitorPolicy> Union;
class Enum;
class Typedef;
class Field;
class Method;
class Variable;
class Function;
#include "CppTagVisitor.h"
#include "CppTagModelPolicies.h"
class TagLocation
{
private:
std::string file;
size_t line;
size_t column;
public:
TagLocation(const std::string& n = "", size_t l = 0, size_t c = 0)
: file(n), line(l), column(c) {};
const std::string& getFile() const { return file; }
size_t getLine() const { return line; }
size_t getColumn() const { return column; }
};
class CppTag : public AccessPolicy
{
private:
TagLocation mDeclaration;
TagLocation mDefinition;
FullQualifiedName mFQN;
smart_ptr<CppTag> mScope;
std::list<smart_ptr<CppTag> > mInnerTags;
AccessQualifier mAccessQualifier;
mutable long mHash;
public:
CppTag();
CppTag(const std::string &name, AccessQualifier access = ePublic);
virtual ~CppTag();
virtual void acceptVisitor(CppTagVisitor *) = 0;
const TagLocation& getDeclaration() const { return mDeclaration; }
void setDeclaration(const TagLocation& info) { mDeclaration = info; }
const TagLocation& getDefinition() const { return mDefinition; }
void setDefinition(const TagLocation &info) { mDefinition = info; }
const std::string& getName() const { return mFQN.getName(); };
const std::string& getScopeName() const { return mFQN.getScope(); }
smart_ptr<CppTag> getScope() const { return mScope; }
void setScope(const smart_ptr<CppTag>& scope) { mScope = scope; }
const FullQualifiedName& getFQN() const { return mFQN; }
const std::list<smart_ptr<CppTag> >& getInnerTags() const { return mInnerTags; };
std::list<smart_ptr<CppTag> >& getInnerTags() { return mInnerTags; };
void setInnerTags(const std::list<smart_ptr<CppTag> >& tags) { mInnerTags = tags;}
virtual long hash(bool weak = false) const
{ if(mHash == 0) mHash = generateHash(weak); return mHash; }
virtual bool equals(const CppTag& other) const
{ return this->hash() == other.hash(); }
protected:
virtual long generateHash(bool weak) const;
};
class Variable : public CppTag, public ConstStaticPolicy
{
private:
std::string mType;
public:
Variable(const std::string &type, const std::string &name);
~Variable();
const std::string& getType() const { return mType; };;
void acceptVisitor(CppTagVisitor *v);
};
class Field : public Variable
{
public:
Field(const std::string &type, const std::string &name);
virtual ~Field();
void acceptVisitor(CppTagVisitor *v);
};
class Function : public CppTag
{
private:
std::string mReturnType;
std::list<Field> mParameters;
public:
Function(const std::string& returnType, const std::string &name, const TagLocation&);
Function(const std::string& returnType, const std::string &name, std::list<Field> ¶meters);
virtual ~Function();
const std::string& getReturnType() const { return mReturnType; };;
const std::list<Field>& getParameters() const { return mParameters; };;
void acceptVisitor(CppTagVisitor *v);
};
class Method : public Function, public ConstStaticPolicy, public ImplementationPolicy
{
private:
public:
Method(const std::string& returnType, const std::string &name, AccessQualifier aq, const TagLocation&);
Method(const std::string& returnType, const std::string &name, std::list<Field> ¶meters);
virtual ~Method();
void acceptVisitor(CppTagVisitor *v);
private:
virtual long generateHash(bool weak = false) const;
};
class CppType : public CppTag
{
public:
CppType();
CppType(const std::string &name, AccessQualifier aq, const TagLocation &decl = TagLocation());
virtual ~CppType();
};
class Namespace : public CppType
{
public:
Namespace(const std::string &name);
void acceptVisitor(CppTagVisitor *v);
};
class Inheritable : public CppType
{
private:
mutable std::list<smart_ptr<Inheritable> > mExtendors;
mutable std::list<smart_ptr<Inheritable> > mParents;
smart_ptr<HierarchyLoader> mHierarchyLoader;
public:
Inheritable(const std::string &name, AccessQualifier access, const TagLocation &decl = TagLocation())
: CppType(name, access, decl) {}
Inheritable(const std::string name, const std::list<Field> &fields,const std::list<Method> &methods)
: CppType(name, ePublic) {}
void setHierarchyLoader(const smart_ptr<HierarchyLoader> &hl)
{ mHierarchyLoader = hl; }
void setExtendors(const std::list<smart_ptr<Inheritable> >& e)
{ mExtendors = e; }
const std::list<smart_ptr<Inheritable> >& getExtendors() const;
void setParents(const std::list<smart_ptr<Inheritable> >& p)
{ mParents = p; }
const std::list<smart_ptr<Inheritable> >& getParents() const;
std::map<long, std::list<smart_ptr<CppTag> > > getMembers(bool inherited = false) const;
};
template<class VisitorPolicy>
class InheritableX : public Inheritable, protected VisitorPolicy
{
private:
public:
InheritableX(const std::string &name, AccessQualifier access, const TagLocation &decl)
: Inheritable(name, access, decl)
{
}
InheritableX(const std::string name, const std::list<Field> &fields,const std::list<Method> &methods)
: Inheritable(name, ePublic)
{
smart_ptr<Field>(*make_field)(const Field&) = make_smart_ptr<Field>;
smart_ptr<Method>(*make_method)(const Method&) = make_smart_ptr<Method>;
transform(fields.begin(), fields.end(), back_inserter(getInnerTags()), make_field);
transform(methods.begin(), methods.end(), back_inserter(getInnerTags()),make_method);
}
virtual ~InheritableX() {};
std::list<smart_ptr<Field> > getFields() const
{ return selectInnerTags(eField, (Field*)NULL); }
void addField(const Field &f)
{ getInnerTags().push_back(smart_ptr<CppTag>(new Field(f))); };
std::list<smart_ptr<Method> > getMethods() const
{ return selectInnerTags(eMethod, (Method*)NULL); }
void addMethod(const Method &m)
{ getInnerTags().push_back(make_smart_ptr(m)); };
std::list<smart_ptr<CppType> > getTypes() const
{ return selectInnerTags(eClass | eStruct | eUnion | eEnum | eTypedef, (CppType*)NULL); }
void acceptVisitor(CppTagVisitor *v)
{ VisitorPolicy::acceptVisitor(v, this); }
protected:
template<class T>
std::list<smart_ptr<T> > selectInnerTags(size_t type, T*dummy) const
{
TagTyper tagTyper;
std::list<smart_ptr<T> > result;
typedef std::list<smart_ptr<CppTag> > TagList;
for(TagList::const_iterator tag = getInnerTags().begin(); tag != getInnerTags().end(); tag++) {
(*tag)->acceptVisitor(&tagTyper);
if(tagTyper.getType() & type) {
result.push_back(Dynamic_cast<T>(*tag));
}
}
return result;
}
};
class Typedef : public CppType
{
public:
Typedef(const std::string &name, AccessQualifier access, const TagLocation &decl);
virtual ~Typedef();
void acceptVisitor(CppTagVisitor *v);
};
class Enum : public CppType
{
private:
std::list<std::string> mValues;
public:
Enum(const std::string &name, AccessQualifier access, const TagLocation &decl);
virtual ~Enum();
void setValues(const std::list<std::string>& values);
const std::list<std::string>& getValues() const;
std::list<std::string>& getValues();
void acceptVisitor(CppTagVisitor *v);
};
template<class T>
struct CppTagScopeSorter : std::binary_function<smart_ptr<T>, smart_ptr<T>, bool> {
bool operator()(const smart_ptr<T>& lhs, const smart_ptr<T> &rhs) const
{ return lhs->getScopeName() < rhs->getScopeName(); }
};
template<class T>
struct CppTagNameSorter : std::binary_function<smart_ptr<T>, smart_ptr<T>, bool> {
bool operator()(const smart_ptr<T>& lhs, const smart_ptr<T> &rhs) const
{ return lhs->getName() < rhs->getName(); }
};
template<class T>
struct CppTagFQNSorter : std::binary_function<smart_ptr<T>, smart_ptr<T>, bool> {
bool operator()(const smart_ptr<T>& lhs, const smart_ptr<T> &rhs) const
{ return lhs->getFQN() < rhs->getFQN(); }
};
class TagCloner : public CppTagVisitor
{
private:
smart_ptr<CppTag> mClone;
public:
const smart_ptr<CppTag>& getClone() { return mClone; }
virtual void visitNamespace(Namespace *n) { setClone(smart_ptr<CppTag>(new Namespace(*n))); }
virtual void visitClass(Class *c) { setClone(smart_ptr<CppTag>(new Class(*c))); }
virtual void visitStruct(Struct *s) { setClone(smart_ptr<CppTag>(new Struct(*s))); }
virtual void visitUnion(Union *u) { setClone(smart_ptr<CppTag>(new Union(*u))); }
virtual void visitEnum(Enum *e) { setClone(smart_ptr<CppTag>(new Enum(*e))); }
virtual void visitTypedef(Typedef *t) { setClone(smart_ptr<CppTag>(new Typedef(*t))); }
virtual void visitField(Field *f) { setClone(smart_ptr<CppTag>(new Field(*f))); }
virtual void visitVariable(Variable *v) { setClone(smart_ptr<CppTag>(new Variable(*v))); }
virtual void visitMethod(Method *m) { setClone(smart_ptr<CppTag>(new Method(*m))); }
virtual void visitFunction(Function*f) { setClone(smart_ptr<CppTag>(new Function(*f))); }
private:
void setClone(const smart_ptr<CppTag>& c) { mClone = c; }
};
#endif