/**************************************************************************** ** ** Copyright (C) 2001-2004 Roberto Raggi ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the qt3to4 porting application of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef CODEMODEL_H #define CODEMODEL_H #include "smallobject.h" #include "tokenengine.h" #include #include #include #include QT_BEGIN_NAMESPACE namespace CodeModel { // types struct Type; struct EnumType; struct EnumeratorType; struct ClassType; struct BuiltinType; struct PointerType; struct ReferenceType; struct GenericType; struct AliasType; struct FunctionType; struct UnknownType; // Scopes contain child scopes, members and types. struct Scope; struct ClassScope; struct NamespaceScope; struct BlockScope; // Members introduces names into scopes, and are also linked to a specific // token in a source file. struct Member; struct FunctionMember; struct VariableMember; struct UsingDeclarationMember; struct NamespaceMember; struct TypeMember; // Name uses links uses of a name to its declaration (a Member), and also to a // token in a source file. struct NameUse; struct Argument; struct UsingDirectiveLink; template class Collection: public QMultiHash { public: void add(CollectedType *collectedItem) { this->insert(collectedItem->name(), collectedItem); } }; typedef Collection ScopeCollection; typedef Collection MemberCollection; typedef Collection TypeCollection; typedef Collection NameUseCollection; typedef Collection ArgumentCollection; struct SemanticInfo { CodeModel::NamespaceScope *codeModel; // tokenindex -> NameUse* map. Use map here bacause we expect name uses to // be sparesly distributed among the tokens. QMap nameUses; }; struct Item { Item() {} virtual ~Item() {} virtual QByteArray name() const = 0; }; struct Type: public Item { virtual QByteArray name() const =0; virtual EnumType *toEnumType() const { return 0; } virtual ClassType *toClassType() const { return 0; } virtual UnknownType *toUnknownType() const { return 0; } virtual BuiltinType *toBuiltinType() const { return 0; } virtual PointerType *toPointerType() const { return 0; } virtual ReferenceType *toReferenceType() const { return 0; } virtual GenericType *toGenericType() const { return 0; } virtual AliasType *toAliasType() const { return 0; } }; struct Scope: public Item { Scope() : m_parent(0) {} void setParent(Scope *parent) { m_parent = parent; } Scope *parent() const { return m_parent; } QByteArray name() const { return m_name; } void setName(const QByteArray &name) { m_name=name; } virtual NamespaceScope *toNamespaceScope() const { return 0; } virtual ClassScope *toClassScope() const { return 0; } virtual BlockScope *toBlockScope() const { return 0; } const Collection scopes() const { return m_scopes; } const Collection types() const { return m_types; } const Collection members() const { return m_members; } const Collection nameUses() const { return m_nameUses; } void addScope(Scope *scope); void addType(Type *type); void addMember(Member *member); void addNameUse(NameUse *nameUse); private: Scope *m_parent; QByteArray m_name; Collection m_scopes; Collection m_types; Collection m_members; Collection m_nameUses; }; struct Member: public Item { enum Binding // ### not used yet { Static, Instance }; enum Access // ### not used yet { Public, Protected, Private }; Member() : m_binding(Static), m_access(Public), m_parent(0), m_constant(0), m_static(0) {} QByteArray name() const { return m_name; } void setName(const QByteArray &name) { m_name = name; } TokenEngine::TokenRef nameToken() const { return m_nameToken; } void setNameToken(TokenEngine::TokenRef nameToken) { m_nameToken = nameToken; } Binding binding() const { return m_binding; } void setBinding(Binding binding) { m_binding = binding; } Access access() const { return m_access; } void setAccess(Access access) { m_access = access; } bool isConstant() const { return m_constant; } void setConstant(bool b) { m_constant = b; } bool isStatic() const { return m_static; } void setStatic(bool b) { m_static = b; } Scope *parent() const { return m_parent; } void setParent(Scope *parent) { m_parent = parent; } virtual FunctionMember *toFunctionMember() const { return 0; } virtual VariableMember *toVariableMember() const { return 0; } virtual UsingDeclarationMember *toUsingDeclarationMember() const { return 0; } virtual NamespaceMember *toNamespaceMember() const { return 0; } virtual TypeMember *toTypeMember() const { return 0; } private: Binding m_binding; Access m_access; Scope *m_parent; QByteArray m_name; TokenEngine::TokenRef m_nameToken; uint m_constant : 1; uint m_static : 1; }; struct ClassScope: public Scope { const Collection baseClasses() const { return m_baseClasses; } void addBaseClass(Type *baseClass) { Q_ASSERT(baseClass->toClassType()); m_baseClasses.add(baseClass); } virtual ClassScope *toClassScope() const { return const_cast(this); } private: Collection m_baseClasses; }; struct UsingDirectiveLinkable : public Scope { const QList usingDirectiveLinks() const { return m_usingDirectiveLinks; } void addUsingDirectiveLink(UsingDirectiveLink *usingDirectiveLink) { m_usingDirectiveLinks.append(usingDirectiveLink); } private: QList m_usingDirectiveLinks; }; struct NamespaceScope: public UsingDirectiveLinkable { NamespaceScope() {} virtual NamespaceScope *toNamespaceScope() const { return const_cast(this); } }; struct BlockScope: public UsingDirectiveLinkable { BlockScope() {} virtual BlockScope *toBlockScope() const { return const_cast(this); } }; struct EnumType: public Type { EnumType() : m_parent(0) {} QByteArray name() const { return m_name; } void setName(const QByteArray &name) { m_name = name; } Scope *parent() const { return m_parent; } void setParent(Scope *parent) { m_parent = parent; } virtual EnumType *toEnumType() const { return const_cast(this); } private: Scope *m_parent; QByteArray m_name; }; struct UnknownType: public Type { UnknownType() : m_parent(0) {} QByteArray name() const { return m_name; } void setName(const QByteArray &name) { m_name = name; } Scope *parent() const { return m_parent; } void setParent(Scope *parent) { m_parent = parent; } virtual UnknownType *toUnknownType() const { return const_cast(this); } private: Scope *m_parent; QByteArray m_name; }; struct ClassType: public Type { ClassType() : m_parent(0), m_scope(0) {} ClassScope *scope() const { return m_scope; } void setScope(ClassScope *scope) { m_scope = scope; } QByteArray name() const { return m_scope ? m_scope->name() : /*anonymous*/ QByteArray(); } Scope *parent() const { return m_parent; } void setParent(Scope *parent) { m_parent = parent; } virtual ClassType *toClassType() const { return const_cast(this); } private: Scope *m_parent; ClassScope *m_scope; }; struct BuiltinType: public Type { protected: BuiltinType(const QByteArray &name, Scope *parent) : m_name(name), m_parent(parent) {} public: QByteArray name() const { return m_name; } Scope *parent() const { return m_parent; } virtual BuiltinType *toBuiltinType() const { return const_cast(this); } static BuiltinType Bool; static BuiltinType Void; static BuiltinType Char; static BuiltinType Short; static BuiltinType Int; static BuiltinType Long; static BuiltinType Double; static BuiltinType Float; static BuiltinType Unsigned; static BuiltinType Signed; // ### more private: QByteArray m_name; Scope *m_parent; }; struct PointerType: public Type { PointerType() : m_parent(0), m_baseType(0) {} Type *baseType() const { return m_baseType; } void setBaseType(Type *baseType) { m_baseType = baseType; } QByteArray name() const { return m_baseType->name(); } Scope *parent() const { return m_parent; } void setParent(Scope *parent) { m_parent = parent; } virtual PointerType *toPointerType() const { return const_cast(this); } private: Scope *m_parent; Type *m_baseType; }; struct ReferenceType: public Type { ReferenceType() : m_parent(0), m_baseType(0) {} Type *baseType() const { return m_baseType; } void setBaseType(Type *baseType) { m_baseType = baseType; } QByteArray name() const { return m_baseType->name(); } Scope *parent() const { return m_parent; } void setParent(Scope *parent) { m_parent = parent; } virtual ReferenceType *toReferenceType() const { return const_cast(this); } private: Scope *m_parent; Type *m_baseType; }; struct GenericType: public Type // ### implement me { virtual GenericType *toGenericType() const { return const_cast(this); } }; struct AliasType: public Type // ### implement me { AliasType () : m_parent(0) {} QByteArray name() const { return m_name; } Scope *parent() const { return m_parent; } virtual AliasType *toAliasType() const { return const_cast(this); } private: QByteArray m_name; Scope *m_parent; }; struct Argument: public Item { Argument() : m_parent(0), m_type(0) {} Type *type() const { return m_type; } void setType(Type *type) { m_type = type; } QByteArray name() const { return m_name; } void setName(const QByteArray &name) { m_name = name; } TokenEngine::TokenRef nameToken() const { return m_nameToken; } void setNameToken(TokenEngine::TokenRef nameToken) { m_nameToken = nameToken; } virtual FunctionMember *parent() const { return m_parent; } void setParent(FunctionMember *parent) { m_parent = parent; } private: FunctionMember *m_parent; Type *m_type; QByteArray m_name; TokenEngine::TokenRef m_nameToken; }; struct FunctionMember: public Member { inline FunctionMember() : m_returnType(0), m_functionBodyScope(0), m_signal(0), m_virtual(0), m_abstract(0) { m_slot = 0; } virtual FunctionMember *toFunctionMember() const { return const_cast(this); } Type *returnType() const { return m_returnType; } void setReturnType(Type *type) { m_returnType = type; } const Collection arguments() const { return m_arguments; } void addArgument(Argument *argument) { m_arguments.insert(argument->name(), argument); } void setFunctionBodyScope(BlockScope *functionBodyScope) { m_functionBodyScope = functionBodyScope; } BlockScope *functionBodyScope() const {return m_functionBodyScope;} bool isSignal() const { return m_signal; } void setSignal(bool b) { m_signal = b; } bool isSlot() const { return m_slot; } void setSlot(bool b) { m_slot = b; } bool isVirtual() const { return m_virtual; } void setVirtual(bool b) { m_virtual = b; } bool isAbstract() const { return m_abstract; } void setAbstract(bool b) { m_abstract = b; } private: Type *m_returnType; Collection m_arguments; BlockScope *m_functionBodyScope; uint m_signal: 1; uint m_slot: 1; uint m_virtual: 1; uint m_abstract: 1; }; struct VariableMember: public Member { VariableMember() : m_type(0) {} Type *type() const { return m_type; } void setType(Type *type) { m_type = type; } virtual VariableMember *toVariableMember() const { return const_cast(this); } private: Type *m_type; }; struct UsingDeclarationMember: public Member { UsingDeclarationMember() : m_member(0) {} virtual UsingDeclarationMember *toUsingDeclarationMember() const { return const_cast(this); } Member *member() const { return m_member; } void setMember(Member *member) { m_member = member; } private: Member *m_member; }; struct NamespaceMember: public Member { NamespaceMember() :m_namespaceScope(0) {} virtual NamespaceMember *toNamespaceMember() const { return const_cast(this); } NamespaceScope *namespaceScope() const { return m_namespaceScope; } void setNamespaceScope(NamespaceScope *namespaceScope) { m_namespaceScope = namespaceScope; } private: NamespaceScope *m_namespaceScope; }; struct TypeMember: public Member { TypeMember() :m_type(0) {} virtual TypeMember *toTypeMember() const { return const_cast(this); } Type *type() const { return m_type; } void setType(Type *type) { m_type = type; } private: Type *m_type; }; struct NameUse: public Item { NameUse() : m_declaration(0), m_parent(0) {} QByteArray name() const { return m_name; } void setName(const QByteArray &name) { m_name = name; } TokenEngine::TokenRef nameToken() const { return m_nameToken; } void setNameToken(TokenEngine::TokenRef nameToken) { m_nameToken = nameToken; } Scope *parent() const { return m_parent; } void setParent(Scope *parent) { m_parent = parent; } Member *declaration() const { return m_declaration; } void setDeclaration(Member *parent) { m_declaration = parent; } private: QByteArray m_name; TokenEngine::TokenRef m_nameToken; Member *m_declaration; Scope *m_parent; }; struct UsingDirectiveLink: public Item { UsingDirectiveLink() : m_parent(0), m_targetNamespace(0), m_insertionNamespace(0) {} QByteArray name() const { return QByteArray(); } Scope *parent() const { return m_parent; } void setParent(Scope *parent) { m_parent = parent; } NamespaceScope *targetNamespace() const { return m_targetNamespace; } void setTargetNamespace(NamespaceScope *targetNamespace) { m_targetNamespace = targetNamespace; } NamespaceScope *insertionNamespace() const { return m_insertionNamespace; } void setInsertionNamespace(NamespaceScope *insertionNamespace) { m_insertionNamespace = insertionNamespace; } private: Scope *m_parent; // targetNamespace is the namespace specified by the using directive. NamespaceScope *m_targetNamespace; // m_insertionNamespace is the namespace where the names from // targetNamespace will be inserted. The C++ standard (7.3.4.1) // defines this as the nearest namespace that includes both m_parent // and m_targetNamespace. NamespaceScope *m_insertionNamespace; }; template T *Create(TypedPool *p) { return new (p->allocate(sizeof(T))) T(); } } // namespace CodeModel QT_END_NAMESPACE #endif // CODEMODEL_H